diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index c085f147814..b690de2d3fb 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -324,9 +324,9 @@ namespace X86II { //===------------------------------------------------------------------===// // Op0Mask - There are several prefix bytes that are used to form two byte - // opcodes. These are currently 0x0F, 0xF3, and 0xD8-0xDF. This mask is - // used to obtain the setting of this field. If no bits in this field is - // set, there is no prefix byte for obtaining a multibyte opcode. + // opcodes. This mask is used to obtain the setting of this field. If no + // bits in this field is set, there is no prefix byte for obtaining a + // multibyte opcode. // Op0Shift = 9, Op0Mask = 0x1F << Op0Shift, @@ -335,10 +335,6 @@ namespace X86II { // starts with a 0x0F byte before the real opcode. TB = 1 << Op0Shift, - // REP - The 0xF3 prefix byte indicating repetition of the following - // instruction. - REP = 2 << Op0Shift, - // D8-DF - These escape opcodes are used by the floating point unit. These // values must remain sequential. D8 = 3 << Op0Shift, D9 = 4 << Op0Shift, @@ -445,9 +441,13 @@ namespace X86II { LOCKShift = FPTypeShift + 3, LOCK = 1 << LOCKShift, - // Execution domain for SSE instructions in bits 23, 24. - // 0 in bits 23-24 means normal, non-SSE instruction. - SSEDomainShift = LOCKShift + 1, + // REP prefix + REPShift = LOCKShift + 1, + REP = 1 << REPShift, + + // Execution domain for SSE instructions. + // 0 means normal, non-SSE instruction. + SSEDomainShift = REPShift + 1, OpcodeShift = SSEDomainShift + 2, diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 7d81bbe9857..986e257392a 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1156,7 +1156,6 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, switch (TSFlags & X86II::Op0Mask) { default: llvm_unreachable("Invalid prefix!"); case 0: break; // No prefix! - case X86II::REP: break; // already handled. case X86II::TB: // Two-byte opcode prefix case X86II::T8: // 0F 38 case X86II::TA: // 0F 3A @@ -1273,7 +1272,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, MI, OS); // Emit the repeat opcode prefix as needed. - if ((TSFlags & X86II::Op0Mask) == X86II::REP) + if (TSFlags & X86II::REP) EmitByte(0xF3, CurByte, OS); // Emit the address size opcode prefix as needed. diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index b377419c0d6..dc75e60345e 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -667,7 +667,6 @@ void Emitter::emitOpcodePrefix(uint64_t TSFlags, case X86II::A7: // 0F A7 Need0FPrefix = true; break; - case X86II::REP: break; // already handled. case X86II::PD: // 66 0F case X86II::T8PD: // 66 0F 38 case X86II::TAPD: // 66 0F 3A @@ -1125,7 +1124,7 @@ void Emitter::emitInstruction(MachineInstr &MI, emitSegmentOverridePrefix(TSFlags, MemoryOperand, MI); // Emit the repeat opcode prefix as needed. - if ((Desc->TSFlags & X86II::Op0Mask) == X86II::REP) + if (Desc->TSFlags & X86II::REP) MCE.emitByte(0xF3); // Emit the address size opcode prefix as needed. diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index ded1d903370..83cd7e1b9db 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -119,8 +119,8 @@ class OpSize16 { bit hasOpSize16Prefix = 1; } class AdSize { bit hasAdSizePrefix = 1; } class REX_W { bit hasREX_WPrefix = 1; } class LOCK { bit hasLockPrefix = 1; } +class REP { bit hasREPPrefix = 1; } class TB { bits<5> Prefix = 1; } -class REP { bits<5> Prefix = 2; } class D8 { bits<5> Prefix = 3; } class D9 { bits<5> Prefix = 4; } class DA { bits<5> Prefix = 5; } @@ -205,6 +205,7 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, FPFormat FPForm = NotFP; // What flavor of FP instruction is this? bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix? Domain ExeDomain = d; + bit hasREPPrefix = 0; // Does this inst have a REP prefix? bit hasVEXPrefix = 0; // Does this inst require a VEX prefix? bit hasVEX_WPrefix = 0; // Does this inst set the VEX_W field? bit hasVEX_4VPrefix = 0; // Does this inst require the VEX.VVVV field? @@ -236,26 +237,27 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, let TSFlags{18-15} = ImmT.Value; let TSFlags{21-19} = FPForm.Value; let TSFlags{22} = hasLockPrefix; - let TSFlags{24-23} = ExeDomain.Value; - let TSFlags{32-25} = Opcode; - let TSFlags{33} = hasVEXPrefix; - let TSFlags{34} = hasVEX_WPrefix; - let TSFlags{35} = hasVEX_4VPrefix; - let TSFlags{36} = hasVEX_4VOp3Prefix; - let TSFlags{37} = hasVEX_i8ImmReg; - let TSFlags{38} = hasVEX_L; - let TSFlags{39} = ignoresVEX_L; - let TSFlags{40} = hasEVEXPrefix; - let TSFlags{41} = hasEVEX_K; - let TSFlags{42} = hasEVEX_Z; - let TSFlags{43} = hasEVEX_L2; - let TSFlags{44} = hasEVEX_B; - let TSFlags{46-45} = EVEX_CD8E; - let TSFlags{49-47} = EVEX_CD8V; - let TSFlags{50} = has3DNow0F0FOpcode; - let TSFlags{51} = hasMemOp4Prefix; - let TSFlags{52} = hasXOP_Prefix; - let TSFlags{53} = hasEVEX_RC; + let TSFlags{23} = hasREPPrefix; + let TSFlags{25-24} = ExeDomain.Value; + let TSFlags{33-26} = Opcode; + let TSFlags{34} = hasVEXPrefix; + let TSFlags{35} = hasVEX_WPrefix; + let TSFlags{36} = hasVEX_4VPrefix; + let TSFlags{37} = hasVEX_4VOp3Prefix; + let TSFlags{38} = hasVEX_i8ImmReg; + let TSFlags{39} = hasVEX_L; + let TSFlags{40} = ignoresVEX_L; + let TSFlags{41} = hasEVEXPrefix; + let TSFlags{42} = hasEVEX_K; + let TSFlags{43} = hasEVEX_Z; + let TSFlags{44} = hasEVEX_L2; + let TSFlags{45} = hasEVEX_B; + let TSFlags{47-46} = EVEX_CD8E; + let TSFlags{50-48} = EVEX_CD8V; + let TSFlags{51} = has3DNow0F0FOpcode; + let TSFlags{52} = hasMemOp4Prefix; + let TSFlags{53} = hasXOP_Prefix; + let TSFlags{54} = hasEVEX_RC; } class PseudoI pattern> diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index e0b4be2eb39..f84fafdde10 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -77,7 +77,6 @@ namespace X86Local { enum { TB = 1, - REP = 2, D8 = 3, D9 = 4, DA = 5, DB = 6, DC = 7, DD = 8, DE = 9, DF = 10, XD = 11, XS = 12, @@ -250,6 +249,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); + HasREPPrefix = Rec->getValueAsBit("hasREPPrefix"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); @@ -480,7 +480,7 @@ InstructionContext RecognizableInstr::insnContext() const { Prefix == X86Local::TAXD) insnContext = IC_XD; else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS || - Prefix == X86Local::REP) + HasREPPrefix) insnContext = IC_XS; else insnContext = IC; @@ -1090,7 +1090,6 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { filter = new ExactFilter(Opcode); opcodeToSet = 0xd8 + (Prefix - X86Local::D8); break; - case X86Local::REP: case 0: opcodeType = ONEBYTE; switch (Opcode) { diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index 08e984e9509..bf758ed2bbd 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -78,6 +78,8 @@ private: bool HasEVEX_B; /// The hasLockPrefix field from the record bool HasLockPrefix; + /// The hasREPPrefix field from the record + bool HasREPPrefix; /// The isCodeGenOnly field from the record bool IsCodeGenOnly; /// The ForceDisassemble field from the record