mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 00:59:08 +02:00
* fixed spilling of and operations on spilled 32 bit values for x86_64
(mantis #14403) git-svn-id: trunk@13573 -
This commit is contained in:
parent
2eebadf944
commit
146a819615
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9238,6 +9238,7 @@ tests/webtbs/tw1430.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw14307.pp svneol=native#text/plain
|
tests/webtbs/tw14307.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1433.pp svneol=native#text/plain
|
tests/webtbs/tw1433.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw14363.pp svneol=native#text/plain
|
tests/webtbs/tw14363.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw14403.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1445.pp svneol=native#text/plain
|
tests/webtbs/tw1445.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1450.pp svneol=native#text/plain
|
tests/webtbs/tw1450.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1451.pp svneol=native#text/plain
|
tests/webtbs/tw1451.pp svneol=native#text/plain
|
||||||
|
@ -2402,6 +2402,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
case getregtype(r) of
|
case getregtype(r) of
|
||||||
R_INTREGISTER :
|
R_INTREGISTER :
|
||||||
|
{ we don't need special code here for 32 bit loads on x86_64, since
|
||||||
|
those will automatically zero-extend the upper 32 bits. }
|
||||||
result:=taicpu.op_ref_reg(A_MOV,reg2opsize(r),ref,r);
|
result:=taicpu.op_ref_reg(A_MOV,reg2opsize(r),ref,r);
|
||||||
R_MMREGISTER :
|
R_MMREGISTER :
|
||||||
case getsubreg(r) of
|
case getsubreg(r) of
|
||||||
@ -2421,10 +2423,24 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
||||||
|
var
|
||||||
|
size: topsize;
|
||||||
begin
|
begin
|
||||||
case getregtype(r) of
|
case getregtype(r) of
|
||||||
R_INTREGISTER :
|
R_INTREGISTER :
|
||||||
result:=taicpu.op_reg_ref(A_MOV,reg2opsize(r),r,ref);
|
begin
|
||||||
|
size:=reg2opsize(r);
|
||||||
|
{$ifdef x86_64}
|
||||||
|
{ even if it's a 32 bit reg, we still have to spill 64 bits
|
||||||
|
because we often perform 64 bit operations on them }
|
||||||
|
if (size=S_L) then
|
||||||
|
begin
|
||||||
|
size:=S_Q;
|
||||||
|
r:=newreg(getregtype(r),getsupreg(r),R_SUBWHOLE);
|
||||||
|
end;
|
||||||
|
{$endif x86_64}
|
||||||
|
result:=taicpu.op_reg_ref(A_MOV,size,r,ref);
|
||||||
|
end;
|
||||||
R_MMREGISTER :
|
R_MMREGISTER :
|
||||||
case getsubreg(r) of
|
case getsubreg(r) of
|
||||||
R_SUBMMD:
|
R_SUBMMD:
|
||||||
|
@ -247,7 +247,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifdef x86_64}
|
||||||
|
{ 32 bit operations on 32 bit registers on x86_64 can result in
|
||||||
|
zeroing the upper 32 bits of the register. This does not happen
|
||||||
|
with memory operations, so we have to perform these calculations
|
||||||
|
in registers. }
|
||||||
|
if (instr.opsize=S_L) then
|
||||||
|
replaceoper:=-1;
|
||||||
|
{$endif x86_64}
|
||||||
|
|
||||||
{ Replace register with spill reference }
|
{ Replace register with spill reference }
|
||||||
if replaceoper<>-1 then
|
if replaceoper<>-1 then
|
||||||
|
47
tests/webtbs/tw14403.pp
Normal file
47
tests/webtbs/tw14403.pp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{$R+}
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
type
|
||||||
|
TDummyShapeTree = class
|
||||||
|
function ShapesCount(const OnlyActive, OnlyVisible, OnlyCollidable: boolean): Cardinal; virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TDummyShapeTreeGroup = class(TDummyShapeTree)
|
||||||
|
public
|
||||||
|
Child: TDummyShapeTree;
|
||||||
|
|
||||||
|
function ShapesCount(const OnlyActive, OnlyVisible, OnlyCollidable: boolean): Cardinal; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TDummyShape = class(TDummyShapeTree)
|
||||||
|
public
|
||||||
|
function ShapesCount(const OnlyActive, OnlyVisible, OnlyCollidable: boolean): Cardinal; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDummyShape.ShapesCount(
|
||||||
|
const OnlyActive, OnlyVisible, OnlyCollidable: boolean): Cardinal;
|
||||||
|
begin
|
||||||
|
Result := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDummyShapeTreeGroup.ShapesCount(
|
||||||
|
const OnlyActive, OnlyVisible, OnlyCollidable: boolean): Cardinal;
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
Something: Cardinal;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for I := 0 to 1 do
|
||||||
|
begin
|
||||||
|
Result := Result + Child.ShapesCount(OnlyActive, OnlyVisible, OnlyCollidable);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
G: TDummyShapeTreeGroup;
|
||||||
|
begin
|
||||||
|
G := TDummyShapeTreeGroup.Create;
|
||||||
|
G.Child := TDummyShape.Create;
|
||||||
|
Writeln(G.ShapesCount(true, true, false));
|
||||||
|
G.Free;
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user