mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-05 03:30:33 +02:00
* adapted 16 byte alignment handling on linux: it is now assumed that the callee tries to clear the stack, so in the caller, the stack is re-adjusted
git-svn-id: trunk@43176 -
This commit is contained in:
parent
67fc9a7853
commit
fb91899457
@ -88,10 +88,11 @@ unit cpupi;
|
|||||||
procedure tcpuprocinfo.generate_parameter_info;
|
procedure tcpuprocinfo.generate_parameter_info;
|
||||||
begin
|
begin
|
||||||
inherited generate_parameter_info;
|
inherited generate_parameter_info;
|
||||||
{ Para_stack_size is only used to determine how many bytes to remove }
|
{ 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"). }
|
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 the stack is fixed, nothing has to be removed by the callee, except
|
||||||
if paramanager.use_fixed_stack then
|
if a 16 byte aligned stack on i386-linux is used }
|
||||||
|
if paramanager.use_fixed_stack and not(target_info.abi=abi_linux386_sysv) then
|
||||||
para_stack_size := 0;
|
para_stack_size := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ implementation
|
|||||||
nbas,nmem,nld,ncnv,
|
nbas,nmem,nld,ncnv,
|
||||||
parabase,
|
parabase,
|
||||||
symdef,symsym,symcpu,symconst,
|
symdef,symsym,symcpu,symconst,
|
||||||
cga,cgobj,cpuinfo;
|
cga,cgobj,cgx86,
|
||||||
|
cpuinfo;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
@ -104,16 +105,21 @@ implementation
|
|||||||
procedure ti386callnode.pop_parasize(pop_size:longint);
|
procedure ti386callnode.pop_parasize(pop_size:longint);
|
||||||
var
|
var
|
||||||
hreg : tregister;
|
hreg : tregister;
|
||||||
|
href : treference;
|
||||||
begin
|
begin
|
||||||
if (paramanager.use_fixed_stack) then
|
if paramanager.use_fixed_stack then
|
||||||
begin
|
begin
|
||||||
{ very weird: in this case the callee does a "ret $4" and the }
|
{ very weird: in this case the callee does a "ret $4" and the }
|
||||||
{ caller immediately a "subl $4,%esp". Possibly this is for }
|
{ caller immediately a "subl $4,%esp". Possibly this is for }
|
||||||
{ use_fixed_stack code to be able to transparently call }
|
{ use_fixed_stack code to be able to transparently call }
|
||||||
{ old-style code (JM) }
|
{ old-style code (JM) }
|
||||||
dec(pop_size,pushedparasize);
|
dec(pop_size,pushedparasize);
|
||||||
if (pop_size < 0) then
|
if pop_size<0 then
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_SUB,S_L,-pop_size,NR_ESP));
|
begin
|
||||||
|
reference_reset_base(href,NR_STACK_POINTER_REG,pop_size,ctempposinvalid,0,[]);
|
||||||
|
{ it is better to use lea here }
|
||||||
|
current_asmdata.CurrAsmList.concat(Taicpu.op_ref_reg(A_LEA,TCGSize2OpSize[OS_ADDR],href,NR_ESP));
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1187,7 +1187,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ Need to remove the parameters from the stack? }
|
{ Need to remove the parameters from the stack? }
|
||||||
if (procdefinition.proccalloption in clearstack_pocalls) then
|
if procdefinition.proccalloption in clearstack_pocalls then
|
||||||
begin
|
begin
|
||||||
pop_size:=pushedparasize;
|
pop_size:=pushedparasize;
|
||||||
{ for Cdecl functions we don't need to pop the funcret when it
|
{ for Cdecl functions we don't need to pop the funcret when it
|
||||||
@ -1202,6 +1202,21 @@ implementation
|
|||||||
{ Remove parameters/alignment from the stack }
|
{ Remove parameters/alignment from the stack }
|
||||||
pop_parasize(pop_size);
|
pop_parasize(pop_size);
|
||||||
end
|
end
|
||||||
|
{ in case we use a fixed stack, we did not push anything, if the stack is
|
||||||
|
really adjusted because a ret xxx was done, depends on
|
||||||
|
pop_parasize which uses pushedparasize to determine this
|
||||||
|
|
||||||
|
This does not apply to interrupt procedures, their ret statment never clears any stack parameters }
|
||||||
|
else if paramanager.use_fixed_stack and not(po_interrupt in procdefinition.procoptions) then
|
||||||
|
begin
|
||||||
|
{ however, a delphi style frame pointer for a nested subroutine
|
||||||
|
is not cleared by the callee, so we have to compensate for this
|
||||||
|
by passing 4 as pushedparasize does include it }
|
||||||
|
if po_delphi_nested_cc in procdefinition.procoptions then
|
||||||
|
pop_parasize(sizeof(pint))
|
||||||
|
else
|
||||||
|
pop_parasize(0);
|
||||||
|
end
|
||||||
{ frame pointer parameter is popped by the caller when it's passed the
|
{ frame pointer parameter is popped by the caller when it's passed the
|
||||||
Delphi way }
|
Delphi way }
|
||||||
else if (po_delphi_nested_cc in procdefinition.procoptions) and
|
else if (po_delphi_nested_cc in procdefinition.procoptions) and
|
||||||
|
@ -775,9 +775,9 @@ implementation
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
parasize:=current_procinfo.para_stack_size;
|
parasize:=current_procinfo.para_stack_size;
|
||||||
{ the parent frame pointer para has to be removed by the caller in
|
{ the parent frame pointer para has to be removed always by the caller in
|
||||||
case of Delphi-style parent frame pointer passing }
|
case of Delphi-style parent frame pointer passing }
|
||||||
if not paramanager.use_fixed_stack and
|
if (not(paramanager.use_fixed_stack) or (target_info.abi=abi_linux386_sysv)) and
|
||||||
(po_delphi_nested_cc in current_procinfo.procdef.procoptions) then
|
(po_delphi_nested_cc in current_procinfo.procdef.procoptions) then
|
||||||
dec(parasize,sizeof(pint));
|
dec(parasize,sizeof(pint));
|
||||||
end;
|
end;
|
||||||
|
@ -321,6 +321,7 @@
|
|||||||
,abi_old_win32_gnu
|
,abi_old_win32_gnu
|
||||||
,abi_aarch64_darwin
|
,abi_aarch64_darwin
|
||||||
,abi_riscv_hf
|
,abi_riscv_hf
|
||||||
|
,abi_linux386_sysv
|
||||||
);
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -239,7 +239,7 @@ interface
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
tabiinfo = record
|
tabiinfo = record
|
||||||
name: string[11];
|
name: string[13];
|
||||||
supported: boolean;
|
supported: boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -433,7 +433,8 @@ interface
|
|||||||
(name: 'EABIHF' ; supported:{$ifdef FPC_ARMHF}true{$else}false{$endif}),
|
(name: 'EABIHF' ; supported:{$ifdef FPC_ARMHF}true{$else}false{$endif}),
|
||||||
(name: 'OLDWIN32GNU'; supported:{$ifdef I386}true{$else}false{$endif}),
|
(name: 'OLDWIN32GNU'; supported:{$ifdef I386}true{$else}false{$endif}),
|
||||||
(name: 'AARCH64IOS'; supported:{$ifdef aarch64}true{$else}false{$endif}),
|
(name: 'AARCH64IOS'; supported:{$ifdef aarch64}true{$else}false{$endif}),
|
||||||
(name: 'RISCVHF'; supported:{$if defined(riscv32) or defined(riscv64)}true{$else}false{$endif})
|
(name: 'RISCVHF'; supported:{$if defined(riscv32) or defined(riscv64)}true{$else}false{$endif}),
|
||||||
|
(name: 'LINUX386_SYSV'; supported:{$if defined(i386)}true{$else}false{$endif})
|
||||||
);
|
);
|
||||||
|
|
||||||
{ x86 asm modes with an Intel-style syntax }
|
{ x86 asm modes with an Intel-style syntax }
|
||||||
|
@ -101,7 +101,7 @@ unit i_linux;
|
|||||||
first_parm_offset : 8;
|
first_parm_offset : 8;
|
||||||
stacksize : 8*1024*1024;
|
stacksize : 8*1024*1024;
|
||||||
stackalign : 16;
|
stackalign : 16;
|
||||||
abi : abi_default;
|
abi : abi_linux386_sysv;
|
||||||
{ note: default LLVM stack alignment is 16 bytes for this target }
|
{ note: default LLVM stack alignment is 16 bytes for this target }
|
||||||
llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32';
|
llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32';
|
||||||
);
|
);
|
||||||
|
@ -22,7 +22,7 @@ begin
|
|||||||
push word $beef
|
push word $beef
|
||||||
call test
|
call test
|
||||||
{$if FPC_STACKALIGNMENT=16}
|
{$if FPC_STACKALIGNMENT=16}
|
||||||
lea esp,[esp+16]
|
lea esp,[esp-4]
|
||||||
{$endif FPC_STACKALIGNMENT=16}
|
{$endif FPC_STACKALIGNMENT=16}
|
||||||
end;
|
end;
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user