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 &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 &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 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(*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(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> &Infos, - bool HasMnemonicFirst, raw_ostream &OS) { + raw_ostream &OS) { SmallSetVector OperandConversionKinds; SmallSetVector InstructionConversionKinds; std::vector > 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"; + 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 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 " + "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(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"; }