1 //===- SubtargetFeatureInfo.cpp - Helpers for subtarget features ----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "SubtargetFeatureInfo.h" 11 12 #include "Types.h" 13 #include "llvm/TableGen/Record.h" 14 15 #include <map> 16 17 using namespace llvm; 18 19 void SubtargetFeatureInfo::dump() const { 20 errs() << getEnumName() << " " << Index << "\n"; 21 TheDef->dump(); 22 } 23 24 std::vector<std::pair<Record *, SubtargetFeatureInfo>> 25 SubtargetFeatureInfo::getAll(const RecordKeeper &Records) { 26 std::vector<std::pair<Record *, SubtargetFeatureInfo>> SubtargetFeatures; 27 std::vector<Record *> AllPredicates = 28 Records.getAllDerivedDefinitions("Predicate"); 29 for (Record *Pred : AllPredicates) { 30 // Ignore predicates that are not intended for the assembler. 31 // 32 // The "AssemblerMatcherPredicate" string should be promoted to an argument 33 // if we re-use the machinery for non-assembler purposes in future. 34 if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) 35 continue; 36 37 if (Pred->getName().empty()) 38 PrintFatalError(Pred->getLoc(), "Predicate has no name!"); 39 40 SubtargetFeatures.emplace_back( 41 Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size())); 42 } 43 return SubtargetFeatures; 44 } 45 46 void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration( 47 std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, 48 raw_ostream &OS) { 49 OS << "// Flags for subtarget features that participate in " 50 << "instruction matching.\n"; 51 OS << "enum SubtargetFeatureFlag : " 52 << getMinimalTypeForEnumBitfield(SubtargetFeatures.size()) << " {\n"; 53 for (const auto &SF : SubtargetFeatures) { 54 const SubtargetFeatureInfo &SFI = SF.second; 55 OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n"; 56 } 57 OS << " Feature_None = 0\n"; 58 OS << "};\n\n"; 59 } 60 61 void SubtargetFeatureInfo::emitNameTable( 62 std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, 63 raw_ostream &OS) { 64 OS << "static const char *SubtargetFeatureNames[] = {\n"; 65 for (const auto &SF : SubtargetFeatures) { 66 const SubtargetFeatureInfo &SFI = SF.second; 67 OS << " \"" << SFI.getEnumName() << "\",\n"; 68 } 69 // A small number of targets have no predicates. Null terminate the array to 70 // avoid a zero-length array. 71 OS << " nullptr\n" 72 << "};\n\n"; 73 } 74 75 void SubtargetFeatureInfo::emitComputeAvailableFeatures( 76 StringRef TargetName, StringRef ClassName, StringRef FuncName, 77 std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, 78 raw_ostream &OS) { 79 OS << "uint64_t " << TargetName << ClassName << "::\n" 80 << FuncName << "(const FeatureBitset& FB) const {\n"; 81 OS << " uint64_t Features = 0;\n"; 82 for (const auto &SF : SubtargetFeatures) { 83 const SubtargetFeatureInfo &SFI = SF.second; 84 85 OS << " if ("; 86 std::string CondStorage = 87 SFI.TheDef->getValueAsString("AssemblerCondString"); 88 StringRef Conds = CondStorage; 89 std::pair<StringRef, StringRef> Comma = Conds.split(','); 90 bool First = true; 91 do { 92 if (!First) 93 OS << " && "; 94 95 bool Neg = false; 96 StringRef Cond = Comma.first; 97 if (Cond[0] == '!') { 98 Neg = true; 99 Cond = Cond.substr(1); 100 } 101 102 OS << "("; 103 if (Neg) 104 OS << "!"; 105 OS << "FB[" << TargetName << "::" << Cond << "])"; 106 107 if (Comma.second.empty()) 108 break; 109 110 First = false; 111 Comma = Comma.second.split(','); 112 } while (true); 113 114 OS << ")\n"; 115 OS << " Features |= " << SFI.getEnumName() << ";\n"; 116 } 117 OS << " return Features;\n"; 118 OS << "}\n\n"; 119 } 120