aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-07-04 18:42:25 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-07-04 18:42:25 +0000
commit4e63fc498c003b74e03c67e907588cd42389b594 (patch)
treeaf7883c2b753d113ea9b3b11c55319465a6657f4 /llvm/utils
parentdddd1fd9f44ee04b9fb1081a5e03075fde1398a3 (diff)
downloadllvm-4e63fc498c003b74e03c67e907588cd42389b594.zip
llvm-4e63fc498c003b74e03c67e907588cd42389b594.tar.gz
llvm-4e63fc498c003b74e03c67e907588cd42389b594.tar.bz2
TableGen: introduce support for MSBuiltin
Add MSBuiltin which is similar in vein to GCCBuiltin. This allows for adding intrinsics for Microsoft compatibility to individual instructions. This is needed to permit the creation of ARM specific MSVC extensions. This is not currently in use, and requires an associated change in clang to enable use of the intrinsics defined by this new class. This merely sets the LLVM portion of the infrastructure in place to permit the use of this functionality. A separate set of changes will enable the new intrinsics. llvm-svn: 212350
Diffstat (limited to 'llvm/utils')
-rw-r--r--llvm/utils/TableGen/CodeGenIntrinsics.h1
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.cpp2
-rw-r--r--llvm/utils/TableGen/IntrinsicEmitter.cpp54
3 files changed, 57 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h
index 06daa97..a9ece01 100644
--- a/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -28,6 +28,7 @@ namespace llvm {
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
std::string EnumName; // The name of the enum "bswap_i32"
std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
+ std::string MSBuiltinName; // Name of the corresponding MS builtin, or "".
std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics.
/// IntrinsicSignature - This structure holds the return values and
diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp
index de00dc6..d1b5711 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -459,6 +459,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+ if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
+ MSBuiltinName = R->getValueAsString("MSBuiltinName");
TargetPrefix = R->getValueAsString("TargetPrefix");
Name = R->getValueAsString("LLVMName");
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 5dba951..430ef32 100644
--- a/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -54,6 +54,8 @@ public:
raw_ostream &OS);
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS);
+ void EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
+ raw_ostream &OS);
void EmitSuffix(raw_ostream &OS);
};
} // End anonymous namespace
@@ -96,6 +98,9 @@ void IntrinsicEmitter::run(raw_ostream &OS) {
// Emit code to translate GCC builtins into LLVM intrinsics.
EmitIntrinsicToGCCBuiltinMap(Ints, OS);
+ // Emit code to translate MS builtins into LLVM intrinsics.
+ EmitIntrinsicToMSBuiltinMap(Ints, OS);
+
EmitSuffix(OS);
}
@@ -790,6 +795,55 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
OS << "#endif\n\n";
}
+void IntrinsicEmitter::
+EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
+ raw_ostream &OS) {
+ std::map<std::string, std::map<std::string, std::string>> TargetBuiltins;
+
+ for (const auto &Intrinsic : Ints) {
+ if (Intrinsic.MSBuiltinName.empty())
+ continue;
+
+ auto &Builtins = TargetBuiltins[Intrinsic.TargetPrefix];
+ if (!Builtins.insert(std::make_pair(Intrinsic.MSBuiltinName,
+ Intrinsic.EnumName)).second)
+ PrintFatalError("Intrinsic '" + Intrinsic.TheDef->getName() + "': "
+ "duplicate MS builtin name!");
+ }
+
+ OS << "// Get the LLVM intrinsic that corresponds to a MS builtin.\n"
+ "// This is used by the C front-end. The MS builtin name is passed\n"
+ "// in as a BuiltinName, and a target prefix (e.g. 'arm') is passed\n"
+ "// in as a TargetPrefix. The result is assigned to 'IntrinsicID'.\n"
+ "#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN\n";
+
+ OS << (TargetOnly ? "static " + TargetPrefix : "") << "Intrinsic::ID "
+ << (TargetOnly ? "" : "Intrinsic::")
+ << "getIntrinsicForMSBuiltin(const char *TP, const char *BN) {\n";
+ OS << " StringRef BuiltinName(BN);\n"
+ " StringRef TargetPrefix(TP);\n"
+ "\n";
+
+ for (const auto &Builtins : TargetBuiltins) {
+ OS << " ";
+ if (Builtins.first.empty())
+ OS << "/* Target Independent Builtins */ ";
+ else
+ OS << "if (TargetPrefix == \"" << Builtins.first << "\") ";
+ OS << "{\n";
+ EmitTargetBuiltins(Builtins.second, TargetPrefix, OS);
+ OS << "}";
+ }
+
+ OS << " return ";
+ if (!TargetPrefix.empty())
+ OS << "(" << TargetPrefix << "Intrinsic::ID)";
+ OS << "Intrinsic::not_intrinsic;\n";
+ OS << "}\n";
+
+ OS << "#endif\n\n";
+}
+
void llvm::EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly) {
IntrinsicEmitter(RK, TargetOnly).run(OS);
}