-- 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; end;
{ return from proc } { return from proc }
if (po_interrupt in current_procinfo.procdef.procoptions) and if po_interrupt in current_procinfo.procdef.procoptions then
{ this messes up stack alignment }
(target_info.stackalign=4) then
begin begin
if assigned(current_procinfo.procdef.funcretloc[calleeside].location) and if assigned(current_procinfo.procdef.funcretloc[calleeside].location) and
(current_procinfo.procdef.funcretloc[calleeside].location^.loc=LOC_REGISTER) then (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 { we push Flags and CS as long
to cope with the IRETD to cope with the IRETD
and we save 6 register + 4 selectors } 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); inc(parasize,8+6*4+4*2);
{ Offset is calculated like: { Offset is calculated like:
sub esp,12 sub esp,12

View File

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

View File

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

View File

@ -1176,25 +1176,40 @@ 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
was pushed by para. Except for safecall functions with was pushed by para. Except for safecall functions with
safecall-exceptions enabled. In that case the funcret is always safecall-exceptions enabled. In that case the funcret is always
returned as a para which is considered a normal para on the returned as a para which is considered a normal para on the
c-side, so the funcret has to be pop'ed normally. } c-side, so the funcret has to be pop'ed normally. }
if not ((procdefinition.proccalloption=pocall_safecall) and if not ((procdefinition.proccalloption=pocall_safecall) and
(tf_safecall_exceptions in target_info.flags)) and (tf_safecall_exceptions in target_info.flags)) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition) then paramanager.ret_in_param(procdefinition.returndef,procdefinition) then
dec(pop_size,sizeof(pint)); dec(pop_size,sizeof(pint));
{ 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
not paramanager.use_fixed_stack then not paramanager.use_fixed_stack then
pop_parasize(sizeof(pint)); pop_parasize(sizeof(pint));
{ Release registers, but not the registers that contain the { Release registers, but not the registers that contain the
function result } function result }

View File

@ -1392,9 +1392,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;

View File

@ -4386,6 +4386,8 @@ begin
end; end;
end; end;
{$pop} {$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.free;
Option:=nil; Option:=nil;

View File

@ -49,6 +49,8 @@ program pp;
EXTDEBUG some extra debug code is executed EXTDEBUG some extra debug code is executed
EXTERN_MSG Don't compile the msgfiles in the compiler, always EXTERN_MSG Don't compile the msgfiles in the compiler, always
use external messagefiles, default for TP 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 ARM specfic switches

View File

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

View File

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

View File

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

View File

@ -3315,6 +3315,7 @@ unit cgx86;
end; end;
begin begin
stackmisalignment:=0;
{$ifdef i8086} {$ifdef i8086}
{ Win16 callback/exported proc prologue support. { Win16 callback/exported proc prologue support.
Since callbacks can be called from different modules, DS on entry may be Since callbacks can be called from different modules, DS on entry may be
@ -3415,9 +3416,7 @@ unit cgx86;
{$endif i8086} {$endif i8086}
{$ifdef i386} {$ifdef i386}
{ interrupt support for i386 } { interrupt support for i386 }
if (po_interrupt in current_procinfo.procdef.procoptions) and if (po_interrupt in current_procinfo.procdef.procoptions) then
{ this messes up stack alignment }
not(target_info.system in [system_i386_darwin,system_i386_iphonesim,system_i386_android]) then
begin begin
{ .... also the segment registers } { .... also the segment registers }
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_GS)); 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_ECX));
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EBX)); list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EBX));
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EAX)); list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_EAX));
inc(stackmisalignment,4*2+6*8);
end; end;
{$endif i386} {$endif i386}
@ -3438,7 +3438,7 @@ unit cgx86;
if not nostackframe then if not nostackframe then
begin begin
{ return address } { return address }
stackmisalignment := sizeof(pint); inc(stackmisalignment,sizeof(pint));
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil)); 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
begin 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 Primitives
****************************************************************************} ****************************************************************************}
@ -1433,7 +1437,15 @@ asm
je .Lj3596 je .Lj3596
.Lj3620: .Lj3620:
movl %esi,%eax 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 call FPC_FREEMEM
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal 8(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
.Lj3596: .Lj3596:
popl %esi popl %esi
.Lquit: .Lquit:
@ -1459,7 +1471,13 @@ asm
je .Lj4038 je .Lj4038
// [441] result:=fpc_truely_ansistr_unique(s); // [441] result:=fpc_truely_ansistr_unique(s);
movl %edx,%eax movl %edx,%eax
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal -12(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
call fpc_truely_ansistr_unique call fpc_truely_ansistr_unique
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal 12(%esp),%esp
{$endif FPC_SYSTEM_STACKALIGNMENT16}
.Lj4038: .Lj4038:
.Lj4031: .Lj4031:
// [442] end; // [442] end;

View File

@ -888,15 +888,25 @@ begin
{ Avoid recursive calls when called from the exit routines } { Avoid recursive calls when called from the exit routines }
if StackError then if StackError then
exit; 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 decreased when this routine is called
} }
c := Sptr - STACK_MARGIN; c := Sptr - STACK_MARGIN;
if (c <= StackBottom) then if (c <= StackBottom) then
begin begin
StackError:=true; StackError:=true;
HandleError(202); HandleError(202);
end; end;
end; end;
{$POP} {$POP}

View File

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

View File

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

View File

@ -7,14 +7,14 @@ program tasm23a;
const const
t_size = 19; t_size = 19;
procedure t; assembler; procedure t; nostackframe; assembler;
asm 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, [[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] }
mov eax, [5+[7]] { mov eax, [000Ch] } mov eax, [5+[7]] { mov eax, [000Ch] }
end; end;
procedure t_verify; assembler; procedure t_verify; nostackframe; assembler;
asm 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] }
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 } { %cpu=i386 }
{ %target=win32,linux,freebsd,haiku } { %target=win32,freebsd,haiku }
{$ifdef fpc} {$ifdef fpc}
{$mode delphi} {$mode delphi}

View File

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

View File

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