Просмотр исходного кода

* workaround for bug in Apple's assembler regarding movq/vmovq and integer
registers

git-svn-id: trunk@25396 -

Jonas Maebe 12 лет назад
Родитель
Сommit
1a78ec1f11
3 измененных файлов с 62 добавлено и 0 удалено
  1. 1 0
      .gitattributes
  2. 21 0
      compiler/x86/agx86att.pas
  3. 40 0
      tests/tbs/tb0599.pp

+ 1 - 0
.gitattributes

@@ -9978,6 +9978,7 @@ tests/tbs/tb0595.pp svneol=native#text/plain
 tests/tbs/tb0596.pp svneol=native#text/pascal
 tests/tbs/tb0597.pp svneol=native#text/plain
 tests/tbs/tb0598.pp svneol=native#text/plain
+tests/tbs/tb0599.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain

+ 21 - 0
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 }

+ 40 - 0
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.