From bbd065f5a415ed20cba0fc3f90e02a36252da45f Mon Sep 17 00:00:00 2001 From: jonas Date: Mon, 2 Sep 2013 14:39:26 +0000 Subject: * 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 --- compiler/x86/agx86att.pas | 21 +++++++++++++++++++++ tests/tbs/tb0599.pp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/tbs/tb0599.pp 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. -- cgit v1.2.1