diff options
author | Craig Topper <craig.topper@gmail.com> | 2011-10-15 20:46:47 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2011-10-15 20:46:47 +0000 |
commit | 566f233ba64c0bb2773b5717cb18753c7564f4b7 (patch) | |
tree | befeba913e8cabb5cdec9d4aa59a6b9700178645 /lib/Target | |
parent | 4d83b79c76044e3f3cefd2a6c1b0b792266935c8 (diff) | |
download | external_llvm-566f233ba64c0bb2773b5717cb18753c7564f4b7.zip external_llvm-566f233ba64c0bb2773b5717cb18753c7564f4b7.tar.gz external_llvm-566f233ba64c0bb2773b5717cb18753c7564f4b7.tar.bz2 |
Add support for X86 blsr, blsmsk, and blsi instructions. Required extra work because these are the first VEX encoded instructions to use the reg field as an opcode extension.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142082 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 9 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 32 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 22 |
3 files changed, 46 insertions, 17 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index e6ba705..555ca17 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -495,8 +495,13 @@ namespace X86II { case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: - case X86II::MRM6m: case X86II::MRM7m: - return 0; + case X86II::MRM6m: case X86II::MRM7m: { + bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; + unsigned FirstMemOp = 0; + if (HasVEX_4V) + ++FirstMemOp;// Skip the register dest (which is encoded in VEX_VVVV). + return FirstMemOp; + } case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 2eee112..918d4a0 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -63,9 +63,8 @@ public: unsigned OpNum) { unsigned SrcReg = MI.getOperand(OpNum).getReg(); unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum)); - if ((SrcReg >= X86::XMM8 && SrcReg <= X86::XMM15) || - (SrcReg >= X86::YMM8 && SrcReg <= X86::YMM15)) - SrcRegNum += 8; + if (X86II::isX86_64ExtendedReg(SrcReg)) + SrcRegNum |= 8; // The registers represented through VEX_VVVV should // be encoded in 1's complement form. @@ -516,7 +515,7 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, VEX_R = 0x0; break; } - case X86II::MRMSrcMem: { + case X86II::MRMSrcMem: // MRMSrcMem instructions forms: // src1(ModR/M), MemAddr // src1(ModR/M), src2(VEX_4V), MemAddr @@ -526,31 +525,34 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, if (X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) VEX_R = 0x0; - unsigned MemAddrOffset = 1; - if (HasVEX_4V) { + if (HasVEX_4V) VEX_4V = getVEXRegisterEncoding(MI, 1); - MemAddrOffset++; - } if (X86II::isX86_64ExtendedReg( - MI.getOperand(MemAddrOffset+X86::AddrBaseReg).getReg())) + MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) VEX_B = 0x0; if (X86II::isX86_64ExtendedReg( - MI.getOperand(MemAddrOffset+X86::AddrIndexReg).getReg())) + MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) VEX_X = 0x0; break; - } case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: - case X86II::MRM6m: case X86II::MRM7m: + case X86II::MRM6m: case X86II::MRM7m: { // MRM[0-9]m instructions forms: // MemAddr - if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrBaseReg).getReg())) + // src1(VEX_4V), MemAddr + if (HasVEX_4V) + VEX_4V = getVEXRegisterEncoding(MI, 0); + + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) VEX_B = 0x0; - if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrIndexReg).getReg())) + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) VEX_X = 0x0; break; + } case X86II::MRMSrcReg: // MRMSrcReg instructions forms: // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) @@ -976,6 +978,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: case X86II::MRM6m: case X86II::MRM7m: + if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). + CurOp++; EmitByte(BaseOpcode, CurByte, OS); EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, TSFlags, CurByte, OS, Fixups); diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index d54bf27..a9b59d7 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1375,7 +1375,7 @@ let Predicates = [HasLZCNT], Defs = [EFLAGS] in { } //===----------------------------------------------------------------------===// -// TZCNT Instruction +// BMI Instructions // let Predicates = [HasBMI], Defs = [EFLAGS] in { def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), @@ -1405,6 +1405,26 @@ let Predicates = [HasBMI], Defs = [EFLAGS] in { (implicit EFLAGS)]>, XS; } +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}"), []>; + def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src), + !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>; +} + +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; +} + //===----------------------------------------------------------------------===// // Subsystems. //===----------------------------------------------------------------------===// |