Remove unnecessary stirng comparison from disassembler.
[oota-llvm.git] / utils / TableGen / X86RecognizableInstr.cpp
index 7ac2336d73216b9141df56680b705b2c6fd5288b..6ae7c3820e4d1d9660a6f7a8616b328d5707df3b 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "X86DisassemblerShared.h"
 #include "X86RecognizableInstr.h"
+#include "X86DisassemblerShared.h"
 #include "X86ModRMFilters.h"
-
 #include "llvm/Support/ErrorHandling.h"
-
 #include <string>
 
 using namespace llvm;
@@ -31,21 +29,25 @@ using namespace llvm;
   MAP(C4, 36)           \
   MAP(C8, 37)           \
   MAP(C9, 38)           \
-  MAP(E8, 39)           \
-  MAP(F0, 40)           \
-  MAP(F8, 41)           \
-  MAP(F9, 42)           \
-  MAP(D0, 45)           \
-  MAP(D1, 46)           \
-  MAP(D4, 47)           \
-  MAP(D8, 48)           \
-  MAP(D9, 49)           \
-  MAP(DA, 50)           \
-  MAP(DB, 51)           \
-  MAP(DC, 52)           \
-  MAP(DD, 53)           \
-  MAP(DE, 54)           \
-  MAP(DF, 55)
+  MAP(CA, 39)           \
+  MAP(CB, 40)           \
+  MAP(E8, 41)           \
+  MAP(F0, 42)           \
+  MAP(F8, 45)           \
+  MAP(F9, 46)           \
+  MAP(D0, 47)           \
+  MAP(D1, 48)           \
+  MAP(D4, 49)           \
+  MAP(D5, 50)           \
+  MAP(D6, 51)           \
+  MAP(D8, 52)           \
+  MAP(D9, 53)           \
+  MAP(DA, 54)           \
+  MAP(DB, 55)           \
+  MAP(DC, 56)           \
+  MAP(DD, 57)           \
+  MAP(DE, 58)           \
+  MAP(DF, 59)
 
 // A clone of X86 since we can't depend on something that is generated.
 namespace X86Local {
@@ -77,7 +79,8 @@ namespace X86Local {
     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
+    A6 = 15,  A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19,
+    XOP8 = 20, XOP9 = 21, XOPA = 22
   };
 }
 
@@ -120,6 +123,7 @@ namespace X86Local {
 #define TWO_BYTE_EXTENSION_TABLES \
   EXTENSION_TABLE(00)             \
   EXTENSION_TABLE(01)             \
+  EXTENSION_TABLE(0d)             \
   EXTENSION_TABLE(18)             \
   EXTENSION_TABLE(71)             \
   EXTENSION_TABLE(72)             \
@@ -131,6 +135,10 @@ namespace X86Local {
 #define THREE_BYTE_38_EXTENSION_TABLES \
   EXTENSION_TABLE(F3)
 
+#define XOP9_MAP_EXTENSION_TABLES \
+  EXTENSION_TABLE(01)             \
+  EXTENSION_TABLE(02)
+
 using namespace X86Disassembler;
 
 /// needsModRMForDecode - Indicates whether a particular instruction requires a
@@ -233,6 +241,11 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   HasVEX_WPrefix   = Rec->getValueAsBit("hasVEX_WPrefix");
   HasMemOp4Prefix  = Rec->getValueAsBit("hasMemOp4Prefix");
   IgnoresVEX_L     = Rec->getValueAsBit("ignoresVEX_L");
+  HasEVEXPrefix    = Rec->getValueAsBit("hasEVEXPrefix");
+  HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
+  HasEVEX_K        = Rec->getValueAsBit("hasEVEX_K");
+  HasEVEX_KZ       = Rec->getValueAsBit("hasEVEX_Z");
+  HasEVEX_B        = Rec->getValueAsBit("hasEVEX_B");
   HasLockPrefix    = Rec->getValueAsBit("hasLockPrefix");
   IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
 
@@ -244,7 +257,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   IsSSE            = (HasOpSizePrefix && (Name.find("16") == Name.npos)) ||
                      (Name.find("CRC32") != Name.npos);
   HasFROperands    = hasFROperands();
-  HasVEX_LPrefix   = has256BitOperands() || Rec->getValueAsBit("hasVEX_L");
+  HasVEX_LPrefix   = Rec->getValueAsBit("hasVEX_L");
 
   // Check for 64-bit inst which does not require REX
   Is32Bit = false;
@@ -252,18 +265,18 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   // FIXME: Is there some better way to check for In64BitMode?
   std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
   for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
-    if (Predicates[i]->getName().find("32Bit") != Name.npos) {
+    if (Predicates[i]->getName().find("Not64Bit") != Name.npos ||
+       Predicates[i]->getName().find("In32Bit") != Name.npos) {
       Is32Bit = true;
       break;
     }
-    if (Predicates[i]->getName().find("64Bit") != Name.npos) {
+    if (Predicates[i]->getName().find("In64Bit") != Name.npos) {
       Is64Bit = true;
       break;
     }
   }
   // FIXME: These instructions aren't marked as 64-bit in any way
   Is64Bit |= Rec->getName() == "JMP64pcrel32" ||
-             Rec->getName() == "MASKMOVDQU64" ||
              Rec->getName() == "POPFS64" ||
              Rec->getName() == "POPGS64" ||
              Rec->getName() == "PUSHFS64" ||
@@ -286,21 +299,105 @@ void RecognizableInstr::processInstr(DisassemblerTables &tables,
 
   RecognizableInstr recogInstr(tables, insn, uid);
 
-  recogInstr.emitInstructionSpecifier(tables);
+  recogInstr.emitInstructionSpecifier();
 
   if (recogInstr.shouldBeEmitted())
     recogInstr.emitDecodePath(tables);
 }
 
+#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \
+                    (HasEVEX_K && HasEVEX_B ? n##_K_B : \
+                    (HasEVEX_KZ ? n##_KZ : \
+                    (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n)))))
+
 InstructionContext RecognizableInstr::insnContext() const {
   InstructionContext insnContext;
 
-  if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix|| HasVEXPrefix) {
+  if (HasEVEXPrefix) {
+    if (HasVEX_LPrefix && HasEVEX_L2Prefix) {
+      errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";
+      llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
+    }
+    // VEX_L & VEX_W
+    if (HasVEX_LPrefix && HasVEX_WPrefix) {
+      if (HasOpSizePrefix)
+        insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = EVEX_KB(IC_EVEX_L_W_XS);
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+               Prefix == X86Local::TAXD)
+        insnContext = EVEX_KB(IC_EVEX_L_W_XD);
+      else
+        insnContext = EVEX_KB(IC_EVEX_L_W);
+    } else if (HasVEX_LPrefix) {
+      // VEX_L
+      if (HasOpSizePrefix)
+        insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = EVEX_KB(IC_EVEX_L_XS);
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+               Prefix == X86Local::TAXD)
+        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)
+        insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = EVEX_KB(IC_EVEX_L2_W_XS);
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+               Prefix == X86Local::TAXD)
+        insnContext = EVEX_KB(IC_EVEX_L2_W_XD);
+      else
+        insnContext = EVEX_KB(IC_EVEX_L2_W);
+    } else if (HasEVEX_L2Prefix) {
+      // EVEX_L2
+      if (HasOpSizePrefix)
+        insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+          Prefix == X86Local::TAXD)
+        insnContext = EVEX_KB(IC_EVEX_L2_XD);
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = EVEX_KB(IC_EVEX_L2_XS);
+      else 
+        insnContext = EVEX_KB(IC_EVEX_L2);
+    }
+    else if (HasVEX_WPrefix) {
+      // VEX_W
+      if (HasOpSizePrefix)
+        insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = EVEX_KB(IC_EVEX_W_XS);
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+               Prefix == X86Local::TAXD)
+        insnContext = EVEX_KB(IC_EVEX_W_XD);
+      else
+        insnContext = EVEX_KB(IC_EVEX_W);
+    }
+    // No L, no W
+    else if (HasOpSizePrefix)
+      insnContext = EVEX_KB(IC_EVEX_OPSIZE);
+    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+             Prefix == X86Local::TAXD)
+      insnContext = EVEX_KB(IC_EVEX_XD);
+    else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+      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)
         insnContext = IC_VEX_L_W_OPSIZE;
+      else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+        insnContext = IC_VEX_L_W_XS;
+      else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+               Prefix == X86Local::TAXD)
+        insnContext = IC_VEX_L_W_XD;
       else
-        llvm_unreachable("Don't support VEX.L and VEX.W together");
+        insnContext = IC_VEX_L_W;
     } else if (HasOpSizePrefix && HasVEX_LPrefix)
       insnContext = IC_VEX_L_OPSIZE;
     else if (HasOpSizePrefix && HasVEX_WPrefix)
@@ -397,17 +494,14 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
   assert(Rec->isSubClassOf("X86Inst") && "Can only filter X86 instructions");
 
   if (Form == X86Local::Pseudo ||
-      (IsCodeGenOnly && Name.find("_REV") == Name.npos))
+      (IsCodeGenOnly && Name.find("_REV") == Name.npos &&
+       Name.find("INC32") == Name.npos && Name.find("DEC32") == Name.npos))
     return FILTER_STRONG;
 
 
   // Filter out artificial instructions but leave in the LOCK_PREFIX so it is
   // printed as a separate "instruction".
 
-  if (Name.find("_Int") != Name.npos       ||
-      Name.find("Int_") != Name.npos)
-    return FILTER_STRONG;
-
   // Filter out instructions with segment override prefixes.
   // They're too messy to handle now and we'll special case them if needed.
 
@@ -427,41 +521,24 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
 
   // Filter out alternate forms of AVX instructions
   if (Name.find("_alt") != Name.npos ||
-      Name.find("XrYr") != Name.npos ||
-      (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) ||
+      (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos && Name.find("r64r8") == Name.npos) ||
       Name.find("_64mr") != Name.npos ||
-      Name.find("Xrr") != Name.npos ||
       Name.find("rr64") != Name.npos)
     return FILTER_WEAK;
 
   // Special cases.
 
-  if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
-    return FILTER_WEAK;
-  if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
-    return FILTER_WEAK;
-
-  if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
-    return FILTER_WEAK;
-  if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
-    return FILTER_WEAK;
-  if (Name.find("Fs") != Name.npos)
-    return FILTER_WEAK;
   if (Name == "PUSH64i16"         ||
       Name == "MOVPQI2QImr"       ||
       Name == "VMOVPQI2QImr"      ||
-      Name == "MMX_MOVD64rrv164"  ||
-      Name == "MOV64ri64i32"      ||
-      Name == "VMASKMOVDQU64"     ||
-      Name == "VEXTRACTPSrr64"    ||
-      Name == "VMOVQd64rr"        ||
-      Name == "VMOVQs64rr")
+      Name == "VMASKMOVDQU64")
     return FILTER_WEAK;
 
-  if (HasFROperands && Name.find("MOV") != Name.npos &&
-     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
-      (Name.find("to") != Name.npos)))
-    return FILTER_STRONG;
+  // XACQUIRE and XRELEASE reuse REPNE and REP respectively.
+  // For now, just prefer the REP versions.
+  if (Name == "XACQUIRE_PREFIX" ||
+      Name == "XRELEASE_PREFIX")
+    return FILTER_WEAK;
 
   return FILTER_NORMAL;
 }
@@ -479,20 +556,6 @@ bool RecognizableInstr::hasFROperands() const {
   return false;
 }
 
-bool RecognizableInstr::has256BitOperands() const {
-  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
-  unsigned numOperands = OperandList.size();
-
-  for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
-    const std::string &recName = OperandList[operandIndex].Rec->getName();
-
-    if (!recName.compare("VR256")) {
-      return true;
-    }
-  }
-  return false;
-}
-
 void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
                                       unsigned &physicalOperandIndex,
                                       unsigned &numPhysicalOperands,
@@ -527,7 +590,7 @@ void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
   ++physicalOperandIndex;
 }
 
-void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
+void RecognizableInstr::emitInstructionSpecifier() {
   Spec->name       = Name;
 
   if (!ShouldBeEmitted)
@@ -646,6 +709,9 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
              "Unexpected number of operands for MRMDestMemFrm");
     HANDLE_OPERAND(memory)
 
+    if (HasEVEX_K)
+      HANDLE_OPERAND(writemaskRegister)
+
     if (HasVEX_4VPrefix)
       // FIXME: In AVX, the register below becomes the one encoded
       // in ModRMVEX and the one above the one in the VEX.VVVV field
@@ -670,6 +736,9 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
 
     HANDLE_OPERAND(roRegister)
 
+    if (HasEVEX_K)
+      HANDLE_OPERAND(writemaskRegister)
+
     if (HasVEX_4VPrefix)
       // FIXME: In AVX, the register below becomes the one encoded
       // in ModRMVEX and the one above the one in the VEX.VVVV field
@@ -703,6 +772,9 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
 
     HANDLE_OPERAND(roRegister)
 
+    if (HasEVEX_K)
+      HANDLE_OPERAND(writemaskRegister)
+
     if (HasVEX_4VPrefix)
       // FIXME: In AVX, the register below becomes the one encoded
       // in ModRMVEX and the one above the one in the VEX.VVVV field
@@ -728,17 +800,20 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
   case X86Local::MRM5r:
   case X86Local::MRM6r:
   case X86Local::MRM7r:
-    // Operand 1 is a register operand in the R/M field.
-    // Operand 2 (optional) is an immediate or relocation.
-    // Operand 3 (optional) is an immediate.
-    if (HasVEX_4VPrefix)
-      assert(numPhysicalOperands <= 3 &&
-             "Unexpected number of operands for MRMnRFrm with VEX_4V");
-    else
-      assert(numPhysicalOperands <= 3 &&
-             "Unexpected number of operands for MRMnRFrm");
+    {
+      // Operand 1 is a register operand in the R/M field.
+      // Operand 2 (optional) is an immediate or relocation.
+      // Operand 3 (optional) is an immediate.
+      unsigned kOp = (HasEVEX_K) ? 1:0;
+      unsigned Op4v = (HasVEX_4VPrefix) ? 1:0;
+      if (numPhysicalOperands > 3 + kOp + Op4v)
+        llvm_unreachable("Unexpected number of operands for MRMnr");
+    }
     if (HasVEX_4VPrefix)
       HANDLE_OPERAND(vvvvRegister)
+
+    if (HasEVEX_K)
+      HANDLE_OPERAND(writemaskRegister)
     HANDLE_OPTIONAL(rmRegister)
     HANDLE_OPTIONAL(relocation)
     HANDLE_OPTIONAL(immediate)
@@ -751,16 +826,19 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
   case X86Local::MRM5m:
   case X86Local::MRM6m:
   case X86Local::MRM7m:
-    // Operand 1 is a memory operand (possibly SIB-extended)
-    // Operand 2 (optional) is an immediate or relocation.
-    if (HasVEX_4VPrefix)
-      assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
-             "Unexpected number of operands for MRMnMFrm");
-    else
-      assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
-             "Unexpected number of operands for MRMnMFrm");
+    {
+      // Operand 1 is a memory operand (possibly SIB-extended)
+      // Operand 2 (optional) is an immediate or relocation.
+      unsigned kOp = (HasEVEX_K) ? 1:0;
+      unsigned Op4v = (HasVEX_4VPrefix) ? 1:0;
+      if (numPhysicalOperands < 1 + kOp + Op4v ||
+          numPhysicalOperands > 2 + kOp + Op4v)
+        llvm_unreachable("Unexpected number of operands for MRMnm");
+    }
     if (HasVEX_4VPrefix)
       HANDLE_OPERAND(vvvvRegister)
+    if (HasEVEX_K)
+      HANDLE_OPERAND(writemaskRegister)
     HANDLE_OPERAND(memory)
     HANDLE_OPTIONAL(relocation)
     break;
@@ -778,6 +856,17 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
     HANDLE_OPERAND(immediate)
     HANDLE_OPERAND(immediate)
     break;
+  case X86Local::MRM_F8:
+    if (Opcode == 0xc6) {
+      assert(numPhysicalOperands == 1 &&
+             "Unexpected number of operands for X86Local::MRM_F8");
+      HANDLE_OPERAND(immediate)
+    } else if (Opcode == 0xc7) {
+      assert(numPhysicalOperands == 1 &&
+             "Unexpected number of operands for X86Local::MRM_F8");
+      HANDLE_OPERAND(relocation)
+    }
+    break;
   case X86Local::MRMInitReg:
     // Ignored.
     break;
@@ -801,6 +890,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
   uint8_t       opcodeToSet = 0;
 
   switch (Prefix) {
+  default: llvm_unreachable("Invalid prefix!");
   // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
   case X86Local::XD:
   case X86Local::XS:
@@ -914,6 +1004,63 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
       filter = new DumbFilter();
     opcodeToSet = Opcode;
     break;
+  case X86Local::XOP8:
+    opcodeType = XOP8_MAP;
+    if (needsModRMForDecode(Form))
+      filter = new ModFilter(isRegFormat(Form));
+    else
+      filter = new DumbFilter();
+    opcodeToSet = Opcode;
+    break;
+  case X86Local::XOP9:
+    opcodeType = XOP9_MAP;
+    switch (Opcode) {
+    default:
+      if (needsModRMForDecode(Form))
+        filter = new ModFilter(isRegFormat(Form));
+      else
+        filter = new DumbFilter();
+      break;
+#define EXTENSION_TABLE(n) case 0x##n:
+    XOP9_MAP_EXTENSION_TABLES
+#undef EXTENSION_TABLE
+      switch (Form) {
+      default:
+        llvm_unreachable("Unhandled XOP9 extended opcode");
+      case X86Local::MRM0r:
+      case X86Local::MRM1r:
+      case X86Local::MRM2r:
+      case X86Local::MRM3r:
+      case X86Local::MRM4r:
+      case X86Local::MRM5r:
+      case X86Local::MRM6r:
+      case X86Local::MRM7r:
+        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
+        break;
+      case X86Local::MRM0m:
+      case X86Local::MRM1m:
+      case X86Local::MRM2m:
+      case X86Local::MRM3m:
+      case X86Local::MRM4m:
+      case X86Local::MRM5m:
+      case X86Local::MRM6m:
+      case X86Local::MRM7m:
+        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
+        break;
+      MRM_MAPPING
+      } // switch (Form)
+      break;
+    } // switch (Opcode)
+    opcodeToSet = Opcode;
+    break;
+  case X86Local::XOPA:
+    opcodeType = XOPA_MAP;
+    if (needsModRMForDecode(Form))
+      filter = new ModFilter(isRegFormat(Form));
+    else
+      filter = new DumbFilter();
+    opcodeToSet = Opcode;
+    break;
   case X86Local::D8:
   case X86Local::D9:
   case X86Local::DA:
@@ -923,18 +1070,13 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
   case X86Local::DE:
   case X86Local::DF:
     assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
+    assert(Form == X86Local::RawFrm);
     opcodeType = ONEBYTE;
-    if (Form == X86Local::AddRegFrm) {
-      Spec->modifierType = MODIFIER_MODRM;
-      Spec->modifierBase = Opcode;
-      filter = new AddRegEscapeFilter(Opcode);
-    } else {
-      filter = new EscapeFilter(true, Opcode);
-    }
+    filter = new ExactFilter(Opcode);
     opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
     break;
   case X86Local::REP:
-  default:
+  case 0:
     opcodeType = ONEBYTE;
     switch (Opcode) {
 #define EXTENSION_TABLE(n) case 0x##n:
@@ -975,7 +1117,30 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
     case 0xdd:
     case 0xde:
     case 0xdf:
-      filter = new EscapeFilter(false, Form - X86Local::MRM0m);
+      switch (Form) {
+      default:
+        llvm_unreachable("Unhandled escape opcode form");
+      case X86Local::MRM0r:
+      case X86Local::MRM1r:
+      case X86Local::MRM2r:
+      case X86Local::MRM3r:
+      case X86Local::MRM4r:
+      case X86Local::MRM5r:
+      case X86Local::MRM6r:
+      case X86Local::MRM7r:
+        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
+        break;
+      case X86Local::MRM0m:
+      case X86Local::MRM1m:
+      case X86Local::MRM2m:
+      case X86Local::MRM3m:
+      case X86Local::MRM4m:
+      case X86Local::MRM5m:
+      case X86Local::MRM6m:
+      case X86Local::MRM7m:
+        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
+        break;
+      } // switch (Form)
       break;
     default:
       if (needsModRMForDecode(Form))
@@ -992,40 +1157,25 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
   assert(filter && "Filter not set");
 
   if (Form == X86Local::AddRegFrm) {
-    if(Spec->modifierType != MODIFIER_MODRM) {
-      assert(opcodeToSet < 0xf9 &&
-             "Not enough room for all ADDREG_FRM operands");
-
-      uint8_t currentOpcode;
-
-      for (currentOpcode = opcodeToSet;
-           currentOpcode < opcodeToSet + 8;
-           ++currentOpcode)
-        tables.setTableFields(opcodeType,
-                              insnContext(),
-                              currentOpcode,
-                              *filter,
-                              UID, Is32Bit, IgnoresVEX_L);
-
-      Spec->modifierType = MODIFIER_OPCODE;
-      Spec->modifierBase = opcodeToSet;
-    } else {
-      // modifierBase was set where MODIFIER_MODRM was set
+    assert(((opcodeToSet & 7) == 0) &&
+           "ADDREG_FRM opcode not aligned");
+
+    uint8_t currentOpcode;
+
+    for (currentOpcode = opcodeToSet;
+         currentOpcode < opcodeToSet + 8;
+         ++currentOpcode)
       tables.setTableFields(opcodeType,
                             insnContext(),
-                            opcodeToSet,
+                            currentOpcode,
                             *filter,
                             UID, Is32Bit, IgnoresVEX_L);
-    }
   } else {
     tables.setTableFields(opcodeType,
                           insnContext(),
                           opcodeToSet,
                           *filter,
                           UID, Is32Bit, IgnoresVEX_L);
-
-    Spec->modifierType = MODIFIER_NONE;
-    Spec->modifierBase = opcodeToSet;
   }
 
   delete filter;
@@ -1065,6 +1215,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("i32i8imm",            TYPE_IMM32)
   TYPE("u32u8imm",            TYPE_IMM32)
   TYPE("GR32",                TYPE_Rv)
+  TYPE("GR32orGR64",          TYPE_R32)
   TYPE("i64mem",              TYPE_Mv)
   TYPE("i64i32imm",           TYPE_IMM64)
   TYPE("i64i8imm",            TYPE_IMM64)
@@ -1073,22 +1224,28 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("i8imm",               TYPE_IMM8)
   TYPE("GR8",                 TYPE_R8)
   TYPE("VR128",               TYPE_XMM128)
+  TYPE("VR128X",              TYPE_XMM128)
   TYPE("f128mem",             TYPE_M128)
   TYPE("f256mem",             TYPE_M256)
+  TYPE("f512mem",             TYPE_M512)
   TYPE("FR64",                TYPE_XMM64)
+  TYPE("FR64X",               TYPE_XMM64)
   TYPE("f64mem",              TYPE_M64FP)
   TYPE("sdmem",               TYPE_M64FP)
   TYPE("FR32",                TYPE_XMM32)
+  TYPE("FR32X",               TYPE_XMM32)
   TYPE("f32mem",              TYPE_M32FP)
   TYPE("ssmem",               TYPE_M32FP)
   TYPE("RST",                 TYPE_ST)
   TYPE("i128mem",             TYPE_M128)
   TYPE("i256mem",             TYPE_M256)
+  TYPE("i512mem",             TYPE_M512)
   TYPE("i64i32imm_pcrel",     TYPE_REL64)
   TYPE("i16imm_pcrel",        TYPE_REL16)
   TYPE("i32imm_pcrel",        TYPE_REL32)
   TYPE("SSECC",               TYPE_IMM3)
   TYPE("AVXCC",               TYPE_IMM5)
+  TYPE("AVX512RC",            TYPE_IMM32)
   TYPE("brtarget",            TYPE_RELv)
   TYPE("uncondbrtarget",      TYPE_RELv)
   TYPE("brtarget8",           TYPE_REL8)
@@ -1110,13 +1267,24 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("offset32",            TYPE_MOFFS32)
   TYPE("offset64",            TYPE_MOFFS64)
   TYPE("VR256",               TYPE_XMM256)
+  TYPE("VR256X",              TYPE_XMM256)
+  TYPE("VR512",               TYPE_XMM512)
+  TYPE("VK1",                 TYPE_VK1)
+  TYPE("VK1WM",               TYPE_VK1)
+  TYPE("VK8",                 TYPE_VK8)
+  TYPE("VK8WM",               TYPE_VK8)
+  TYPE("VK16",                TYPE_VK16)
+  TYPE("VK16WM",              TYPE_VK16)
   TYPE("GR16_NOAX",           TYPE_Rv)
   TYPE("GR32_NOAX",           TYPE_Rv)
   TYPE("GR64_NOAX",           TYPE_R64)
   TYPE("vx32mem",             TYPE_M32)
   TYPE("vy32mem",             TYPE_M32)
+  TYPE("vz32mem",             TYPE_M32)
   TYPE("vx64mem",             TYPE_M64)
   TYPE("vy64mem",             TYPE_M64)
+  TYPE("vy64xmem",            TYPE_M64)
+  TYPE("vz64mem",             TYPE_M64)
   errs() << "Unhandled type string " << s << "\n";
   llvm_unreachable("Unhandled type string");
 }
@@ -1135,6 +1303,7 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
   ENCODING("u32u8imm",        ENCODING_IB)
   ENCODING("SSECC",           ENCODING_IB)
   ENCODING("AVXCC",           ENCODING_IB)
+  ENCODING("AVX512RC",        ENCODING_IB)
   ENCODING("i16imm",          ENCODING_Iv)
   ENCODING("i16i8imm",        ENCODING_IB)
   ENCODING("i32imm",          ENCODING_Iv)
@@ -1143,8 +1312,15 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
   ENCODING("i8imm",           ENCODING_IB)
   // This is not a typo.  Instructions like BLENDVPD put
   // register IDs in 8-bit immediates nowadays.
-  ENCODING("VR256",           ENCODING_IB)
+  ENCODING("FR32",            ENCODING_IB)
+  ENCODING("FR64",            ENCODING_IB)
   ENCODING("VR128",           ENCODING_IB)
+  ENCODING("VR256",           ENCODING_IB)
+  ENCODING("FR32X",           ENCODING_IB)
+  ENCODING("FR64X",           ENCODING_IB)
+  ENCODING("VR128X",          ENCODING_IB)
+  ENCODING("VR256X",          ENCODING_IB)
+  ENCODING("VR512",           ENCODING_IB)
   errs() << "Unhandled immediate encoding " << s << "\n";
   llvm_unreachable("Unhandled immediate encoding");
 }
@@ -1152,15 +1328,25 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
 OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
   (const std::string &s,
    bool hasOpSizePrefix) {
+  ENCODING("RST",             ENCODING_FP)
   ENCODING("GR16",            ENCODING_RM)
   ENCODING("GR32",            ENCODING_RM)
+  ENCODING("GR32orGR64",      ENCODING_RM)
   ENCODING("GR64",            ENCODING_RM)
   ENCODING("GR8",             ENCODING_RM)
   ENCODING("VR128",           ENCODING_RM)
+  ENCODING("VR128X",          ENCODING_RM)
   ENCODING("FR64",            ENCODING_RM)
   ENCODING("FR32",            ENCODING_RM)
+  ENCODING("FR64X",           ENCODING_RM)
+  ENCODING("FR32X",           ENCODING_RM)
   ENCODING("VR64",            ENCODING_RM)
   ENCODING("VR256",           ENCODING_RM)
+  ENCODING("VR256X",          ENCODING_RM)
+  ENCODING("VR512",           ENCODING_RM)
+  ENCODING("VK1",             ENCODING_RM)
+  ENCODING("VK8",             ENCODING_RM)
+  ENCODING("VK16",            ENCODING_RM)
   errs() << "Unhandled R/M register encoding " << s << "\n";
   llvm_unreachable("Unhandled R/M register encoding");
 }
@@ -1170,6 +1356,7 @@ OperandEncoding RecognizableInstr::roRegisterEncodingFromString
    bool hasOpSizePrefix) {
   ENCODING("GR16",            ENCODING_REG)
   ENCODING("GR32",            ENCODING_REG)
+  ENCODING("GR32orGR64",      ENCODING_REG)
   ENCODING("GR64",            ENCODING_REG)
   ENCODING("GR8",             ENCODING_REG)
   ENCODING("VR128",           ENCODING_REG)
@@ -1180,6 +1367,17 @@ OperandEncoding RecognizableInstr::roRegisterEncodingFromString
   ENCODING("DEBUG_REG",       ENCODING_REG)
   ENCODING("CONTROL_REG",     ENCODING_REG)
   ENCODING("VR256",           ENCODING_REG)
+  ENCODING("VR256X",          ENCODING_REG)
+  ENCODING("VR128X",          ENCODING_REG)
+  ENCODING("FR64X",           ENCODING_REG)
+  ENCODING("FR32X",           ENCODING_REG)
+  ENCODING("VR512",           ENCODING_REG)
+  ENCODING("VK1",             ENCODING_REG)
+  ENCODING("VK8",             ENCODING_REG)
+  ENCODING("VK16",            ENCODING_REG)
+  ENCODING("VK1WM",           ENCODING_REG)
+  ENCODING("VK8WM",           ENCODING_REG)
+  ENCODING("VK16WM",          ENCODING_REG)
   errs() << "Unhandled reg/opcode register encoding " << s << "\n";
   llvm_unreachable("Unhandled reg/opcode register encoding");
 }
@@ -1193,10 +1391,28 @@ OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString
   ENCODING("FR64",            ENCODING_VVVV)
   ENCODING("VR128",           ENCODING_VVVV)
   ENCODING("VR256",           ENCODING_VVVV)
+  ENCODING("FR32X",           ENCODING_VVVV)
+  ENCODING("FR64X",           ENCODING_VVVV)
+  ENCODING("VR128X",          ENCODING_VVVV)
+  ENCODING("VR256X",          ENCODING_VVVV)
+  ENCODING("VR512",           ENCODING_VVVV)
+  ENCODING("VK1",             ENCODING_VVVV)
+  ENCODING("VK8",             ENCODING_VVVV)
+  ENCODING("VK16",            ENCODING_VVVV)
   errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
   llvm_unreachable("Unhandled VEX.vvvv register encoding");
 }
 
+OperandEncoding RecognizableInstr::writemaskRegisterEncodingFromString
+  (const std::string &s,
+   bool hasOpSizePrefix) {
+  ENCODING("VK1WM",           ENCODING_WRITEMASK)
+  ENCODING("VK8WM",           ENCODING_WRITEMASK)
+  ENCODING("VK16WM",          ENCODING_WRITEMASK)
+  errs() << "Unhandled mask register encoding " << s << "\n";
+  llvm_unreachable("Unhandled mask register encoding");
+}
+
 OperandEncoding RecognizableInstr::memoryEncodingFromString
   (const std::string &s,
    bool hasOpSizePrefix) {
@@ -1208,10 +1424,12 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
   ENCODING("sdmem",           ENCODING_RM)
   ENCODING("f128mem",         ENCODING_RM)
   ENCODING("f256mem",         ENCODING_RM)
+  ENCODING("f512mem",         ENCODING_RM)
   ENCODING("f64mem",          ENCODING_RM)
   ENCODING("f32mem",          ENCODING_RM)
   ENCODING("i128mem",         ENCODING_RM)
   ENCODING("i256mem",         ENCODING_RM)
+  ENCODING("i512mem",         ENCODING_RM)
   ENCODING("f80mem",          ENCODING_RM)
   ENCODING("lea32mem",        ENCODING_RM)
   ENCODING("lea64_32mem",     ENCODING_RM)
@@ -1222,8 +1440,11 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
   ENCODING("opaque512mem",    ENCODING_RM)
   ENCODING("vx32mem",         ENCODING_RM)
   ENCODING("vy32mem",         ENCODING_RM)
+  ENCODING("vz32mem",         ENCODING_RM)
   ENCODING("vx64mem",         ENCODING_RM)
   ENCODING("vy64mem",         ENCODING_RM)
+  ENCODING("vy64xmem",        ENCODING_RM)
+  ENCODING("vz64mem",         ENCODING_RM)
   errs() << "Unhandled memory encoding " << s << "\n";
   llvm_unreachable("Unhandled memory encoding");
 }
@@ -1260,7 +1481,6 @@ OperandEncoding RecognizableInstr::relocationEncodingFromString
 OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
   (const std::string &s,
    bool hasOpSizePrefix) {
-  ENCODING("RST",             ENCODING_I)
   ENCODING("GR32",            ENCODING_Rv)
   ENCODING("GR64",            ENCODING_RO)
   ENCODING("GR16",            ENCODING_Rv)