diff options
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 19 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Instr3DNow.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrFormats.td | 23 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.cpp | 19 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.h | 4 |
6 files changed, 42 insertions, 44 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 94536715682..69e468168e7 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -433,6 +433,14 @@ namespace X86II { // XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions. XOPA = 6 << OpMapShift, + /// ThreeDNow - This indicates that the instruction uses the + /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents + /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction + /// storing a classifier in the imm8 field. To simplify our implementation, + /// we handle this by storeing the classifier in the opcode field and using + /// this flag to indicate that the encoder should do the wacky 3DNow! thing. + ThreeDNow = 7 << OpMapShift, + //===------------------------------------------------------------------===// // REX_W - REX prefixes are instruction prefixes used in 64-bit mode. // They are used to specify GPRs and SSE registers, 64-bit operand size, @@ -562,17 +570,8 @@ namespace X86II { CD8_Scale_Shift = EVEX_BShift + 1, CD8_Scale_Mask = 127ULL << CD8_Scale_Shift, - /// Has3DNow0F0FOpcode - This flag indicates that the instruction uses the - /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents - /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction - /// storing a classifier in the imm8 field. To simplify our implementation, - /// we handle this by storeing the classifier in the opcode field and using - /// this flag to indicate that the encoder should do the wacky 3DNow! thing. - Has3DNow0F0FOpcodeShift = CD8_Scale_Shift + 7, - Has3DNow0F0FOpcode = 1ULL << Has3DNow0F0FOpcodeShift, - /// Explicitly specified rounding control - EVEX_RCShift = Has3DNow0F0FOpcodeShift + 1, + EVEX_RCShift = CD8_Scale_Shift + 7, EVEX_RC = 1ULL << EVEX_RCShift, // NOTRACK prefix diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 3ba8b500dfd..4cf8dd9e782 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1163,9 +1163,10 @@ bool X86MCCodeEmitter::emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // 0x0F escape code must be emitted just before the opcode. switch (TSFlags & X86II::OpMapMask) { - case X86II::TB: // Two-byte opcode map - case X86II::T8: // 0F 38 - case X86II::TA: // 0F 3A + case X86II::TB: // Two-byte opcode map + case X86II::T8: // 0F 38 + case X86II::TA: // 0F 3A + case X86II::ThreeDNow: // 0F 0F, second 0F emitted by caller. EmitByte(0x0F, CurByte, OS); break; } @@ -1261,7 +1262,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags); - if (TSFlags & X86II::Has3DNow0F0FOpcode) + if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow) BaseOpcode = 0x0F; // Weird 3DNow! encoding. uint64_t Form = TSFlags & X86II::FormMask; @@ -1555,7 +1556,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, } } - if (TSFlags & X86II::Has3DNow0F0FOpcode) + if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow) EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); #ifndef NDEBUG diff --git a/llvm/lib/Target/X86/X86Instr3DNow.td b/llvm/lib/Target/X86/X86Instr3DNow.td index edb7dd619fb..065383f67a4 100644 --- a/llvm/lib/Target/X86/X86Instr3DNow.td +++ b/llvm/lib/Target/X86/X86Instr3DNow.td @@ -44,14 +44,14 @@ def I3DNOW_PSHUF_ITINS : OpndItins< class I3DNow<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pat, InstrItinClass itin> - : I<o, F, outs, ins, asm, pat, itin>, TB, Requires<[Has3DNow]> { + : I<o, F, outs, ins, asm, pat, itin>, Requires<[Has3DNow]> { } class I3DNow_binop<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat, InstrItinClass itin> : I3DNow<o, F, (outs VR64:$dst), ins, !strconcat(Mnemonic, "\t{$src2, $dst|$dst, $src2}"), pat, itin>, - Has3DNow0F0FOpcode { + ThreeDNow { let Constraints = "$src1 = $dst"; } @@ -59,7 +59,7 @@ class I3DNow_conv<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat, InstrItinClass itin> : I3DNow<o, F, (outs VR64:$dst), ins, !strconcat(Mnemonic, "\t{$src, $dst|$dst, $src}"), pat, itin>, - Has3DNow0F0FOpcode; + ThreeDNow; multiclass I3DNow_binop_rm_int<bits<8> opc, string Mn, OpndItins itins, bit Commutable = 0, string Ver = ""> { @@ -111,7 +111,7 @@ defm PMULHRW : I3DNow_binop_rm_int<0xB7, "pmulhrw", I3DNOW_MISC_FUNC_ITINS, 1>; // FIXME: Is there a better scheduler class for EMMS/FEMMS? let SchedRW = [WriteMicrocoded] in def FEMMS : I3DNow<0x0E, RawFrm, (outs), (ins), "femms", - [(int_x86_mmx_femms)], IIC_MMX_EMMS>; + [(int_x86_mmx_femms)], IIC_MMX_EMMS>, TB; // PREFETCHWT1 is supported we want to use it for everything but T0. def PrefetchWLevel : PatFrag<(ops), (i32 imm), [{ @@ -128,7 +128,7 @@ let Predicates = [Has3DNow, NoSSEPrefetch] in def PREFETCH : I3DNow<0x0D, MRM0m, (outs), (ins i8mem:$addr), "prefetch\t$addr", [(prefetch addr:$addr, imm, imm, (i32 1))], - IIC_SSE_PREFETCH>; + IIC_SSE_PREFETCH>, TB; def PREFETCHW : I<0x0D, MRM1m, (outs), (ins i8mem:$addr), "prefetchw\t$addr", [(prefetch addr:$addr, (i32 1), (i32 PrefetchWLevel), (i32 1))], diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td index 53f71127d2b..ba8e077c433 100644 --- a/llvm/lib/Target/X86/X86InstrFormats.td +++ b/llvm/lib/Target/X86/X86InstrFormats.td @@ -136,13 +136,14 @@ def XD : Prefix<4>; class Map<bits<3> val> { bits<3> Value = val; } -def OB : Map<0>; -def TB : Map<1>; -def T8 : Map<2>; -def TA : Map<3>; -def XOP8 : Map<4>; -def XOP9 : Map<5>; -def XOPA : Map<6>; +def OB : Map<0>; +def TB : Map<1>; +def T8 : Map<2>; +def TA : Map<3>; +def XOP8 : Map<4>; +def XOP9 : Map<5>; +def XOPA : Map<6>; +def ThreeDNow : Map<7>; // Class specifying the encoding class Encoding<bits<2> val> { @@ -188,6 +189,7 @@ class TA { Map OpMap = TA; } class XOP8 { Map OpMap = XOP8; Prefix OpPrefix = PS; } class XOP9 { Map OpMap = XOP9; Prefix OpPrefix = PS; } class XOPA { Map OpMap = XOPA; Prefix OpPrefix = PS; } +class ThreeDNow { Map OpMap = ThreeDNow; } class OBXS { Prefix OpPrefix = XS; } class PS : TB { Prefix OpPrefix = PS; } class PD : TB { Prefix OpPrefix = PD; } @@ -224,7 +226,6 @@ class EVEX_CD8<int esize, CD8VForm form> { bits<3> CD8_Form = form.Value; } -class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; } class XOP { Encoding OpEnc = EncXOP; } class XOP_4V : XOP { bit hasVEX_4V = 1; } @@ -295,7 +296,6 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins, // Declare it int rather than bits<4> so that all bits are defined when // assigning to bits<7>. int CD8_EltSize = 0; // Compressed disp8 form - element-size in bytes. - bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding? bit hasEVEX_RC = 0; // Explicitly specified rounding control in FP instruction. bit hasNoTrackPrefix = 0; // Does this inst has 0x3E (NoTrack) prefix? @@ -347,9 +347,8 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins, let TSFlags{45} = hasEVEX_B; // If we run out of TSFlags bits, it's possible to encode this in 3 bits. let TSFlags{52-46} = CD8_Scale; - let TSFlags{53} = has3DNow0F0FOpcode; - let TSFlags{54} = hasEVEX_RC; - let TSFlags{55} = hasNoTrackPrefix; + let TSFlags{53} = hasEVEX_RC; + let TSFlags{54} = hasNoTrackPrefix; } class PseudoI<dag oops, dag iops, list<dag> pattern, diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index 5da4a1f04b5..e223e859f6f 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -90,7 +90,6 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); - Has3DNow0F0FOpcode = Rec->getValueAsBit("has3DNow0F0FOpcode"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); CD8_Scale = byteFromRec(Rec, "CD8_Scale"); @@ -289,7 +288,7 @@ InstructionContext RecognizableInstr::insnContext() const { errs() << "Instruction does not use a prefix: " << Name << "\n"; llvm_unreachable("Invalid prefix"); } - } else if (Has3DNow0F0FOpcode) { + } else if (OpMap == X86Local::ThreeDNow) { insnContext = IC_3DNOW; } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) { if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)) @@ -716,15 +715,17 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::XOP8: case X86Local::XOP9: case X86Local::XOPA: + case X86Local::ThreeDNow: switch (OpMap) { default: llvm_unreachable("Unexpected map!"); - case X86Local::OB: opcodeType = ONEBYTE; break; - case X86Local::TB: opcodeType = TWOBYTE; break; - case X86Local::T8: opcodeType = THREEBYTE_38; break; - case X86Local::TA: opcodeType = THREEBYTE_3A; break; - case X86Local::XOP8: opcodeType = XOP8_MAP; break; - case X86Local::XOP9: opcodeType = XOP9_MAP; break; - case X86Local::XOPA: opcodeType = XOPA_MAP; break; + case X86Local::OB: opcodeType = ONEBYTE; break; + case X86Local::TB: opcodeType = TWOBYTE; break; + case X86Local::T8: opcodeType = THREEBYTE_38; break; + case X86Local::TA: opcodeType = THREEBYTE_3A; break; + case X86Local::XOP8: opcodeType = XOP8_MAP; break; + case X86Local::XOP9: opcodeType = XOP9_MAP; break; + case X86Local::XOPA: opcodeType = XOPA_MAP; break; + case X86Local::ThreeDNow: opcodeType = TWOBYTE; break; } switch (Form) { diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index 0959704e716..36579d0fcaf 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -122,7 +122,7 @@ namespace X86Local { }; enum { - OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6 + OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6, ThreeDNow = 7 }; enum { @@ -191,8 +191,6 @@ private: bool HasEVEX_KZ; /// The hasEVEX_B field from the record bool HasEVEX_B; - /// The has3DNow0F0FOpcode field from the record - bool Has3DNow0F0FOpcode; /// Indicates that the instruction uses the L and L' fields for RC. bool EncodeRC; /// The isCodeGenOnly field from the record |