+ 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:
Jonas Maebe 2006-03-10 19:59:44 +00:00
parent 86a15e83e9
commit 9de2847865
11 changed files with 64 additions and 41 deletions

View File

@ -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,

View File

@ -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.

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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
{

View File

@ -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));