mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 16:49:00 +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/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
|
||||
|
@ -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:
|
||||
|
@ -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
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