Index: include/llvm/MC/MCTargetAsmParser.h
===================================================================
--- include/llvm/MC/MCTargetAsmParser.h
+++ include/llvm/MC/MCTargetAsmParser.h
@@ -154,10 +154,6 @@
   /// \return True on failure.
   virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                 SMLoc NameLoc, OperandVector &Operands) = 0;
-  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
-                                AsmToken Token, OperandVector &Operands) {
-    return ParseInstruction(Info, Name, Token.getLoc(), Operands);
-  }
 
   /// ParseDirective - Parse a target specific assembler directive
   ///
@@ -203,11 +199,6 @@
   virtual void convertToMapAndConstraints(unsigned Kind,
                                           const OperandVector &Operands) = 0;
 
-  // Return whether this parser uses assignment statements with equals tokens
-  virtual bool equalIsAsmAssignment() { return true; };
-  // Return whether this start of statement identifier is a label
-  virtual bool isLabel(AsmToken &Token) { return true; };
-
   virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
                                             MCSymbolRefExpr::VariantKind,
                                             MCContext &Ctx) {
Index: include/llvm/Target/Target.td
===================================================================
--- include/llvm/Target/Target.td
+++ include/llvm/Target/Target.td
@@ -937,9 +937,8 @@
   // written register name matcher
   bit ShouldEmitMatchRegisterName = 1;
 
-  // HasMnemonicFirst - Set to false if target instructions don't always
-  // start with a mnemonic as the first token.
-  bit HasMnemonicFirst = 1;
+  /// Does the instruction mnemonic allow '.'
+  bit MnemonicContainsDot = 0;
 }
 def DefaultAsmParser : AsmParser;
 
@@ -967,15 +966,6 @@
   // register tokens as constrained registers, instead of tokens, for the
   // purposes of matching.
   string RegisterPrefix = "";
-
-  // TokenizingCharacters - Characters that are standalone tokens
-  string TokenizingCharacters = "[]*!";
-
-  // SeparatorCharacters - Characters that are not tokens
-  string SeparatorCharacters = " \t,";
-
-  // BreakCharacters - Characters that start new identifiers
-  string BreakCharacters = "";
 }
 def DefaultAsmParserVariant : AsmParserVariant;
 
Index: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- lib/MC/MCParser/AsmParser.cpp
+++ lib/MC/MCParser/AsmParser.cpp
@@ -1408,8 +1408,6 @@
   // See what kind of statement we have.
   switch (Lexer.getKind()) {
   case AsmToken::Colon: {
-    if (!getTargetParser().isLabel(ID))
-      break;
     checkForValidSection();
 
     // identifier ':'   -> Label.
@@ -1468,8 +1466,6 @@
   }
 
   case AsmToken::Equal:
-    if (!getTargetParser().equalIsAsmAssignment())
-      break;
     // identifier '=' ... -> assignment statement
     Lex();
 
@@ -1721,7 +1717,7 @@
   // Canonicalize the opcode to lower case.
   std::string OpcodeStr = IDVal.lower();
   ParseInstructionInfo IInfo(Info.AsmRewrites);
-  bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
+  bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, IDLoc,
                                                      Info.ParsedOperands);
   Info.ParseError = HadError;
 
Index: lib/Target/AArch64/AArch64.td
===================================================================
--- lib/Target/AArch64/AArch64.td
+++ lib/Target/AArch64/AArch64.td
@@ -144,13 +144,11 @@
 def GenericAsmParserVariant : AsmParserVariant {
   int Variant = 0;
   string Name = "generic";
-  string BreakCharacters = ".";
 }
 
 def AppleAsmParserVariant : AsmParserVariant {
   int Variant = 1;
   string Name = "apple-neon";
-  string BreakCharacters = ".";
 }
 
 //===----------------------------------------------------------------------===//
Index: lib/Target/ARM/ARM.td
===================================================================
--- lib/Target/ARM/ARM.td
+++ lib/Target/ARM/ARM.td
@@ -677,15 +677,8 @@
   bit isMCAsmWriter = 1;
 }
 
-def ARMAsmParserVariant : AsmParserVariant {
-  int Variant = 0;
-  string Name = "ARM";
-  string BreakCharacters = ".";
-}
-
 def ARM : Target {
   // Pull in Instruction Info:
   let InstructionSet = ARMInstrInfo;
   let AssemblyWriters = [ARMAsmWriter];
-  let AssemblyParserVariants = [ARMAsmParserVariant];
 }
Index: lib/Target/BPF/BPF.td
===================================================================
--- lib/Target/BPF/BPF.td
+++ lib/Target/BPF/BPF.td
@@ -25,14 +25,7 @@
   bit isMCAsmWriter = 1;
 }
 
-def BPFAsmParserVariant : AsmParserVariant {
-  int Variant = 0;
-  string Name = "BPF";
-  string BreakCharacters = ".";
-}
-
 def BPF : Target {
   let InstructionSet = BPFInstrInfo;
   let AssemblyWriters = [BPFInstPrinter];
-  let AssemblyParserVariants = [BPFAsmParserVariant];
 }
Index: lib/Target/Hexagon/CMakeLists.txt
===================================================================
--- lib/Target/Hexagon/CMakeLists.txt
+++ lib/Target/Hexagon/CMakeLists.txt
@@ -1,6 +1,5 @@
 set(LLVM_TARGET_DEFINITIONS Hexagon.td)
 
-tablegen(LLVM HexagonGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
@@ -51,7 +50,6 @@
   HexagonVLIWPacketizer.cpp
 )
 
-add_subdirectory(AsmParser)
 add_subdirectory(TargetInfo)
 add_subdirectory(MCTargetDesc)
 add_subdirectory(Disassembler)
Index: lib/Target/Hexagon/Hexagon.td
===================================================================
--- lib/Target/Hexagon/Hexagon.td
+++ lib/Target/Hexagon/Hexagon.td
@@ -251,10 +251,6 @@
 // Declare the target which we are implementing
 //===----------------------------------------------------------------------===//
 
-def HexagonAsmParser : AsmParser {
-  bit HasMnemonicFirst = 0;
-}
-
 def HexagonAsmParserVariant : AsmParserVariant {
   int Variant = 0;
   string TokenizingCharacters = "#()=:.<>!+*";
@@ -263,6 +259,5 @@
 def Hexagon : Target {
   // Pull in Instruction Info:
   let InstructionSet = HexagonInstrInfo;
-  let AssemblyParsers = [HexagonAsmParser];
   let AssemblyParserVariants = [HexagonAsmParserVariant];
 }
Index: lib/Target/Hexagon/LLVMBuild.txt
===================================================================
--- lib/Target/Hexagon/LLVMBuild.txt
+++ lib/Target/Hexagon/LLVMBuild.txt
@@ -16,7 +16,7 @@
 ;===------------------------------------------------------------------------===;
 
 [common]
-subdirectories = AsmParser Disassembler MCTargetDesc TargetInfo
+subdirectories = Disassembler MCTargetDesc TargetInfo
 
 [component_0]
 type = TargetGroup
@@ -33,7 +33,6 @@
  AsmPrinter
  CodeGen
  Core
- HexagonAsmParser
  HexagonDesc
  HexagonInfo
  MC
Index: lib/Target/Mips/Mips.td
===================================================================
--- lib/Target/Mips/Mips.td
+++ lib/Target/Mips/Mips.td
@@ -206,6 +206,7 @@
 
 def MipsAsmParser : AsmParser {
   let ShouldEmitMatchRegisterName = 0;
+  let MnemonicContainsDot = 1;
 }
 
 def MipsAsmParserVariant : AsmParserVariant {
Index: lib/Target/PowerPC/PPC.td
===================================================================
--- lib/Target/PowerPC/PPC.td
+++ lib/Target/PowerPC/PPC.td
@@ -412,7 +412,6 @@
   // InstAlias definitions use immediate literals.  Set RegisterPrefix
   // so that those are not misinterpreted as registers.
   string RegisterPrefix = "%";
-  string BreakCharacters = ".";
 }
 
 def PPC : Target {
Index: lib/Target/X86/X86.td
===================================================================
--- lib/Target/X86/X86.td
+++ lib/Target/X86/X86.td
@@ -779,9 +779,14 @@
   int Variant = 1;
 }
 
+def X86AsmParser : AsmParser {
+  let MnemonicContainsDot = 1;
+}
+
 def X86 : Target {
   // Information about the instructions...
   let InstructionSet = X86InstrInfo;
+  let AssemblyParsers = [X86AsmParser];
   let AssemblyParserVariants = [ATTAsmParserVariant, IntelAsmParserVariant];
   let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
 }
Index: utils/TableGen/AsmMatcherEmitter.cpp
===================================================================
--- utils/TableGen/AsmMatcherEmitter.cpp
+++ utils/TableGen/AsmMatcherEmitter.cpp
@@ -297,9 +297,6 @@
 class AsmVariantInfo {
 public:
   std::string RegisterPrefix;
-  std::string TokenizingCharacters;
-  std::string SeparatorCharacters;
-  std::string BreakCharacters;
   int AsmVariantNo;
 };
 
@@ -493,8 +490,7 @@
 
   void initialize(const AsmMatcherInfo &Info,
                   SmallPtrSetImpl<Record*> &SingletonRegisters,
-                  AsmVariantInfo const &Variant,
-                  bool HasMnemonicFirst);
+                  AsmVariantInfo const &Variant);
 
   /// validate - Return true if this matchable is a valid thing to match against
   /// and perform a bunch of validity checking.
@@ -838,8 +834,7 @@
 
 void MatchableInfo::initialize(const AsmMatcherInfo &Info,
                                SmallPtrSetImpl<Record*> &SingletonRegisters,
-                               AsmVariantInfo const &Variant,
-                               bool HasMnemonicFirst) {
+                               AsmVariantInfo const &Variant) {
   AsmVariantID = Variant.AsmVariantNo;
   AsmString =
     CodeGenInstruction::FlattenAsmStringVariants(AsmString,
@@ -847,24 +842,6 @@
 
   tokenizeAsmString(Info, Variant);
 
-  // The first token of the instruction is the mnemonic, which must be a
-  // simple string, not a $foo variable or a singleton register.
-  if (AsmOperands.empty())
-    PrintFatalError(TheDef->getLoc(),
-                  "Instruction '" + TheDef->getName() + "' has no tokens");
-
-  assert(!AsmOperands[0].Token.empty());
-  if (HasMnemonicFirst) {
-    Mnemonic = AsmOperands[0].Token;
-    if (Mnemonic[0] == '$')
-      PrintFatalError(TheDef->getLoc(),
-                      "Invalid instruction mnemonic '" + Mnemonic + "'!");
-
-    // Remove the first operand, it is tracked in the mnemonic field.
-    AsmOperands.erase(AsmOperands.begin());
-  } else if (AsmOperands[0].Token[0] != '$')
-    Mnemonic = AsmOperands[0].Token;
-
   // Compute the require features.
   for (Record *Predicate : TheDef->getValueAsListOfDefs("Predicates"))
     if (const SubtargetFeatureInfo *Feature =
@@ -896,21 +873,16 @@
                                       AsmVariantInfo const &Variant) {
   StringRef String = AsmString;
   size_t Prev = 0;
-  bool InTok = false;
+  bool InTok = true;
   bool IsIsolatedToken = true;
   for (size_t i = 0, e = String.size(); i != e; ++i) {
     char Char = String[i];
-    if (Variant.BreakCharacters.find(Char) != std::string::npos) {
+    switch(Char) {
+    case '[':
+    case ']':
+    case '*':
+    case '!':
       if (InTok) {
-        addAsmOperand(String.slice(Prev, i), false);
-        Prev = i;
-        IsIsolatedToken = false;
-      }
-      InTok = true;
-      continue;
-    }
-    if (Variant.TokenizingCharacters.find(Char) != std::string::npos) {
-      if (InTok) {
         addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
         InTok = false;
         IsIsolatedToken = false;
@@ -918,9 +890,10 @@
       addAsmOperand(String.slice(i, i + 1), IsIsolatedToken);
       Prev = i + 1;
       IsIsolatedToken = true;
-      continue;
-    }
-    if (Variant.SeparatorCharacters.find(Char) != std::string::npos) {
+      break;
+    case ' ':
+    case '\t':
+    case ',':
       if (InTok) {
         addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
         InTok = false;
@@ -927,10 +900,16 @@
       }
       Prev = i + 1;
       IsIsolatedToken = true;
-      continue;
-    }
-
-    switch (Char) {
+      break;
+    case '.':
+      if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) {
+        if (InTok)
+          addAsmOperand(String.slice(Prev, i), false);
+        Prev = i;
+        IsIsolatedToken = false;
+      }
+      InTok = true;
+      break;
     case '\\':
       if (InTok) {
         addAsmOperand(String.slice(Prev, i), false);
@@ -974,6 +953,15 @@
   }
   if (InTok && Prev != String.size())
     addAsmOperand(String.substr(Prev), IsIsolatedToken);
+
+  // The first token of the instruction is the mnemonic, which must be a
+  // simple string, not a $foo variable or a singleton register.
+  if (AsmOperands.empty())
+    PrintFatalError(TheDef->getLoc(),
+                  "Instruction '" + TheDef->getName() + "' has no tokens");
+  assert(!AsmOperands[0].Token.empty());
+  if (AsmOperands[0].Token[0] != '$')
+    Mnemonic = AsmOperands[0].Token;
 }
 
 bool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const {
@@ -1380,8 +1368,6 @@
     assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!");
   }
 
-  bool HasMnemonicFirst = AsmParser->getValueAsBit("HasMnemonicFirst");
-
   // Parse the instructions; we need to do this first so that we can gather the
   // singleton register classes.
   SmallPtrSet<Record*, 16> SingletonRegisters;
@@ -1392,12 +1378,6 @@
       AsmVariant->getValueAsString("CommentDelimiter");
     AsmVariantInfo Variant;
     Variant.RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
-    Variant.TokenizingCharacters =
-        AsmVariant->getValueAsString("TokenizingCharacters");
-    Variant.SeparatorCharacters =
-        AsmVariant->getValueAsString("SeparatorCharacters");
-    Variant.BreakCharacters =
-        AsmVariant->getValueAsString("BreakCharacters");
     Variant.AsmVariantNo = AsmVariant->getValueAsInt("Variant");
 
     for (const CodeGenInstruction *CGI : Target.instructions()) {
@@ -1413,7 +1393,7 @@
 
       auto II = llvm::make_unique<MatchableInfo>(*CGI);
 
-      II->initialize(*this, SingletonRegisters, Variant, HasMnemonicFirst);
+      II->initialize(*this, SingletonRegisters, Variant);
 
       // Ignore instructions which shouldn't be matched and diagnose invalid
       // instruction definitions with an error.
@@ -1441,7 +1421,7 @@
 
       auto II = llvm::make_unique<MatchableInfo>(std::move(Alias));
 
-      II->initialize(*this, SingletonRegisters, Variant, HasMnemonicFirst);
+      II->initialize(*this, SingletonRegisters, Variant);
 
       // Validate the alias definitions.
       II->validate(CommentDelimiter, false);
@@ -1747,7 +1727,7 @@
 
 static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
                              std::vector<std::unique_ptr<MatchableInfo>> &Infos,
-                             bool HasMnemonicFirst, raw_ostream &OS) {
+                             raw_ostream &OS) {
   SmallSetVector<std::string, 16> OperandConversionKinds;
   SmallSetVector<std::string, 16> InstructionConversionKinds;
   std::vector<std::vector<uint8_t> > ConversionTable;
@@ -1881,7 +1861,7 @@
 
         // Add the operand entry to the instruction kind conversion row.
         ConversionRow.push_back(ID);
-        ConversionRow.push_back(OpInfo.AsmOperandNum + HasMnemonicFirst);
+        ConversionRow.push_back(OpInfo.AsmOperandNum);
 
         if (!IsNewConverter)
           break;
@@ -2480,7 +2460,7 @@
 static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
                               const AsmMatcherInfo &Info, StringRef ClassName,
                               StringToOffsetTable &StringTable,
-                              unsigned MaxMnemonicIndex, bool HasMnemonicFirst) {
+                              unsigned MaxMnemonicIndex) {
   unsigned MaxMask = 0;
   for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
     MaxMask |= OMI.OperandMask;
@@ -2594,25 +2574,19 @@
   OS << "  uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
 
   OS << "  // Get the next operand index.\n";
-  OS << "  unsigned NextOpNum = Operands.size()"
-     << (HasMnemonicFirst ? " - 1" : "") << ";\n";
+  OS << "  unsigned NextOpNum = Operands.size();\n";
 
   // Emit code to search the table.
   OS << "  // Search the table.\n";
-  if (HasMnemonicFirst) {
-    OS << "  auto MnemonicRange =\n";
-    OS << "    std::equal_range(std::begin(OperandMatchTable), "
-          "std::end(OperandMatchTable),\n";
-    OS << "                     Mnemonic, LessOpcodeOperand());\n\n";
-  } else {
-    OS << "  auto MnemonicRange = std::make_pair(std::begin(OperandMatchTable),"
-          " std::end(OperandMatchTable));\n";
-    OS << "  if (!Mnemonic.empty())\n";
-    OS << "    MnemonicRange =\n";
-    OS << "      std::equal_range(std::begin(OperandMatchTable), "
-          "std::end(OperandMatchTable),\n";
-    OS << "                       Mnemonic, LessOpcodeOperand());\n\n";
-  }
+  OS << "  std::pair<const OperandMatchEntry*, const OperandMatchEntry*>";
+  OS << " MnemonicRange\n";
+  OS << "       (OperandMatchTable, OperandMatchTable+";
+  OS << Info.OperandMatchInfo.size() << ");\n";
+  OS << "  if(!Mnemonic.empty())\n";
+  OS << "    MnemonicRange = std::equal_range(OperandMatchTable,";
+  OS << " OperandMatchTable+"
+     << Info.OperandMatchInfo.size() << ", Mnemonic,\n"
+     << "                     LessOpcodeOperand());\n\n";
 
   OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
   OS << "    return MatchOperand_NoMatch;\n\n";
@@ -2697,8 +2671,6 @@
   // Compute the information on the custom operand parsing.
   Info.buildOperandMatchInfo();
 
-  bool HasMnemonicFirst = AsmParser->getValueAsBit("HasMnemonicFirst");
-
   // Write the output.
 
   // Information for the class declaration.
@@ -2713,8 +2685,7 @@
      << "&Operands);\n";
   OS << "  void convertToMapAndConstraints(unsigned Kind,\n                ";
   OS << "           const OperandVector &Operands) override;\n";
-  if (HasMnemonicFirst)
-    OS << "  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
+  OS << "  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
   OS << "  unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
      << "                                MCInst &Inst,\n"
      << "                                uint64_t &ErrorInfo,"
@@ -2775,7 +2746,7 @@
   // Generate the convertToMCInst function to convert operands into an MCInst.
   // Also, generate the convertToMapAndConstraints function for MS-style inline
   // assembly.  The latter doesn't actually generate a MCInst.
-  emitConvertFuncs(Target, ClassName, Info.Matchables, HasMnemonicFirst, OS);
+  emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
 
   // Emit the enumeration for classes which participate in matching.
   emitMatchClassEnumeration(Target, Info.Classes, OS);
@@ -2897,26 +2868,24 @@
   }
 
   // A method to determine if a mnemonic is in the list.
-  if (HasMnemonicFirst) {
-    OS << "bool " << Target.getName() << ClassName << "::\n"
-       << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n";
-    OS << "  // Find the appropriate table for this asm variant.\n";
-    OS << "  const MatchEntry *Start, *End;\n";
-    OS << "  switch (VariantID) {\n";
-    OS << "  default: llvm_unreachable(\"invalid variant!\");\n";
-    for (unsigned VC = 0; VC != VariantCount; ++VC) {
-      Record *AsmVariant = Target.getAsmParserVariant(VC);
-      int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
-      OS << "  case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
-         << "); End = std::end(MatchTable" << VC << "); break;\n";
-    }
-    OS << "  }\n";
-    OS << "  // Search the table.\n";
-    OS << "  auto MnemonicRange = ";
-    OS << "std::equal_range(Start, End, Mnemonic, LessOpcode());\n";
-    OS << "  return MnemonicRange.first != MnemonicRange.second;\n";
-    OS << "}\n\n";
+  OS << "bool " << Target.getName() << ClassName << "::\n"
+     << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n";
+  OS << "  // Find the appropriate table for this asm variant.\n";
+  OS << "  const MatchEntry *Start, *End;\n";
+  OS << "  switch (VariantID) {\n";
+  OS << "  default: llvm_unreachable(\"invalid variant!\");\n";
+  for (unsigned VC = 0; VC != VariantCount; ++VC) {
+    Record *AsmVariant = Target.getAsmParserVariant(VC);
+    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
+    OS << "  case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
+       << "); End = std::end(MatchTable" << VC << "); break;\n";
   }
+  OS << "  }\n";
+  OS << "  // Search the table.\n";
+  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
+  OS << "    std::equal_range(Start, End, Mnemonic, LessOpcode());\n";
+  OS << "  return MnemonicRange.first != MnemonicRange.second;\n";
+  OS << "}\n\n";
 
   // Finally, build the match function.
   OS << "unsigned " << Target.getName() << ClassName << "::\n"
@@ -2925,10 +2894,8 @@
      << "                     bool matchingInlineAsm, unsigned VariantID) {\n";
 
   OS << "  // Eliminate obvious mismatches.\n";
-  OS << "  if (Operands.size() > "
-     << (MaxNumOperands + HasMnemonicFirst) << ") {\n";
-  OS << "    ErrorInfo = "
-     << (MaxNumOperands + HasMnemonicFirst) << ";\n";
+  OS << "  if (Operands.size() > " << MaxNumOperands << ") {\n";
+  OS << "    ErrorInfo = " << MaxNumOperands << ";\n";
   OS << "    return Match_InvalidOperand;\n";
   OS << "  }\n\n";
 
@@ -2937,15 +2904,10 @@
   OS << "  uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
 
   OS << "  // Get the instruction mnemonic, which is the first token.\n";
-  if (HasMnemonicFirst) {
-    OS << "  StringRef Mnemonic = ((" << Target.getName()
-       << "Operand&)*Operands[0]).getToken();\n\n";
-  } else {
-    OS << "  StringRef Mnemonic;\n";
-    OS << "  if (Operands[0]->isToken())\n";
-    OS << "    Mnemonic = ((" << Target.getName()
-       << "Operand&)*Operands[0]).getToken();\n\n";
-  }
+  OS << "  StringRef Mnemonic;\n";
+  OS << "  if (Operands[0]->isToken())\n";
+  OS << "    Mnemonic = ((" << Target.getName()
+     << "Operand&)*Operands[0]).getToken();\n\n";
 
   if (HasMnemonicAliases) {
     OS << "  // Process all MnemonicAliases to remap the mnemonic.\n";
@@ -2974,18 +2936,12 @@
        << "); End = std::end(MatchTable" << VC << "); break;\n";
   }
   OS << "  }\n";
-
   OS << "  // Search the table.\n";
-  if (HasMnemonicFirst) {
-    OS << "  auto MnemonicRange = "
-          "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
-  } else {
-    OS << "  auto MnemonicRange = std::make_pair(Start, End);\n";
-    OS << "  unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
-    OS << "  if (!Mnemonic.empty())\n";
-    OS << "    MnemonicRange = "
-          "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
-  }
+  OS << "  std::pair<const MatchEntry*, const MatchEntry*> "
+        "MnemonicRange(Start, End);\n";
+  OS << "  unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
+  OS << "  if (!Mnemonic.empty())\n";
+  OS << "    MnemonicRange = std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
 
   OS << "  // Return a more specific error code if no mnemonics match.\n";
   OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
@@ -2995,25 +2951,16 @@
      << "*ie = MnemonicRange.second;\n";
   OS << "       it != ie; ++it) {\n";
 
-  if (HasMnemonicFirst) {
-    OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
-    OS << "    assert(Mnemonic == it->getMnemonic());\n";
-  }
-
   // Emit check that the subclasses match.
   OS << "    bool OperandsValid = true;\n";
-  OS << "    for (unsigned i = " << (HasMnemonicFirst ? "0" : "SIndex")
-     << "; i != " << MaxNumOperands << "; ++i) {\n";
+  OS << "    for (unsigned i = SIndex; i != " << MaxNumOperands << "; ++i) {\n";
   OS << "      auto Formal = static_cast<MatchClassKind>(it->Classes[i]);\n";
-  OS << "      if (i" << (HasMnemonicFirst ? "+1" : "")
-     << " >= Operands.size()) {\n";
+  OS << "      if (i >= Operands.size()) {\n";
   OS << "        OperandsValid = (Formal == " <<"InvalidMatchClass);\n";
-  OS << "        if (!OperandsValid) ErrorInfo = i"
-     << (HasMnemonicFirst ? "+1" : "") << ";\n";
+  OS << "        if (!OperandsValid) ErrorInfo = i;\n";
   OS << "        break;\n";
   OS << "      }\n";
-  OS << "      MCParsedAsmOperand &Actual = *Operands[i"
-     << (HasMnemonicFirst ? "+1" : "") << "];\n";
+  OS << "      MCParsedAsmOperand &Actual = *Operands[i];\n";
   OS << "      unsigned Diag = validateOperandClass(Actual, Formal);\n";
   OS << "      if (Diag == Match_Success)\n";
   OS << "        continue;\n";
@@ -3029,9 +2976,8 @@
   OS << "      // If we already had a match that only failed due to a\n";
   OS << "      // target predicate, that diagnostic is preferred.\n";
   OS << "      if (!HadMatchOtherThanPredicate &&\n";
-  OS << "          (it == MnemonicRange.first || ErrorInfo <= i"
-     << (HasMnemonicFirst ? "+1" : "") << ")) {\n";
-  OS << "        ErrorInfo = i" << (HasMnemonicFirst ? "+1" : "") << ";\n";
+  OS << "          (it == MnemonicRange.first || ErrorInfo <= i)) {\n";
+  OS << "        ErrorInfo = i;\n";
   OS << "        // InvalidOperand is the default. Prefer specificity.\n";
   OS << "        if (Diag != Match_InvalidOperand)\n";
   OS << "          RetCode = Diag;\n";
@@ -3106,7 +3052,7 @@
 
   if (!Info.OperandMatchInfo.empty())
     emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
-                             MaxMnemonicIndex, HasMnemonicFirst);
+                             MaxMnemonicIndex);
 
   OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
 }