* support floating point parameters split over multiple locations, including

integer registers, for homogeneous records/arrays on ppc64le (related to
    mantis #36934)

git-svn-id: trunk@45205 -
(cherry picked from commit 722ad1ff7b)
This commit is contained in:
Jonas Maebe 2020-05-01 13:02:48 +00:00
parent 28b2b299da
commit 8a31764a7b
2 changed files with 109 additions and 43 deletions

View File

@ -1158,7 +1158,7 @@ implementation
end; end;
LOC_FPUREGISTER,LOC_CFPUREGISTER: LOC_FPUREGISTER,LOC_CFPUREGISTER:
begin begin
a_loadfpu_ref_reg(list,size,location^.size,tmpref,location^.register); a_loadfpu_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
end end
else else
internalerror(2010053111); internalerror(2010053111);
@ -1880,49 +1880,56 @@ implementation
procedure tcg.a_loadfpu_ref_cgpara(list : TAsmList;size : tcgsize;const ref : treference;const cgpara : TCGPara); procedure tcg.a_loadfpu_ref_cgpara(list : TAsmList;size : tcgsize;const ref : treference;const cgpara : TCGPara);
var var
href : treference; srcref,
hsize: tcgsize; href : treference;
paraloc: PCGParaLocation; hsize: tcgsize;
paraloc: PCGParaLocation;
sizeleft: tcgint;
begin begin
case cgpara.location^.loc of sizeleft:=cgpara.intsize;
LOC_FPUREGISTER,LOC_CFPUREGISTER: paraloc:=cgpara.location;
begin paramanager.alloccgpara(list,cgpara);
paramanager.alloccgpara(list,cgpara); srcref:=ref;
paraloc:=cgpara.location; repeat
href:=ref; case paraloc^.loc of
while assigned(paraloc) do LOC_FPUREGISTER,LOC_CFPUREGISTER:
begin begin
if not(paraloc^.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then { force fpu size }
internalerror(2015031501); hsize:=int_float_cgsize(tcgsize2size[paraloc^.size]);
a_loadfpu_ref_reg(list,paraloc^.size,paraloc^.size,href,paraloc^.register); a_loadfpu_ref_reg(list,hsize,hsize,srcref,paraloc^.register);
inc(href.offset,tcgsize2size[paraloc^.size]); end;
paraloc:=paraloc^.next; LOC_REFERENCE,LOC_CREFERENCE:
end; begin
end; if assigned(paraloc^.next) then
LOC_REFERENCE,LOC_CREFERENCE: internalerror(2020050101);
begin reference_reset_base(href,paraloc^.reference.index,paraloc^.reference.offset,ctempposinvalid,newalignment(cgpara.alignment,cgpara.intsize-sizeleft),[]);
cgpara.check_simple_location; { concatcopy should choose the best way to copy the data }
reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,ctempposinvalid,cgpara.alignment,[]); g_concatcopy(list,srcref,href,sizeleft);
{ concatcopy should choose the best way to copy the data } end;
g_concatcopy(list,ref,href,tcgsize2size[size]); LOC_REGISTER,LOC_CREGISTER:
end; begin
LOC_REGISTER,LOC_CREGISTER: { force integer size }
begin hsize:=int_cgsize(tcgsize2size[paraloc^.size]);
{ force integer size } {$ifndef cpu64bitalu}
hsize:=int_cgsize(tcgsize2size[size]); if (hsize in [OS_S64,OS_64]) then
{$ifndef cpu64bitalu} begin
if (hsize in [OS_S64,OS_64]) then { if this is not a simple location, we'll have to add support to cg64 to load parts of a cgpara }
cg64.a_load64_ref_cgpara(list,ref,cgpara) cgpara.check_simple_location;
else cg64.a_load64_ref_cgpara(list,srcref,cgpara)
{$endif not cpu64bitalu} end
begin else
cgpara.check_simple_location; {$endif not cpu64bitalu}
a_load_ref_cgpara(list,hsize,ref,cgpara) begin
end; a_load_ref_reg(list,hsize,hsize,srcref,paraloc^.register)
end end;
else end
internalerror(200402201); else
end; internalerror(200402201);
end;
inc(srcref.offset,tcgsize2size[paraloc^.size]);
dec(sizeleft,tcgsize2size[paraloc^.size]);
paraloc:=paraloc^.next;
until not assigned(paraloc);
end; end;

59
tests/webtbs/tw36934b.pp Normal file
View File

@ -0,0 +1,59 @@
type
TPointF = record
x,y,z,v,u: single;
end;
procedure test(pt1, pt2, pt3: TPointF);
begin
if pt1.x<>1.0 then
halt(1);
if pt1.y<>2.0 then
halt(2);
if pt1.z<>3.0 then
halt(3);
if pt1.u<>4.0 then
halt(4);
if pt1.v<>5.0 then
halt(5);
if pt2.x<>6.0 then
halt(6);
if pt2.y<>7.0 then
halt(7);
if pt2.z<>8.0 then
halt(8);
if pt2.u<>9.0 then
halt(9);
if pt2.v<>10.0 then
halt(10);
if pt3.x<>11.0 then
halt(11);
if pt3.y<>12.0 then
halt(12);
if pt3.z<>13.0 then
halt(13);
if pt3.u<>14.0 then
halt(14);
if pt3.v<>15.0 then
halt(15);
end;
var
p1,p2,p3,p4,t1,t2,t3,t4: tpointf;
begin
p1.x:=1.0;
p1.y:=2.0;
p1.z:=3.0;
p1.u:=4.0;
p1.v:=5.0;
p2.x:=6.0;
p2.y:=7.0;
p2.z:=8.0;
p2.u:=9.0;
p2.v:=10.0;
p3.x:=11.0;
p3.y:=12.0;
p3.z:=13.0;
p3.u:=14.0;
p3.v:=15.0;
test(p1,p2,p3);
end.