llvm.org GIT mirror llvm / bb5f622
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 Saleem Abdulrasool 5 years ago
6 changed file(s) with 69 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
7070
7171 /// Map a GCC builtin name to an intrinsic ID.
7272 ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
73
74 /// Map a MS builtin name to an intrinsic ID.
75 ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
7376
7477 /// IITDescriptor - This is a type descriptor which explains the type
7578 /// requirements of an intrinsic. This is returned by
223223 /// support.
224224 class GCCBuiltin {
225225 string GCCBuiltinName = name;
226 }
227
228 class MSBuiltin {
229 string MSBuiltinName = name;
226230 }
227231
228232
734734 #include "llvm/IR/Intrinsics.gen"
735735 #undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
736736
737 // This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method.
738 #define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
739 #include "llvm/IR/Intrinsics.gen"
740 #undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
741
737742 /// hasAddressTaken - returns true if there are any uses of this function
738743 /// other than direct calls or invokes to it.
739744 bool Function::hasAddressTaken(const User* *PutOffender) const {
2727 std::string Name; // The name of the LLVM function "llvm.bswap.i32"
2828 std::string EnumName; // The name of the enum "bswap_i32"
2929 std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
30 std::string MSBuiltinName; // Name of the corresponding MS builtin, or "".
3031 std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics.
3132
3233 /// IntrinsicSignature - This structure holds the return values and
458458
459459 if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
460460 GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
461 if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
462 MSBuiltinName = R->getValueAsString("MSBuiltinName");
461463
462464 TargetPrefix = R->getValueAsString("TargetPrefix");
463465 Name = R->getValueAsString("LLVMName");
5353 raw_ostream &OS);
5454 void EmitIntrinsicToGCCBuiltinMap(const std::vector &Ints,
5555 raw_ostream &OS);
56 void EmitIntrinsicToMSBuiltinMap(const std::vector &Ints,
57 raw_ostream &OS);
5658 void EmitSuffix(raw_ostream &OS);
5759 };
5860 } // End anonymous namespace
9496
9597 // Emit code to translate GCC builtins into LLVM intrinsics.
9698 EmitIntrinsicToGCCBuiltinMap(Ints, OS);
99
100 // Emit code to translate MS builtins into LLVM intrinsics.
101 EmitIntrinsicToMSBuiltinMap(Ints, OS);
97102
98103 EmitSuffix(OS);
99104 }
789794 OS << "#endif\n\n";
790795 }
791796
797 void IntrinsicEmitter::
798 EmitIntrinsicToMSBuiltinMap(const std::vector &Ints,
799 raw_ostream &OS) {
800 std::map> TargetBuiltins;
801
802 for (const auto &Intrinsic : Ints) {
803 if (Intrinsic.MSBuiltinName.empty())
804 continue;
805
806 auto &Builtins = TargetBuiltins[Intrinsic.TargetPrefix];
807 if (!Builtins.insert(std::make_pair(Intrinsic.MSBuiltinName,
808 Intrinsic.EnumName)).second)
809 PrintFatalError("Intrinsic '" + Intrinsic.TheDef->getName() + "': "
810 "duplicate MS builtin name!");
811 }
812
813 OS << "// Get the LLVM intrinsic that corresponds to a MS builtin.\n"
814 "// This is used by the C front-end. The MS builtin name is passed\n"
815 "// in as a BuiltinName, and a target prefix (e.g. 'arm') is passed\n"
816 "// in as a TargetPrefix. The result is assigned to 'IntrinsicID'.\n"
817 "#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN\n";
818
819 OS << (TargetOnly ? "static " + TargetPrefix : "") << "Intrinsic::ID "
820 << (TargetOnly ? "" : "Intrinsic::")
821 << "getIntrinsicForMSBuiltin(const char *TP, const char *BN) {\n";
822 OS << " StringRef BuiltinName(BN);\n"
823 " StringRef TargetPrefix(TP);\n"
824 "\n";
825
826 for (const auto &Builtins : TargetBuiltins) {
827 OS << " ";
828 if (Builtins.first.empty())
829 OS << "/* Target Independent Builtins */ ";
830 else
831 OS << "if (TargetPrefix == \"" << Builtins.first << "\") ";
832 OS << "{\n";
833 EmitTargetBuiltins(Builtins.second, TargetPrefix, OS);
834 OS << "}";
835 }
836
837 OS << " return ";
838 if (!TargetPrefix.empty())
839 OS << "(" << TargetPrefix << "Intrinsic::ID)";
840 OS << "Intrinsic::not_intrinsic;\n";
841 OS << "}\n";
842
843 OS << "#endif\n\n";
844 }
845
792846 void llvm::EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly) {
793847 IntrinsicEmitter(RK, TargetOnly).run(OS);
794848 }