瀏覽代碼

* Fixed VMOVQ instruction encoding, now assembles correctly also in 32-bit code.
+ Test

git-svn-id: trunk@34949 -

sergei 8 年之前
父節點
當前提交
133fcb5ab2

+ 1 - 0
.gitattributes

@@ -11986,6 +11986,7 @@ tests/test/tasm5.pp svneol=native#text/plain
 tests/test/tasm6.pp svneol=native#text/plain
 tests/test/tasm7.pp svneol=native#text/pascal
 tests/test/tasm8.pp svneol=native#text/plain
+tests/test/tasm9.pp svneol=native#text/pascal
 tests/test/tasmread.pp svneol=native#text/plain
 tests/test/tasout.pp svneol=native#text/plain
 tests/test/tassignmentoperator1.pp svneol=native#text/pascal

+ 1 - 1
compiler/i386/i386nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
-1953;
+1955;

+ 18 - 4
compiler/i386/i386tab.inc

@@ -9824,15 +9824,29 @@
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_rm_gpr or ot_bits64,ot_xmmreg,ot_none,ot_none);
-    code    : #241#242#243#248#1#126#65;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_memory or ot_bits64,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
     flags   : if_avx or if_sandybridge
   ),
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_xmmreg,ot_rm_gpr or ot_bits64,ot_none,ot_none);
-    code    : #241#242#243#248#1#110#72;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_memory or ot_bits64,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
     flags   : if_avx or if_sandybridge
   ),
   (

+ 1 - 1
compiler/i8086/i8086nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
-1985;
+1987;

+ 18 - 4
compiler/i8086/i8086tab.inc

@@ -9852,15 +9852,29 @@
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_rm_gpr or ot_bits64,ot_xmmreg,ot_none,ot_none);
-    code    : #241#242#243#248#1#126#65;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_memory or ot_bits64,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
     flags   : if_avx or if_sandybridge
   ),
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_xmmreg,ot_rm_gpr or ot_bits64,ot_none,ot_none);
-    code    : #241#242#243#248#1#110#72;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_memory or ot_bits64,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
     flags   : if_avx or if_sandybridge
   ),
   (

+ 6 - 2
compiler/x86/x86ins.dat

@@ -3936,8 +3936,12 @@ mem128,xmmreg                        \362\370\1\x2B\101                   AVX,SA
 
 [VMOVQ]
 (Ch_Wop2, Ch_Rop1, Ch_None)
-rm64,xmmreg                          \361\362\363\370\1\x7E\101           AVX,SANDYBRIDGE
-xmmreg,rm64                          \361\362\363\370\1\x6E\110           AVX,SANDYBRIDGE
+xmmreg,xmmreg                        \362\333\370\1\x7E\110               AVX,SANDYBRIDGE
+xmmreg,mem64                         \362\333\370\1\x7E\110               AVX,SANDYBRIDGE
+xmmreg,xmmreg                        \362\361\370\1\xD6\101               AVX,SANDYBRIDGE
+mem64,xmmreg                         \362\361\370\1\xD6\101               AVX,SANDYBRIDGE
+rm64,xmmreg                          \362\361\363\370\1\x7E\101           AVX,SANDYBRIDGE,X86_64
+xmmreg,rm64                          \362\361\363\370\1\x6E\110           AVX,SANDYBRIDGE,X86_64
 
 [VMOVSD]
 ; the three ops must be handle by the compiler internally

+ 1 - 1
compiler/x86_64/x8664nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
-1976;
+1980;

+ 32 - 4
compiler/x86_64/x8664tab.inc

@@ -9943,17 +9943,45 @@
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_rm_gpr or ot_bits64,ot_xmmreg,ot_none,ot_none);
-    code    : #241#242#243#248#1#126#65;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
     flags   : if_avx or if_sandybridge
   ),
   (
     opcode  : A_VMOVQ;
     ops     : 2;
-    optypes : (ot_xmmreg,ot_rm_gpr or ot_bits64,ot_none,ot_none);
-    code    : #241#242#243#248#1#110#72;
+    optypes : (ot_xmmreg,ot_memory or ot_bits64,ot_none,ot_none);
+    code    : #242#219#248#1#126#72;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
+    flags   : if_avx or if_sandybridge
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_memory or ot_bits64,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#248#1#214#65;
     flags   : if_avx or if_sandybridge
   ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits64,ot_xmmreg,ot_none,ot_none);
+    code    : #242#241#243#248#1#126#65;
+    flags   : if_avx or if_sandybridge or if_x86_64
+  ),
+  (
+    opcode  : A_VMOVQ;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_rm_gpr or ot_bits64,ot_none,ot_none);
+    code    : #242#241#243#248#1#110#72;
+    flags   : if_avx or if_sandybridge or if_x86_64
+  ),
   (
     opcode  : A_VMOVSD;
     ops     : 3;

+ 67 - 0
tests/test/tasm9.pp

@@ -0,0 +1,67 @@
+{ %cpu=i386,x86_64 }
+
+{$asmmode att}
+{$ifdef cpui386}
+{$warn 7104 off} //"Using -offset(%ebp) is not recommended"
+procedure test_i386; assembler; nostackframe;
+asm
+  vmovd  %xmm0, -16(%ebp)
+  vmovd  -16(%ebp), %xmm0
+  
+  vmovq  %xmm6, -16(%ebp)
+  vmovq  -16(%ebp), %xmm6
+  vmovq  %xmm0, %xmm2
+end;
+
+const
+  expected_i386: array[0..23] of byte = (
+    $C5,$F9,$7E,$45,$F0,
+    $C5,$F9,$6E,$45,$F0,
+    $C5,$F9,$D6,$75,$F0,
+    $C5,$FA,$7E,$75,$F0,
+    $C5,$FA,$7E,$D0
+  );
+{$endif}
+
+{$ifdef cpux86_64}  
+procedure test_x86_64; assembler; nostackframe;
+asm
+  vmovq  0x12345678(%rip), %xmm0
+  vmovq  %xmm0, 0x12345678(%rip)
+  vmovq  %xmm1, %xmm0
+  vmovq  %rax, %xmm0
+  vmovq  %xmm0, %rax
+end;
+
+const
+  expected_x86_64: array[0..29] of byte = (
+    $C5,$FA,$7E,$05,$78,$56,$34,$12,
+    $C5,$F9,$D6,$05,$78,$56,$34,$12,
+    $C5,$FA,$7E,$C1,
+    $C4,$E1,$F9,$6E,$C0,
+    $C4,$E1,$F9,$7E,$C0
+  );
+{$endif}
+
+
+procedure check(const id: string; const expected: array of byte; p: pointer);
+var
+  i : longint;
+begin
+  for i:=0 to high(expected) do
+    if expected[i]<>pbyte(p)[i] then
+      begin
+        writeln(id, ' mismatch at offset $',hexstr(i,4), ', expected=$',hexstr(expected[i],2),' actual=$',hexstr(pbyte(p)[i],2));
+        halt(1);
+      end;
+end;
+  
+begin
+{$ifdef cpux86_64}
+  check('x86_64',expected_x86_64,@test_x86_64);
+{$endif}
+{$ifdef cpui386}
+  check('i386',expected_i386,@test_i386);
+{$endif}  
+  writeln('ok');
+end.