Make x86 asm parser to check for xmm vs ymm for index register in gather instructions...
authorCraig Topper <craig.topper@gmail.com>
Wed, 18 Jul 2012 04:11:12 +0000 (04:11 +0000)
committerCraig Topper <craig.topper@gmail.com>
Wed, 18 Jul 2012 04:11:12 +0000 (04:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160420 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86InstrSSE.td
test/MC/Disassembler/X86/intel-syntax.txt
test/MC/X86/intel-syntax.s
test/MC/X86/x86_64-avx-encoding.s
utils/TableGen/EDEmitter.cpp
utils/TableGen/X86RecognizableInstr.cpp

index 417842b4676a7daa9aa5978c1f1e2af24394f481..8905509143996b7ab490570616185292267f734e 100644 (file)
@@ -331,6 +331,23 @@ struct X86Operand : public MCParsedAsmOperand {
     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
   }
 
+  bool isMemVX32() const {
+    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
+      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
+  }
+  bool isMemVY32() const {
+    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
+      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
+  }
+  bool isMemVX64() const {
+    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
+      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
+  }
+  bool isMemVY64() const {
+    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
+      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
+  }
+
   bool isAbsMem() const {
     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
       !getMemIndexReg() && getMemScale() == 1;
@@ -377,6 +394,18 @@ struct X86Operand : public MCParsedAsmOperand {
   void addMem256Operands(MCInst &Inst, unsigned N) const {
     addMemOperands(Inst, N);
   }
+  void addMemVX32Operands(MCInst &Inst, unsigned N) const {
+    addMemOperands(Inst, N);
+  }
+  void addMemVY32Operands(MCInst &Inst, unsigned N) const {
+    addMemOperands(Inst, N);
+  }
+  void addMemVX64Operands(MCInst &Inst, unsigned N) const {
+    addMemOperands(Inst, N);
+  }
+  void addMemVY64Operands(MCInst &Inst, unsigned N) const {
+    addMemOperands(Inst, N);
+  }
 
   void addMemOperands(MCInst &Inst, unsigned N) const {
     assert((N == 5) && "Invalid number of operands!");
index 2c4e393556bacb24799ea1f83dda13c32a8d2cc8..d293156c1f713c65fdd27cf127a53999ecd95313 100644 (file)
@@ -292,6 +292,20 @@ def X86Mem256AsmOperand : AsmOperandClass {
   let Name = "Mem256"; let PredicateMethod = "isMem256";
 }
 
+// Gather mem operands
+def X86MemVX32Operand : AsmOperandClass {
+  let Name = "MemVX32"; let PredicateMethod = "isMemVX32";
+}
+def X86MemVY32Operand : AsmOperandClass {
+  let Name = "MemVY32"; let PredicateMethod = "isMemVY32";
+}
+def X86MemVX64Operand : AsmOperandClass {
+  let Name = "MemVX64"; let PredicateMethod = "isMemVX64";
+}
+def X86MemVY64Operand : AsmOperandClass {
+  let Name = "MemVY64"; let PredicateMethod = "isMemVY64";
+}
+
 def X86AbsMemAsmOperand : AsmOperandClass {
   let Name = "AbsMem";
   let SuperClasses = [X86MemAsmOperand];
@@ -330,12 +344,20 @@ def f128mem : X86MemOperand<"printf128mem"> {
   let ParserMatchClass = X86Mem128AsmOperand; }
 def f256mem : X86MemOperand<"printf256mem">{ 
   let ParserMatchClass = X86Mem256AsmOperand; }
-def v128mem : X86MemOperand<"printf128mem"> {
+
+// Gather mem operands
+def vx32mem : X86MemOperand<"printi32mem">{
   let MIOperandInfo = (ops ptr_rc, i8imm, VR128, i32imm, i8imm);
-  let ParserMatchClass = X86Mem128AsmOperand; }
-def v256mem : X86MemOperand<"printf256mem"> {
+  let ParserMatchClass = X86MemVX32Operand; }
+def vy32mem : X86MemOperand<"printi32mem">{
   let MIOperandInfo = (ops ptr_rc, i8imm, VR256, i32imm, i8imm);
-  let ParserMatchClass = X86Mem256AsmOperand; }
+  let ParserMatchClass = X86MemVY32Operand; }
+def vx64mem : X86MemOperand<"printi64mem">{
+  let MIOperandInfo = (ops ptr_rc, i8imm, VR128, i32imm, i8imm);
+  let ParserMatchClass = X86MemVX64Operand; }
+def vy64mem : X86MemOperand<"printi64mem">{
+  let MIOperandInfo = (ops ptr_rc, i8imm, VR256, i32imm, i8imm);
+  let ParserMatchClass = X86MemVY64Operand; }
 }
 
 // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of
index e4caace00ca46ffc0ee8d242f2d9932d8ef39f44..10cc48377c47bef6b32856fb6bf3d69c3871f935 100644 (file)
@@ -8036,10 +8036,10 @@ defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
 
 //===----------------------------------------------------------------------===//
 // VGATHER - GATHER Operations
-multiclass avx2_gather<bits<8> opc, string OpcodeStr,
-                       RegisterClass RC256, X86MemOperand memop256> {
+multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
+                       X86MemOperand memop128, X86MemOperand memop256> {
   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),
-            (ins VR128:$src1, v128mem:$src2, VR128:$mask),
+            (ins VR128:$src1, memop128:$src2, VR128:$mask),
             !strconcat(OpcodeStr,
               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
             []>, VEX_4VOp3;
@@ -8051,12 +8051,12 @@ multiclass avx2_gather<bits<8> opc, string OpcodeStr,
 }
 
 let Constraints = "$src1 = $dst, $mask = $mask_wb" in {
-  defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, v128mem>, VEX_W;
-  defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, v256mem>, VEX_W;
-  defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, v256mem>;
-  defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, v256mem>;
-  defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, v128mem>, VEX_W;
-  defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, v256mem>, VEX_W;
-  defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, v256mem>;
-  defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, v256mem>;
+  defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx64mem, vx64mem>, VEX_W;
+  defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx64mem, vy64mem>, VEX_W;
+  defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx32mem, vy32mem>;
+  defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx32mem, vy32mem>;
+  defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx64mem, vx64mem>, VEX_W;
+  defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx64mem, vy64mem>, VEX_W;
+  defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx32mem, vy32mem>;
+  defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx32mem, vy32mem>;
 }
index a5dbcf29b96475327ce60b1eb913aac8f1164664..27694cd014461cc26fa07aa4322b5a5f7c1f70fe 100644 (file)
 # CHECK: retf
 0x66 0xcb
 
+# CHECK: vpgatherqq YMM2, QWORD PTR [RDI + 2*YMM1], YMM0
+0xc4 0xe2 0xfd 0x91 0x14 0x4f
+
+# CHECK: vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
+0xc4 0x02 0x39 0x90 0x14 0x4f
index 7cd56777b0e9c81930f84c34af5c95e31f30e784..7edd26a1382f34d05239e7d5b77e1407b55bba2a 100644 (file)
@@ -63,4 +63,6 @@ _main:
         mov     ECX, DWORD PTR [4*ECX + _fnan]
 // CHECK:       movq    %fs:320, %rax
         mov     RAX, QWORD PTR FS:[320]
+// CHECK:       vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm1
+        vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
        ret
index 9333246d8c020f9d2740f2ada7c416ec69a69f8b..930e33b3c63ee7fac7952e1d8e092fc04792aded 100644 (file)
@@ -4126,14 +4126,30 @@ _foo2:
 // CHECK: encoding: [0xc4,0xe2,0xf9,0x92,0x14,0x4f]
           vgatherdpd %xmm0, (%rdi,%xmm1,2), %xmm2
 
+// CHECK: vgatherqpd %xmm0, (%rdi,%xmm1,2), %xmm2
+// CHECK: encoding: [0xc4,0xe2,0xf9,0x93,0x14,0x4f]
+          vgatherqpd %xmm0, (%rdi,%xmm1,2), %xmm2
+
 // CHECK: vgatherdpd %ymm0, (%rdi,%xmm1,2), %ymm2
 // CHECK: encoding: [0xc4,0xe2,0xfd,0x92,0x14,0x4f]
           vgatherdpd %ymm0, (%rdi,%xmm1,2), %ymm2
 
+// CHECK: vgatherqpd %ymm0, (%rdi,%ymm1,2), %ymm2
+// CHECK: encoding: [0xc4,0xe2,0xfd,0x93,0x14,0x4f]
+          vgatherqpd %ymm0, (%rdi,%ymm1,2), %ymm2
+
+// CHECK: vgatherdps %xmm8, (%r15,%xmm9,2), %xmm10
+// CHECK: encoding: [0xc4,0x02,0x39,0x92,0x14,0x4f]
+          vgatherdps %xmm8, (%r15,%xmm9,2), %xmm10
+
 // CHECK: vgatherqps %xmm8, (%r15,%xmm9,2), %xmm10
 // CHECK: encoding: [0xc4,0x02,0x39,0x93,0x14,0x4f]
           vgatherqps %xmm8, (%r15,%xmm9,2), %xmm10
 
+// CHECK: vgatherdps %ymm8, (%r15,%ymm9,2), %ymm10
+// CHECK: encoding: [0xc4,0x02,0x3d,0x92,0x14,0x4f]
+          vgatherdps %ymm8, (%r15,%ymm9,2), %ymm10
+
 // CHECK: vgatherqps %xmm8, (%r15,%ymm9,2), %xmm10
 // CHECK: encoding: [0xc4,0x02,0x3d,0x93,0x14,0x4f]
           vgatherqps %xmm8, (%r15,%ymm9,2), %xmm10
@@ -4142,14 +4158,30 @@ _foo2:
 // CHECK: encoding: [0xc4,0xe2,0xf9,0x90,0x14,0x4f]
           vpgatherdq %xmm0, (%rdi,%xmm1,2), %xmm2
 
+// CHECK: vpgatherqq %xmm0, (%rdi,%xmm1,2), %xmm2
+// CHECK: encoding: [0xc4,0xe2,0xf9,0x91,0x14,0x4f]
+          vpgatherqq %xmm0, (%rdi,%xmm1,2), %xmm2
+
 // CHECK: vpgatherdq %ymm0, (%rdi,%xmm1,2), %ymm2
 // CHECK: encoding: [0xc4,0xe2,0xfd,0x90,0x14,0x4f]
           vpgatherdq %ymm0, (%rdi,%xmm1,2), %ymm2
 
+// CHECK: vpgatherqq %ymm0, (%rdi,%ymm1,2), %ymm2
+// CHECK: encoding: [0xc4,0xe2,0xfd,0x91,0x14,0x4f]
+          vpgatherqq %ymm0, (%rdi,%ymm1,2), %ymm2
+
+// CHECK: vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm10
+// CHECK: encoding: [0xc4,0x02,0x39,0x90,0x14,0x4f]
+          vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm10
+
 // CHECK: vpgatherqd %xmm8, (%r15,%xmm9,2), %xmm10
 // CHECK: encoding: [0xc4,0x02,0x39,0x91,0x14,0x4f]
           vpgatherqd %xmm8, (%r15,%xmm9,2), %xmm10
 
+// CHECK: vpgatherdd %ymm8, (%r15,%ymm9,2), %ymm10
+// CHECK: encoding: [0xc4,0x02,0x3d,0x90,0x14,0x4f]
+          vpgatherdd %ymm8, (%r15,%ymm9,2), %ymm10
+
 // CHECK: vpgatherqd %xmm8, (%r15,%ymm9,2), %xmm10
 // CHECK: encoding: [0xc4,0x02,0x3d,0x91,0x14,0x4f]
           vpgatherqd %xmm8, (%r15,%ymm9,2), %xmm10
index 7099f57a966b82b0bce282a026a6f02cd54aa45c..0c8b28d220279bb8ccbf326e77d71ad46164f4b0 100644 (file)
@@ -316,9 +316,12 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type,
   MEM("i256mem");
   MEM("f128mem");
   MEM("f256mem");
-  MEM("v128mem");
-  MEM("v256mem");
   MEM("opaque512mem");
+  // Gather
+  MEM("vx32mem")
+  MEM("vy32mem")
+  MEM("vx64mem")
+  MEM("vy64mem")
 
   // all R, I, R, I
   LEA("lea32mem");
index 1cc67c24e38734c3592e550ecd6a77dbc12c2b2e..c40cc9f63c605c81ab47cdf36eff2924edb69430 100644 (file)
@@ -1106,8 +1106,6 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("VR128",               TYPE_XMM128)
   TYPE("f128mem",             TYPE_M128)
   TYPE("f256mem",             TYPE_M256)
-  TYPE("v128mem",             TYPE_M128)
-  TYPE("v256mem",             TYPE_M256)
   TYPE("FR64",                TYPE_XMM64)
   TYPE("f64mem",              TYPE_M64FP)
   TYPE("sdmem",               TYPE_M64FP)
@@ -1146,6 +1144,10 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("GR16_NOAX",           TYPE_Rv)
   TYPE("GR32_NOAX",           TYPE_Rv)
   TYPE("GR64_NOAX",           TYPE_R64)
+  TYPE("vx32mem",             TYPE_M32)
+  TYPE("vy32mem",             TYPE_M32)
+  TYPE("vx64mem",             TYPE_M64)
+  TYPE("vy64mem",             TYPE_M64)
   errs() << "Unhandled type string " << s << "\n";
   llvm_unreachable("Unhandled type string");
 }
@@ -1237,8 +1239,6 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
   ENCODING("sdmem",           ENCODING_RM)
   ENCODING("f128mem",         ENCODING_RM)
   ENCODING("f256mem",         ENCODING_RM)
-  ENCODING("v128mem",         ENCODING_RM)
-  ENCODING("v256mem",         ENCODING_RM)
   ENCODING("f64mem",          ENCODING_RM)
   ENCODING("f32mem",          ENCODING_RM)
   ENCODING("i128mem",         ENCODING_RM)
@@ -1251,6 +1251,10 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
   ENCODING("opaque48mem",     ENCODING_RM)
   ENCODING("opaque80mem",     ENCODING_RM)
   ENCODING("opaque512mem",    ENCODING_RM)
+  ENCODING("vx32mem",         ENCODING_RM)
+  ENCODING("vy32mem",         ENCODING_RM)
+  ENCODING("vx64mem",         ENCODING_RM)
+  ENCODING("vy64mem",         ENCODING_RM)
   errs() << "Unhandled memory encoding " << s << "\n";
   llvm_unreachable("Unhandled memory encoding");
 }