mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 06:29:16 +02:00
+ no stackframe is generated for i386 if possible
git-svn-id: trunk@2162 -
This commit is contained in:
parent
a85bb43749
commit
f7d2c47f73
@ -240,7 +240,9 @@ than 255 characters. That's why using Ansi Strings}
|
|||||||
pi_needs_got,
|
pi_needs_got,
|
||||||
{ references var/proc/type/const in static symtable,
|
{ references var/proc/type/const in static symtable,
|
||||||
i.e. not allowed for inlining from other units }
|
i.e. not allowed for inlining from other units }
|
||||||
pi_uses_static_symtable
|
pi_uses_static_symtable,
|
||||||
|
{ set if the procedure has to push parameters onto the stack }
|
||||||
|
pi_has_stackparameter
|
||||||
);
|
);
|
||||||
tprocinfoflags=set of tprocinfoflag;
|
tprocinfoflags=set of tprocinfoflag;
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ unit cgcpu;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
list.concat(Taicpu.op_none(A_LEAVE,S_NO));
|
list.concat(Taicpu.op_none(A_LEAVE,S_NO));
|
||||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
|
list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ return from proc }
|
{ return from proc }
|
||||||
|
@ -130,6 +130,9 @@ interface
|
|||||||
procedure printnodedata(var t:text);override;
|
procedure printnodedata(var t:text);override;
|
||||||
function para_count:longint;
|
function para_count:longint;
|
||||||
function get_load_methodpointer:tnode;
|
function get_load_methodpointer:tnode;
|
||||||
|
{ checks if there are any parameters which end up at the stack, i.e.
|
||||||
|
which have LOC_REFERENCE and set pi_has_stackparameter if this applies }
|
||||||
|
procedure check_stack_parameters;
|
||||||
private
|
private
|
||||||
AbstractMethodsList : TStringList;
|
AbstractMethodsList : TStringList;
|
||||||
end;
|
end;
|
||||||
@ -2333,6 +2336,22 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcallnode.check_stack_parameters;
|
||||||
|
var
|
||||||
|
hp : tcallparanode;
|
||||||
|
begin
|
||||||
|
hp:=tcallparanode(left);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
if assigned(hp.parasym) and
|
||||||
|
assigned(hp.parasym.paraloc[callerside].location) and
|
||||||
|
(hp.parasym.paraloc[callerside].location^.loc=LOC_REFERENCE) then
|
||||||
|
include(current_procinfo.flags,pi_has_stackparameter);
|
||||||
|
hp:=tcallparanode(hp.right);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tcallnode.pass_1 : tnode;
|
function tcallnode.pass_1 : tnode;
|
||||||
var
|
var
|
||||||
st : tsymtable;
|
st : tsymtable;
|
||||||
@ -2378,7 +2397,16 @@ type
|
|||||||
|
|
||||||
{ work trough all parameters to get the register requirements }
|
{ work trough all parameters to get the register requirements }
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
tcallparanode(left).det_registers;
|
begin
|
||||||
|
tcallparanode(left).det_registers;
|
||||||
|
|
||||||
|
if cs_optimize in aktglobalswitches then
|
||||||
|
begin
|
||||||
|
{ check for stacked parameters }
|
||||||
|
check_stack_parameters;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ order parameters }
|
{ order parameters }
|
||||||
order_parameters;
|
order_parameters;
|
||||||
|
@ -54,6 +54,8 @@ interface
|
|||||||
procedure add_to_symtablestack;
|
procedure add_to_symtablestack;
|
||||||
procedure remove_from_symtablestack;
|
procedure remove_from_symtablestack;
|
||||||
procedure parse_body;
|
procedure parse_body;
|
||||||
|
|
||||||
|
function stack_tainting_parameter : boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ implementation
|
|||||||
scanner,import,gendef,
|
scanner,import,gendef,
|
||||||
pbase,pstatmnt,pdecl,pdecsub,pexports,
|
pbase,pstatmnt,pdecl,pdecsub,pexports,
|
||||||
{ codegen }
|
{ codegen }
|
||||||
tgobj,cgobj,dbgbase,
|
tgobj,cgbase,cgobj,dbgbase,
|
||||||
ncgutil,regvars
|
ncgutil,regvars
|
||||||
{$if defined(arm) or defined(powerpc) or defined(powerpc64)}
|
{$if defined(arm) or defined(powerpc) or defined(powerpc64)}
|
||||||
,aasmcpu
|
,aasmcpu
|
||||||
@ -604,6 +606,29 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure check_for_stack(p : tnamedindexitem;arg:pointer);
|
||||||
|
begin
|
||||||
|
if tsym(p).typ=paravarsym then
|
||||||
|
begin
|
||||||
|
{ check if there no parameter of the current procedure is stack dependend }
|
||||||
|
if is_open_array(tparavarsym(p).vartype.def) or
|
||||||
|
is_array_of_const(tparavarsym(p).vartype.def) then
|
||||||
|
pboolean(arg)^:=true;
|
||||||
|
if assigned(p) and
|
||||||
|
assigned(tparavarsym(p).paraloc[calleeside].location) and
|
||||||
|
(tparavarsym(p).paraloc[calleeside].location^.loc=LOC_REFERENCE) then
|
||||||
|
pboolean(arg)^:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgprocinfo.stack_tainting_parameter : boolean;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
procdef.parast.foreach_static(@check_for_stack,@result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgprocinfo.generate_code;
|
procedure tcgprocinfo.generate_code;
|
||||||
var
|
var
|
||||||
oldprocinfo : tprocinfo;
|
oldprocinfo : tprocinfo;
|
||||||
@ -680,6 +705,38 @@ implementation
|
|||||||
{ set the start offset to the start of the temp area in the stack }
|
{ set the start offset to the start of the temp area in the stack }
|
||||||
tg:=ttgobj.create;
|
tg:=ttgobj.create;
|
||||||
|
|
||||||
|
{$ifdef i386}
|
||||||
|
{ try to strip the stack frame }
|
||||||
|
{ set the framepointer to esp if:
|
||||||
|
- no assembler directive, those are handled elsewhere
|
||||||
|
- no exceptions are used
|
||||||
|
- no debug info
|
||||||
|
- no pushes are used/esp modifications, could be:
|
||||||
|
* outgoing parameters on the stack
|
||||||
|
* incoming parameters on the stack
|
||||||
|
* open arrays
|
||||||
|
- no inline assembler
|
||||||
|
}
|
||||||
|
if (cs_optimize in aktglobalswitches) and
|
||||||
|
not(po_assembler in procdef.procoptions) and
|
||||||
|
((flags*[pi_has_assembler_block,pi_uses_exceptions,pi_is_assembler,
|
||||||
|
pi_needs_implicit_finally,pi_has_implicit_finally,pi_has_stackparameter])=[]) then
|
||||||
|
begin
|
||||||
|
{ we need the parameter info here to determine if the procedure gets
|
||||||
|
parameters on the stack
|
||||||
|
|
||||||
|
calling generate_parameter_info doesn't hurt but it costs time
|
||||||
|
}
|
||||||
|
generate_parameter_info;
|
||||||
|
if not(stack_tainting_parameter) then
|
||||||
|
begin
|
||||||
|
{ Only need to set the framepointer }
|
||||||
|
framepointer:=NR_STACK_POINTER_REG;
|
||||||
|
tg.direction:=1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{$endif i386}
|
||||||
|
|
||||||
{ Create register allocator }
|
{ Create register allocator }
|
||||||
cg.init_register_allocators;
|
cg.init_register_allocators;
|
||||||
|
|
||||||
@ -713,6 +770,7 @@ implementation
|
|||||||
procdef.has_paraloc_info:=true;
|
procdef.has_paraloc_info:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ generate code for the node tree }
|
{ generate code for the node tree }
|
||||||
do_secondpass(code);
|
do_secondpass(code);
|
||||||
aktproccode.concatlist(exprasmlist);
|
aktproccode.concatlist(exprasmlist);
|
||||||
|
@ -1839,11 +1839,12 @@ unit cgx86;
|
|||||||
{ save old framepointer }
|
{ save old framepointer }
|
||||||
if not nostackframe then
|
if not nostackframe then
|
||||||
begin
|
begin
|
||||||
|
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil));
|
||||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||||
CGmessage(cg_d_stackframe_omited)
|
CGmessage(cg_d_stackframe_omited)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG,nil));
|
|
||||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
|
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));
|
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||||
{ Return address and FP are both on stack }
|
{ Return address and FP are both on stack }
|
||||||
|
Loading…
Reference in New Issue
Block a user