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
This commit is contained in:
Craig Topper 2012-07-18 04:11:12 +00:00
parent d3a32b952b
commit 75dc33a60b
8 changed files with 118 additions and 21 deletions

View File

@ -331,6 +331,23 @@ struct X86Operand : public MCParsedAsmOperand {
return Kind == Memory && (!Mem.Size || Mem.Size == 256); 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 { bool isAbsMem() const {
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
!getMemIndexReg() && getMemScale() == 1; !getMemIndexReg() && getMemScale() == 1;
@ -377,6 +394,18 @@ struct X86Operand : public MCParsedAsmOperand {
void addMem256Operands(MCInst &Inst, unsigned N) const { void addMem256Operands(MCInst &Inst, unsigned N) const {
addMemOperands(Inst, N); 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 { void addMemOperands(MCInst &Inst, unsigned N) const {
assert((N == 5) && "Invalid number of operands!"); assert((N == 5) && "Invalid number of operands!");

View File

@ -292,6 +292,20 @@ def X86Mem256AsmOperand : AsmOperandClass {
let Name = "Mem256"; let PredicateMethod = "isMem256"; 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 { def X86AbsMemAsmOperand : AsmOperandClass {
let Name = "AbsMem"; let Name = "AbsMem";
let SuperClasses = [X86MemAsmOperand]; let SuperClasses = [X86MemAsmOperand];
@ -330,12 +344,20 @@ def f128mem : X86MemOperand<"printf128mem"> {
let ParserMatchClass = X86Mem128AsmOperand; } let ParserMatchClass = X86Mem128AsmOperand; }
def f256mem : X86MemOperand<"printf256mem">{ def f256mem : X86MemOperand<"printf256mem">{
let ParserMatchClass = X86Mem256AsmOperand; } let ParserMatchClass = X86Mem256AsmOperand; }
def v128mem : X86MemOperand<"printf128mem"> {
// Gather mem operands
def vx32mem : X86MemOperand<"printi32mem">{
let MIOperandInfo = (ops ptr_rc, i8imm, VR128, i32imm, i8imm); let MIOperandInfo = (ops ptr_rc, i8imm, VR128, i32imm, i8imm);
let ParserMatchClass = X86Mem128AsmOperand; } let ParserMatchClass = X86MemVX32Operand; }
def v256mem : X86MemOperand<"printf256mem"> { def vy32mem : X86MemOperand<"printi32mem">{
let MIOperandInfo = (ops ptr_rc, i8imm, VR256, i32imm, i8imm); 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 // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of

View File

@ -8036,10 +8036,10 @@ defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// VGATHER - GATHER Operations // VGATHER - GATHER Operations
multiclass avx2_gather<bits<8> opc, string OpcodeStr, multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
RegisterClass RC256, X86MemOperand memop256> { X86MemOperand memop128, X86MemOperand memop256> {
def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb), 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, !strconcat(OpcodeStr,
"\t{$mask, $src2, $dst|$dst, $src2, $mask}"), "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
[]>, VEX_4VOp3; []>, VEX_4VOp3;
@ -8051,12 +8051,12 @@ multiclass avx2_gather<bits<8> opc, string OpcodeStr,
} }
let Constraints = "$src1 = $dst, $mask = $mask_wb" in { let Constraints = "$src1 = $dst, $mask = $mask_wb" in {
defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, v128mem>, VEX_W; defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx64mem, vx64mem>, VEX_W;
defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, v256mem>, VEX_W; defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx64mem, vy64mem>, VEX_W;
defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, v256mem>; defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx32mem, vy32mem>;
defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, v256mem>; defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx32mem, vy32mem>;
defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, v128mem>, VEX_W; defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx64mem, vx64mem>, VEX_W;
defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, v256mem>, VEX_W; defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx64mem, vy64mem>, VEX_W;
defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, v256mem>; defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx32mem, vy32mem>;
defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, v256mem>; defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx32mem, vy32mem>;
} }

View File

@ -105,3 +105,8 @@
# CHECK: retf # CHECK: retf
0x66 0xcb 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

View File

@ -63,4 +63,6 @@ _main:
mov ECX, DWORD PTR [4*ECX + _fnan] mov ECX, DWORD PTR [4*ECX + _fnan]
// CHECK: movq %fs:320, %rax // CHECK: movq %fs:320, %rax
mov RAX, QWORD PTR FS:[320] mov RAX, QWORD PTR FS:[320]
// CHECK: vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm1
vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
ret ret

View File

@ -4126,14 +4126,30 @@ _foo2:
// CHECK: encoding: [0xc4,0xe2,0xf9,0x92,0x14,0x4f] // CHECK: encoding: [0xc4,0xe2,0xf9,0x92,0x14,0x4f]
vgatherdpd %xmm0, (%rdi,%xmm1,2), %xmm2 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: vgatherdpd %ymm0, (%rdi,%xmm1,2), %ymm2
// CHECK: encoding: [0xc4,0xe2,0xfd,0x92,0x14,0x4f] // CHECK: encoding: [0xc4,0xe2,0xfd,0x92,0x14,0x4f]
vgatherdpd %ymm0, (%rdi,%xmm1,2), %ymm2 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: vgatherqps %xmm8, (%r15,%xmm9,2), %xmm10
// CHECK: encoding: [0xc4,0x02,0x39,0x93,0x14,0x4f] // CHECK: encoding: [0xc4,0x02,0x39,0x93,0x14,0x4f]
vgatherqps %xmm8, (%r15,%xmm9,2), %xmm10 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: vgatherqps %xmm8, (%r15,%ymm9,2), %xmm10
// CHECK: encoding: [0xc4,0x02,0x3d,0x93,0x14,0x4f] // CHECK: encoding: [0xc4,0x02,0x3d,0x93,0x14,0x4f]
vgatherqps %xmm8, (%r15,%ymm9,2), %xmm10 vgatherqps %xmm8, (%r15,%ymm9,2), %xmm10
@ -4142,14 +4158,30 @@ _foo2:
// CHECK: encoding: [0xc4,0xe2,0xf9,0x90,0x14,0x4f] // CHECK: encoding: [0xc4,0xe2,0xf9,0x90,0x14,0x4f]
vpgatherdq %xmm0, (%rdi,%xmm1,2), %xmm2 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: vpgatherdq %ymm0, (%rdi,%xmm1,2), %ymm2
// CHECK: encoding: [0xc4,0xe2,0xfd,0x90,0x14,0x4f] // CHECK: encoding: [0xc4,0xe2,0xfd,0x90,0x14,0x4f]
vpgatherdq %ymm0, (%rdi,%xmm1,2), %ymm2 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: vpgatherqd %xmm8, (%r15,%xmm9,2), %xmm10
// CHECK: encoding: [0xc4,0x02,0x39,0x91,0x14,0x4f] // CHECK: encoding: [0xc4,0x02,0x39,0x91,0x14,0x4f]
vpgatherqd %xmm8, (%r15,%xmm9,2), %xmm10 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: vpgatherqd %xmm8, (%r15,%ymm9,2), %xmm10
// CHECK: encoding: [0xc4,0x02,0x3d,0x91,0x14,0x4f] // CHECK: encoding: [0xc4,0x02,0x3d,0x91,0x14,0x4f]
vpgatherqd %xmm8, (%r15,%ymm9,2), %xmm10 vpgatherqd %xmm8, (%r15,%ymm9,2), %xmm10

View File

@ -316,9 +316,12 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type,
MEM("i256mem"); MEM("i256mem");
MEM("f128mem"); MEM("f128mem");
MEM("f256mem"); MEM("f256mem");
MEM("v128mem");
MEM("v256mem");
MEM("opaque512mem"); MEM("opaque512mem");
// Gather
MEM("vx32mem")
MEM("vy32mem")
MEM("vx64mem")
MEM("vy64mem")
// all R, I, R, I // all R, I, R, I
LEA("lea32mem"); LEA("lea32mem");

View File

@ -1106,8 +1106,6 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("VR128", TYPE_XMM128) TYPE("VR128", TYPE_XMM128)
TYPE("f128mem", TYPE_M128) TYPE("f128mem", TYPE_M128)
TYPE("f256mem", TYPE_M256) TYPE("f256mem", TYPE_M256)
TYPE("v128mem", TYPE_M128)
TYPE("v256mem", TYPE_M256)
TYPE("FR64", TYPE_XMM64) TYPE("FR64", TYPE_XMM64)
TYPE("f64mem", TYPE_M64FP) TYPE("f64mem", TYPE_M64FP)
TYPE("sdmem", TYPE_M64FP) TYPE("sdmem", TYPE_M64FP)
@ -1146,6 +1144,10 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("GR16_NOAX", TYPE_Rv) TYPE("GR16_NOAX", TYPE_Rv)
TYPE("GR32_NOAX", TYPE_Rv) TYPE("GR32_NOAX", TYPE_Rv)
TYPE("GR64_NOAX", TYPE_R64) 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"; errs() << "Unhandled type string " << s << "\n";
llvm_unreachable("Unhandled type string"); llvm_unreachable("Unhandled type string");
} }
@ -1237,8 +1239,6 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
ENCODING("sdmem", ENCODING_RM) ENCODING("sdmem", ENCODING_RM)
ENCODING("f128mem", ENCODING_RM) ENCODING("f128mem", ENCODING_RM)
ENCODING("f256mem", ENCODING_RM) ENCODING("f256mem", ENCODING_RM)
ENCODING("v128mem", ENCODING_RM)
ENCODING("v256mem", ENCODING_RM)
ENCODING("f64mem", ENCODING_RM) ENCODING("f64mem", ENCODING_RM)
ENCODING("f32mem", ENCODING_RM) ENCODING("f32mem", ENCODING_RM)
ENCODING("i128mem", ENCODING_RM) ENCODING("i128mem", ENCODING_RM)
@ -1251,6 +1251,10 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
ENCODING("opaque48mem", ENCODING_RM) ENCODING("opaque48mem", ENCODING_RM)
ENCODING("opaque80mem", ENCODING_RM) ENCODING("opaque80mem", ENCODING_RM)
ENCODING("opaque512mem", 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"; errs() << "Unhandled memory encoding " << s << "\n";
llvm_unreachable("Unhandled memory encoding"); llvm_unreachable("Unhandled memory encoding");
} }