aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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");
}