summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-09-02 14:39:26 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-09-02 14:39:26 +0000
commitbbd065f5a415ed20cba0fc3f90e02a36252da45f (patch)
tree417741d6026ad8e5b89539200b12aa6bca32ea17
parent6ad6b878795ab741af2dd7808d2aa8e47260b1e9 (diff)
downloadfpc-bbd065f5a415ed20cba0fc3f90e02a36252da45f.tar.gz
* workaround for bug in Apple's assembler regarding movq/vmovq and integer
registers git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@25396 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/x86/agx86att.pas21
-rw-r--r--tests/tbs/tb0599.pp40
2 files changed, 61 insertions, 0 deletions
diff --git a/compiler/x86/agx86att.pas b/compiler/x86/agx86att.pas
index 252aec6f39..03a5af4f2c 100644
--- a/compiler/x86/agx86att.pas
+++ b/compiler/x86/agx86att.pas
@@ -53,6 +53,8 @@ interface
procedure WriteOper_jmp(const o:toper);
protected
fskipPopcountSuffix: boolean;
+ { http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56656 }
+ fNoInterUnitMovQ: boolean;
public
procedure WriteInstruction(hp: tai);override;
end;
@@ -90,6 +92,8 @@ interface
InstrWriter := Tx86InstrWriter.create(self);
{ Apple's assembler does not support a size suffix for popcount }
Tx86InstrWriter(InstrWriter).fskipPopcountSuffix := true;
+ { Apple's assembler is broken regarding some movq suffix handling }
+ Tx86InstrWriter(InstrWriter).fNoInterUnitMovQ := true;
end;
{****************************************************************************
@@ -293,6 +297,23 @@ interface
end;
end;
{$endif x86_64}
+ { see fNoInterUnitMovQ declaration comment }
+ if fNoInterUnitMovQ then
+ begin
+ if ((op=A_MOVQ) or
+ (op=A_VMOVQ)) and
+ (((taicpu(hp).oper[0]^.typ=top_reg) and
+ (getregtype(taicpu(hp).oper[0]^.reg)=R_INTREGISTER)) or
+ ((taicpu(hp).oper[1]^.typ=top_reg) and
+ (getregtype(taicpu(hp).oper[1]^.reg)=R_INTREGISTER))) then
+ begin
+ if op=A_MOVQ then
+ op:=A_MOVD
+ else
+ op:=A_VMOVD;
+ taicpu(hp).opcode:=op;
+ end;
+ end;
owner.AsmWrite(#9);
{ movsd should not be translated to movsl when there
are (xmm) arguments }
diff --git a/tests/tbs/tb0599.pp b/tests/tbs/tb0599.pp
new file mode 100644
index 0000000000..aba46a2323
--- /dev/null
+++ b/tests/tbs/tb0599.pp
@@ -0,0 +1,40 @@
+{$mode delphi}
+
+type
+ TVector2=record
+ case byte of
+ 0:(x,y:single);
+ 1:(u,v:single);
+ 2:(s,t:single);
+ 3:(xy:array[0..1] of single);
+ 4:(uv:array[0..1] of single);
+ 5:(st:array[0..1] of single);
+ end;
+
+
+function Vector2Length(const v:TVector2):single;
+begin
+ result:=sqrt(sqr(v.x)+sqr(v.y));
+end;
+
+function Vector2Sub(const v1,v2:TVector2):TVector2;
+begin
+ result.x:=v1.x-v2.x;
+ result.y:=v1.y-v2.y;
+end;
+
+function Vector2Dist(const v1,v2:TVector2):single;
+begin
+ result:=Vector2Length(Vector2Sub(v2,v1));
+end;
+
+var
+ v1, v2: tvector2;
+begin
+ v1.x:=2.0;
+ v1.y:=3.0;
+ v2.x:=5.0;
+ v2.y:=7.0;
+ if trunc(Vector2Dist(v1,v2))<>5 then
+ halt(1);
+end.