mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:29:28 +02:00
+ support for passing parameters via pre-allocated stack space on i386
(override/adjust cgutils.use_fixed_stack to change conditions where this is done, currently only activated for darwin-i386) * make sure the stack is always aligned to 16 bytes on darwin-i386 git-svn-id: trunk@2840 -
This commit is contained in:
parent
86a15e83e9
commit
9de2847865
@ -37,7 +37,6 @@ unit cpupi;
|
||||
// procedure handle_body_start;override;
|
||||
// procedure after_pass1;override;
|
||||
procedure set_first_temp_offset;override;
|
||||
procedure allocate_push_parasize(size: longint);override;
|
||||
function calc_stackframe_size:longint;override;
|
||||
end;
|
||||
|
||||
@ -67,13 +66,6 @@ unit cpupi;
|
||||
end;
|
||||
|
||||
|
||||
procedure tarmprocinfo.allocate_push_parasize(size:longint);
|
||||
begin
|
||||
if size>maxpushedparasize then
|
||||
maxpushedparasize:=size;
|
||||
end;
|
||||
|
||||
|
||||
function tarmprocinfo.calc_stackframe_size:longint;
|
||||
var
|
||||
firstfloatreg,lastfloatreg,
|
||||
|
@ -113,8 +113,15 @@ unit cgutils;
|
||||
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
||||
procedure location_swap(var destloc,sourceloc : tlocation);
|
||||
|
||||
|
||||
{ allocate room for parameters on the stack in the entry code? }
|
||||
function use_fixed_stack: boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
systems;
|
||||
|
||||
{****************************************************************************
|
||||
TReference
|
||||
****************************************************************************}
|
||||
@ -182,5 +189,13 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function use_fixed_stack: boolean;
|
||||
begin
|
||||
{$ifdef i386}
|
||||
result := (target_info.system = system_i386_darwin);
|
||||
{$else i386}
|
||||
result := false;
|
||||
{$endif i386}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -71,7 +71,8 @@ unit cgcpu;
|
||||
|
||||
function use_push(const cgpara:tcgpara):boolean;
|
||||
begin
|
||||
result:=assigned(cgpara.location) and
|
||||
result:=(not use_fixed_stack) and
|
||||
assigned(cgpara.location) and
|
||||
(cgpara.location^.loc=LOC_REFERENCE) and
|
||||
(cgpara.location^.reference.index=NR_STACK_POINTER_REG);
|
||||
end;
|
||||
@ -295,7 +296,8 @@ unit cgcpu;
|
||||
list.concat(Taicpu.Op_none(A_IRET,S_NO));
|
||||
end
|
||||
{ Routines with the poclearstack flag set use only a ret }
|
||||
else if current_procinfo.procdef.proccalloption in clearstack_pocalls then
|
||||
else if (current_procinfo.procdef.proccalloption in clearstack_pocalls) and
|
||||
(not use_fixed_stack) then
|
||||
begin
|
||||
{ complex return values are removed from stack in C code PM }
|
||||
if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,
|
||||
|
@ -396,7 +396,8 @@ unit cpupara;
|
||||
hp.paraloc[side].intsize:=paralen;
|
||||
hp.paraloc[side].Alignment:=paraalign;
|
||||
{ Copy to stack? }
|
||||
if paracgsize=OS_NO then
|
||||
if (paracgsize=OS_NO) or
|
||||
(use_fixed_stack) then
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
@ -406,6 +407,13 @@ unit cpupara;
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
|
||||
{ don't let push_size return 16, because then we can }
|
||||
{ read past the end of the heap since the value is only }
|
||||
{ 10 bytes long (JM) }
|
||||
if (paracgsize = OS_F80) and
|
||||
(target_info.system = system_i386_darwin) then
|
||||
paralen:=16;
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if side=calleeside then
|
||||
inc(paraloc^.reference.offset,target_info.first_parm_offset);
|
||||
@ -509,7 +517,8 @@ unit cpupara;
|
||||
else
|
||||
begin
|
||||
{ Copy to stack? }
|
||||
if paracgsize=OS_NO then
|
||||
if (use_fixed_stack) or
|
||||
(paracgsize=OS_NO) then
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
|
@ -34,6 +34,7 @@ unit cpupi;
|
||||
ti386procinfo = class(tcgprocinfo)
|
||||
constructor create(aparent:tprocinfo);override;
|
||||
function calc_stackframe_size:longint;override;
|
||||
procedure generate_parameter_info;override;
|
||||
end;
|
||||
|
||||
|
||||
@ -43,7 +44,8 @@ unit cpupi;
|
||||
cutils,
|
||||
systems,globals,
|
||||
tgobj,
|
||||
cpubase;
|
||||
cpubase,
|
||||
cgutils;
|
||||
|
||||
constructor ti386procinfo.create(aparent:tprocinfo);
|
||||
begin
|
||||
@ -59,10 +61,20 @@ unit cpupi;
|
||||
if (target_info.system <> system_i386_darwin) then
|
||||
result:=Align(tg.direction*tg.lasttemp,min(aktalignment.localalignmin,4))
|
||||
else
|
||||
result:=Align(tg.direction*tg.lasttemp,min(aktalignment.localalignmin,16));
|
||||
result:=tg.direction*tg.lasttemp+maxpushedparasize;
|
||||
end;
|
||||
|
||||
|
||||
procedure ti386procinfo.generate_parameter_info;
|
||||
begin
|
||||
inherited generate_parameter_info;
|
||||
{ Para_stack_size is only used to determine how many bytes to remove }
|
||||
{ from the stack at the end of the procedure (in the "ret $xx"). }
|
||||
{ If the stack is fixed, nothing has to be removed by the callee }
|
||||
if use_fixed_stack then
|
||||
para_stack_size := 0;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
cprocinfo:=ti386procinfo;
|
||||
|
@ -43,7 +43,7 @@ implementation
|
||||
uses
|
||||
globtype,systems,
|
||||
cutils,verbose,globals,
|
||||
cgbase,
|
||||
cgbase,cgutils,
|
||||
cpubase,paramgr,
|
||||
aasmtai,aasmcpu,
|
||||
ncal,nbas,nmem,nld,ncnv,
|
||||
@ -66,6 +66,8 @@ implementation
|
||||
var
|
||||
hreg : tregister;
|
||||
begin
|
||||
if (use_fixed_stack) then
|
||||
exit;
|
||||
{ better than an add on all processors }
|
||||
if pop_size=4 then
|
||||
begin
|
||||
|
@ -66,7 +66,6 @@ unit cpupi;
|
||||
|
||||
begin
|
||||
inherited create(aparent);
|
||||
maxpushedparasize:=0;
|
||||
first_save_int_reg:=32;
|
||||
first_save_fpu_reg:=32;
|
||||
needs_frame_pointer:=false;
|
||||
@ -126,13 +125,6 @@ unit cpupi;
|
||||
*)
|
||||
|
||||
|
||||
procedure tppcprocinfo.allocate_push_parasize(size:longint);
|
||||
begin
|
||||
if size>maxpushedparasize then
|
||||
maxpushedparasize:=size;
|
||||
end;
|
||||
|
||||
|
||||
function tppcprocinfo.uses_stack_temps: boolean;
|
||||
begin
|
||||
result := tg.firsttemp <> tg.lasttemp;
|
||||
|
@ -37,7 +37,6 @@ type
|
||||
parent_framepointer_offset: longint;
|
||||
constructor create(aparent: tprocinfo); override;
|
||||
procedure set_first_temp_offset; override;
|
||||
procedure allocate_push_parasize(size: longint); override;
|
||||
function calc_stackframe_size: longint; override;
|
||||
function calc_stackframe_size(numgpr, numfpr : longint): longint;
|
||||
|
||||
@ -87,12 +86,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tppcprocinfo.allocate_push_parasize(size: longint);
|
||||
begin
|
||||
if size > maxpushedparasize then
|
||||
maxpushedparasize := size;
|
||||
end;
|
||||
|
||||
function tppcprocinfo.calc_stackframe_size: longint;
|
||||
begin
|
||||
result := calc_stackframe_size(18, 18);
|
||||
|
@ -99,7 +99,7 @@ unit procinfo;
|
||||
constructor create(aparent:tprocinfo);virtual;
|
||||
destructor destroy;override;
|
||||
|
||||
procedure allocate_push_parasize(size:longint);virtual;
|
||||
procedure allocate_push_parasize(size:longint);
|
||||
|
||||
function calc_stackframe_size:longint;virtual;
|
||||
|
||||
@ -146,6 +146,7 @@ implementation
|
||||
{ labels }
|
||||
objectlibrary.getjumplabel(aktexitlabel);
|
||||
objectlibrary.getjumplabel(gotlabel);
|
||||
maxpushedparasize:=0;
|
||||
end;
|
||||
|
||||
|
||||
@ -158,6 +159,8 @@ implementation
|
||||
|
||||
procedure tprocinfo.allocate_push_parasize(size:longint);
|
||||
begin
|
||||
if size>maxpushedparasize then
|
||||
maxpushedparasize:=size;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -34,7 +34,6 @@ interface
|
||||
TSparcProcInfo=class(tcgprocinfo)
|
||||
public
|
||||
constructor create(aparent:tprocinfo);override;
|
||||
procedure allocate_push_parasize(size:longint);override;
|
||||
function calc_stackframe_size:longint;override;
|
||||
end;
|
||||
|
||||
@ -51,13 +50,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tsparcprocinfo.allocate_push_parasize(size:longint);
|
||||
begin
|
||||
if size>maxpushedparasize then
|
||||
maxpushedparasize:=size;
|
||||
end;
|
||||
|
||||
|
||||
function TSparcProcInfo.calc_stackframe_size:longint;
|
||||
begin
|
||||
{
|
||||
|
@ -557,8 +557,8 @@ unit cgx86;
|
||||
|
||||
asmlist[al_imports].concat(Tai_section.create(sec_stub,'',0));
|
||||
result := objectlibrary.newasmsymbol(stubname,AB_EXTERNAL,AT_FUNCTION);
|
||||
asmlist[al_imports].concat(tai_directive.create(asd_indirect_symbol,s));
|
||||
asmlist[al_imports].concat(Tai_symbol.Create(result,0));
|
||||
asmlist[al_imports].concat(tai_directive.create(asd_indirect_symbol,s));
|
||||
asmlist[al_imports].concat(taicpu.op_none(A_HLT));
|
||||
asmlist[al_imports].concat(taicpu.op_none(A_HLT));
|
||||
asmlist[al_imports].concat(taicpu.op_none(A_HLT));
|
||||
@ -1857,6 +1857,8 @@ unit cgx86;
|
||||
|
||||
|
||||
procedure tcgx86.g_proc_entry(list : taasmoutput;localsize : longint;nostackframe:boolean);
|
||||
var
|
||||
stackmisalignment: longint;
|
||||
begin
|
||||
{$ifdef i386}
|
||||
{ interrupt support for i386 }
|
||||
@ -1880,11 +1882,15 @@ unit cgx86;
|
||||
{ save old framepointer }
|
||||
if not nostackframe then
|
||||
begin
|
||||
{ return address }
|
||||
stackmisalignment := sizeof(aint);
|
||||
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil));
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
CGmessage(cg_d_stackframe_omited)
|
||||
else
|
||||
begin
|
||||
{ push <frame_pointer> }
|
||||
inc(stackmisalignment,sizeof(aint));
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
|
||||
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||
{ Return address and FP are both on stack }
|
||||
@ -1895,8 +1901,13 @@ unit cgx86;
|
||||
end;
|
||||
|
||||
{ allocate stackframe space }
|
||||
if localsize<>0 then
|
||||
if (localsize<>0) or
|
||||
((target_info.system = system_i386_darwin) and
|
||||
(stackmisalignment <> 0) and
|
||||
(pi_do_call in current_procinfo.flags)) then
|
||||
begin
|
||||
if (target_info.system = system_i386_darwin) then
|
||||
localsize := align(localsize+stackmisalignment,16)-stackmisalignment;
|
||||
cg.g_stackpointer_alloc(list,localsize);
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
dwarfcfi.cfa_def_cfa_offset(list,localsize+sizeof(aint));
|
||||
|
Loading…
Reference in New Issue
Block a user