mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 00:09:32 +02:00
-- 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:
parent
4fbb2d9cf0
commit
7cdb39b3f9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -316,6 +316,7 @@
|
||||
,abi_eabi,abi_armeb,abi_eabihf
|
||||
,abi_old_win32_gnu
|
||||
,abi_aarch64_darwin
|
||||
,abi_linux386_sysv
|
||||
);
|
||||
|
||||
const
|
||||
|
@ -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
|
||||
|
@ -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';
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 }
|
||||
|
@ -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]] }
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ %cpu=i386 }
|
||||
{ %target=win32,linux,freebsd,haiku }
|
||||
{ %target=win32,freebsd,haiku }
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
|
@ -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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ %cpu=i386 }
|
||||
{ %target=win32,linux,freebsd,haiku }
|
||||
{ %target=win32,freebsd,haiku }
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
|
Loading…
Reference in New Issue
Block a user