diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index e141c90e4ab7..01e865ac684c 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -626,82 +626,86 @@ namespace X86II { /// MRMDestMem - This form is used for instructions that use the Mod/RM byte /// to specify a destination, which in this case is memory. /// - MRMDestMem = 32, + MRMDestMem = 24, /// MRMSrcMem - This form is used for instructions that use the Mod/RM byte /// to specify a source, which in this case is memory. /// - MRMSrcMem = 33, + MRMSrcMem = 25, /// MRMSrcMem4VOp3 - This form is used for instructions that encode /// operand 3 with VEX.VVVV and load from memory. /// - MRMSrcMem4VOp3 = 34, + MRMSrcMem4VOp3 = 26, /// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM /// byte to specify the fourth source, which in this case is memory. /// - MRMSrcMemOp4 = 35, + MRMSrcMemOp4 = 27, /// MRMSrcMemCC - This form is used for instructions that use the Mod/RM /// byte to specify the operands and also encodes a condition code. /// - MRMSrcMemCC = 36, + MRMSrcMemCC = 28, /// MRMXm - This form is used for instructions that use the Mod/RM byte /// to specify a memory source, but doesn't use the middle field. And has /// a condition code. /// - MRMXmCC = 38, + MRMXmCC = 30, /// MRMXm - This form is used for instructions that use the Mod/RM byte /// to specify a memory source, but doesn't use the middle field. /// - MRMXm = 39, + MRMXm = 31, // Next, instructions that operate on a memory r/m operand... - MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43, // Format /0 /1 /2 /3 - MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47, // Format /4 /5 /6 /7 + MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35, // Format /0 /1 /2 /3 + MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39, // Format /4 /5 /6 /7 /// MRMDestReg - This form is used for instructions that use the Mod/RM byte /// to specify a destination, which in this case is a register. /// - MRMDestReg = 48, + MRMDestReg = 40, /// MRMSrcReg - This form is used for instructions that use the Mod/RM byte /// to specify a source, which in this case is a register. /// - MRMSrcReg = 49, + MRMSrcReg = 41, /// MRMSrcReg4VOp3 - This form is used for instructions that encode /// operand 3 with VEX.VVVV and do not load from memory. /// - MRMSrcReg4VOp3 = 50, + MRMSrcReg4VOp3 = 42, /// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM /// byte to specify the fourth source, which in this case is a register. /// - MRMSrcRegOp4 = 51, + MRMSrcRegOp4 = 43, /// MRMSrcRegCC - This form is used for instructions that use the Mod/RM /// byte to specify the operands and also encodes a condition code /// - MRMSrcRegCC = 52, + MRMSrcRegCC = 44, /// MRMXCCr - This form is used for instructions that use the Mod/RM byte /// to specify a register source, but doesn't use the middle field. And has /// a condition code. /// - MRMXrCC = 54, + MRMXrCC = 46, /// MRMXr - This form is used for instructions that use the Mod/RM byte /// to specify a register source, but doesn't use the middle field. /// - MRMXr = 55, + MRMXr = 47, // Instructions that operate on a register r/m operand... - MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59, // Format /0 /1 /2 /3 - MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63, // Format /4 /5 /6 /7 + MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51, // Format /0 /1 /2 /3 + MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55, // Format /4 /5 /6 /7 + + // Instructions that operate that have mod=11 and an opcode but ignore r/m. + MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59, // Format /0 /1 /2 /3 + MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63, // Format /4 /5 /6 /7 /// MRM_XX - A mod/rm byte of exactly 0xXX. MRM_C0 = 64, MRM_C1 = 65, MRM_C2 = 66, MRM_C3 = 67, @@ -1105,6 +1109,11 @@ namespace X86II { case X86II::MRM4r: case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: return -1; + case X86II::MRM0X: case X86II::MRM1X: + case X86II::MRM2X: case X86II::MRM3X: + case X86II::MRM4X: case X86II::MRM5X: + case X86II::MRM6X: case X86II::MRM7X: + return -1; case X86II::MRMXmCC: case X86II::MRMXm: case X86II::MRM0m: case X86II::MRM1m: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 88865fc8a90b..98330f60e63d 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1670,6 +1670,18 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, CurOp += X86::AddrNumOperands; break; + case X86II::MRM0X: + case X86II::MRM1X: + case X86II::MRM2X: + case X86II::MRM3X: + case X86II::MRM4X: + case X86II::MRM5X: + case X86II::MRM6X: + case X86II::MRM7X: + emitByte(BaseOpcode, OS); + emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), OS); + break; + case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2: diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td index 7da1f3593fe0..41326a6bbe07 100644 --- a/llvm/lib/Target/X86/X86InstrFormats.td +++ b/llvm/lib/Target/X86/X86InstrFormats.td @@ -28,26 +28,29 @@ def RawFrmImm8 : Format<7>; def RawFrmImm16 : Format<8>; def AddCCFrm : Format<9>; def PrefixByte : Format<10>; -def MRMDestMem : Format<32>; -def MRMSrcMem : Format<33>; -def MRMSrcMem4VOp3 : Format<34>; -def MRMSrcMemOp4 : Format<35>; -def MRMSrcMemCC : Format<36>; -def MRMXmCC: Format<38>; -def MRMXm : Format<39>; -def MRM0m : Format<40>; def MRM1m : Format<41>; def MRM2m : Format<42>; -def MRM3m : Format<43>; def MRM4m : Format<44>; def MRM5m : Format<45>; -def MRM6m : Format<46>; def MRM7m : Format<47>; -def MRMDestReg : Format<48>; -def MRMSrcReg : Format<49>; -def MRMSrcReg4VOp3 : Format<50>; -def MRMSrcRegOp4 : Format<51>; -def MRMSrcRegCC : Format<52>; -def MRMXrCC: Format<54>; -def MRMXr : Format<55>; -def MRM0r : Format<56>; def MRM1r : Format<57>; def MRM2r : Format<58>; -def MRM3r : Format<59>; def MRM4r : Format<60>; def MRM5r : Format<61>; -def MRM6r : Format<62>; def MRM7r : Format<63>; +def MRMDestMem : Format<24>; +def MRMSrcMem : Format<25>; +def MRMSrcMem4VOp3 : Format<26>; +def MRMSrcMemOp4 : Format<27>; +def MRMSrcMemCC : Format<28>; +def MRMXmCC: Format<30>; +def MRMXm : Format<31>; +def MRM0m : Format<32>; def MRM1m : Format<33>; def MRM2m : Format<34>; +def MRM3m : Format<35>; def MRM4m : Format<36>; def MRM5m : Format<37>; +def MRM6m : Format<38>; def MRM7m : Format<39>; +def MRMDestReg : Format<40>; +def MRMSrcReg : Format<41>; +def MRMSrcReg4VOp3 : Format<42>; +def MRMSrcRegOp4 : Format<43>; +def MRMSrcRegCC : Format<44>; +def MRMXrCC: Format<46>; +def MRMXr : Format<47>; +def MRM0r : Format<48>; def MRM1r : Format<49>; def MRM2r : Format<50>; +def MRM3r : Format<51>; def MRM4r : Format<52>; def MRM5r : Format<53>; +def MRM6r : Format<54>; def MRM7r : Format<55>; +def MRM0X : Format<56>; def MRM1X : Format<57>; def MRM2X : Format<58>; +def MRM3X : Format<59>; def MRM4X : Format<60>; def MRM5X : Format<61>; +def MRM6X : Format<62>; def MRM7X : Format<63>; def MRM_C0 : Format<64>; def MRM_C1 : Format<65>; def MRM_C2 : Format<66>; def MRM_C3 : Format<67>; def MRM_C4 : Format<68>; def MRM_C5 : Format<69>; def MRM_C6 : Format<70>; def MRM_C7 : Format<71>; def MRM_C8 : Format<72>; diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index 013f9f7bd25b..c3c9f22381f8 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -3192,11 +3192,11 @@ let SchedRW = [WriteFence] in { // Load, store, and memory fence // TODO: As with mfence, we may want to ease the availability of sfence/lfence // to include any 64-bit target. -def SFENCE : I<0xAE, MRM_F8, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>, +def SFENCE : I<0xAE, MRM7X, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>, PS, Requires<[HasSSE1]>; -def LFENCE : I<0xAE, MRM_E8, (outs), (ins), "lfence", [(int_x86_sse2_lfence)]>, +def LFENCE : I<0xAE, MRM5X, (outs), (ins), "lfence", [(int_x86_sse2_lfence)]>, PS, Requires<[HasSSE2]>; -def MFENCE : I<0xAE, MRM_F0, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>, +def MFENCE : I<0xAE, MRM6X, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>, PS, Requires<[HasMFence]>; } // SchedRW diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt index 5fba2a8be65b..baa12bf0c179 100644 --- a/llvm/test/MC/Disassembler/X86/x86-32.txt +++ b/llvm/test/MC/Disassembler/X86/x86-32.txt @@ -57,11 +57,56 @@ # CHECK: callw -1 0x66 0xe8 0xff 0xff +# CHECK: lfence +# CHECK: lfence +# CHECK: lfence +# CHECK: lfence +# CHECK: lfence +# CHECK: lfence +# CHECK: lfence # CHECK: lfence 0x0f 0xae 0xe8 +0x0f 0xae 0xe9 +0x0f 0xae 0xea +0x0f 0xae 0xeb +0x0f 0xae 0xec +0x0f 0xae 0xed +0x0f 0xae 0xee +0x0f 0xae 0xef +# CHECK: mfence +# CHECK: mfence +# CHECK: mfence +# CHECK: mfence +# CHECK: mfence +# CHECK: mfence +# CHECK: mfence # CHECK: mfence 0x0f 0xae 0xf0 +0x0f 0xae 0xf1 +0x0f 0xae 0xf2 +0x0f 0xae 0xf3 +0x0f 0xae 0xf4 +0x0f 0xae 0xf5 +0x0f 0xae 0xf6 +0x0f 0xae 0xf7 + +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +# CHECK: sfence +0x0f 0xae 0xf8 +0x0f 0xae 0xf9 +0x0f 0xae 0xfa +0x0f 0xae 0xfb +0x0f 0xae 0xfc +0x0f 0xae 0xfd +0x0f 0xae 0xfe +0x0f 0xae 0xff # CHECK: monitor 0x0f 0x01 0xc8 diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index b4fc76405a88..fe235e8a3dfb 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -49,6 +49,14 @@ static const char *isInvalidMemoryInstr(const Instruction &Instr) { case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: + case X86II::MRM0X: + case X86II::MRM1X: + case X86II::MRM2X: + case X86II::MRM3X: + case X86II::MRM4X: + case X86II::MRM5X: + case X86II::MRM6X: + case X86II::MRM7X: case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2: diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index 621e529197ae..f31e43bd9fca 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -708,6 +708,14 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPERAND(immediate) HANDLE_OPERAND(immediate) break; + case X86Local::MRM0X: + case X86Local::MRM1X: + case X86Local::MRM2X: + case X86Local::MRM3X: + case X86Local::MRM4X: + case X86Local::MRM5X: + case X86Local::MRM6X: + case X86Local::MRM7X: #define MAP(from, to) case X86Local::MRM_##from: X86_INSTR_MRM_MAPPING #undef MAP @@ -778,6 +786,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::MRM6r: case X86Local::MRM7r: filter = std::make_unique(true, Form - X86Local::MRM0r); break; + case X86Local::MRM0X: case X86Local::MRM1X: + case X86Local::MRM2X: case X86Local::MRM3X: + case X86Local::MRM4X: case X86Local::MRM5X: + case X86Local::MRM6X: case X86Local::MRM7X: + filter = std::make_unique(true, Form - X86Local::MRM0X); + break; case X86Local::MRM0m: case X86Local::MRM1m: case X86Local::MRM2m: case X86Local::MRM3m: case X86Local::MRM4m: case X86Local::MRM5m: diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index 31f2383ad489..2bf6d1a39803 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -103,22 +103,24 @@ namespace X86Local { RawFrmImm16 = 8, AddCCFrm = 9, PrefixByte = 10, - MRMDestMem = 32, - MRMSrcMem = 33, - MRMSrcMem4VOp3 = 34, - MRMSrcMemOp4 = 35, - MRMSrcMemCC = 36, - MRMXmCC = 38, MRMXm = 39, - MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43, - MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47, - MRMDestReg = 48, - MRMSrcReg = 49, - MRMSrcReg4VOp3 = 50, - MRMSrcRegOp4 = 51, - MRMSrcRegCC = 52, - MRMXrCC = 54, MRMXr = 55, - MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59, - MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63, + MRMDestMem = 24, + MRMSrcMem = 25, + MRMSrcMem4VOp3 = 26, + MRMSrcMemOp4 = 27, + MRMSrcMemCC = 28, + MRMXmCC = 30, MRMXm = 31, + MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35, + MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39, + MRMDestReg = 40, + MRMSrcReg = 41, + MRMSrcReg4VOp3 = 42, + MRMSrcRegOp4 = 43, + MRMSrcRegCC = 44, + MRMXrCC = 46, MRMXr = 47, + MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51, + MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55, + MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59, + MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63, #define MAP(from, to) MRM_##from = to, X86_INSTR_MRM_MAPPING #undef MAP