diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index b690de2d3fb..78ed12dc4ce 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -323,60 +323,56 @@ namespace X86II { AdSize = 1 << 8, //===------------------------------------------------------------------===// - // Op0Mask - There are several prefix bytes that are used to form two byte - // 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. + // OpPrefix - There are several prefix bytes that are used as opcode + // extensions. These are 0x66, 0xF3, and 0xF2. If this field is 0 there is + // no prefix. // - Op0Shift = 9, - Op0Mask = 0x1F << Op0Shift, - - // TB - TwoByte - Set if this instruction has a two byte opcode, which - // starts with a 0x0F byte before the real opcode. - TB = 1 << Op0Shift, - - // D8-DF - These escape opcodes are used by the floating point unit. These - // values must remain sequential. - D8 = 3 << Op0Shift, D9 = 4 << Op0Shift, - DA = 5 << Op0Shift, DB = 6 << Op0Shift, - DC = 7 << Op0Shift, DD = 8 << Op0Shift, - DE = 9 << Op0Shift, DF = 10 << Op0Shift, - - // XS, XD - These prefix codes are for single and double precision scalar - // floating point operations performed in the SSE registers. - XD = 11 << Op0Shift, XS = 12 << Op0Shift, - - // T8, TA, A6, A7 - Prefix after the 0x0F prefix. - T8 = 13 << Op0Shift, TA = 14 << Op0Shift, - A6 = 15 << Op0Shift, A7 = 16 << Op0Shift, - - // T8XD - Prefix before and after 0x0F. Combination of T8 and XD. - T8XD = 17 << Op0Shift, - - // T8XS - Prefix before and after 0x0F. Combination of T8 and XS. - T8XS = 18 << Op0Shift, - - // TAXD - Prefix before and after 0x0F. Combination of TA and XD. - TAXD = 19 << Op0Shift, - - // XOP8 - Prefix to include use of imm byte. - XOP8 = 20 << Op0Shift, - - // XOP9 - Prefix to exclude use of imm byte. - XOP9 = 21 << Op0Shift, - - // XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions. - XOPA = 22 << Op0Shift, + OpPrefixShift = 9, + OpPrefixMask = 0x3 << OpPrefixShift, // PD - Prefix code for packed double precision vector floating point // operations performed in the SSE registers. - PD = 23 << Op0Shift, + PD = 1 << OpPrefixShift, - // T8PD - Prefix before and after 0x0F. Combination of T8 and PD. - T8PD = 24 << Op0Shift, + // XS, XD - These prefix codes are for single and double precision scalar + // floating point operations performed in the SSE registers. + XS = 2 << OpPrefixShift, XD = 3 << OpPrefixShift, - // TAPD - Prefix before and after 0x0F. Combination of TA and PD. - TAPD = 25 << Op0Shift, + //===------------------------------------------------------------------===// + // OpMap - This field determines which opcode map this instruction + // belongs to. i.e. one-byte, two-byte, 0x0f 0x38, 0x0f 0x3a, etc. + // + OpMapShift = OpPrefixShift + 2, + OpMapMask = 0x1f << OpMapShift, + + // OB - OneByte - Set if this instruction has a one byte opcode. + OB = 0 << OpMapShift, + + // TB - TwoByte - Set if this instruction has a two byte opcode, which + // starts with a 0x0F byte before the real opcode. + TB = 1 << OpMapShift, + + // T8, TA - Prefix after the 0x0F prefix. + T8 = 2 << OpMapShift, TA = 3 << OpMapShift, + + // XOP8 - Prefix to include use of imm byte. + XOP8 = 4 << OpMapShift, + + // XOP9 - Prefix to exclude use of imm byte. + XOP9 = 5 << OpMapShift, + + // XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions. + XOPA = 6 << OpMapShift, + + // D8-DF - These escape opcodes are used by the floating point unit. These + // values must remain sequential. + D8 = 7 << OpMapShift, D9 = 8 << OpMapShift, + DA = 9 << OpMapShift, DB = 10 << OpMapShift, + DC = 11 << OpMapShift, DD = 12 << OpMapShift, + DE = 13 << OpMapShift, DF = 14 << OpMapShift, + + // A6, A7 - Prefix after the 0x0F prefix. + A6 = 15 << OpMapShift, A7 = 16 << OpMapShift, //===------------------------------------------------------------------===// // REX_W - REX prefixes are instruction prefixes used in 64-bit mode. @@ -384,7 +380,7 @@ namespace X86II { // etc. We only cares about REX.W and REX.R bits and only the former is // statically determined. // - REXShift = Op0Shift + 5, + REXShift = OpMapShift + 5, REX_W = 1 << REXShift, //===------------------------------------------------------------------===// diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 986e257392a..7affe800bef 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -651,7 +651,7 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // 0b01000: XOP map select - 08h instructions with imm byte // 0b01001: XOP map select - 09h instructions with no imm byte // 0b01010: XOP map select - 0Ah instructions with imm dword - unsigned char VEX_5M = 0x1; + unsigned char VEX_5M = 0; // VEX_4V (VEX vvvv field): a register specifier // (in 1's complement form) or 1111 if unused. @@ -707,56 +707,22 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, if (HasEVEX && ((TSFlags >> X86II::VEXShift) & X86II::EVEX_B)) EVEX_b = 1; - switch (TSFlags & X86II::Op0Mask) { - default: llvm_unreachable("Invalid prefix!"); - case X86II::T8: // 0F 38 - VEX_5M = 0x2; - break; - case X86II::TA: // 0F 3A - VEX_5M = 0x3; - break; - case X86II::T8PD: // 66 0F 38 - VEX_PP = 0x1; - VEX_5M = 0x2; - break; - case X86II::T8XS: // F3 0F 38 - VEX_PP = 0x2; - VEX_5M = 0x2; - break; - case X86II::T8XD: // F2 0F 38 - VEX_PP = 0x3; - VEX_5M = 0x2; - break; - case X86II::TAPD: // 66 0F 3A - VEX_PP = 0x1; - VEX_5M = 0x3; - break; - case X86II::TAXD: // F2 0F 3A - VEX_PP = 0x3; - VEX_5M = 0x3; - break; - case X86II::PD: // 66 0F - VEX_PP = 0x1; - break; - case X86II::XS: // F3 0F - VEX_PP = 0x2; - break; - case X86II::XD: // F2 0F - VEX_PP = 0x3; - break; - case X86II::XOP8: - VEX_5M = 0x8; - break; - case X86II::XOP9: - VEX_5M = 0x9; - break; - case X86II::XOPA: - VEX_5M = 0xA; - break; - case X86II::TB: // VEX_5M/VEX_PP already correct - break; + switch (TSFlags & X86II::OpPrefixMask) { + default: break; // VEX_PP already correct + case X86II::PD: VEX_PP = 0x1; break; // 66 + case X86II::XS: VEX_PP = 0x2; break; // F3 + case X86II::XD: VEX_PP = 0x3; break; // F2 } + switch (TSFlags & X86II::OpMapMask) { + default: llvm_unreachable("Invalid prefix!"); + case X86II::TB: VEX_5M = 0x1; break; // 0F + case X86II::T8: VEX_5M = 0x2; break; // 0F 38 + case X86II::TA: VEX_5M = 0x3; break; // 0F 3A + case X86II::XOP8: VEX_5M = 0x8; break; + case X86II::XOP9: VEX_5M = 0x9; break; + case X86II::XOPA: VEX_5M = 0xA; break; + } // Classify VEX_B, VEX_4V, VEX_R, VEX_X unsigned NumOps = Desc.getNumOperands(); @@ -1152,44 +1118,15 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, if (TSFlags & (is16BitMode(STI) ? X86II::OpSize16 : X86II::OpSize)) EmitByte(0x66, CurByte, OS); - bool Need0FPrefix = false; - switch (TSFlags & X86II::Op0Mask) { - default: llvm_unreachable("Invalid prefix!"); - case 0: break; // No prefix! - case X86II::TB: // Two-byte opcode prefix - case X86II::T8: // 0F 38 - case X86II::TA: // 0F 3A - case X86II::A6: // 0F A6 - case X86II::A7: // 0F A7 - Need0FPrefix = true; - break; - case X86II::PD: // 66 0F - case X86II::T8PD: // 66 0F 38 - case X86II::TAPD: // 66 0F 3A + switch (TSFlags & X86II::OpPrefixMask) { + case X86II::PD: // 66 EmitByte(0x66, CurByte, OS); - Need0FPrefix = true; break; - case X86II::XS: // F3 0F - case X86II::T8XS: // F3 0F 38 + case X86II::XS: // F3 EmitByte(0xF3, CurByte, OS); - Need0FPrefix = true; break; - case X86II::XD: // F2 0F - case X86II::T8XD: // F2 0F 38 - case X86II::TAXD: // F2 0F 3A + case X86II::XD: // F2 EmitByte(0xF2, CurByte, OS); - Need0FPrefix = true; - break; - case X86II::D8: - case X86II::D9: - case X86II::DA: - case X86II::DB: - case X86II::DC: - case X86II::DD: - case X86II::DE: - case X86II::DF: - EmitByte(0xD8+(((TSFlags & X86II::Op0Mask) - X86II::D8) >> X86II::Op0Shift), - CurByte, OS); break; } @@ -1201,19 +1138,25 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, } // 0x0F escape code must be emitted just before the opcode. - if (Need0FPrefix) + switch (TSFlags & X86II::OpMapMask) { + case X86II::TB: // Two-byte opcode map + case X86II::T8: // 0F 38 + case X86II::TA: // 0F 3A + case X86II::A6: // 0F A6 + case X86II::A7: // 0F A7 EmitByte(0x0F, CurByte, OS); + break; + case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: + case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: + EmitByte(0xD8+(((TSFlags & X86II::OpMapMask) - X86II::D8) >> + X86II::OpMapShift), CurByte, OS); + break; + } - // FIXME: Pull this up into previous switch if REX can be moved earlier. - switch (TSFlags & X86II::Op0Mask) { - case X86II::T8PD: // 66 0F 38 - case X86II::T8XS: // F3 0F 38 - case X86II::T8XD: // F2 0F 38 + switch (TSFlags & X86II::OpMapMask) { case X86II::T8: // 0F 38 EmitByte(0x38, CurByte, OS); break; - case X86II::TAPD: // 66 0F 3A - case X86II::TAXD: // F2 0F 3A case X86II::TA: // 0F 3A EmitByte(0x3A, CurByte, OS); break; diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index dc75e60345e..5d36d936c58 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -658,40 +658,16 @@ void Emitter::emitOpcodePrefix(uint64_t TSFlags, if (TSFlags & X86II::OpSize) MCE.emitByte(0x66); - bool Need0FPrefix = false; - switch (Desc->TSFlags & X86II::Op0Mask) { - case X86II::TB: // Two-byte opcode prefix - case X86II::T8: // 0F 38 - case X86II::TA: // 0F 3A - case X86II::A6: // 0F A6 - case X86II::A7: // 0F A7 - Need0FPrefix = true; - break; - case X86II::PD: // 66 0F - case X86II::T8PD: // 66 0F 38 - case X86II::TAPD: // 66 0F 3A - MCE.emitByte(0x66); - Need0FPrefix = true; - break; - case X86II::T8XS: // F3 0F 38 - case X86II::XS: // F3 0F - MCE.emitByte(0xF3); - Need0FPrefix = true; - break; - case X86II::T8XD: // F2 0F 38 - case X86II::TAXD: // F2 0F 3A - case X86II::XD: // F2 0F - MCE.emitByte(0xF2); - Need0FPrefix = true; - break; - case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: - case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: - MCE.emitByte(0xD8+ - (((Desc->TSFlags & X86II::Op0Mask)-X86II::D8) - >> X86II::Op0Shift)); - break; // Two-byte opcode prefix - default: llvm_unreachable("Invalid prefix!"); - case 0: break; // No prefix! + switch (Desc->TSFlags & X86II::OpPrefixMask) { + case X86II::PD: // 66 + MCE.emitByte(0x66); + break; + case X86II::XS: // F3 + MCE.emitByte(0xF3); + break; + case X86II::XD: // F2 + MCE.emitByte(0xF2); + break; } // Handle REX prefix. @@ -701,27 +677,35 @@ void Emitter::emitOpcodePrefix(uint64_t TSFlags, } // 0x0F escape code must be emitted just before the opcode. - if (Need0FPrefix) + switch (Desc->TSFlags & X86II::OpMapMask) { + case X86II::TB: // Two-byte opcode map + case X86II::T8: // 0F 38 + case X86II::TA: // 0F 3A + case X86II::A6: // 0F A6 + case X86II::A7: // 0F A7 MCE.emitByte(0x0F); + break; + case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: + case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: + MCE.emitByte(0xD8+ + (((Desc->TSFlags & X86II::OpMapMask)-X86II::D8) + >> X86II::OpMapShift)); + break; + } - switch (Desc->TSFlags & X86II::Op0Mask) { - case X86II::T8PD: // 66 0F 38 - case X86II::T8XD: // F2 0F 38 - case X86II::T8XS: // F3 0F 38 - case X86II::T8: // 0F 38 - MCE.emitByte(0x38); - break; - case X86II::TAPD: // 66 0F 38 - case X86II::TAXD: // F2 0F 38 - case X86II::TA: // 0F 3A - MCE.emitByte(0x3A); - break; - case X86II::A6: // 0F A6 - MCE.emitByte(0xA6); - break; - case X86II::A7: // 0F A7 - MCE.emitByte(0xA7); - break; + switch (Desc->TSFlags & X86II::OpMapMask) { + case X86II::T8: // 0F 38 + MCE.emitByte(0x38); + break; + case X86II::TA: // 0F 3A + MCE.emitByte(0x3A); + break; + case X86II::A6: // 0F A6 + MCE.emitByte(0xA6); + break; + case X86II::A7: // 0F A7 + MCE.emitByte(0xA7); + break; } } @@ -817,7 +801,7 @@ void Emitter::emitVEXOpcodePrefix(uint64_t TSFlags, // 0b01000: XOP map select - 08h instructions with imm byte // 0b01001: XOP map select - 09h instructions with no imm byte // 0b01010: XOP map select - 0Ah instructions with imm dword - unsigned char VEX_5M = 0x1; + unsigned char VEX_5M = 0; // VEX_4V (VEX vvvv field): a register specifier // (in 1's complement form) or 1111 if unused. @@ -846,56 +830,22 @@ void Emitter::emitVEXOpcodePrefix(uint64_t TSFlags, if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) VEX_L = 1; - switch (TSFlags & X86II::Op0Mask) { - default: llvm_unreachable("Invalid prefix!"); - case X86II::T8: // 0F 38 - VEX_5M = 0x2; - break; - case X86II::TA: // 0F 3A - VEX_5M = 0x3; - break; - case X86II::T8PD: // 66 0F 38 - VEX_PP = 0x1; - VEX_5M = 0x2; - break; - case X86II::T8XS: // F3 0F 38 - VEX_PP = 0x2; - VEX_5M = 0x2; - break; - case X86II::T8XD: // F2 0F 38 - VEX_PP = 0x3; - VEX_5M = 0x2; - break; - case X86II::TAPD: // 66 0F 3A - VEX_PP = 0x1; - VEX_5M = 0x3; - break; - case X86II::TAXD: // F2 0F 3A - VEX_PP = 0x3; - VEX_5M = 0x3; - break; - case X86II::PD: // 66 0F - VEX_PP = 0x1; - break; - case X86II::XS: // F3 0F - VEX_PP = 0x2; - break; - case X86II::XD: // F2 0F - VEX_PP = 0x3; - break; - case X86II::XOP8: - VEX_5M = 0x8; - break; - case X86II::XOP9: - VEX_5M = 0x9; - break; - case X86II::XOPA: - VEX_5M = 0xA; - break; - case X86II::TB: // VEX_5M/VEX_PP already correct - break; + switch (TSFlags & X86II::OpPrefixMask) { + default: break; // VEX_PP already correct + case X86II::PD: VEX_PP = 0x1; break; // 66 + case X86II::XS: VEX_PP = 0x2; break; // F3 + case X86II::XD: VEX_PP = 0x3; break; // F2 } + switch (TSFlags & X86II::OpMapMask) { + default: llvm_unreachable("Invalid prefix!"); + case X86II::TB: VEX_5M = 0x1; break; // 0F + case X86II::T8: VEX_5M = 0x2; break; // 0F 38 + case X86II::TA: VEX_5M = 0x3; break; // 0F 3A + case X86II::XOP8: VEX_5M = 0x8; break; + case X86II::XOP9: VEX_5M = 0x9; break; + case X86II::XOPA: VEX_5M = 0xA; break; + } // Classify VEX_B, VEX_4V, VEX_R, VEX_X unsigned NumOps = Desc->getNumOperands(); diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index 83cd7e1b9db..ac04fc4f27a 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -112,6 +112,37 @@ def CD8VT2 : CD8VForm<5>; // v := 2 def CD8VT4 : CD8VForm<6>; // v := 4 def CD8VT8 : CD8VForm<7>; // v := 8 +// Class specifying the prefix used an opcode extension. +class Prefix val> { + bits<2> Value = val; +} +def NoPrfx : Prefix<0>; +def PD : Prefix<1>; +def XS : Prefix<2>; +def XD : Prefix<3>; + +// Class specifying the opcode map. +class Map val> { + bits<5> 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 D8 : Map<7>; +def D9 : Map<8>; +def DA : Map<9>; +def DB : Map<10>; +def DC : Map<11>; +def DD : Map<12>; +def DE : Map<13>; +def DF : Map<14>; +def A6 : Map<15>; +def A7 : Map<16>; + // Prefix byte classes which are used to indicate to the ad-hoc machine code // emitter that various prefix bytes are required. class OpSize { bit hasOpSizePrefix = 1; } @@ -120,30 +151,30 @@ 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 D8 { bits<5> Prefix = 3; } -class D9 { bits<5> Prefix = 4; } -class DA { bits<5> Prefix = 5; } -class DB { bits<5> Prefix = 6; } -class DC { bits<5> Prefix = 7; } -class DD { bits<5> Prefix = 8; } -class DE { bits<5> Prefix = 9; } -class DF { bits<5> Prefix = 10; } -class XD { bits<5> Prefix = 11; } -class XS { bits<5> Prefix = 12; } -class T8 { bits<5> Prefix = 13; } -class TA { bits<5> Prefix = 14; } -class A6 { bits<5> Prefix = 15; } -class A7 { bits<5> Prefix = 16; } -class T8XD { bits<5> Prefix = 17; } -class T8XS { bits<5> Prefix = 18; } -class TAXD { bits<5> Prefix = 19; } -class XOP8 { bits<5> Prefix = 20; } -class XOP9 { bits<5> Prefix = 21; } -class XOPA { bits<5> Prefix = 22; } -class PD { bits<5> Prefix = 23; } -class T8PD { bits<5> Prefix = 24; } -class TAPD { bits<5> Prefix = 25; } +class TB { Prefix OpPrefix = NoPrfx; Map OpMap = TB; } +class D8 { Map OpMap = D8; } +class D9 { Map OpMap = D9; } +class DA { Map OpMap = DA; } +class DB { Map OpMap = DB; } +class DC { Map OpMap = DC; } +class DD { Map OpMap = DD; } +class DE { Map OpMap = DE; } +class DF { Map OpMap = DF; } +class XD { Map OpMap = TB; Prefix OpPrefix = XD; } +class XS { Map OpMap = TB; Prefix OpPrefix = XS; } +class T8 { Map OpMap = T8; } +class TA { Map OpMap = TA; } +class A6 { Map OpMap = A6; } +class A7 { Map OpMap = A7; } +class T8XD { Map OpMap = T8; Prefix OpPrefix = XD; } +class T8XS { Map OpMap = T8; Prefix OpPrefix = XS; } +class TAXD { Map OpMap = TA; Prefix OpPrefix = XD; } +class XOP8 { Map OpMap = XOP8; } +class XOP9 { Map OpMap = XOP9; } +class XOPA { Map OpMap = XOPA; } +class PD { Map OpMap = TB; Prefix OpPrefix = PD; } +class T8PD { Map OpMap = T8; Prefix OpPrefix = PD; } +class TAPD { Map OpMap = TA; Prefix OpPrefix = PD; } class VEX { bit hasVEXPrefix = 1; } class VEX_W { bit hasVEX_WPrefix = 1; } class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; } @@ -200,7 +231,8 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, bit hasOpSize16Prefix = 0;// Does this inst have a 0x66 prefix in 16-bit mode? bit hasAdSizePrefix = 0; // Does this inst have a 0x67 prefix? - bits<5> Prefix = 0; // Which prefix byte does this inst have? + Prefix OpPrefix = NoPrfx; // Which prefix byte does this inst have? + Map OpMap = OB; // Which opcode map does this inst have? bit hasREX_WPrefix = 0; // Does this inst require the REX.W prefix? FPFormat FPForm = NotFP; // What flavor of FP instruction is this? bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix? @@ -232,32 +264,33 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, let TSFlags{6} = hasOpSizePrefix; let TSFlags{7} = hasOpSize16Prefix; let TSFlags{8} = hasAdSizePrefix; - let TSFlags{13-9} = Prefix; - let TSFlags{14} = hasREX_WPrefix; - let TSFlags{18-15} = ImmT.Value; - let TSFlags{21-19} = FPForm.Value; - let TSFlags{22} = hasLockPrefix; - 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; + let TSFlags{10-9} = OpPrefix.Value; + let TSFlags{15-11} = OpMap.Value; + let TSFlags{16} = hasREX_WPrefix; + let TSFlags{20-17} = ImmT.Value; + let TSFlags{23-21} = FPForm.Value; + let TSFlags{24} = hasLockPrefix; + let TSFlags{25} = hasREPPrefix; + let TSFlags{27-26} = ExeDomain.Value; + let TSFlags{35-28} = Opcode; + let TSFlags{36} = hasVEXPrefix; + let TSFlags{37} = hasVEX_WPrefix; + let TSFlags{38} = hasVEX_4VPrefix; + let TSFlags{39} = hasVEX_4VOp3Prefix; + let TSFlags{40} = hasVEX_i8ImmReg; + let TSFlags{41} = hasVEX_L; + let TSFlags{42} = ignoresVEX_L; + let TSFlags{43} = hasEVEXPrefix; + let TSFlags{44} = hasEVEX_K; + let TSFlags{45} = hasEVEX_Z; + let TSFlags{46} = hasEVEX_L2; + let TSFlags{47} = hasEVEX_B; + let TSFlags{49-48} = EVEX_CD8E; + let TSFlags{52-50} = EVEX_CD8V; + let TSFlags{53} = has3DNow0F0FOpcode; + let TSFlags{54} = hasMemOp4Prefix; + let TSFlags{55} = hasXOP_Prefix; + let TSFlags{56} = hasEVEX_RC; } class PseudoI pattern> @@ -362,9 +395,10 @@ class SI o, Format F, dag outs, dag ins, string asm, : I { let Predicates = !if(hasEVEXPrefix /* EVEX */, [HasAVX512], !if(hasVEXPrefix /* VEX */, [UseAVX], - !if(!eq(Prefix, __xs.Prefix), [UseSSE1], - !if(!eq(Prefix, __xd.Prefix), [UseSSE2], - !if(!eq(Prefix, __pd.Prefix), [UseSSE2], [UseSSE1]))))); + !if(!eq(OpPrefix.Value, __xs.OpPrefix.Value), [UseSSE1], + !if(!eq(OpPrefix.Value, __xd.OpPrefix.Value), [UseSSE2], + !if(!eq(OpPrefix.Value, __pd.OpPrefix.Value), [UseSSE2], + [UseSSE1]))))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(hasVEXPrefix, !strconcat("v", asm), asm); @@ -376,7 +410,8 @@ class SIi8 o, Format F, dag outs, dag ins, string asm, : Ii8 { let Predicates = !if(hasEVEXPrefix /* EVEX */, [HasAVX512], !if(hasVEXPrefix /* VEX */, [UseAVX], - !if(!eq(Prefix, __xs.Prefix), [UseSSE1], [UseSSE2]))); + !if(!eq(OpPrefix.Value, __xs.OpPrefix.Value), [UseSSE1], + [UseSSE2]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(hasVEXPrefix, !strconcat("v", asm), asm); @@ -388,7 +423,8 @@ class PI o, Format F, dag outs, dag ins, string asm, list pattern, : I { let Predicates = !if(hasEVEXPrefix /* EVEX */, [HasAVX512], !if(hasVEXPrefix /* VEX */, [HasAVX], - !if(!eq(Prefix, __pd.Prefix), [UseSSE2], [UseSSE1]))); + !if(!eq(OpPrefix.Value, __pd.OpPrefix.Value), [UseSSE2], + [UseSSE1]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(hasVEXPrefix, !strconcat("v", asm), asm); @@ -398,7 +434,8 @@ class PI o, Format F, dag outs, dag ins, string asm, list pattern, class MMXPI o, Format F, dag outs, dag ins, string asm, list pattern, InstrItinClass itin, Domain d> : I { - let Predicates = !if(!eq(Prefix, __pd.Prefix), [HasSSE2], [HasSSE1]); + let Predicates = !if(!eq(OpPrefix.Value, __pd.OpPrefix.Value), [HasSSE2], + [HasSSE1]); } // PIi8 - SSE 1 & 2 packed instructions with immediate @@ -407,7 +444,8 @@ class PIi8 o, Format F, dag outs, dag ins, string asm, : Ii8 { let Predicates = !if(hasEVEXPrefix /* EVEX */, [HasAVX512], !if(hasVEXPrefix /* VEX */, [HasAVX], - !if(!eq(Prefix, __pd.Prefix), [UseSSE2], [UseSSE1]))); + !if(!eq(OpPrefix.Value, __pd.OpPrefix.Value), [UseSSE2], + [UseSSE1]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(hasVEXPrefix, !strconcat("v", asm), asm); diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index f84fafdde10..3c606225ba5 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -76,13 +76,14 @@ namespace X86Local { }; enum { - TB = 1, - D8 = 3, D9 = 4, DA = 5, DB = 6, - DC = 7, DD = 8, DE = 9, DF = 10, - XD = 11, XS = 12, - T8 = 13, P_TA = 14, - A6 = 15, A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19, - XOP8 = 20, XOP9 = 21, XOPA = 22, PD = 23, T8PD = 24, TAPD = 25 + OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6, + D8 = 7, D9 = 8, DA = 9, DB = 10, + DC = 11, DD = 12, DE = 13, DF = 14, + A6 = 15, A7 = 16 + }; + + enum { + PD = 1, XS = 2, XD = 3 }; } @@ -152,15 +153,12 @@ using namespace X86Disassembler; /// @return - true if the form implies that a ModR/M byte is required, false /// otherwise. static bool needsModRMForDecode(uint8_t form) { - if (form == X86Local::MRMDestReg || - form == X86Local::MRMDestMem || - form == X86Local::MRMSrcReg || - form == X86Local::MRMSrcMem || - (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || - (form >= X86Local::MRM0m && form <= X86Local::MRM7m)) - return true; - else - return false; + return (form == X86Local::MRMDestReg || + form == X86Local::MRMDestMem || + form == X86Local::MRMSrcReg || + form == X86Local::MRMSrcMem || + (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || + (form >= X86Local::MRM0m && form <= X86Local::MRM7m)); } /// isRegFormat - Indicates whether a particular form requires the Mod field of @@ -170,12 +168,9 @@ static bool needsModRMForDecode(uint8_t form) { /// @return - true if the form implies that Mod must be 0b11, false /// otherwise. static bool isRegFormat(uint8_t form) { - if (form == X86Local::MRMDestReg || - form == X86Local::MRMSrcReg || - (form >= X86Local::MRM0r && form <= X86Local::MRM7r)) - return true; - else - return false; + return (form == X86Local::MRMDestReg || + form == X86Local::MRMSrcReg || + (form >= X86Local::MRM0r && form <= X86Local::MRM7r)); } /// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. @@ -229,7 +224,8 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, return; } - Prefix = byteFromRec(Rec, "Prefix"); + OpPrefix = byteFromRec(Rec->getValueAsDef("OpPrefix"), "Value"); + OpMap = byteFromRec(Rec->getValueAsDef("OpMap"), "Value"); Opcode = byteFromRec(Rec, "Opcode"); Form = byteFromRec(Rec, "FormBits"); @@ -311,176 +307,136 @@ InstructionContext RecognizableInstr::insnContext() const { } // VEX_L & VEX_W if (HasVEX_LPrefix && HasVEX_WPrefix) { - if (HasOpSizePrefix || Prefix == X86Local::PD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_L_W_XS); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_L_W_XD); else insnContext = EVEX_KB(IC_EVEX_L_W); } else if (HasVEX_LPrefix) { // VEX_L - if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_L_XS); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_L_XD); else insnContext = EVEX_KB(IC_EVEX_L); } else if (HasEVEX_L2Prefix && HasVEX_WPrefix) { // EVEX_L2 & VEX_W - if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_L2_W_XS); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_L2_W_XD); else insnContext = EVEX_KB(IC_EVEX_L2_W); } else if (HasEVEX_L2Prefix) { // EVEX_L2 - if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_L2_XD); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_L2_XS); - else + else insnContext = EVEX_KB(IC_EVEX_L2); } else if (HasVEX_WPrefix) { // VEX_W - if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_W_OPSIZE); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_W_XS); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_W_XD); else insnContext = EVEX_KB(IC_EVEX_W); } // No L, no W - else if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + else if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_OPSIZE); - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = EVEX_KB(IC_EVEX_XD); - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = EVEX_KB(IC_EVEX_XS); else insnContext = EVEX_KB(IC_EVEX); /// eof EVEX } else if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix|| HasVEXPrefix) { if (HasVEX_LPrefix && HasVEX_WPrefix) { - if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = IC_VEX_L_W_OPSIZE; - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = IC_VEX_L_W_XS; - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = IC_VEX_L_W_XD; else insnContext = IC_VEX_L_W; - } else if ((HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) && - HasVEX_LPrefix) + } else if ((HasOpSizePrefix || OpPrefix == X86Local::PD) && HasVEX_LPrefix) insnContext = IC_VEX_L_OPSIZE; - else if ((HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) && - HasVEX_WPrefix) + else if ((HasOpSizePrefix || OpPrefix == X86Local::PD) && HasVEX_WPrefix) insnContext = IC_VEX_W_OPSIZE; - else if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + else if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = IC_VEX_OPSIZE; - else if (HasVEX_LPrefix && - (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) + else if (HasVEX_LPrefix && OpPrefix == X86Local::XS) insnContext = IC_VEX_L_XS; - else if (HasVEX_LPrefix && (Prefix == X86Local::XD || - Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD)) + else if (HasVEX_LPrefix && OpPrefix == X86Local::XD) insnContext = IC_VEX_L_XD; - else if (HasVEX_WPrefix && - (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) + else if (HasVEX_WPrefix && OpPrefix == X86Local::XS) insnContext = IC_VEX_W_XS; - else if (HasVEX_WPrefix && (Prefix == X86Local::XD || - Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD)) + else if (HasVEX_WPrefix && OpPrefix == X86Local::XD) insnContext = IC_VEX_W_XD; else if (HasVEX_WPrefix) insnContext = IC_VEX_W; else if (HasVEX_LPrefix) insnContext = IC_VEX_L; - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = IC_VEX_XD; - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = IC_VEX_XS; else insnContext = IC_VEX; } else if (Is64Bit || HasREX_WPrefix) { - if (HasREX_WPrefix && (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD)) + if (HasREX_WPrefix && (HasOpSizePrefix || OpPrefix == X86Local::PD)) insnContext = IC_64BIT_REXW_OPSIZE; - else if (HasOpSizePrefix && (Prefix == X86Local::XD || - Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD)) + else if (HasOpSizePrefix && OpPrefix == X86Local::XD) insnContext = IC_64BIT_XD_OPSIZE; - else if (HasOpSizePrefix && - (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) + else if (HasOpSizePrefix && OpPrefix == X86Local::XS) insnContext = IC_64BIT_XS_OPSIZE; - else if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + else if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = IC_64BIT_OPSIZE; else if (HasAdSizePrefix) insnContext = IC_64BIT_ADSIZE; - else if (HasREX_WPrefix && - (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) + else if (HasREX_WPrefix && OpPrefix == X86Local::XS) insnContext = IC_64BIT_REXW_XS; - else if (HasREX_WPrefix && (Prefix == X86Local::XD || - Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD)) + else if (HasREX_WPrefix && OpPrefix == X86Local::XD) insnContext = IC_64BIT_REXW_XD; - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = IC_64BIT_XD; - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) + else if (OpPrefix == X86Local::XS) insnContext = IC_64BIT_XS; else if (HasREX_WPrefix) insnContext = IC_64BIT_REXW; else insnContext = IC_64BIT; } else { - if (HasOpSizePrefix && (Prefix == X86Local::XD || - Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD)) + if (HasOpSizePrefix && OpPrefix == X86Local::XD) insnContext = IC_XD_OPSIZE; - else if (HasOpSizePrefix && - (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) + else if (HasOpSizePrefix && OpPrefix == X86Local::XS) insnContext = IC_XS_OPSIZE; - else if (HasOpSizePrefix || Prefix == X86Local::PD || - Prefix == X86Local::T8PD || Prefix == X86Local::TAPD) + else if (HasOpSizePrefix || OpPrefix == X86Local::PD) insnContext = IC_OPSIZE; else if (HasAdSizePrefix) insnContext = IC_ADSIZE; - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || - Prefix == X86Local::TAXD) + else if (OpPrefix == X86Local::XD) insnContext = IC_XD; - else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS || - HasREPPrefix) + else if (OpPrefix == X86Local::XS || HasREPPrefix) insnContext = IC_XS; else insnContext = IC; @@ -901,12 +857,9 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { ModRMFilter* filter = NULL; uint8_t opcodeToSet = 0; - switch (Prefix) { - default: llvm_unreachable("Invalid prefix!"); + switch (OpMap) { + default: llvm_unreachable("Invalid map!"); // Extended two-byte opcodes can start with 66 0f, f2 0f, f3 0f, or 0f - case X86Local::PD: - case X86Local::XD: - case X86Local::XS: case X86Local::TB: opcodeType = TWOBYTE; @@ -950,9 +903,6 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { opcodeToSet = Opcode; break; case X86Local::T8: - case X86Local::T8PD: - case X86Local::T8XD: - case X86Local::T8XS: opcodeType = THREEBYTE_38; switch (Opcode) { default: @@ -993,9 +943,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { } // switch (Opcode) opcodeToSet = Opcode; break; - case X86Local::P_TA: - case X86Local::TAPD: - case X86Local::TAXD: + case X86Local::TA: opcodeType = THREEBYTE_3A; if (needsModRMForDecode(Form)) filter = new ModFilter(isRegFormat(Form)); @@ -1088,9 +1036,9 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { assert(Form == X86Local::RawFrm); opcodeType = ONEBYTE; filter = new ExactFilter(Opcode); - opcodeToSet = 0xd8 + (Prefix - X86Local::D8); + opcodeToSet = 0xd8 + (OpMap - X86Local::D8); break; - case 0: + case X86Local::OB: opcodeType = ONEBYTE; switch (Opcode) { #define EXTENSION_TABLE(n) case 0x##n: @@ -1164,7 +1112,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { break; } // switch (Opcode) opcodeToSet = Opcode; - } // switch (Prefix) + } // switch (OpMap) assert(opcodeType != (OpcodeType)-1 && "Opcode type not set"); diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index bf758ed2bbd..edaa03515b3 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -37,8 +37,10 @@ private: InstrUID UID; /// The record from the .td files corresponding to this instruction const Record* Rec; - /// The prefix field from the record - uint8_t Prefix; + /// The OpPrefix field from the record + uint8_t OpPrefix; + /// The OpMap field from the record + uint8_t OpMap; /// The opcode field from the record; this is the opcode used in the Intel /// encoding and therefore distinct from the UID uint8_t Opcode;