mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-09 19:17:21 +01:00
* zero/sign extend parameter values and return values < 32 bit to 32 bit on
x86_64 (mantis #19269) * this is also required for darwin/i386 and was already done there for parameters, but not yet for return values git-svn-id: trunk@17388 -
This commit is contained in:
parent
e3feef2126
commit
a08989a76b
@ -350,7 +350,18 @@ unit cpupara;
|
||||
else
|
||||
begin
|
||||
retcgsize:=def_cgsize(def);
|
||||
result.intsize:=def.size;
|
||||
{ darwin/x86 requires that results < sizeof(aint) are sign/ }
|
||||
{ zero extended to sizeof(aint) }
|
||||
if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
|
||||
(side=calleeside) and
|
||||
(result.intsize>0) and
|
||||
(result.intsize<sizeof(aint)) then
|
||||
begin
|
||||
result.intsize:=sizeof(aint);
|
||||
retcgsize:=OS_SINT;
|
||||
end
|
||||
else
|
||||
result.intsize:=def.size;
|
||||
end;
|
||||
result.size:=retcgsize;
|
||||
{ Return is passed as var parameter }
|
||||
@ -456,7 +467,7 @@ unit cpupara;
|
||||
(paralen < sizeof(aint)) then
|
||||
begin
|
||||
paralen := sizeof(aint);
|
||||
paracgsize:=OS_INT;
|
||||
paracgsize:=OS_SINT;
|
||||
end
|
||||
else
|
||||
paracgsize:=def_cgsize(hp.vardef);
|
||||
|
||||
@ -827,7 +827,16 @@ unit cpupara;
|
||||
else
|
||||
begin
|
||||
retcgsize:=def_cgsize(def);
|
||||
result.intsize:=def.size;
|
||||
{ integer sizes < 32 bit have to be sign/zero extended to 32 bit on
|
||||
the callee side (caller can expect those bits are valid) }
|
||||
if (side=calleeside) and
|
||||
(retcgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
|
||||
begin
|
||||
retcgsize:=OS_S32;
|
||||
result.intsize:=4;
|
||||
end
|
||||
else
|
||||
result.intsize:=def.size;
|
||||
end;
|
||||
result.size:=retcgsize;
|
||||
{ Return is passed as var parameter }
|
||||
@ -973,13 +982,21 @@ unit cpupara;
|
||||
loc[1]:=X86_64_INTEGER_CLASS;
|
||||
loc[2]:=X86_64_NO_CLASS;
|
||||
paracgsize:=OS_ADDR;
|
||||
paralen:=sizeof(aint);
|
||||
paralen:=sizeof(pint);
|
||||
end
|
||||
else
|
||||
begin
|
||||
getvalueparaloc(hp.varspez,hp.vardef,loc[1],loc[2]);
|
||||
paralen:=push_size(hp.varspez,hp.vardef,p.proccalloption);
|
||||
paracgsize:=def_cgsize(hp.vardef);
|
||||
{ integer sizes < 32 bit have to be sign/zero extended to 32 bit
|
||||
on the caller side }
|
||||
if (side=callerside) and
|
||||
(paracgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
|
||||
begin
|
||||
paracgsize:=OS_S32;
|
||||
paralen:=4;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ cheat for now, we should copy the value to an mm reg as well (FK) }
|
||||
|
||||
@ -543,6 +543,8 @@ var
|
||||
s14 : struct14;
|
||||
s15 : struct15;
|
||||
s31 : struct31;
|
||||
|
||||
c: cardinal;
|
||||
|
||||
begin
|
||||
randseed := 30;
|
||||
@ -584,7 +586,9 @@ begin
|
||||
fill(sa33, sizeof(sa33));
|
||||
|
||||
|
||||
verify(pass1(s1,1), check1(s1), 1);
|
||||
{ check that the upper bits of the parameter are cleared when required }
|
||||
c:=$f070d001;
|
||||
verify(pass1(s1,c), check1(s1), 1);
|
||||
verify(pass2(s2,2), check2(s2), 2);
|
||||
verify(pass3(s3,3), check3(s3), 3);
|
||||
verify(pass4(s4,4), check4(s4), 4);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user