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: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -235,7 +235,8 @@ def IsLE : Predicate<"Subtarget->isLittle()">; def IsBE : Predicate<"!Subtarget->isLittle()">; def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; -def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">; +def UseTCCInDIV : Predicate<"Subtarget->useTCCInDIV()">, + AssemblerPredicate<"FeatureUseTCCInDIV">; def HasEVA : Predicate<"Subtarget->hasEVA()">, AssemblerPredicate<"FeatureEVA">; def HasMSA : Predicate<"Subtarget->hasMSA()">, Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -292,6 +292,7 @@ bool hasDSPR2() const { return HasDSPR2; } bool hasDSPR3() const { return HasDSPR3; } bool hasMSA() const { return HasMSA; } + bool useTCCInDIV() const { return UseTCCInDIV; } bool disableMadd4() const { return DisableMadd4; } bool hasEVA() const { return HasEVA; } bool hasMT() const { return HasMT; } 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.h =================================================================== --- utils/TableGen/SubtargetFeatureInfo.h +++ utils/TableGen/SubtargetFeatureInfo.h @@ -33,7 +33,12 @@ /// An unique index assigned to represent this feature. uint64_t Index; - SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) {} + SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) { + if (!TheDef->isSubClassOf("Predicate")) { + PrintFatalError(TheDef->getLoc(), + TheDef->getName().str() + " must be a Predicate"); + } + } /// The name of the enumerated constant identifying this feature. std::string getEnumName() const { 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!");