-- Aufzeichnung der Informationen für Zusammenführung von r43005 in ».«:

G   .
-- Aufzeichnung der Informationen für Zusammenführung von r43006 in ».«:
 G   .
-- Aufzeichnung der Informationen für Zusammenführung von r43007 in ».«:
 G   .
-- Aufzeichnung der Informationen für Zusammenführung von r43008 in ».«:
 G   .
-- Zusammenführen von r43000 in ».«:
U    compiler/pp.pas
-- Aufzeichnung der Informationen für Zusammenführung von r43000 in ».«:
 G   .
-- Zusammenführen von r43011 in ».«:
U    rtl/inc/system.inc
-- Aufzeichnung der Informationen für Zusammenführung von r43011 in ».«:
 G   .
-- Zusammenführen von r43012 in ».«:
U    rtl/i386/i386.inc
-- Aufzeichnung der Informationen für Zusammenführung von r43012 in ».«:
 G   .
-- Zusammenführen von r43013 in ».«:
U    rtl/linux/i386/si_c21.inc
-- Aufzeichnung der Informationen für Zusammenführung von r43013 in ».«:
 G   .
-- Zusammenführen von r43014 in ».«:
U    compiler/systems/i_linux.pas
-- Aufzeichnung der Informationen für Zusammenführung von r43014 in ».«:
 G   .
-- Zusammenführen von r43176 in ».«:
U    compiler/i386/cpupi.pas
U    compiler/i386/n386cal.pas
U    compiler/ncgcal.pas
U    compiler/ncgutil.pas
G    compiler/systems/i_linux.pas
U    compiler/systems.inc
C    compiler/systems.pas
G    tests/webtbs/tw7808.pp
-- Aufzeichnung der Informationen für Zusammenführung von r43176 in ».«:
 G   .
Konfliktübersicht:
  Textkonflikte: 1
Konfliktübersicht:
  Textkonflikte: 1

git-svn-id: branches/fixes_3_2@43434 -
This commit is contained in:
florian 2019-11-09 22:07:33 +00:00
parent 4fbb2d9cf0
commit 7cdb39b3f9
20 changed files with 121 additions and 56 deletions

View File

@ -334,9 +334,7 @@ unit cgcpu;
end;
{ return from proc }
if (po_interrupt in current_procinfo.procdef.procoptions) and
{ this messes up stack alignment }
(target_info.stackalign=4) then
if po_interrupt in current_procinfo.procdef.procoptions then
begin
if assigned(current_procinfo.procdef.funcretloc[calleeside].location) and
(current_procinfo.procdef.funcretloc[calleeside].location^.loc=LOC_REGISTER) then

View File

@ -423,7 +423,7 @@ unit cpupara;
{ we push Flags and CS as long
to cope with the IRETD
and we save 6 register + 4 selectors }
if po_interrupt in p.procoptions then
if (po_interrupt in p.procoptions) and (side=calleeside) then
inc(parasize,8+6*4+4*2);
{ Offset is calculated like:
sub esp,12

View File

@ -88,10 +88,11 @@ unit cpupi;
procedure tcpuprocinfo.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 paramanager.use_fixed_stack then
{ 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, except
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;
end;

View File

@ -52,7 +52,8 @@ implementation
nbas,nmem,nld,ncnv,
parabase,
symdef,symsym,symcpu,symconst,
cga,cgobj,cpuinfo;
cga,cgobj,cgx86,
cpuinfo;
{*****************************************************************************
@ -104,16 +105,21 @@ implementation
procedure ti386callnode.pop_parasize(pop_size:longint);
var
hreg : tregister;
href : treference;
begin
if (paramanager.use_fixed_stack) then
if paramanager.use_fixed_stack then
begin
{ very weird: in this case the callee does a "ret $4" and the }
{ caller immediately a "subl $4,%esp". Possibly this is for }
{ use_fixed_stack code to be able to transparently call }
{ old-style code (JM) }
dec(pop_size,pushedparasize);
if (pop_size < 0) then
current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_SUB,S_L,-pop_size,NR_ESP));
if pop_size<0 then
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;
end;

View File

@ -1176,25 +1176,40 @@ implementation
end;
{ Need to remove the parameters from the stack? }
if (procdefinition.proccalloption in clearstack_pocalls) then
begin
pop_size:=pushedparasize;
{ for Cdecl functions we don't need to pop the funcret when it
was pushed by para. Except for safecall functions with
safecall-exceptions enabled. In that case the funcret is always
returned as a para which is considered a normal para on the
c-side, so the funcret has to be pop'ed normally. }
if not ((procdefinition.proccalloption=pocall_safecall) and
(tf_safecall_exceptions in target_info.flags)) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition) then
dec(pop_size,sizeof(pint));
{ Remove parameters/alignment from the stack }
pop_parasize(pop_size);
end
if procdefinition.proccalloption in clearstack_pocalls then
begin
pop_size:=pushedparasize;
{ for Cdecl functions we don't need to pop the funcret when it
was pushed by para. Except for safecall functions with
safecall-exceptions enabled. In that case the funcret is always
returned as a para which is considered a normal para on the
c-side, so the funcret has to be pop'ed normally. }
if not ((procdefinition.proccalloption=pocall_safecall) and
(tf_safecall_exceptions in target_info.flags)) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition) then
dec(pop_size,sizeof(pint));
{ Remove parameters/alignment from the stack }
pop_parasize(pop_size);
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
Delphi way }
else if (po_delphi_nested_cc in procdefinition.procoptions) and
not paramanager.use_fixed_stack then
not paramanager.use_fixed_stack then
pop_parasize(sizeof(pint));
{ Release registers, but not the registers that contain the
function result }

View File

@ -1392,9 +1392,9 @@ implementation
else
begin
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 }
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
dec(parasize,sizeof(pint));
end;

View File

@ -4386,6 +4386,8 @@ begin
end;
end;
{$pop}
{ as stackalign is not part of the alignment record, we do not need to define the others alignments for symmetry yet }
set_system_macro('FPC_STACKALIGNMENT',tostr(target_info.stackalign));
option.free;
Option:=nil;

View File

@ -49,6 +49,8 @@ program pp;
EXTDEBUG some extra debug code is executed
EXTERN_MSG Don't compile the msgfiles in the compiler, always
use external messagefiles, default for TP
LLVM Create an LLVM-based code generator for the selected
target architecture (not supported for all targets)
-----------------------------------------------------------------
ARM specfic switches

View File

@ -316,6 +316,7 @@
,abi_eabi,abi_armeb,abi_eabihf
,abi_old_win32_gnu
,abi_aarch64_darwin
,abi_linux386_sysv
);
const

View File

@ -220,7 +220,7 @@ interface
end;
tabiinfo = record
name: string[11];
name: string[13];
supported: boolean;
end;
@ -411,7 +411,8 @@ interface
(name: 'ARMEB' ; supported:{$ifdef FPC_ARMEB}true{$else}false{$endif}),
(name: 'EABIHF' ; supported:{$ifdef FPC_ARMHF}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: 'LINUX386_SYSV'; supported:{$if defined(i386)}true{$else}false{$endif})
);
var

View File

@ -93,8 +93,8 @@ unit i_linux;
);
first_parm_offset : 8;
stacksize : 8*1024*1024;
stackalign : 4;
abi : abi_default;
stackalign : 16;
abi : abi_linux386_sysv;
{ 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';
);

View File

@ -3315,6 +3315,7 @@ unit cgx86;
end;
begin
stackmisalignment:=0;
{$ifdef i8086}
{ Win16 callback/exported proc prologue support.
Since callbacks can be called from different modules, DS on entry may be
@ -3415,9 +3416,7 @@ unit cgx86;
{$endif i8086}
{$ifdef i386}
{ interrupt support for i386 }
if (po_interrupt in current_procinfo.procdef.procoptions) and
{ this messes up stack alignment }
not(target_info.system in [system_i386_darwin,system_i386_iphonesim,system_i386_android]) then
if (po_interrupt in current_procinfo.procdef.procoptions) then
begin
{ .... also the segment registers }
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_GS));
@ -3431,6 +3430,7 @@ unit cgx86;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_ECX));
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EBX));
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EAX));
inc(stackmisalignment,4*2+6*8);
end;
{$endif i386}
@ -3438,7 +3438,7 @@ unit cgx86;
if not nostackframe then
begin
{ return address }
stackmisalignment := sizeof(pint);
inc(stackmisalignment,sizeof(pint));
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil));
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
begin

View File

@ -14,6 +14,10 @@
**********************************************************************}
{$if not(defined(VER3_0)) and defined(linux)}
{$define FPC_SYSTEM_STACKALIGNMENT16}
{$endif not(defined(VER3_0)) and defined(linux)}
{****************************************************************************
Primitives
****************************************************************************}
@ -1433,7 +1437,15 @@ asm
je .Lj3596
.Lj3620:
movl %esi,%eax
{ freemem is not an assembler leaf function like fpc_geteipasebx and cpudeclocked, so it
needs to be called with proper stack alignment }
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal -8(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
call FPC_FREEMEM
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal 8(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
.Lj3596:
popl %esi
.Lquit:
@ -1459,7 +1471,13 @@ asm
je .Lj4038
// [441] result:=fpc_truely_ansistr_unique(s);
movl %edx,%eax
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal -12(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
call fpc_truely_ansistr_unique
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal 12(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
.Lj4038:
.Lj4031:
// [442] end;

View File

@ -888,15 +888,25 @@ begin
{ Avoid recursive calls when called from the exit routines }
if StackError then
exit;
{ don't use sack_size, since the stack pointer has already been
{ check stack alignment }
{$ifdef CPUI386}
{$ifdef FPC_STACKALIGNMENT=16}
if ((PtrUInt(Sptr)+4) mod 16)<>0 then
begin
StackError:=true;
HandleError(202);
end;
{$endif FPC_STACKALIGNMENT=16}
{$endif CPUI386}
{ don't use stack_size, since the stack pointer has already been
decreased when this routine is called
}
c := Sptr - STACK_MARGIN;
if (c <= StackBottom) then
begin
StackError:=true;
HandleError(202);
end;
begin
StackError:=true;
HandleError(202);
end;
end;
{$POP}

View File

@ -103,9 +103,11 @@ asm
hlt
end;
procedure _FPC_libc21_haltproc(e: longint); cdecl; assembler; public name '_haltproc';
asm
push e
call libc_exit
hlt
end;
procedure _FPC_libc21_haltproc(e: longint); cdecl; public name '_haltproc';
begin
libc_exit(e);
{ we should never return from libc_exit }
asm
hlt
end;
end;

View File

@ -90,7 +90,7 @@ const
);
procedure test1; assembler;
procedure test1; nostackframe; assembler;
asm
test [edi+foo2], cval { test word ptr [edi], 1 }
test byte ptr [edi+foo], cval { test byte ptr [edi], 1 }
@ -142,7 +142,7 @@ asm
test word ptr [edi+foo32_2.l], cval { test word ptr [edi+1], 1 }
end;
procedure test2; assembler;
procedure test2; nostackframe; assembler;
asm
test [edi+foo32], cval { test dword ptr [edi], 1 }
test [edi+foo32_2.l], cval { test dword ptr [edi+1], 1 }

View File

@ -7,14 +7,14 @@ program tasm23a;
const
t_size = 19;
procedure t; assembler;
procedure t; nostackframe; assembler;
asm
mov eax, [ebx[5]][edi][54][-17][45][4] { mov eax, [ebx+edi+5Bh] }
mov eax, [[ebx+5]+[edi+54]+[-17]+[45]+[4]] { mov eax, [ebx+edi+5Bh] }
mov eax, [5[7]] { mov eax, [000Ch] }
mov eax, [5+[7]] { mov eax, [000Ch] }
end;
procedure t_verify; assembler;
procedure t_verify; nostackframe; assembler;
asm
mov eax, [ebx+edi+5Bh] { mov eax, [ebx[5]][edi][54][-17][45][4] }
mov eax, [ebx+edi+5Bh] { mov eax, [[ebx+5]+[edi+54]+[-17]+[45]+[4]] }

View File

@ -1,5 +1,5 @@
{ %cpu=i386 }
{ %target=win32,linux,freebsd,haiku }
{ %target=win32,freebsd,haiku }
{$ifdef fpc}
{$mode delphi}

View File

@ -2,6 +2,9 @@
{ %target=go32v2,linux,freebsd,win32,haiku}
{ %opt=-Sew -vw }
{ do not warn about the lea esp,[esp+16] }
{$WARN 7105 OFF}
{$mode delphi}
procedure test(l: longint); stdcall;
@ -12,8 +15,14 @@ end;
begin
asm
{$if FPC_STACKALIGNMENT=16}
lea esp,[esp-12]
{$endif FPC_STACKALIGNMENT=16}
push word $dead
push word $beef
call test
call test
{$if FPC_STACKALIGNMENT=16}
lea esp,[esp-4]
{$endif FPC_STACKALIGNMENT=16}
end;
end.

View File

@ -1,5 +1,5 @@
{ %cpu=i386 }
{ %target=win32,linux,freebsd,haiku }
{ %target=win32,freebsd,haiku }
{$ifdef fpc}
{$mode delphi}