]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
Copy needed include files from EDK2. This is a minimal set gleened
[FreeBSD/FreeBSD.git] / contrib / llvm / utils / TableGen / SubtargetFeatureInfo.cpp
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 }