[llvm-commits] [llvm] r142105 - in /llvm/trunk: lib/Target/X86/MCTargetDesc/X86BaseInfo.h lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp lib/Target/X86/X86InstrInfo.td test/MC/Disassembler/X86/simple-tests.txt test/MC/Disassembler/X86/x86-32.txt test/MC/X86/x86_64-bmi-encoding.s utils/TableGen/X86RecognizableInstr.cpp utils/TableGen/X86RecognizableInstr.h
Craig Topper
craig.topper at gmail.com
Sat Oct 15 20:51:14 PDT 2011
Author: ctopper
Date: Sat Oct 15 22:51:13 2011
New Revision: 142105
URL: http://llvm.org/viewvc/llvm-project?rev=142105&view=rev
Log:
Add X86 BEXTR instruction. This instruction uses VEX.vvvv to encode Operand 3 instead of Operand 2 so needs special casing in the disassembler and code emitter. Ultimately, should pass this information from tablegen
Modified:
llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.td
llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt
llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
llvm/trunk/test/MC/X86/x86_64-bmi-encoding.s
llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
llvm/trunk/utils/TableGen/X86RecognizableInstr.h
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h Sat Oct 15 22:51:13 2011
@@ -462,7 +462,7 @@
/// is duplicated in the MCInst (e.g. "EAX = addl EAX, [mem]") it is only
/// counted as one operand.
///
- static inline int getMemoryOperandNo(uint64_t TSFlags) {
+ static inline int getMemoryOperandNo(uint64_t TSFlags, unsigned Opcode) {
switch (TSFlags & X86II::FormMask) {
case X86II::MRMInitReg: assert(0 && "FIXME: Remove this form");
default: assert(0 && "Unknown FormMask value in getMemoryOperandNo!");
@@ -477,9 +477,12 @@
case X86II::MRMDestMem:
return 0;
case X86II::MRMSrcMem: {
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3
+ bool IsBEXTR = (Opcode == X86::BEXTR32rr || Opcode == X86::BEXTR32rm ||
+ Opcode == X86::BEXTR64rr || Opcode == X86::BEXTR64rm);
bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V;
unsigned FirstMemOp = 1;
- if (HasVEX_4V)
+ if (HasVEX_4V && !IsBEXTR)
++FirstMemOp;// Skip the register source (which is encoded in VEX_VVVV).
// FIXME: Maybe lea should have its own form? This is a horrible hack.
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp Sat Oct 15 22:51:13 2011
@@ -447,6 +447,11 @@
//
unsigned char VEX_PP = 0;
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3 instead of Operand 2
+ unsigned Opcode = MI.getOpcode();
+ bool IsBEXTR = (Opcode == X86::BEXTR32rr || Opcode == X86::BEXTR32rm ||
+ Opcode == X86::BEXTR64rr || Opcode == X86::BEXTR64rm);
+
// Encode the operand size opcode prefix as needed.
if (TSFlags & X86II::OpSize)
VEX_PP = 0x01;
@@ -525,7 +530,8 @@
if (X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
VEX_R = 0x0;
- if (HasVEX_4V)
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3
+ if (HasVEX_4V && !IsBEXTR)
VEX_4V = getVEXRegisterEncoding(MI, 1);
if (X86II::isX86_64ExtendedReg(
@@ -534,6 +540,9 @@
if (X86II::isX86_64ExtendedReg(
MI.getOperand(MemOperand+X86::AddrIndexReg).getReg()))
VEX_X = 0x0;
+
+ if (IsBEXTR)
+ VEX_4V = getVEXRegisterEncoding(MI, X86::AddrNumOperands+1);
break;
case X86II::MRM0m: case X86II::MRM1m:
case X86II::MRM2m: case X86II::MRM3m:
@@ -563,10 +572,14 @@
VEX_R = 0x0;
CurOp++;
- if (HasVEX_4V)
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3
+ if (HasVEX_4V && !IsBEXTR)
VEX_4V = getVEXRegisterEncoding(MI, CurOp++);
if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
VEX_B = 0x0;
+ CurOp++;
+ if (IsBEXTR)
+ VEX_4V = getVEXRegisterEncoding(MI, CurOp);
break;
case X86II::MRMDestReg:
// MRMDestReg instructions forms:
@@ -872,7 +885,7 @@
HasVEX_4V = true;
// Determine where the memory operand starts, if present.
- int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
+ int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode);
if (MemoryOperand != -1) MemoryOperand += CurOp;
if (!HasVEXPrefix)
@@ -885,6 +898,10 @@
if ((TSFlags >> X86II::VEXShift) & X86II::Has3DNow0F0FOpcode)
BaseOpcode = 0x0F; // Weird 3DNow! encoding.
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3 instead of Operand 2
+ bool IsBEXTR = (Opcode == X86::BEXTR32rr || Opcode == X86::BEXTR32rm ||
+ Opcode == X86::BEXTR64rr || Opcode == X86::BEXTR64rm);
+
unsigned SrcRegNum = 0;
switch (TSFlags & X86II::FormMask) {
case X86II::MRMInitReg:
@@ -939,18 +956,20 @@
EmitByte(BaseOpcode, CurByte, OS);
SrcRegNum = CurOp + 1;
- if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
+ if (HasVEX_4V && !IsBEXTR) // Skip 1st src (which is encoded in VEX_VVVV)
SrcRegNum++;
EmitRegModRMByte(MI.getOperand(SrcRegNum),
GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
CurOp = SrcRegNum + 1;
+ if (IsBEXTR)
+ ++CurOp;
break;
case X86II::MRMSrcMem: {
int AddrOperands = X86::AddrNumOperands;
unsigned FirstMemOp = CurOp+1;
- if (HasVEX_4V) {
+ if (HasVEX_4V && !IsBEXTR) {
++AddrOperands;
++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
}
@@ -960,6 +979,8 @@
EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
TSFlags, CurByte, OS, Fixups);
CurOp += AddrOperands + 1;
+ if (IsBEXTR)
+ ++CurOp;
break;
}
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Oct 15 22:51:13 2011
@@ -1408,21 +1408,33 @@
multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
RegisterClass RC, X86MemOperand x86memop> {
def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
- !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>;
+ !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, T8, VEX_4V;
def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
- !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>;
+ !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, T8, VEX_4V;
}
let Predicates = [HasBMI], Defs = [EFLAGS] in {
- defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>, T8, VEX_4V;
- defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, T8, VEX_4V,
- VEX_W;
- defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>, T8, VEX_4V;
- defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, T8, VEX_4V,
- VEX_W;
- defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>, T8, VEX_4V;
- defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, T8, VEX_4V,
- VEX_W;
+ defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
+ defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
+ defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
+ defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
+ defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
+ defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
+}
+
+multiclass bmi_bextr<string mnemonic, RegisterClass RC,
+ X86MemOperand x86memop> {
+ def rr : I<0xF7, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
+ !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
+ []>, T8, VEX_4V;
+ def rm : I<0xF7, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
+ !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
+ []>, T8, VEX_4V;
+}
+
+let Predicates = [HasBMI], Defs = [EFLAGS] in {
+ defm BEXTR32 : bmi_bextr<"bextr{l}", GR32, i32mem>;
+ defm BEXTR64 : bmi_bextr<"bextr{q}", GR64, i64mem>, VEX_W;
}
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Sat Oct 15 22:51:13 2011
@@ -536,3 +536,15 @@
# CHECK: blsiq (%rax), %r15
0xc4 0xe2 0x80 0xf3 0x18
+
+# CHECK: bextrl %r12d, (%rax), %r10d
+0xc4 0x62 0x18 0xf7 0x10
+
+# CHECK: bextrl %r12d, %r11d, %r10d
+0xc4 0x42 0x18 0xf7 0xd3
+
+# CHECK: bextrq %r12, (%rax), %r10
+0xc4 0x62 0x98 0xf7 0x10
+
+# CHECK: bextrq %r12, %r11, %r10
+0xc4 0x42 0x98 0xf7 0xd3
Modified: llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-32.txt?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/x86-32.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/x86-32.txt Sat Oct 15 22:51:13 2011
@@ -504,3 +504,9 @@
# CHECK: blsil (%eax), %edi
0xc4 0xe2 0x40 0xf3 0x18
+
+# CHECK: bextrl %esi, (%eax), %edx
+0xc4 0xe2 0x08 0xf7 0x10
+
+# CHECK: bextrl %esi, %ebx, %edx
+0xc4 0xe2 0x08 0xf7 0xd3
Modified: llvm/trunk/test/MC/X86/x86_64-bmi-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86_64-bmi-encoding.s?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86_64-bmi-encoding.s (original)
+++ llvm/trunk/test/MC/X86/x86_64-bmi-encoding.s Sat Oct 15 22:51:13 2011
@@ -55,3 +55,19 @@
// CHECK: andnq (%rax), %r11, %r10
// CHECK: encoding: [0xc4,0x62,0xa0,0xf2,0x10]
andnq (%rax), %r11, %r10
+
+// CHECK: bextrl %r12d, (%rax), %r10d
+// CHECK: encoding: [0xc4,0x62,0x18,0xf7,0x10]
+ bextrl %r12d, (%rax), %r10d
+
+// CHECK: bextrl %r12d, %r11d, %r10d
+// CHECK: encoding: [0xc4,0x42,0x18,0xf7,0xd3]
+ bextrl %r12d, %r11d, %r10d
+
+// CHECK: bextrq %r12, (%rax), %r10
+// CHECK: encoding: [0xc4,0x62,0x98,0xf7,0x10]
+ bextrq %r12, (%rax), %r10
+
+// CHECK: bextrq %r12, %r11, %r10
+// CHECK: encoding: [0xc4,0x42,0x98,0xf7,0xd3]
+ bextrq %r12, %r11, %r10
Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Sat Oct 15 22:51:13 2011
@@ -233,7 +233,7 @@
(Name.find("CRC32") != Name.npos);
HasFROperands = hasFROperands();
HasVEX_LPrefix = has256BitOperands() || Rec->getValueAsBit("hasVEX_L");
-
+
// Check for 64-bit inst which does not require REX
Is32Bit = false;
Is64Bit = false;
@@ -265,6 +265,9 @@
Rec->getName().find("PUSH64") != Name.npos ||
Rec->getName().find("POP64") != Name.npos;
+ // FIXME: BEXTR uses VEX.vvvv to encode its third operand
+ IsBEXTR = Rec->getName().find("BEXTR") != Name.npos;
+
ShouldBeEmitted = true;
}
@@ -695,13 +698,18 @@
"Unexpected number of operands for MRMSrcRegFrm");
HANDLE_OPERAND(roRegister)
-
- if (HasVEX_4VPrefix)
+
+ if (HasVEX_4VPrefix && !IsBEXTR)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
-
+
HANDLE_OPERAND(rmRegister)
+
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3
+ if (IsBEXTR)
+ HANDLE_OPERAND(vvvvRegister)
+
HANDLE_OPTIONAL(immediate)
break;
case X86Local::MRMSrcMem:
@@ -719,12 +727,17 @@
HANDLE_OPERAND(roRegister)
- if (HasVEX_4VPrefix)
+ if (HasVEX_4VPrefix && !IsBEXTR)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
HANDLE_OPERAND(memory)
+
+ // FIXME: BEXTR uses VEX.vvvv for Operand 3
+ if (IsBEXTR)
+ HANDLE_OPERAND(vvvvRegister)
+
HANDLE_OPTIONAL(immediate)
break;
case X86Local::MRM0r:
Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.h?rev=142105&r1=142104&r2=142105&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.h (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.h Sat Oct 15 22:51:13 2011
@@ -70,7 +70,9 @@
bool Is64Bit;
// Whether the instruction has the predicate "In32BitMode"
bool Is32Bit;
-
+ // Whether the instruction is BEXTR
+ bool IsBEXTR;
+
/// The instruction name as listed in the tables
std::string Name;
/// The AT&T AsmString for the instruction
More information about the llvm-commits
mailing list