aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-07-18 04:11:12 +0000
committerCraig Topper <craig.topper@gmail.com>2012-07-18 04:11:12 +0000
commit75dc33a60b65bbbf2253b0b916df1d36a4da4237 (patch)
tree6229c4bde616334381d0a9217508a87ebd06e462
parentd3a32b952b893c9799828fc2e8264385424f87ff (diff)
Make x86 asm parser to check for xmm vs ymm for index register in gather instructions. Also fix Intel syntax for gather instructions to use 'DWORD PTR' or 'QWORD PTR' to match gas.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160420 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp29
-rw-r--r--lib/Target/X86/X86InstrInfo.td30
-rw-r--r--lib/Target/X86/X86InstrSSE.td22
-rw-r--r--test/MC/Disassembler/X86/intel-syntax.txt5
-rw-r--r--test/MC/X86/intel-syntax.s2
-rw-r--r--test/MC/X86/x86_64-avx-encoding.s32
-rw-r--r--utils/TableGen/EDEmitter.cpp7
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp12
8 files changed, 118 insertions, 21 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 417842b467..8905509143 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -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!");
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 2c4e393556..d293156c1f 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -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
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index e4caace00c..10cc48377c 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -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>;
}
diff --git a/test/MC/Disassembler/X86/intel-syntax.txt b/test/MC/Disassembler/X86/intel-syntax.txt
index a5dbcf29b9..27694cd014 100644
--- a/test/MC/Disassembler/X86/intel-syntax.txt
+++ b/test/MC/Disassembler/X86/intel-syntax.txt
@@ -105,3 +105,8 @@
# 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
diff --git a/test/MC/X86/intel-syntax.s b/test/MC/X86/intel-syntax.s
index 7cd56777b0..7edd26a138 100644
--- a/test/MC/X86/intel-syntax.s
+++ b/test/MC/X86/intel-syntax.s
@@ -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
diff --git a/test/MC/X86/x86_64-avx-encoding.s b/test/MC/X86/x86_64-avx-encoding.s
index 9333246d8c..930e33b3c6 100644
--- a/test/MC/X86/x86_64-avx-encoding.s
+++ b/test/MC/X86/x86_64-avx-encoding.s
@@ -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
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index 7099f57a96..0c8b28d220 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -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");
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 1cc67c24e3..c40cc9f63c 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -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");
}