* 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:
Jonas Maebe 2009-08-21 16:20:16 +00:00
parent 2eebadf944
commit 146a819615
4 changed files with 75 additions and 2 deletions

1
.gitattributes vendored
View File

@ -9238,6 +9238,7 @@ tests/webtbs/tw1430.pp svneol=native#text/plain
tests/webtbs/tw14307.pp svneol=native#text/plain
tests/webtbs/tw1433.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/tw1450.pp svneol=native#text/plain
tests/webtbs/tw1451.pp svneol=native#text/plain

View File

@ -2402,6 +2402,8 @@ implementation
begin
case getregtype(r) of
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);
R_MMREGISTER :
case getsubreg(r) of
@ -2421,10 +2423,24 @@ implementation
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
var
size: topsize;
begin
case getregtype(r) of
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 :
case getsubreg(r) of
R_SUBMMD:

View File

@ -247,7 +247,16 @@ implementation
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 }
if replaceoper<>-1 then

47
tests/webtbs/tw14403.pp Normal file
View 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.