Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -595,20 +595,6 @@ class Predicate { string CondString = cond; - /// AssemblerMatcherPredicate - If this feature can be used by the assembler - /// matcher, this is true. Targets should set this by inheriting their - /// feature from the AssemblerPredicate class in addition to Predicate. - bit AssemblerMatcherPredicate = 0; - - /// AssemblerCondString - Name of the subtarget feature being tested used - /// as alternative condition string used for assembler matcher. - /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0". - /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0". - /// It can also list multiple features separated by ",". - /// e.g. "ModeThumb,FeatureThumb2" is translated to - /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0". - string AssemblerCondString = ""; - /// PredicateName - User-level name to use for the predicate. Mainly for use /// in diagnostics such as missing feature errors in the asm matcher. string PredicateName = ""; @@ -1271,8 +1257,15 @@ /// AssemblerPredicate - This is a Predicate that can be used when the assembler /// matches instructions and aliases. class AssemblerPredicate { - bit AssemblerMatcherPredicate = 1; + /// AssemblerCondString - Name of the subtarget feature being tested used as + /// alternative condition string used for assembler matcher. + /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0". + /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0". + /// It can also list multiple features separated by ",". + /// e.g. "ModeThumb,FeatureThumb2" is translated to + /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0". string AssemblerCondString = cond; + string PredicateName = name; } Index: utils/TableGen/AsmWriterEmitter.cpp =================================================================== --- utils/TableGen/AsmWriterEmitter.cpp +++ utils/TableGen/AsmWriterEmitter.cpp @@ -815,7 +815,7 @@ std::vector RF = CGA.TheDef->getValueAsListOfDefs("Predicates"); copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) { - return R->getValueAsBit("AssemblerMatcherPredicate"); + return R->isSubClassOf("AssemblerPredicate"); }); } @@ -1089,14 +1089,14 @@ << " break;\n"; } O << " }\n"; - } + } O << "}\n\n"; if (!MCOpPredicates.empty()) { O << "static bool " << Target.getName() << ClassName << "ValidateMCOperand(const MCOperand &MCOp,\n" << " const MCSubtargetInfo &STI,\n" - << " unsigned PredicateIndex) {\n" + << " unsigned PredicateIndex) {\n" << " switch (PredicateIndex) {\n" << " default:\n" << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" Index: utils/TableGen/FixedLenDecoderEmitter.cpp =================================================================== --- utils/TableGen/FixedLenDecoderEmitter.cpp +++ utils/TableGen/FixedLenDecoderEmitter.cpp @@ -1142,7 +1142,7 @@ bool IsFirstEmission = true; for (unsigned i = 0; i < Predicates->size(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); - if (!Pred->getValue("AssemblerMatcherPredicate")) + if (!Pred->isSubClassOf("AssemblerPredicate")) continue; StringRef P = Pred->getValueAsString("AssemblerCondString"); @@ -1170,7 +1170,7 @@ AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); for (unsigned i = 0; i < Predicates->size(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); - if (!Pred->getValue("AssemblerMatcherPredicate")) + if (!Pred->isSubClassOf("AssemblerPredicate")) continue; StringRef P = Pred->getValueAsString("AssemblerCondString"); Index: utils/TableGen/RISCVCompressInstEmitter.cpp =================================================================== --- utils/TableGen/RISCVCompressInstEmitter.cpp +++ utils/TableGen/RISCVCompressInstEmitter.cpp @@ -464,9 +464,8 @@ // Get the target features for the CompressPat. std::vector PatReqFeatures; std::vector RF = Rec->getValueAsListOfDefs("Predicates"); - copy_if(RF, std::back_inserter(PatReqFeatures), [](Record *R) { - return R->getValueAsBit("AssemblerMatcherPredicate"); - }); + copy_if(RF, std::back_inserter(PatReqFeatures), + [](Record *R) { return R->isSubClassOf("AssemblerPredicate"); }); CompressPatterns.push_back(CompressPat(SourceInst, DestInst, PatReqFeatures, SourceOperandMap, DestOperandMap)); @@ -624,9 +623,8 @@ // Add Dest instruction required features. std::vector ReqFeatures; std::vector RF = Dest.TheDef->getValueAsListOfDefs("Predicates"); - copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) { - return R->getValueAsBit("AssemblerMatcherPredicate"); - }); + copy_if(RF, std::back_inserter(ReqFeatures), + [](Record *R) { return R->isSubClassOf("AssemblerPredicate"); }); getReqFeatures(FeaturesMap, ReqFeatures); // Emit checks for all required features. Index: utils/TableGen/SubtargetFeatureInfo.cpp =================================================================== --- utils/TableGen/SubtargetFeatureInfo.cpp +++ utils/TableGen/SubtargetFeatureInfo.cpp @@ -26,16 +26,9 @@ std::vector> SubtargetFeatureInfo::getAll(const RecordKeeper &Records) { std::vector> SubtargetFeatures; - std::vector AllPredicates = - Records.getAllDerivedDefinitions("Predicate"); - for (Record *Pred : AllPredicates) { - // Ignore predicates that are not intended for the assembler. - // - // The "AssemblerMatcherPredicate" string should be promoted to an argument - // if we re-use the machinery for non-assembler purposes in future. - if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) - continue; - + std::vector AllAssemblerPredicates = + Records.getAllDerivedDefinitions("AssemblerPredicate"); + for (Record *Pred : AllAssemblerPredicates) { if (Pred->getName().empty()) PrintFatalError(Pred->getLoc(), "Predicate has no name!"); @@ -111,6 +104,10 @@ for (const auto &SF : SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; + if (!SFI.TheDef->isSubClassOf("Predicate")) { + PrintFatalError(SFI.TheDef->getLoc(), + SFI.TheDef->getName().str() + " must be a Predicate"); + } OS << " if (" << SFI.TheDef->getValueAsString("CondString") << ")\n"; OS << " Features[" << SFI.getEnumBitName() << "] = 1;\n"; } @@ -127,6 +124,11 @@ for (const auto &SF : SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; + if (!SFI.TheDef->isSubClassOf("AssemblerPredicate")) { + PrintFatalError(SFI.TheDef->getLoc(), + SFI.TheDef->getName().str() + + " must be an AssemblerPredicate"); + } OS << " if ("; std::string CondStorage = SFI.TheDef->getValueAsString("AssemblerCondString");