aboutsummaryrefslogtreecommitdiff
path: root/clang/utils/TableGen/SveEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/utils/TableGen/SveEmitter.cpp')
-rw-r--r--clang/utils/TableGen/SveEmitter.cpp110
1 files changed, 107 insertions, 3 deletions
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index af2dcf6..553c7a3 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -243,7 +243,9 @@ public:
/// Return the name, mangled with type information. The name is mangled for
/// ClassS, so will add type suffixes such as _u32/_s32.
- std::string getMangledName() const { return mangleName(ClassS); }
+ std::string getMangledName(ClassKind CK = ClassS) const {
+ return mangleName(CK);
+ }
/// As above, but mangles the LLVM name instead.
std::string getMangledLLVMName() const { return mangleLLVMName(); }
@@ -309,6 +311,7 @@ private:
StringMap<uint64_t> FlagTypes;
StringMap<uint64_t> MergeTypes;
StringMap<uint64_t> ImmCheckTypes;
+ std::vector<llvm::StringRef> ImmCheckTypeNames;
public:
SVEEmitter(const RecordKeeper &R) : Records(R) {
@@ -320,8 +323,15 @@ public:
FlagTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
for (auto *RV : Records.getAllDerivedDefinitions("MergeType"))
MergeTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
- for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType"))
- ImmCheckTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
+ for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType")) {
+ auto [it, inserted] = ImmCheckTypes.try_emplace(
+ RV->getNameInitAsString(), RV->getValueAsInt("Value"));
+ if (!inserted)
+ llvm_unreachable("Duplicate imm check");
+ if ((size_t)it->second >= ImmCheckTypeNames.size())
+ ImmCheckTypeNames.resize((size_t)it->second + 1);
+ ImmCheckTypeNames[it->second] = it->first();
+ }
}
/// Returns the enum value for the immcheck type
@@ -340,6 +350,13 @@ public:
llvm_unreachable("Unsupported flag");
}
+ /// Returns the name for the immcheck type
+ StringRef getImmCheckForEnumValue(unsigned Id) {
+ if ((size_t)Id < ImmCheckTypeNames.size())
+ return ImmCheckTypeNames[Id];
+ llvm_unreachable("Unsupported imm check");
+ }
+
// Returns the SVETypeFlags for a given value and mask.
uint64_t encodeFlag(uint64_t V, StringRef MaskName) const {
auto It = FlagTypes.find(MaskName);
@@ -389,6 +406,9 @@ public:
/// Emit all the __builtin prototypes and code needed by Sema.
void createBuiltins(raw_ostream &o);
+ /// Emit all the __builtin prototypes in JSON format.
+ void createBuiltinsJSON(raw_ostream &o);
+
/// Emit all the information needed to map builtin -> LLVM IR intrinsic.
void createCodeGenMap(raw_ostream &o);
@@ -1552,6 +1572,82 @@ void SVEEmitter::createBuiltins(raw_ostream &OS) {
OS << "#endif // GET_SVE_BUILTIN_INFOS\n\n";
}
+void SVEEmitter::createBuiltinsJSON(raw_ostream &OS) {
+ SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
+ std::vector<const Record *> RV = Records.getAllDerivedDefinitions("Inst");
+ for (auto *R : RV)
+ createIntrinsic(R, Defs);
+
+ OS << "[\n";
+ bool FirstDef = true;
+
+ for (auto &Def : Defs) {
+ std::vector<std::string> Flags;
+
+ if (Def->isFlagSet(getEnumValueForFlag("IsStreaming")))
+ Flags.push_back("streaming-only");
+ else if (Def->isFlagSet(getEnumValueForFlag("IsStreamingCompatible")))
+ Flags.push_back("streaming-compatible");
+ else if (Def->isFlagSet(getEnumValueForFlag("VerifyRuntimeMode")))
+ Flags.push_back("feature-dependent");
+
+ if (Def->isFlagSet(getEnumValueForFlag("IsInZA")) ||
+ Def->isFlagSet(getEnumValueForFlag("IsOutZA")) ||
+ Def->isFlagSet(getEnumValueForFlag("IsInOutZA")))
+ Flags.push_back("requires-za");
+
+ if (Def->isFlagSet(getEnumValueForFlag("IsInZT0")) ||
+ Def->isFlagSet(getEnumValueForFlag("IsOutZT0")) ||
+ Def->isFlagSet(getEnumValueForFlag("IsInOutZT0")))
+ Flags.push_back("requires-zt");
+
+ if (!FirstDef)
+ OS << ",\n";
+
+ OS << "{ ";
+ OS << "\"guard\": \"" << Def->getSVEGuard() << "\",";
+ OS << "\"streaming_guard\": \"" << Def->getSMEGuard() << "\",";
+ OS << "\"flags\": \"";
+
+ for (size_t I = 0; I < Flags.size(); ++I) {
+ if (I != 0)
+ OS << ',';
+ OS << Flags[I];
+ }
+
+ OS << "\",\"builtin\": \"";
+
+ std::string BuiltinName = Def->getMangledName(Def->getClassKind());
+
+ OS << Def->getReturnType().str() << " " << BuiltinName << "(";
+ for (unsigned I = 0; I < Def->getTypes().size() - 1; ++I) {
+ if (I != 0)
+ OS << ", ";
+
+ SVEType ParamType = Def->getParamType(I);
+
+ // These are ImmCheck'd but their type names are sufficiently clear.
+ if (ParamType.isPredicatePattern() || ParamType.isPrefetchOp()) {
+ OS << ParamType.str();
+ continue;
+ }
+
+ // Pass ImmCheck information by pretending it's a type.
+ auto Iter = llvm::find_if(Def->getImmChecks(), [I](const auto &Chk) {
+ return (unsigned)Chk.getImmArgIdx() == I;
+ });
+ if (Iter != Def->getImmChecks().end())
+ OS << getImmCheckForEnumValue(Iter->getKind());
+ else
+ OS << ParamType.str();
+ }
+ OS << ");\" }";
+ FirstDef = false;
+ }
+
+ OS << "\n]\n";
+}
+
void SVEEmitter::createCodeGenMap(raw_ostream &OS) {
std::vector<const Record *> RV = Records.getAllDerivedDefinitions("Inst");
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
@@ -1937,6 +2033,10 @@ void EmitSveBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createBuiltins(OS);
}
+void EmitSveBuiltinsJSON(const RecordKeeper &Records, raw_ostream &OS) {
+ SVEEmitter(Records).createBuiltinsJSON(OS);
+}
+
void EmitSveBuiltinCG(const RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createCodeGenMap(OS);
}
@@ -1965,6 +2065,10 @@ void EmitSmeBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createSMEBuiltins(OS);
}
+void EmitSmeBuiltinsJSON(const RecordKeeper &Records, raw_ostream &OS) {
+ SVEEmitter(Records).createBuiltinsJSON(OS);
+}
+
void EmitSmeBuiltinCG(const RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createSMECodeGenMap(OS);
}