X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FAsmMatcherEmitter.cpp;h=1fb92ee733ae1000a0bffb02bd0b007ea9fa8401;hb=bea6f615eefae279e53bbb63a31d2c3c67274c45;hp=776ab6382e0c4d339d1593e0c153d99cc0a7595f;hpb=b45c7c270c2845b8ad3322ef44a1ce2032ed0113;p=oota-llvm.git diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 776ab6382e0..1fb92ee733a 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -88,7 +88,7 @@ // 2. The operand matcher will try every possible entry with the same // mnemonic and will check if the target feature for this mnemonic also // matches. After that, if the operand to be matched has its index -// present in the mask, a successfull match occurs. Otherwise, fallback +// present in the mask, a successful match occurs. Otherwise, fallback // to the regular operand parsing. // // 3. For a match success, each operand class that has a 'ParserMethod' @@ -98,6 +98,7 @@ #include "AsmMatcherEmitter.h" #include "CodeGenTarget.h" +#include "Error.h" #include "Record.h" #include "StringMatcher.h" #include "llvm/ADT/OwningPtr.h" @@ -258,7 +259,7 @@ public: return ValueName < RHS.ValueName; default: - // This class preceeds the RHS if it is a proper subset of the RHS. + // This class precedes the RHS if it is a proper subset of the RHS. if (isSubsetOf(RHS)) return true; if (RHS.isSubsetOf(*this)) @@ -870,6 +871,31 @@ AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, if (SubOpIdx != -1) Rec = dynamic_cast(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); + if (Rec->isSubClassOf("RegisterOperand")) { + // RegisterOperand may have an associated ParserMatchClass. If it does, + // use it, else just fall back to the underlying register class. + const RecordVal *R = Rec->getValue("ParserMatchClass"); + if (R == 0 || R->getValue() == 0) + throw "Record `" + Rec->getName() + + "' does not have a ParserMatchClass!\n"; + + if (DefInit *DI= dynamic_cast(R->getValue())) { + Record *MatchClass = DI->getDef(); + if (ClassInfo *CI = AsmOperandClasses[MatchClass]) + return CI; + } + + // No custom match class. Just use the register class. + Record *ClassRec = Rec->getValueAsDef("RegClass"); + if (!ClassRec) + throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() + + "' has no associated register class!\n"); + if (ClassInfo *CI = RegisterClassClasses[ClassRec]) + return CI; + throw TGError(Rec->getLoc(), "register class has no class info!"); + } + + if (Rec->isSubClassOf("RegisterClass")) { if (ClassInfo *CI = RegisterClassClasses[Rec]) return CI; @@ -886,7 +912,8 @@ AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, void AsmMatcherInfo:: BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { - const std::vector &Registers = Target.getRegisters(); + const std::vector &Registers = + Target.getRegBank().getRegisters(); const std::vector &RegClassList = Target.getRegisterClasses(); @@ -896,8 +923,8 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { // Gather the defined sets. for (std::vector::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) - RegisterSets.insert(std::set(it->Elements.begin(), - it->Elements.end())); + RegisterSets.insert(std::set(it->getOrder().begin(), + it->getOrder().end())); // Add any required singleton sets. for (SmallPtrSet::iterator it = SingletonRegisters.begin(), @@ -910,9 +937,9 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { // a unique register set class), and build the mapping of registers to the set // they should classify to. std::map > RegisterMap; - for (std::vector::const_iterator it = Registers.begin(), + for (std::vector::const_iterator it = Registers.begin(), ie = Registers.end(); it != ie; ++it) { - const CodeGenRegister &CGR = *it; + const CodeGenRegister &CGR = **it; // Compute the intersection of all sets containing this register. std::set ContainingSet; @@ -971,8 +998,8 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { // Name the register classes which correspond to a user defined RegisterClass. for (std::vector::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { - ClassInfo *CI = RegisterSetClasses[std::set(it->Elements.begin(), - it->Elements.end())]; + ClassInfo *CI = RegisterSetClasses[std::set(it->getOrder().begin(), + it->getOrder().end())]; if (CI->ValueName.empty()) { CI->ClassName = it->getName(); CI->Name = "MCK_" + it->getName(); @@ -1265,7 +1292,7 @@ void AsmMatcherInfo::BuildInfo() { II->BuildAliasResultOperands(); } - // Reorder classes so that classes preceed super classes. + // Reorder classes so that classes precede super classes. std::sort(Classes.begin(), Classes.end(), less_ptr()); } @@ -1483,10 +1510,10 @@ static void EmitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, MatchableInfo &II = **it; // Check if we have a custom match function. - StringRef AsmMatchConverter = II.getResultInst()->TheDef->getValueAsString( - "AsmMatchConverter"); + std::string AsmMatchConverter = + II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); if (!AsmMatchConverter.empty()) { - std::string Signature = "ConvertCustom_" + AsmMatchConverter.str(); + std::string Signature = "ConvertCustom_" + AsmMatchConverter; II.ConversionFnKind = Signature; // Check if we have already generated this signature. @@ -1538,7 +1565,7 @@ static void EmitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, // operand from the earlier one.We can only tie single MCOperand values. //assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand"); unsigned TiedOp = OpInfo.TiedOperandNum; - assert(i > TiedOp && "Tied operand preceeds its target!"); + assert(i > TiedOp && "Tied operand precedes its target!"); CaseOS << " Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n"; Signature += "__Tie" + utostr(TiedOp); break; @@ -1745,14 +1772,16 @@ static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, raw_ostream &OS) { // Construct the match list. std::vector Matches; - for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) { - const CodeGenRegister &Reg = Target.getRegisters()[i]; - if (Reg.TheDef->getValueAsString("AsmName").empty()) + const std::vector &Regs = + Target.getRegBank().getRegisters(); + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister *Reg = Regs[i]; + if (Reg->TheDef->getValueAsString("AsmName").empty()) continue; Matches.push_back(StringMatcher::StringPair( - Reg.TheDef->getValueAsString("AsmName"), - "return " + utostr(i + 1) + ";")); + Reg->TheDef->getValueAsString("AsmName"), + "return " + utostr(Reg->EnumValue) + ";")); } OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; @@ -1881,6 +1910,8 @@ static bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) { AliasWithNoPredicate = i; continue; } + if (R->getValueAsString("ToMnemonic") == I->first) + throw TGError(R->getLoc(), "MnemonicAlias to the same string"); if (!MatchCode.empty()) MatchCode += "else "; @@ -1974,7 +2005,8 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Emit the operand class switch to call the correct custom parser for // the found operand class. - OS << "bool " << Target.getName() << ClassName << "::\n" + OS << Target.getName() << ClassName << "::OperandMatchResultTy " + << Target.getName() << ClassName << "::\n" << "TryCustomParseOperand(SmallVectorImpl" << " &Operands,\n unsigned MCK) {\n\n" << " switch(MCK) {\n"; @@ -1989,15 +2021,15 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, } OS << " default:\n"; - OS << " return true;\n"; + OS << " return MatchOperand_NoMatch;\n"; OS << " }\n"; - OS << " return true;\n"; + OS << " return MatchOperand_NoMatch;\n"; OS << "}\n\n"; // Emit the static custom operand parser. This code is very similar with // the other matcher. Also use MatchResultTy here just in case we go for // a better error handling. - OS << Target.getName() << ClassName << "::MatchResultTy " + OS << Target.getName() << ClassName << "::OperandMatchResultTy " << Target.getName() << ClassName << "::\n" << "MatchOperandParserImpl(SmallVectorImpl" << " &Operands,\n StringRef Mnemonic) {\n"; @@ -2009,9 +2041,6 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, OS << " // Get the next operand index.\n"; OS << " unsigned NextOpNum = Operands.size()-1;\n"; - OS << " // Some state to try to produce better error messages.\n"; - OS << " bool HadMatchOtherThanFeatures = false;\n\n"; - // Emit code to search the table. OS << " // Search the table.\n"; OS << " std::pair"; @@ -2020,9 +2049,8 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, << Info.OperandMatchInfo.size() << ", Mnemonic,\n" << " LessOpcodeOperand());\n\n"; - OS << " // Return a more specific error code if no mnemonics match.\n"; OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; - OS << " return Match_MnemonicFail;\n\n"; + OS << " return MatchOperand_NoMatch;\n\n"; OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n" << " *ie = MnemonicRange.second; it != ie; ++it) {\n"; @@ -2034,7 +2062,6 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, OS << " // check if the available features match\n"; OS << " if ((AvailableFeatures & it->RequiredFeatures) " << "!= it->RequiredFeatures) {\n"; - OS << " HadMatchOtherThanFeatures = true;\n"; OS << " continue;\n"; OS << " }\n\n"; @@ -2045,13 +2072,14 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Emit call to the custom parser method OS << " // call custom parse method to handle the operand\n"; - OS << " if (!TryCustomParseOperand(Operands, it->Class))\n"; - OS << " return Match_Success;\n"; + OS << " OperandMatchResultTy Result = "; + OS << "TryCustomParseOperand(Operands, it->Class);\n"; + OS << " if (Result != MatchOperand_NoMatch)\n"; + OS << " return Result;\n"; OS << " }\n\n"; - OS << " // Okay, we had no match. Try to return a useful error code.\n"; - OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; - OS << " return Match_InvalidOperand;\n"; + OS << " // Okay, we had no match.\n"; + OS << " return MatchOperand_NoMatch;\n"; OS << "}\n\n"; } @@ -2110,7 +2138,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Information for the class declaration. OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; OS << "#undef GET_ASSEMBLER_HEADER\n"; - OS << " // This should be included into the middle of the declaration of \n"; + OS << " // This should be included into the middle of the declaration of\n"; OS << " // your subclasses implementation of TargetAsmParser.\n"; OS << " unsigned ComputeAvailableFeatures(const " << Target.getName() << "Subtarget *Subtarget) const;\n"; @@ -2131,11 +2159,16 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " MCInst &Inst, unsigned &ErrorInfo);\n"; if (Info.OperandMatchInfo.size()) { - OS << " MatchResultTy MatchOperandParserImpl(\n"; + OS << "\n enum OperandMatchResultTy {\n"; + OS << " MatchOperand_Success, // operand matched successfully\n"; + OS << " MatchOperand_NoMatch, // operand did not match\n"; + OS << " MatchOperand_ParseFail // operand matched but had errors\n"; + OS << " };\n"; + OS << " OperandMatchResultTy MatchOperandParserImpl(\n"; OS << " SmallVectorImpl &Operands,\n"; OS << " StringRef Mnemonic);\n"; - OS << " bool TryCustomParseOperand(\n"; + OS << " OperandMatchResultTy TryCustomParseOperand(\n"; OS << " SmallVectorImpl &Operands,\n"; OS << " unsigned MCK);\n\n"; } @@ -2291,7 +2324,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " // Some state to try to produce better error messages.\n"; OS << " bool HadMatchOtherThanFeatures = false;\n\n"; - OS << " // Set ErrorInfo to the operand that mismatches if it is \n"; + OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; OS << " // wrong for all instances of the instruction.\n"; OS << " ErrorInfo = ~0U;\n"; @@ -2317,7 +2350,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; OS << " if (i + 1 >= Operands.size()) {\n"; OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n"; - OS << " break;"; + OS << " break;\n"; OS << " }\n"; OS << " if (ValidateOperandClass(Operands[i+1], it->Classes[i]))\n"; OS << " continue;\n";