diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index a1f73dd287d97..b9758e22a46ae 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -608,6 +608,10 @@ namespace X86II { /// in the lower 4 bits of the opcode. AddCCFrm = 9, + /// PrefixByte - This form is used for instructions that represent a prefix + /// byte like data16 or rep. + PrefixByte = 10, + /// MRM[0-7][rm] - These forms are used to represent instructions that use /// a Mod/RM byte, and use the middle field to hold extended opcode /// information. In the intel manual these are represented as /0, /1, ... @@ -927,6 +931,11 @@ namespace X86II { NOTRACK = 1ULL << NoTrackShift }; + /// \returns true if the instruction with given opcode is a prefix. + inline bool isPrefix(uint64_t TSFlags) { + return (TSFlags & X86II::FormMask) == PrefixByte; + } + /// \returns the "base" X86 opcode for the specified machine /// instruction. inline uint8_t getBaseOpcodeFor(uint64_t TSFlags) { @@ -1055,6 +1064,7 @@ namespace X86II { case X86II::RawFrmDst: case X86II::RawFrmDstSrc: case X86II::AddCCFrm: + case X86II::PrefixByte: return -1; case X86II::MRMDestMem: return 0; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index cec04012aa67d..c93f85168970b 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -870,6 +870,7 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, default: llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!"); case X86II::RawFrm: + case X86II::PrefixByte: break; case X86II::MRMDestMem: { // MRMDestMem instructions forms: @@ -1423,6 +1424,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case X86II::RawFrmDstSrc: case X86II::RawFrmSrc: case X86II::RawFrmDst: + case X86II::PrefixByte: emitByte(BaseOpcode, CurByte, OS); break; case X86II::AddCCFrm: { diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td index 2f797fcfb8de6..7da1f3593fe02 100644 --- a/llvm/lib/Target/X86/X86InstrFormats.td +++ b/llvm/lib/Target/X86/X86InstrFormats.td @@ -27,6 +27,7 @@ def RawFrmDstSrc : Format<6>; 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>; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 7d999c61aa1a9..8629cf728b45c 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -2169,24 +2169,24 @@ def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst), // Lock instruction prefix let SchedRW = [WriteMicrocoded] in -def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>; +def LOCK_PREFIX : I<0xF0, PrefixByte, (outs), (ins), "lock", []>; let SchedRW = [WriteNop] in { // Rex64 instruction prefix -def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>, +def REX64_PREFIX : I<0x48, PrefixByte, (outs), (ins), "rex64", []>, Requires<[In64BitMode]>; // Data16 instruction prefix -def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>; +def DATA16_PREFIX : I<0x66, PrefixByte, (outs), (ins), "data16", []>; } // SchedRW // Repeat string operation instruction prefixes let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in { // Repeat (used with INS, OUTS, MOVS, LODS and STOS) -def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>; +def REP_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "rep", []>; // Repeat while not equal (used with CMPS and SCAS) -def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>; +def REPNE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "repne", []>; } // String manipulation instructions diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index 7f41feb6c0d90..8469632fafe69 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -149,12 +149,12 @@ def MOV64cr : I<0x22, MRMSrcReg, (outs CONTROL_REG:$dst), (ins GR64:$src), // Segment override instruction prefixes let SchedRW = [WriteNop] in { -def CS_PREFIX : I<0x2E, RawFrm, (outs), (ins), "cs", []>; -def SS_PREFIX : I<0x36, RawFrm, (outs), (ins), "ss", []>; -def DS_PREFIX : I<0x3E, RawFrm, (outs), (ins), "ds", []>; -def ES_PREFIX : I<0x26, RawFrm, (outs), (ins), "es", []>; -def FS_PREFIX : I<0x64, RawFrm, (outs), (ins), "fs", []>; -def GS_PREFIX : I<0x65, RawFrm, (outs), (ins), "gs", []>; +def CS_PREFIX : I<0x2E, PrefixByte, (outs), (ins), "cs", []>; +def SS_PREFIX : I<0x36, PrefixByte, (outs), (ins), "ss", []>; +def DS_PREFIX : I<0x3E, PrefixByte, (outs), (ins), "ds", []>; +def ES_PREFIX : I<0x26, PrefixByte, (outs), (ins), "es", []>; +def FS_PREFIX : I<0x64, PrefixByte, (outs), (ins), "fs", []>; +def GS_PREFIX : I<0x65, PrefixByte, (outs), (ins), "gs", []>; } // SchedRW //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86InstrTSX.td b/llvm/lib/Target/X86/X86InstrTSX.td index 41b839425ccd9..1bdb9741676a5 100644 --- a/llvm/lib/Target/X86/X86InstrTSX.td +++ b/llvm/lib/Target/X86/X86InstrTSX.td @@ -52,8 +52,8 @@ def XABORT : Ii8<0xc6, MRM_F8, (outs), (ins i8imm:$imm), let SchedRW = [WriteSystem] in { let isAsmParserOnly = 1 in { -def XACQUIRE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "xacquire", []>; -def XRELEASE_PREFIX : I<0xF3, RawFrm, (outs), (ins), "xrelease", []>; +def XACQUIRE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "xacquire", []>; +def XRELEASE_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "xrelease", []>; } } // SchedRW diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 232af30b4aee8..b4fc76405a880 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -33,6 +33,7 @@ static const char *isInvalidMemoryInstr(const Instruction &Instr) { case X86II::Pseudo: case X86II::RawFrm: case X86II::AddCCFrm: + case X86II::PrefixByte: case X86II::MRMDestReg: case X86II::MRMSrcReg: case X86II::MRMSrcReg4VOp3: diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index ff3a111858ec1..621e529197ae3 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -459,6 +459,8 @@ void RecognizableInstr::emitInstructionSpecifier() { switch (Form) { default: llvm_unreachable("Unhandled form"); + case X86Local::PrefixByte: + return; case X86Local::RawFrmSrc: HANDLE_OPERAND(relocation); return; @@ -749,6 +751,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::RawFrmImm8: case X86Local::RawFrmImm16: case X86Local::AddCCFrm: + case X86Local::PrefixByte: filter = std::make_unique(); break; case X86Local::MRMDestReg: diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index b15bef4e1931d..31f2383ad4895 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -102,6 +102,7 @@ namespace X86Local { RawFrmImm8 = 7, RawFrmImm16 = 8, AddCCFrm = 9, + PrefixByte = 10, MRMDestMem = 32, MRMSrcMem = 33, MRMSrcMem4VOp3 = 34,