diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-09-02 14:39:26 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-09-02 14:39:26 +0000 |
commit | bbd065f5a415ed20cba0fc3f90e02a36252da45f (patch) | |
tree | 417741d6026ad8e5b89539200b12aa6bca32ea17 | |
parent | 6ad6b878795ab741af2dd7808d2aa8e47260b1e9 (diff) | |
download | fpc-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.pas | 21 | ||||
-rw-r--r-- | tests/tbs/tb0599.pp | 40 |
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. |