mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 00:08:12 +02:00
* fix parameter alignment on x86_64 when more than 6 parameters are involved (aka the stack is used)
+ added test
This commit is contained in:
parent
ec0b830bba
commit
82dd70e72f
@ -1650,10 +1650,11 @@ unit cpupara;
|
||||
locidx,
|
||||
i,j,
|
||||
varalign,
|
||||
procparaalign,
|
||||
paraalign : longint;
|
||||
use_ms_abi : boolean;
|
||||
begin
|
||||
paraalign:=get_para_align(p.proccalloption);
|
||||
procparaalign:=get_para_align(p.proccalloption);
|
||||
use_ms_abi:=x86_64_use_ms_abi(p.proccalloption);
|
||||
{ Register parameters are assigned from left to right }
|
||||
for i:=0 to paras.count-1 do
|
||||
@ -1695,6 +1696,7 @@ unit cpupara;
|
||||
paralen:=sizeof(pint);
|
||||
paradef:=cpointerdef.getreusable_no_free(paradef);
|
||||
paralocdef:=paradef;
|
||||
paraalign:=procparaalign;
|
||||
loc[0].def:=paralocdef;
|
||||
loc[1].def:=nil;
|
||||
for j:=2 to high(loc) do
|
||||
@ -1707,7 +1709,7 @@ unit cpupara;
|
||||
begin
|
||||
getvalueparaloc(p.proccalloption,hp.varspez,paralocdef,loc);
|
||||
paralen:=push_size(hp.varspez,paralocdef,p.proccalloption);
|
||||
paraalign:=max(paraalign,paradef.alignment);
|
||||
paraalign:=max(procparaalign,paradef.alignment);
|
||||
if p.proccalloption = pocall_vectorcall then
|
||||
begin
|
||||
{ TODO: Can this set of instructions be put into 'defutil' without it relying on the argument classification? [Kit] }
|
||||
@ -1990,7 +1992,7 @@ unit cpupara;
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
paraloc^.reference.offset:=align(parasize,varalign);
|
||||
parasize:=align(parasize+paralen,varalign);
|
||||
paralen:=0;
|
||||
end;
|
||||
|
@ -240,7 +240,7 @@ endif
|
||||
.PHONY: create_c_objects delete_c_objects copyfiles test_c_objects
|
||||
|
||||
C_SOURCE_DIR=test/cg/obj
|
||||
C_SOURCES=ctest.c tcext3.c tcext4.c tcext5.c tcext6.c
|
||||
C_SOURCES=ctest.c tcext3.c tcext4.c tcext5.c tcext6.c tcext7.c
|
||||
CPP_SOURCES=cpptcl1.cpp cpptcl2.cpp
|
||||
TASM_SOURCES=ttasm1.asm
|
||||
ifneq ($(TEST_ABI),)
|
||||
|
BIN
tests/test/cg/obj/linux/x86_64/tcext7.o
Normal file
BIN
tests/test/cg/obj/linux/x86_64/tcext7.o
Normal file
Binary file not shown.
46
tests/test/cg/obj/tcext7.c
Normal file
46
tests/test/cg/obj/tcext7.c
Normal file
@ -0,0 +1,46 @@
|
||||
struct CTest
|
||||
{
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
unsigned long c;
|
||||
unsigned long d;
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
int TestFunc(unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4,
|
||||
unsigned long arg5, unsigned long arg6, unsigned long arg7, struct CTest arg8,
|
||||
unsigned long arg9, struct CTest arg10)
|
||||
{
|
||||
if (arg1 != 1)
|
||||
return 1;
|
||||
if (arg2 != 2)
|
||||
return 2;
|
||||
if (arg3 != 3)
|
||||
return 3;
|
||||
if (arg4 != 4)
|
||||
return 4;
|
||||
if (arg5 != 5)
|
||||
return 5;
|
||||
if (arg6 != 6)
|
||||
return 6;
|
||||
if (arg7 != 7)
|
||||
return 7;
|
||||
if (arg8.a != 801)
|
||||
return 801;
|
||||
if (arg8.b != 802)
|
||||
return 802;
|
||||
if (arg8.c != 803)
|
||||
return 803;
|
||||
if (arg8.d != 804)
|
||||
return 804;
|
||||
if (arg9 != 9)
|
||||
return 9;
|
||||
if (arg10.a != 1001)
|
||||
return 1001;
|
||||
if (arg10.b != 1002)
|
||||
return 1002;
|
||||
if (arg10.c != 1003)
|
||||
return 1003;
|
||||
if (arg10.d != 1004)
|
||||
return 1004;
|
||||
return 0;
|
||||
}
|
71
tests/test/cg/tcalext7.pp
Normal file
71
tests/test/cg/tcalext7.pp
Normal file
@ -0,0 +1,71 @@
|
||||
{ %CPU=x86_64 }
|
||||
{ %TARGET=linux }
|
||||
|
||||
program tcalext7;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$L tcext7.o}
|
||||
|
||||
type
|
||||
TTest = record
|
||||
a, b: Int64;
|
||||
case Boolean of
|
||||
True: (c, d: Int64);
|
||||
{ to enforce 16-Byte alignment }
|
||||
False: (e: Extended);
|
||||
end;
|
||||
|
||||
function TestFunc(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6, aArg7: Int64; aArg8: TTest; aArg9: Int64; aArg10: TTest): LongInt; cdecl; external name 'TestFunc';
|
||||
|
||||
function MakeTest(aArg1, aArg2, aArg3, aArg4: Int64): TTest;
|
||||
begin
|
||||
Result.a := aArg1;
|
||||
Result.b := aArg2;
|
||||
Result.c := aArg3;
|
||||
Result.d := aArg4;
|
||||
end;
|
||||
|
||||
procedure Test(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6, aArg7: Int64; aArg8: TTest; aArg9: Int64; aArg10: TTest);
|
||||
begin
|
||||
if aArg1 <> 1 then
|
||||
Halt(1);
|
||||
if aArg2 <> 2 then
|
||||
Halt(2);
|
||||
if aArg3 <> 3 then
|
||||
Halt(3);
|
||||
if aArg4 <> 4 then
|
||||
Halt(4);
|
||||
if aArg5 <> 5 then
|
||||
Halt(5);
|
||||
if aArg6 <> 6 then
|
||||
Halt(6);
|
||||
if aArg7 <> 7 then
|
||||
Halt(7);
|
||||
if aArg8.a <> 801 then
|
||||
Halt(801);
|
||||
if aArg8.b <> 802 then
|
||||
Halt(802);
|
||||
if aArg8.c <> 803 then
|
||||
Halt(803);
|
||||
if aArg8.d <> 804 then
|
||||
Halt(804);
|
||||
if aArg9 <> 9 then
|
||||
Halt(9);
|
||||
if aArg10.a <> 1001 then
|
||||
Halt(1001);
|
||||
if aArg10.b <> 1002 then
|
||||
Halt(1002);
|
||||
if aArg10.c <> 1003 then
|
||||
Halt(1003);
|
||||
if aArg10.d <> 1004 then
|
||||
Halt(1004);
|
||||
end;
|
||||
|
||||
var
|
||||
res: LongInt;
|
||||
begin
|
||||
Test(1, 2, 3, 4, 5, 6, 7, MakeTest(801, 802, 803, 804), 9, MakeTest(1001, 1002, 1003, 1004));
|
||||
res := TestFunc(1, 2, 3, 4, 5, 6, 7, MakeTest(801, 802, 803, 804), 9, MakeTest(1001, 1002, 1003, 1004));
|
||||
if res <> 0 then
|
||||
Halt(res + 10000);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user