Separate x86 opcode maps and 0x66/0xf2/0xf3 prefixes from each other in the TSFlags. This greatly simplifies the switch statements in the disassembler tables and the code emitters.

llvm-svn: 200522
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index b690de2..78ed12d 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -323,60 +323,56 @@
     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 @@
     // 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/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 986e257..7affe80 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -651,7 +651,7 @@
   //  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 @@
   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 @@
   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 @@
   }
 
   // 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/llvm/lib/Target/X86/X86CodeEmitter.cpp b/llvm/lib/Target/X86/X86CodeEmitter.cpp
index dc75e60..5d36d93 100644
--- a/llvm/lib/Target/X86/X86CodeEmitter.cpp
+++ b/llvm/lib/Target/X86/X86CodeEmitter.cpp
@@ -658,40 +658,16 @@
   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 @@
   }
 
   // 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 @@
   //  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 @@
   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/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td
index 83cd7e1..ac04fc4 100644
--- a/llvm/lib/Target/X86/X86InstrFormats.td
+++ b/llvm/lib/Target/X86/X86InstrFormats.td
@@ -112,6 +112,37 @@
 def CD8VT4 : CD8VForm<6>;  // v := 4
 def CD8VT8 : CD8VForm<7>;  // v := 8
 
+// Class specifying the prefix used an opcode extension.
+class Prefix<bits<2> 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<bits<5> 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 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 @@
   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 @@
   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<dag oops, dag iops, list<dag> pattern>
@@ -362,9 +395,10 @@
       : I<o, F, outs, ins, asm, pattern, itin> {
   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 @@
       : Ii8<o, F, outs, ins, asm, pattern, itin> {
   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 @@
       : I<o, F, outs, ins, asm, pattern, itin, d> {
   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 MMXPI<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern,
             InstrItinClass itin, Domain d>
       : I<o, F, outs, ins, asm, pattern, itin, d> {
-  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 @@
       : Ii8<o, F, outs, ins, asm, pattern, itin, d> {
   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);