llvm.org GIT mirror llvm / f922c47
AsmMatcher custom operand parser failure enhancements. Teach the AsmMatcher handling to distinguish between an error custom-parsing an operand and a failure to match. The former should propogate the error upwards, while the latter should continue attempting to parse with alternative matchers. Update the ARM asm parser accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125426 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 9 years ago
4 changed file(s) with 53 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
151151 def MemBarrierOptOperand : AsmOperandClass {
152152 let Name = "MemBarrierOpt";
153153 let SuperClasses = [];
154 let ParserMethod = "ParseMemBarrierOptOperand";
154 let ParserMethod = "tryParseMemBarrierOptOperand";
155155 }
156156
157157 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
590590 def CoprocNumAsmOperand : AsmOperandClass {
591591 let Name = "CoprocNum";
592592 let SuperClasses = [];
593 let ParserMethod = "ParseCoprocNumOperand";
593 let ParserMethod = "tryParseCoprocNumOperand";
594594 }
595595
596596 def CoprocRegAsmOperand : AsmOperandClass {
597597 let Name = "CoprocReg";
598598 let SuperClasses = [];
599 let ParserMethod = "ParseCoprocRegOperand";
599 let ParserMethod = "tryParseCoprocRegOperand";
600600 }
601601
602602 def p_imm : Operand {
5454 int TryParseRegister();
5555 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
5656 bool TryParseRegisterWithWriteBack(SmallVectorImpl &);
57 bool ParseCoprocNumOperand(SmallVectorImpl&);
58 bool ParseCoprocRegOperand(SmallVectorImpl&);
5957 bool ParseRegisterList(SmallVectorImpl &);
60 bool ParseMemBarrierOptOperand(SmallVectorImpl &);
6158 bool ParseMemory(SmallVectorImpl &);
6259 bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic);
6360 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
9390 #include "ARMGenAsmMatcher.inc"
9491
9592 /// }
93
94 OperandMatchResultTy tryParseCoprocNumOperand(
95 SmallVectorImpl&);
96 OperandMatchResultTy tryParseCoprocRegOperand(
97 SmallVectorImpl&);
98 OperandMatchResultTy tryParseMemBarrierOptOperand(
99 SmallVectorImpl &);
96100
97101 public:
98102 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
733737 return -1;
734738 }
735739
736 /// ParseCoprocNumOperand - Try to parse an coprocessor number operand. The
740 /// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
737741 /// token must be an Identifier when called, and if it is a coprocessor
738742 /// number, the token is eaten and the operand is added to the operand list.
739 bool ARMAsmParser::
740 ParseCoprocNumOperand(SmallVectorImpl &Operands) {
743 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
744 tryParseCoprocNumOperand(SmallVectorImpl &Operands) {
741745 SMLoc S = Parser.getTok().getLoc();
742746 const AsmToken &Tok = Parser.getTok();
743747 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
744748
745749 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
746750 if (Num == -1)
747 return true;
751 return MatchOperand_NoMatch;
748752
749753 Parser.Lex(); // Eat identifier token.
750754 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
751 return false;
752 }
753
754 /// ParseCoprocRegOperand - Try to parse an coprocessor register operand. The
755 return MatchOperand_Success;
756 }
757
758 /// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
755759 /// token must be an Identifier when called, and if it is a coprocessor
756760 /// number, the token is eaten and the operand is added to the operand list.
757 bool ARMAsmParser::
758 ParseCoprocRegOperand(SmallVectorImpl &Operands) {
761 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
762 tryParseCoprocRegOperand(SmallVectorImpl &Operands) {
759763 SMLoc S = Parser.getTok().getLoc();
760764 const AsmToken &Tok = Parser.getTok();
761765 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
762766
763767 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
764768 if (Reg == -1)
765 return true;
769 return MatchOperand_NoMatch;
766770
767771 Parser.Lex(); // Eat identifier token.
768772 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
769 return false;
773 return MatchOperand_Success;
770774 }
771775
772776 /// Parse a register list, return it if successful else return null. The first
853857 return false;
854858 }
855859
856 /// ParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
857 bool ARMAsmParser::
858 ParseMemBarrierOptOperand(SmallVectorImpl &Operands) {
860 /// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
861 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
862 tryParseMemBarrierOptOperand(SmallVectorImpl &Operands) {
859863 SMLoc S = Parser.getTok().getLoc();
860864 const AsmToken &Tok = Parser.getTok();
861865 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
873877 .Default(~0U);
874878
875879 if (Opt == ~0U)
876 return true;
880 return MatchOperand_NoMatch;
877881
878882 Parser.Lex(); // Eat identifier token.
879883 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
880 return false;
884 return MatchOperand_Success;
881885 }
882886
883887 /// Parse an ARM memory expression, return false if successful else return true
11041108
11051109 // Check if the current operand has a custom associated parser, if so, try to
11061110 // custom parse the operand, or fallback to the general approach.
1107 MatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1108 if (ResTy == Match_Success)
1111 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1112 if (ResTy == MatchOperand_Success)
11091113 return false;
1114 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1115 // there was a match, but an error occurred, in which case, just return that
1116 // the operand parsing failed.
1117 if (ResTy == MatchOperand_ParseFail)
1118 return true;
11101119
11111120 switch (getLexer().getKind()) {
11121121 default:
19731973
19741974 // Emit the operand class switch to call the correct custom parser for
19751975 // the found operand class.
1976 OS << "bool " << Target.getName() << ClassName << "::\n"
1976 OS << Target.getName() << ClassName << "::OperandMatchResultTy "
1977 << Target.getName() << ClassName << "::\n"
19771978 << "TryCustomParseOperand(SmallVectorImpl"
19781979 << " &Operands,\n unsigned MCK) {\n\n"
19791980 << " switch(MCK) {\n";
19881989 }
19891990
19901991 OS << " default:\n";
1991 OS << " return true;\n";
1992 OS << " return MatchOperand_NoMatch;\n";
19921993 OS << " }\n";
1993 OS << " return true;\n";
1994 OS << " return MatchOperand_NoMatch;\n";
19941995 OS << "}\n\n";
19951996
19961997 // Emit the static custom operand parser. This code is very similar with
19971998 // the other matcher. Also use MatchResultTy here just in case we go for
19981999 // a better error handling.
1999 OS << Target.getName() << ClassName << "::MatchResultTy "
2000 OS << Target.getName() << ClassName << "::OperandMatchResultTy "
20002001 << Target.getName() << ClassName << "::\n"
20012002 << "MatchOperandParserImpl(SmallVectorImpl"
20022003 << " &Operands,\n StringRef Mnemonic) {\n";
20072008
20082009 OS << " // Get the next operand index.\n";
20092010 OS << " unsigned NextOpNum = Operands.size()-1;\n";
2010
2011 OS << " // Some state to try to produce better error messages.\n";
2012 OS << " bool HadMatchOtherThanFeatures = false;\n\n";
20132011
20142012 // Emit code to search the table.
20152013 OS << " // Search the table.\n";
20192017 << Info.OperandMatchInfo.size() << ", Mnemonic,\n"
20202018 << " LessOpcodeOperand());\n\n";
20212019
2022 OS << " // Return a more specific error code if no mnemonics match.\n";
20232020 OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
2024 OS << " return Match_MnemonicFail;\n\n";
2021 OS << " return MatchOperand_NoMatch;\n\n";
20252022
20262023 OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n"
20272024 << " *ie = MnemonicRange.second; it != ie; ++it) {\n";
20332030 OS << " // check if the available features match\n";
20342031 OS << " if ((AvailableFeatures & it->RequiredFeatures) "
20352032 << "!= it->RequiredFeatures) {\n";
2036 OS << " HadMatchOtherThanFeatures = true;\n";
20372033 OS << " continue;\n";
20382034 OS << " }\n\n";
20392035
20442040
20452041 // Emit call to the custom parser method
20462042 OS << " // call custom parse method to handle the operand\n";
2047 OS << " if (!TryCustomParseOperand(Operands, it->Class))\n";
2048 OS << " return Match_Success;\n";
2043 OS << " OperandMatchResultTy Result = ";
2044 OS << "TryCustomParseOperand(Operands, it->Class);\n";
2045 OS << " if (Result != MatchOperand_NoMatch)\n";
2046 OS << " return Result;\n";
20492047 OS << " }\n\n";
20502048
2051 OS << " // Okay, we had no match. Try to return a useful error code.\n";
2052 OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n";
2053 OS << " return Match_InvalidOperand;\n";
2049 OS << " // Okay, we had no match.\n";
2050 OS << " return MatchOperand_NoMatch;\n";
20542051 OS << "}\n\n";
20552052 }
20562053
21302127 OS << " MCInst &Inst, unsigned &ErrorInfo);\n";
21312128
21322129 if (Info.OperandMatchInfo.size()) {
2133 OS << " MatchResultTy MatchOperandParserImpl(\n";
2130 OS << "\n enum OperandMatchResultTy {\n";
2131 OS << " MatchOperand_Success, // operand matched successfully\n";
2132 OS << " MatchOperand_NoMatch, // operand did not match\n";
2133 OS << " MatchOperand_ParseFail // operand matched but had errors\n";
2134 OS << " };\n";
2135 OS << " OperandMatchResultTy MatchOperandParserImpl(\n";
21342136 OS << " SmallVectorImpl &Operands,\n";
21352137 OS << " StringRef Mnemonic);\n";
21362138
2137 OS << " bool TryCustomParseOperand(\n";
2139 OS << " OperandMatchResultTy TryCustomParseOperand(\n";
21382140 OS << " SmallVectorImpl &Operands,\n";
21392141 OS << " unsigned MCK);\n\n";
21402142 }