diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 417842b4676..89055091439 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 2c4e393556b..d293156c1f7 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 e4caace00ca..10cc48377c4 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 opc, string OpcodeStr, - RegisterClass RC256, X86MemOperand memop256> { +multiclass avx2_gather opc, string OpcodeStr, RegisterClass RC256, + X86MemOperand memop128, X86MemOperand memop256> { def rm : AVX28I, VEX_4VOp3; @@ -8051,12 +8051,12 @@ multiclass avx2_gather 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 a5dbcf29b96..27694cd0144 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 7cd56777b0e..7edd26a1382 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 9333246d8c0..930e33b3c63 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 7099f57a966..0c8b28d2202 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 1cc67c24e38..c40cc9f63c6 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"); }