mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1c9687eed2
commit
bb5f6229f4
@ -71,6 +71,9 @@ namespace Intrinsic {
|
|||||||
|
|
||||||
/// Map a GCC builtin name to an intrinsic ID.
|
/// Map a GCC builtin name to an intrinsic ID.
|
||||||
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
|
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
|
||||||
|
|
||||||
|
/// Map a MS builtin name to an intrinsic ID.
|
||||||
|
ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
|
||||||
|
|
||||||
/// IITDescriptor - This is a type descriptor which explains the type
|
/// IITDescriptor - This is a type descriptor which explains the type
|
||||||
/// requirements of an intrinsic. This is returned by
|
/// requirements of an intrinsic. This is returned by
|
||||||
|
@ -226,6 +226,10 @@ class GCCBuiltin<string name> {
|
|||||||
string GCCBuiltinName = name;
|
string GCCBuiltinName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MSBuiltin<string name> {
|
||||||
|
string MSBuiltinName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===--------------- Variable Argument Handling Intrinsics ----------------===//
|
//===--------------- Variable Argument Handling Intrinsics ----------------===//
|
||||||
//
|
//
|
||||||
|
@ -735,6 +735,11 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
|
|||||||
#include "llvm/IR/Intrinsics.gen"
|
#include "llvm/IR/Intrinsics.gen"
|
||||||
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
|
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
|
||||||
|
|
||||||
|
// This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method.
|
||||||
|
#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
|
||||||
|
#include "llvm/IR/Intrinsics.gen"
|
||||||
|
#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
|
||||||
|
|
||||||
/// hasAddressTaken - returns true if there are any uses of this function
|
/// hasAddressTaken - returns true if there are any uses of this function
|
||||||
/// other than direct calls or invokes to it.
|
/// other than direct calls or invokes to it.
|
||||||
bool Function::hasAddressTaken(const User* *PutOffender) const {
|
bool Function::hasAddressTaken(const User* *PutOffender) const {
|
||||||
|
@ -28,6 +28,7 @@ namespace llvm {
|
|||||||
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
|
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
|
||||||
std::string EnumName; // The name of the enum "bswap_i32"
|
std::string EnumName; // The name of the enum "bswap_i32"
|
||||||
std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
|
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.
|
std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics.
|
||||||
|
|
||||||
/// IntrinsicSignature - This structure holds the return values and
|
/// IntrinsicSignature - This structure holds the return values and
|
||||||
|
@ -459,6 +459,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
|
|||||||
|
|
||||||
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
|
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
|
||||||
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
|
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
|
||||||
|
if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
|
||||||
|
MSBuiltinName = R->getValueAsString("MSBuiltinName");
|
||||||
|
|
||||||
TargetPrefix = R->getValueAsString("TargetPrefix");
|
TargetPrefix = R->getValueAsString("TargetPrefix");
|
||||||
Name = R->getValueAsString("LLVMName");
|
Name = R->getValueAsString("LLVMName");
|
||||||
|
@ -54,6 +54,8 @@ public:
|
|||||||
raw_ostream &OS);
|
raw_ostream &OS);
|
||||||
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
|
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
|
||||||
raw_ostream &OS);
|
raw_ostream &OS);
|
||||||
|
void EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
|
||||||
|
raw_ostream &OS);
|
||||||
void EmitSuffix(raw_ostream &OS);
|
void EmitSuffix(raw_ostream &OS);
|
||||||
};
|
};
|
||||||
} // End anonymous namespace
|
} // End anonymous namespace
|
||||||
@ -96,6 +98,9 @@ void IntrinsicEmitter::run(raw_ostream &OS) {
|
|||||||
// Emit code to translate GCC builtins into LLVM intrinsics.
|
// Emit code to translate GCC builtins into LLVM intrinsics.
|
||||||
EmitIntrinsicToGCCBuiltinMap(Ints, OS);
|
EmitIntrinsicToGCCBuiltinMap(Ints, OS);
|
||||||
|
|
||||||
|
// Emit code to translate MS builtins into LLVM intrinsics.
|
||||||
|
EmitIntrinsicToMSBuiltinMap(Ints, OS);
|
||||||
|
|
||||||
EmitSuffix(OS);
|
EmitSuffix(OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +795,55 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
|
|||||||
OS << "#endif\n\n";
|
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) {
|
void llvm::EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly) {
|
||||||
IntrinsicEmitter(RK, TargetOnly).run(OS);
|
IntrinsicEmitter(RK, TargetOnly).run(OS);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user