diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 9092c3e0fa01f3139b016d05d267a89e3b07747a (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/Basic/Targets.cpp | |
parent | 4981926bf654fe5a2c3893f24ca44106b217e71e (diff) | |
download | FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz |
Update clang to r84119.
Diffstat (limited to 'lib/Basic/Targets.cpp')
-rw-r--r-- | lib/Basic/Targets.cpp | 1092 |
1 files changed, 791 insertions, 301 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 3f7d9a3..1d4d123 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -16,22 +16,25 @@ #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangOptions.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCSectionMachO.h" using namespace clang; //===----------------------------------------------------------------------===// // Common code shared among targets. //===----------------------------------------------------------------------===// -static void Define(std::vector<char> &Buf, const char *Macro, - const char *Val = "1") { +static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro, + const llvm::StringRef &Val = "1") { const char *Def = "#define "; Buf.insert(Buf.end(), Def, Def+strlen(Def)); - Buf.insert(Buf.end(), Macro, Macro+strlen(Macro)); + Buf.insert(Buf.end(), Macro.begin(), Macro.end()); Buf.push_back(' '); - Buf.insert(Buf.end(), Val, Val+strlen(Val)); + Buf.insert(Buf.end(), Val.begin(), Val.end()); Buf.push_back('\n'); } @@ -51,91 +54,34 @@ static void DefineStd(std::vector<char> &Buf, const char *MacroName, llvm::SmallString<20> TmpStr; TmpStr = "__"; TmpStr += MacroName; - Define(Buf, TmpStr.c_str()); + Define(Buf, TmpStr.str()); // Define __unix__. TmpStr += "__"; - Define(Buf, TmpStr.c_str()); + Define(Buf, TmpStr.str()); } //===----------------------------------------------------------------------===// // Defines specific to certain operating systems. //===----------------------------------------------------------------------===// + namespace { template<typename TgtInfo> class OSTargetInfo : public TgtInfo { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defines) const=0; public: OSTargetInfo(const std::string& triple) : TgtInfo(triple) {} virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { TgtInfo::getTargetDefines(Opts, Defines); - getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines); + getOSDefines(Opts, TgtInfo::getTriple(), Defines); } }; -} - -namespace { -/// getDarwinNumber - Parse the 'darwin number' out of the specific targe -/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is -/// not defined, return 0's. Return true if we have -darwin in the string or -/// false otherwise. -static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) { - Maj = Min = Revision = 0; - const char *Darwin = strstr(Triple, "-darwin"); - if (Darwin == 0) return false; - - Darwin += strlen("-darwin"); - if (Darwin[0] < '0' || Darwin[0] > '9') - return true; - - Maj = Darwin[0]-'0'; - ++Darwin; - - // Handle "darwin11". - if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { - Maj = Maj*10 + (Darwin[0] - '0'); - ++Darwin; - } - - // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" - if (Darwin[0] != '.') - return true; - - ++Darwin; - if (Darwin[0] < '0' || Darwin[0] > '9') - return true; - - Min = Darwin[0]-'0'; - ++Darwin; - - // Handle 10.4.11 -> darwin8.11 - if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { - Min = Min*10 + (Darwin[0] - '0'); - ++Darwin; - } - - // Handle revision darwin8.9.1 - if (Darwin[0] != '.') - return true; - - ++Darwin; - if (Darwin[0] < '0' || Darwin[0] > '9') - return true; - - Revision = Darwin[0]-'0'; - ++Darwin; - - if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { - Revision = Revision*10 + (Darwin[0] - '0'); - ++Darwin; - } +} // end anonymous namespace - return true; -} static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) { Define(Defs, "__APPLE_CC__", "5621"); @@ -156,81 +102,94 @@ static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) { Define(Defs, "__STATIC__"); else Define(Defs, "__DYNAMIC__"); + + if (Opts.POSIXThreads) + Define(Defs, "_REENTRANT", "1"); } -static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) { +static void getDarwinOSXDefines(std::vector<char> &Defs, + const llvm::Triple &Triple) { + if (Triple.getOS() != llvm::Triple::Darwin) + return; + // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. unsigned Maj, Min, Rev; - if (getDarwinNumber(Triple, Maj, Min, Rev)) { - char MacOSXStr[] = "1000"; - if (Maj >= 4 && Maj <= 13) { // 10.0-10.9 - // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc. - MacOSXStr[2] = '0' + Maj-4; - } + Triple.getDarwinNumber(Maj, Min, Rev); - // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" - // Cap 10.4.11 -> darwin8.11 -> "1049" - MacOSXStr[3] = std::min(Min, 9U)+'0'; - Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr); + char MacOSXStr[] = "1000"; + if (Maj >= 4 && Maj <= 13) { // 10.0-10.9 + // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc. + MacOSXStr[2] = '0' + Maj-4; } + + // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" + // Cap 10.4.11 -> darwin8.11 -> "1049" + MacOSXStr[3] = std::min(Min, 9U)+'0'; + Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr); } static void getDarwinIPhoneOSDefines(std::vector<char> &Defs, - const char *Triple) { + const llvm::Triple &Triple) { + if (Triple.getOS() != llvm::Triple::Darwin) + return; + // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. unsigned Maj, Min, Rev; - if (getDarwinNumber(Triple, Maj, Min, Rev)) { - // When targetting iPhone OS, interpret the minor version and - // revision as the iPhone OS version - char iPhoneOSStr[] = "10000"; - if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0 - // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc. - iPhoneOSStr[0] = '0' + Min; - } + Triple.getDarwinNumber(Maj, Min, Rev); - // Handle minor version: 2.2 -> darwin9.2.2 -> 20200 - iPhoneOSStr[2] = std::min(Rev, 9U)+'0'; - Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", - iPhoneOSStr); + // When targetting iPhone OS, interpret the minor version and + // revision as the iPhone OS version + char iPhoneOSStr[] = "10000"; + if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0 + // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc. + iPhoneOSStr[0] = '0' + Min; } + + // Handle minor version: 2.2 -> darwin9.2.2 -> 20200 + iPhoneOSStr[2] = std::min(Rev, 9U)+'0'; + Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", + iPhoneOSStr); } /// GetDarwinLanguageOptions - Set the default language options for darwin. static void GetDarwinLanguageOptions(LangOptions &Opts, - const char *Triple) { + const llvm::Triple &Triple) { Opts.NeXTRuntime = true; - unsigned Maj, Min, Rev; - if (!getDarwinNumber(Triple, Maj, Min, Rev)) + if (Triple.getOS() != llvm::Triple::Darwin) return; + unsigned MajorVersion = Triple.getDarwinMajorNumber(); + // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond. - if (Maj > 9) { + if (MajorVersion > 9) { Opts.Blocks = 1; Opts.setStackProtectorMode(LangOptions::SSPOn); } // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and // beyond. - if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6)) + if (MajorVersion >= 9 && Opts.ObjC1 && + Triple.getArch() == llvm::Triple::x86_64) Opts.ObjCNonFragileABI = 1; } +namespace { template<typename Target> class DarwinTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defines) const { getDarwinDefines(Defines, Opts); getDarwinOSXDefines(Defines, Triple); } - + /// getDefaultLangOptions - Allow the target to specify default settings for /// various language options. These may be overridden by command line /// options. virtual void getDefaultLangOptions(LangOptions &Opts) { TargetInfo::getDefaultLangOptions(Opts); - GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple()); + GetDarwinLanguageOptions(Opts, TargetInfo::getTriple()); } public: DarwinTargetInfo(const std::string& triple) : @@ -238,28 +197,25 @@ public: this->TLSSupported = false; } - virtual const char *getCFStringSymbolPrefix() const { - return "\01L_unnamed_cfstring_"; - } - - virtual const char *getStringSymbolPrefix(bool IsConstant) const { - return IsConstant ? "\01LC" : "\01lC"; - } - - virtual const char *getUnicodeStringSymbolPrefix() const { - return "__utf16_string_"; - } - virtual const char *getUnicodeStringSection() const { return "__TEXT,__ustring"; } + + virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const { + // Let MCSectionMachO validate this. + llvm::StringRef Segment, Section; + unsigned TAA, StubSize; + return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, + TAA, StubSize); + } }; + // DragonFlyBSD Target template<typename Target> class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defs) const { // DragonFly defines; list based off of gcc output Define(Defs, "__DragonFly__"); @@ -270,7 +226,7 @@ protected: DefineStd(Defs, "unix", Opts); } public: - DragonFlyBSDTargetInfo(const std::string &triple) + DragonFlyBSDTargetInfo(const std::string &triple) : OSTargetInfo<Target>(triple) {} }; @@ -278,11 +234,13 @@ public: template<typename Target> class FreeBSDTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defs) const { // FreeBSD defines; list based off of gcc output - const char *FreeBSD = strstr(Triple, "-freebsd"); + // FIXME: Move version number handling to llvm::Triple. + const char *FreeBSD = strstr(Triple.getTriple().c_str(), + "-freebsd"); FreeBSD += strlen("-freebsd"); char release[] = "X"; release[0] = FreeBSD[0]; @@ -296,43 +254,69 @@ protected: Define(Defs, "__ELF__", "1"); } public: - FreeBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + FreeBSDTargetInfo(const std::string &triple) + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + } }; // Linux target template<typename Target> class LinuxTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defs) const { // Linux defines; list based off of gcc output DefineStd(Defs, "unix", Opts); DefineStd(Defs, "linux", Opts); Define(Defs, "__gnu_linux__"); Define(Defs, "__ELF__", "1"); + if (Opts.POSIXThreads) + Define(Defs, "_REENTRANT", "1"); } public: - LinuxTargetInfo(const std::string& triple) + LinuxTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; } }; +// NetBSD Target +template<typename Target> +class NetBSDTargetInfo : public OSTargetInfo<Target> { +protected: + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + std::vector<char> &Defs) const { + // NetBSD defines; list based off of gcc output + Define(Defs, "__NetBSD__", "1"); + Define(Defs, "__unix__", "1"); + Define(Defs, "__ELF__", "1"); + if (Opts.POSIXThreads) + Define(Defs, "_POSIX_THREADS", "1"); + } +public: + NetBSDTargetInfo(const std::string &triple) + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + } +}; + // OpenBSD Target template<typename Target> class OpenBSDTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defs) const { // OpenBSD defines; list based off of gcc output Define(Defs, "__OpenBSD__", "1"); DefineStd(Defs, "unix", Opts); Define(Defs, "__ELF__", "1"); + if (Opts.POSIXThreads) + Define(Defs, "_POSIX_THREADS", "1"); } public: - OpenBSDTargetInfo(const std::string &triple) + OpenBSDTargetInfo(const std::string &triple) : OSTargetInfo<Target>(triple) {} }; @@ -340,7 +324,7 @@ public: template<typename Target> class SolarisTargetInfo : public OSTargetInfo<Target> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defs) const { DefineStd(Defs, "sun", Opts); DefineStd(Defs, "unix", Opts); @@ -349,20 +333,14 @@ protected: Define(Defs, "__SVR4"); } public: - SolarisTargetInfo(const std::string& triple) + SolarisTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; this->WCharType = this->SignedLong; // FIXME: WIntType should be SignedLong } }; -} // end anonymous namespace. - -/// GetWindowsLanguageOptions - Set the default language options for Windows. -static void GetWindowsLanguageOptions(LangOptions &Opts, - const char *Triple) { - Opts.Microsoft = true; -} +} // end anonymous namespace. //===----------------------------------------------------------------------===// // Specific target implementations. @@ -398,9 +376,6 @@ public: " void* reg_save_area;" "} __builtin_va_list[1];";*/ } - virtual const char *getTargetPrefix() const { - return "ppc"; - } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -464,21 +439,21 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, const char * const PPCTargetInfo::GCCRegNames[] = { - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "mq", "lr", "ctr", "ap", - "0", "1", "2", "3", "4", "5", "6", "7", + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", "xer", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" @@ -493,38 +468,71 @@ void PPCTargetInfo::getGCCRegNames(const char * const *&Names, const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { // While some of these aliases do map to different registers // they still share the same register name. - { { "cc", "cr0", "fr0", "r0", "v0"}, "0" }, - { { "cr1", "fr1", "r1", "sp", "v1"}, "1" }, - { { "cr2", "fr2", "r2", "toc", "v2"}, "2" }, - { { "cr3", "fr3", "r3", "v3"}, "3" }, - { { "cr4", "fr4", "r4", "v4"}, "4" }, - { { "cr5", "fr5", "r5", "v5"}, "5" }, - { { "cr6", "fr6", "r6", "v6"}, "6" }, - { { "cr7", "fr7", "r7", "v7"}, "7" }, - { { "fr8", "r8", "v8"}, "8" }, - { { "fr9", "r9", "v9"}, "9" }, - { { "fr10", "r10", "v10"}, "10" }, - { { "fr11", "r11", "v11"}, "11" }, - { { "fr12", "r12", "v12"}, "12" }, - { { "fr13", "r13", "v13"}, "13" }, - { { "fr14", "r14", "v14"}, "14" }, - { { "fr15", "r15", "v15"}, "15" }, - { { "fr16", "r16", "v16"}, "16" }, - { { "fr17", "r17", "v17"}, "17" }, - { { "fr18", "r18", "v18"}, "18" }, - { { "fr19", "r19", "v19"}, "19" }, - { { "fr20", "r20", "v20"}, "20" }, - { { "fr21", "r21", "v21"}, "21" }, - { { "fr22", "r22", "v22"}, "22" }, - { { "fr23", "r23", "v23"}, "23" }, - { { "fr24", "r24", "v24"}, "24" }, - { { "fr25", "r25", "v25"}, "25" }, - { { "fr26", "r26", "v26"}, "26" }, - { { "fr27", "r27", "v27"}, "27" }, - { { "fr28", "r28", "v28"}, "28" }, - { { "fr29", "r29", "v29"}, "29" }, - { { "fr30", "r30", "v30"}, "30" }, - { { "fr31", "r31", "v31"}, "31" }, + { { "0" }, "r0" }, + { { "1"}, "r1" }, + { { "2" }, "r2" }, + { { "3" }, "r3" }, + { { "4" }, "r4" }, + { { "5" }, "r5" }, + { { "6" }, "r6" }, + { { "7" }, "r7" }, + { { "8" }, "r8" }, + { { "9" }, "r9" }, + { { "10" }, "r10" }, + { { "11" }, "r11" }, + { { "12" }, "r12" }, + { { "13" }, "r13" }, + { { "14" }, "r14" }, + { { "15" }, "r15" }, + { { "16" }, "r16" }, + { { "17" }, "r17" }, + { { "18" }, "r18" }, + { { "19" }, "r19" }, + { { "20" }, "r20" }, + { { "21" }, "r21" }, + { { "22" }, "r22" }, + { { "23" }, "r23" }, + { { "24" }, "r24" }, + { { "25" }, "r25" }, + { { "26" }, "r26" }, + { { "27" }, "r27" }, + { { "28" }, "r28" }, + { { "29" }, "r29" }, + { { "30" }, "r30" }, + { { "31" }, "r31" }, + { { "fr0" }, "f0" }, + { { "fr1" }, "f1" }, + { { "fr2" }, "f2" }, + { { "fr3" }, "f3" }, + { { "fr4" }, "f4" }, + { { "fr5" }, "f5" }, + { { "fr6" }, "f6" }, + { { "fr7" }, "f7" }, + { { "fr8" }, "f8" }, + { { "fr9" }, "f9" }, + { { "fr10" }, "f10" }, + { { "fr11" }, "f11" }, + { { "fr12" }, "f12" }, + { { "fr13" }, "f13" }, + { { "fr14" }, "f14" }, + { { "fr15" }, "f15" }, + { { "fr16" }, "f16" }, + { { "fr17" }, "f17" }, + { { "fr18" }, "f18" }, + { { "fr19" }, "f19" }, + { { "fr20" }, "f20" }, + { { "fr21" }, "f21" }, + { { "fr22" }, "f22" }, + { { "fr23" }, "f23" }, + { { "fr24" }, "f24" }, + { { "fr25" }, "f25" }, + { { "fr26" }, "f26" }, + { { "fr27" }, "f27" }, + { { "fr28" }, "f28" }, + { { "fr29" }, "f29" }, + { { "fr30" }, "f30" }, + { { "fr31" }, "f31" }, + { { "cc" }, "cr0" }, }; void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -603,9 +611,6 @@ public: Records = BuiltinInfo; NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; } - virtual const char *getTargetPrefix() const { - return "x86"; - } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { Names = GCCRegNames; @@ -627,12 +632,12 @@ public: virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, const std::string &Name, bool Enabled) const; - virtual void getDefaultFeatures(const std::string &CPU, + virtual void getDefaultFeatures(const std::string &CPU, llvm::StringMap<bool> &Features) const; virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features); }; -void X86TargetInfo::getDefaultFeatures(const std::string &CPU, +void X86TargetInfo::getDefaultFeatures(const std::string &CPU, llvm::StringMap<bool> &Features) const { // FIXME: This should not be here. Features["3dnow"] = false; @@ -676,7 +681,7 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU, setFeatureEnabled(Features, "sse4", true); else if (CPU == "k6" || CPU == "winchip-c6") setFeatureEnabled(Features, "mmx", true); - else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || + else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") { setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "3dnow", true); @@ -685,14 +690,14 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU, setFeatureEnabled(Features, "3dnowa", true); } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" || CPU == "athlon-fx") { - setFeatureEnabled(Features, "sse2", true); + setFeatureEnabled(Features, "sse2", true); setFeatureEnabled(Features, "3dnowa", true); } else if (CPU == "c3-2") setFeatureEnabled(Features, "sse", true); } bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + const std::string &Name, bool Enabled) const { // FIXME: This *really* should not be here. if (!Features.count(Name) && Name != "sse4") @@ -706,13 +711,13 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "sse2") Features["mmx"] = Features["sse"] = Features["sse2"] = true; else if (Name == "sse3") - Features["mmx"] = Features["sse"] = Features["sse2"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = true; else if (Name == "ssse3") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = true; else if (Name == "sse4") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; else if (Name == "3dnow") Features["3dnowa"] = true; @@ -720,16 +725,16 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["3dnow"] = Features["3dnowa"] = true; } else { if (Name == "mmx") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "sse") - Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "sse2") - Features["sse2"] = Features["sse3"] = Features["ssse3"] = + Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "sse3") - Features["sse3"] = Features["ssse3"] = Features["sse41"] = + Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "ssse3") Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; @@ -885,6 +890,24 @@ public: virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; } + + int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 0; + if (RegNo == 1) return 2; + return -1; + } +}; +} // end anonymous namespace + +namespace { +class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { +public: + OpenBSDI386TargetInfo(const std::string& triple) : + OpenBSDTargetInfo<X86_32TargetInfo>(triple) { + SizeType = UnsignedLong; + IntPtrType = SignedLong; + PtrDiffType = SignedLong; + } }; } // end anonymous namespace @@ -927,12 +950,75 @@ public: DefineStd(Defines, "WIN32", Opts); DefineStd(Defines, "WINNT", Opts); Define(Defines, "_X86_"); - Define(Defines, "__MSVCRT__"); } +}; +} // end anonymous namespace +namespace { + +/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows. +static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts) { + Opts.Microsoft = true; +} + +// x86-32 Windows Visual Studio target +class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { +public: + VisualStudioWindowsX86_32TargetInfo(const std::string& triple) + : WindowsX86_32TargetInfo(triple) { + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines); + // The value of the following reflects processor type. + // 300=386, 400=486, 500=Pentium, 600=Blend (default) + // We lost the original triple, so we use the default. + Define(Defines, "_M_IX86", "600"); + } virtual void getDefaultLangOptions(LangOptions &Opts) { - X86_32TargetInfo::getDefaultLangOptions(Opts); - GetWindowsLanguageOptions(Opts, getTargetTriple()); + WindowsX86_32TargetInfo::getDefaultLangOptions(Opts); + GetWindowsVisualStudioLanguageOptions(Opts); + } +}; +} // end anonymous namespace + +namespace { +// x86-32 MinGW target +class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { +public: + MinGWX86_32TargetInfo(const std::string& triple) + : WindowsX86_32TargetInfo(triple) { + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines); + Define(Defines, "__MSVCRT__"); + Define(Defines, "__MINGW32__"); + Define(Defines, "__declspec", "__declspec"); + } +}; +} // end anonymous namespace + +namespace { +// x86-32 Cygwin target +class CygwinX86_32TargetInfo : public X86_32TargetInfo { +public: + CygwinX86_32TargetInfo(const std::string& triple) + : X86_32TargetInfo(triple) { + TLSSupported = false; + WCharType = UnsignedShort; + WCharWidth = WCharAlign = 16; + DoubleAlign = LongLongAlign = 64; + DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" + "a0:0:64-f80:32:32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + X86_32TargetInfo::getTargetDefines(Opts, Defines); + Define(Defines, "__CYGWIN__"); + Define(Defines, "__CYGWIN32__"); + DefineStd(Defines, "unix", Opts); } }; } // end anonymous namespace @@ -963,13 +1049,75 @@ public: "} __va_list_tag;" "typedef __va_list_tag __builtin_va_list[1];"; } + + int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 0; + if (RegNo == 1) return 1; + return -1; + } +}; +} // end anonymous namespace + +namespace { +// x86-64 Windows target +class WindowsX86_64TargetInfo : public X86_64TargetInfo { +public: + WindowsX86_64TargetInfo(const std::string& triple) + : X86_64TargetInfo(triple) { + TLSSupported = false; + WCharType = UnsignedShort; + WCharWidth = WCharAlign = 16; + LongWidth = LongAlign = 32; + DoubleAlign = LongLongAlign = 64; + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + X86_64TargetInfo::getTargetDefines(Opts, Defines); + Define(Defines, "_WIN64"); + DefineStd(Defines, "WIN64", Opts); + } +}; +} // end anonymous namespace + +namespace { +// x86-64 Windows Visual Studio target +class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { +public: + VisualStudioWindowsX86_64TargetInfo(const std::string& triple) + : WindowsX86_64TargetInfo(triple) { + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines); + Define(Defines, "_M_X64"); + } + virtual const char *getVAListDeclaration() const { + return "typedef char* va_list;"; + } +}; +} // end anonymous namespace + +namespace { +// x86-64 MinGW target +class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { +public: + MinGWX86_64TargetInfo(const std::string& triple) + : WindowsX86_64TargetInfo(triple) { + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines); + Define(Defines, "__MSVCRT__"); + Define(Defines, "__MINGW64__"); + Define(Defines, "__declspec"); + } }; } // end anonymous namespace namespace { class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { public: - DarwinX86_64TargetInfo(const std::string& triple) + DarwinX86_64TargetInfo(const std::string& triple) : DarwinTargetInfo<X86_64TargetInfo>(triple) { Int64Type = SignedLongLong; } @@ -977,33 +1125,107 @@ public: } // end anonymous namespace namespace { +class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { +public: + OpenBSDX86_64TargetInfo(const std::string& triple) + : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { + IntMaxType = SignedLongLong; + UIntMaxType = UnsignedLongLong; + Int64Type = SignedLongLong; + } +}; +} // end anonymous namespace + +namespace { class ARMTargetInfo : public TargetInfo { enum { Armv4t, Armv5, Armv6, + Armv7a, XScale } ArmArch; + + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + static const char * const GCCRegNames[]; + + std::string ABI; + bool IsThumb; + public: - ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { - // FIXME: Are the defaults correct for ARM? - DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; - if (triple.find("arm-") == 0 || triple.find("armv6-") == 0) + ARMTargetInfo(const std::string &TripleStr) + : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false) + { + llvm::Triple Triple(TripleStr); + + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + + // FIXME: This shouldn't be done this way, we should use features to + // indicate the arch. See lib/Driver/Tools.cpp. + llvm::StringRef Version(""), Arch = Triple.getArchName(); + if (Arch.startswith("arm")) + Version = Arch.substr(3); + else if (Arch.startswith("thumb")) + Version = Arch.substr(5); + if (Version == "v7") + ArmArch = Armv7a; + else if (Version.empty() || Version == "v6" || Version == "v6t2") ArmArch = Armv6; - else if (triple.find("armv5-") == 0) + else if (Version == "v5") ArmArch = Armv5; - else if (triple.find("armv4t-") == 0) + else if (Version == "v4t") ArmArch = Armv4t; - else if (triple.find("xscale-") == 0) + else if (Arch == "xscale" || Arch == "thumbv5e") ArmArch = XScale; - else if (triple.find("armv") == 0) { - // FIXME: fuzzy match for other random weird arm triples. This is useful - // for the static analyzer and other clients, but probably should be - // re-evaluated when codegen is brought up. + else ArmArch = Armv6; + + if (Arch.startswith("thumb")) + IsThumb = true; + + if (IsThumb) { + DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-" + "v64:64:64-v128:128:128-a0:0:32"); + } else { + DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-" + "v64:64:64-v128:128:128-a0:0:64"); } } + virtual const char *getABI() const { return ABI.c_str(); } + virtual bool setABI(const std::string &Name) { + ABI = Name; + + // The defaults (above) are for AAPCS, check if we need to change them. + // + // FIXME: We need support for -meabi... we could just mangle it into the + // name. + if (Name == "apcs-gnu") { + DoubleAlign = LongLongAlign = 32; + SizeType = UnsignedLong; + + if (IsThumb) { + DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" + "i64:32:32-f32:32:32-f64:32:32-" + "v64:64:64-v128:128:128-a0:0:32"); + } else { + DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:32:32-f32:32:32-f64:32:32-" + "v64:64:64-v128:128:128-a0:0:64"); + } + + // FIXME: Override "preferred align" for double and long long. + } else if (Name == "aapcs") { + // FIXME: Enumerated types are variable width in straight AAPCS. + } else if (Name == "aapcs-linux") { + ; + } else + return false; + + return true; + } virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defs) const { // Target identification. @@ -1014,7 +1236,13 @@ public: Define(Defs, "__LITTLE_ENDIAN__"); // Subtarget options. - if (ArmArch == Armv6) { + // + // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly + // here. + if (ArmArch == Armv7a) { + Define(Defs, "__ARM_ARCH_7A__"); + Define(Defs, "__THUMB_INTERWORK__"); + } else if (ArmArch == Armv6) { Define(Defs, "__ARM_ARCH_6K__"); Define(Defs, "__THUMB_INTERWORK__"); } else if (ArmArch == Armv5) { @@ -1029,9 +1257,22 @@ public: Define(Defs, "__XSCALE__"); Define(Defs, "__SOFTFP__"); } + Define(Defs, "__ARMEL__"); + + if (IsThumb) { + Define(Defs, "__THUMBEL__"); + Define(Defs, "__thumb__"); + if (ArmArch == Armv7a) + Define(Defs, "__thumb2__"); + } + + // Note, this is always on in gcc, even though it doesn't make sense. Define(Defs, "__APCS_32__"); + // FIXME: This should be conditional on VFP instruction support. Define(Defs, "__VFP_FP__"); + + Define(Defs, "__USING_SJLJ_EXCEPTIONS__"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -1042,21 +1283,10 @@ public: virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; } - virtual const char *getTargetPrefix() const { - return "arm"; - } virtual void getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - // FIXME: Implement. - Names = 0; - NumNames = 0; - } + unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const { - // FIXME: Implement. - Aliases = 0; - NumAliases = 0; - } + unsigned &NumAliases) const; virtual bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const { // FIXME: Check if this is complete @@ -1076,21 +1306,58 @@ public: return ""; } }; + +const char * const ARMTargetInfo::GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" +}; + +void ARMTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} + +const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { + + { { "a1" }, "r0" }, + { { "a2" }, "r1" }, + { { "a3" }, "r2" }, + { { "a4" }, "r3" }, + { { "v1" }, "r4" }, + { { "v2" }, "r5" }, + { { "v3" }, "r6" }, + { { "v4" }, "r7" }, + { { "v5" }, "r8" }, + { { "v6", "rfp" }, "r9" }, + { { "sl" }, "r10" }, + { { "fp" }, "r11" }, + { { "ip" }, "r12" }, + { { "sp" }, "r13" }, + { { "lr" }, "r14" }, + { { "pc" }, "r15" }, +}; + +void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); +} } // end anonymous namespace. namespace { -class DarwinARMTargetInfo : +class DarwinARMTargetInfo : public DarwinTargetInfo<ARMTargetInfo> { protected: - virtual void getOSDefines(const LangOptions &Opts, const char *Triple, + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, std::vector<char> &Defines) const { getDarwinDefines(Defines, Opts); getDarwinIPhoneOSDefines(Defines, Triple); } public: - DarwinARMTargetInfo(const std::string& triple) + DarwinARMTargetInfo(const std::string& triple) : DarwinTargetInfo<ARMTargetInfo>(triple) {} }; } // end anonymous namespace. @@ -1118,9 +1385,6 @@ public: virtual const char *getVAListDeclaration() const { return "typedef void* __builtin_va_list;"; } - virtual const char *getTargetPrefix() const { - return "sparc"; - } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -1236,12 +1500,25 @@ namespace { virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { Define(Defines, "__pic16"); + Define(Defines, "rom", "__attribute__((address_space(1)))"); + Define(Defines, "ram", "__attribute__((address_space(0)))"); + Define(Defines, "_section(SectName)", + "__attribute__((section(SectName)))"); + Define(Defines, "_address(Addr)", + "__attribute__((section(\"Address=\"#Addr)))"); + Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)"); + Define(Defines, "_interrupt", + "__attribute__((section(\"interrupt=0x4\"))) \ + __attribute__((used))"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const {} - virtual const char *getVAListDeclaration() const { return "";} - virtual const char *getClobbers() const {return "";} - virtual const char *getTargetPrefix() const {return "pic16";} + virtual const char *getVAListDeclaration() const { + return ""; + } + virtual const char *getClobbers() const { + return ""; + } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const {} virtual bool validateAsmConstraint(const char *&Name, @@ -1286,9 +1563,6 @@ namespace { Records = 0; NumRecords = 0; } - virtual const char *getTargetPrefix() const { - return "msp430"; - } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -1325,93 +1599,309 @@ namespace { } +namespace { + class SystemZTargetInfo : public TargetInfo { + static const char * const GCCRegNames[]; + public: + SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { + TLSSupported = false; + IntWidth = IntAlign = 32; + LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; + PointerWidth = PointerAlign = 64; + DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"; + } + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + Define(Defines, "__s390__"); + Define(Defines, "__s390x__"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + // FIXME: Implement. + Records = 0; + NumRecords = 0; + } + + virtual void getDefaultLangOptions(LangOptions &Opts) { + TargetInfo::getDefaultLangOptions(Opts); + Opts.CharIsSigned = false; + } + + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + // No aliases. + Aliases = 0; + NumAliases = 0; + } + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const { + // FIXME: implement + return true; + } + virtual const char *getClobbers() const { + // FIXME: Is this really right? + return ""; + } + virtual const char *getVAListDeclaration() const { + // FIXME: implement + return "typedef char* __builtin_va_list;"; + } + }; + + const char * const SystemZTargetInfo::GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" + }; + + void SystemZTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); + } +} + +namespace { + class BlackfinTargetInfo : public TargetInfo { + static const char * const GCCRegNames[]; + public: + BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) { + TLSSupported = false; + DoubleAlign = 32; + LongLongAlign = 32; + LongDoubleAlign = 32; + DescriptionString = "e-p:32:32-i64:32-f64:32"; + } + + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + DefineStd(Defines, "bfin", Opts); + DefineStd(Defines, "BFIN", Opts); + Define(Defines, "__ADSPBLACKFIN__"); + // FIXME: This one is really dependent on -mcpu + Define(Defines, "__ADSPLPBLACKFIN__"); + // FIXME: Add cpu-dependent defines and __SILICON_REVISION__ + } + + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + // FIXME: Implement. + Records = 0; + NumRecords = 0; + } + + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + // No aliases. + Aliases = 0; + NumAliases = 0; + } + + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) { + Info.setAllowsRegister(); + return true; + } + return false; + } + + virtual const char *getClobbers() const { + return ""; + } + + virtual const char *getVAListDeclaration() const { + return "typedef char* __builtin_va_list;"; + } + }; + + const char * const BlackfinTargetInfo::GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", + "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3", + "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3", + "a0", "a1", "cc", + "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp", + "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1" + }; + + void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); + } +} + +namespace { + + // LLVM and Clang cannot be used directly to output native binaries for + // target, but is used to compile C code to llvm bitcode with correct + // type and alignment information. + // + // TCE uses the llvm bitcode as input and uses it for generating customized + // target processor and program binary. TCE co-design environment is + // publicly available in http://tce.cs.tut.fi + + class TCETargetInfo : public TargetInfo{ + public: + TCETargetInfo(const std::string& triple) : TargetInfo(triple) { + TLSSupported = false; + IntWidth = 32; + LongWidth = LongLongWidth = 32; + IntMaxTWidth = 32; + PointerWidth = 32; + IntAlign = 32; + LongAlign = LongLongAlign = 32; + PointerAlign = 32; + SizeType = UnsignedInt; + IntMaxType = SignedLong; + UIntMaxType = UnsignedLong; + IntPtrType = SignedInt; + PtrDiffType = SignedInt; + FloatWidth = 32; + FloatAlign = 32; + DoubleWidth = 32; + DoubleAlign = 32; + LongDoubleWidth = 32; + LongDoubleAlign = 32; + FloatFormat = &llvm::APFloat::IEEEsingle; + DoubleFormat = &llvm::APFloat::IEEEsingle; + LongDoubleFormat = &llvm::APFloat::IEEEsingle; + DescriptionString = "E-p:32:32:32-a0:32:32" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" + "-f32:32:32-f64:32:64"; + } + + virtual void getTargetDefines(const LangOptions &Opts, + std::vector<char> &Defines) const { + DefineStd(Defines, "tce", Opts); + Define(Defines, "__TCE__"); + Define(Defines, "__TCE_V1__"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const {} + virtual const char *getClobbers() const { + return ""; + } + virtual const char *getVAListDeclaration() const { + return "typedef void* __builtin_va_list;"; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const {} + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const { + return true; + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const {} + }; +} + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// -static inline bool IsX86(const std::string& TT) { - return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && - TT[4] == '-' && TT[1] - '3' < 6); -} - /// CreateTargetInfo - Return the target info object for the specified target /// triple. TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { - // OS detection; this isn't really anywhere near complete. - // Additions and corrections are welcome. - bool isDarwin = T.find("-darwin") != std::string::npos; - bool isDragonFly = T.find("-dragonfly") != std::string::npos; - bool isOpenBSD = T.find("-openbsd") != std::string::npos; - bool isFreeBSD = T.find("-freebsd") != std::string::npos; - bool isSolaris = T.find("-solaris") != std::string::npos; - bool isLinux = T.find("-linux") != std::string::npos; - bool isWindows = T.find("-windows") != std::string::npos || - T.find("-win32") != std::string::npos || - T.find("-mingw") != std::string::npos; - - if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { - if (isDarwin) + llvm::Triple Triple(T); + llvm::Triple::OSType os = Triple.getOS(); + + switch (Triple.getArch()) { + default: + return NULL; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (os) { + case llvm::Triple::Darwin: + return new DarwinARMTargetInfo(T); + case llvm::Triple::FreeBSD: + return new FreeBSDTargetInfo<ARMTargetInfo>(T); + default: + return new ARMTargetInfo(T); + } + + case llvm::Triple::bfin: + return new BlackfinTargetInfo(T); + + case llvm::Triple::msp430: + return new MSP430TargetInfo(T); + + case llvm::Triple::pic16: + return new PIC16TargetInfo(T); + + case llvm::Triple::ppc: + if (os == llvm::Triple::Darwin) return new DarwinTargetInfo<PPCTargetInfo>(T); return new PPC32TargetInfo(T); - } - if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { - if (isDarwin) + case llvm::Triple::ppc64: + if (os == llvm::Triple::Darwin) return new DarwinTargetInfo<PPC64TargetInfo>(T); return new PPC64TargetInfo(T); - } - - if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) { - if (isDarwin) - return new DarwinARMTargetInfo(T); - if (isFreeBSD) - return new FreeBSDTargetInfo<ARMTargetInfo>(T); - return new ARMTargetInfo(T); - } - if (T.find("sparc-") == 0) { - if (isSolaris) + case llvm::Triple::sparc: + if (os == llvm::Triple::Solaris) return new SolarisSparcV8TargetInfo(T); return new SparcV8TargetInfo(T); - } - - if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) { - if (isDarwin) - return new DarwinX86_64TargetInfo(T); - if (isLinux) - return new LinuxTargetInfo<X86_64TargetInfo>(T); - if (isOpenBSD) - return new OpenBSDTargetInfo<X86_64TargetInfo>(T); - if (isFreeBSD) - return new FreeBSDTargetInfo<X86_64TargetInfo>(T); - if (isSolaris) - return new SolarisTargetInfo<X86_64TargetInfo>(T); - return new X86_64TargetInfo(T); - } - if (T.find("pic16-") == 0) - return new PIC16TargetInfo(T); + case llvm::Triple::systemz: + return new SystemZTargetInfo(T); - if (T.find("msp430-") == 0) - return new MSP430TargetInfo(T); + case llvm::Triple::tce: + return new TCETargetInfo(T); - if (IsX86(T)) { - if (isDarwin) + case llvm::Triple::x86: + switch (os) { + case llvm::Triple::Darwin: return new DarwinI386TargetInfo(T); - if (isLinux) + case llvm::Triple::Linux: return new LinuxTargetInfo<X86_32TargetInfo>(T); - if (isDragonFly) + case llvm::Triple::DragonFly: return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); - if (isOpenBSD) - return new OpenBSDTargetInfo<X86_32TargetInfo>(T); - if (isFreeBSD) + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<X86_32TargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDI386TargetInfo(T); + case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_32TargetInfo>(T); - if (isSolaris) + case llvm::Triple::Solaris: return new SolarisTargetInfo<X86_32TargetInfo>(T); - if (isWindows) - return new WindowsX86_32TargetInfo(T); - return new X86_32TargetInfo(T); - } + case llvm::Triple::Cygwin: + return new CygwinX86_32TargetInfo(T); + case llvm::Triple::MinGW32: + return new MinGWX86_32TargetInfo(T); + case llvm::Triple::Win32: + return new VisualStudioWindowsX86_32TargetInfo(T); + default: + return new X86_32TargetInfo(T); + } - return NULL; + case llvm::Triple::x86_64: + switch (os) { + case llvm::Triple::Darwin: + return new DarwinX86_64TargetInfo(T); + case llvm::Triple::Linux: + return new LinuxTargetInfo<X86_64TargetInfo>(T); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<X86_64TargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDX86_64TargetInfo(T); + case llvm::Triple::FreeBSD: + return new FreeBSDTargetInfo<X86_64TargetInfo>(T); + case llvm::Triple::Solaris: + return new SolarisTargetInfo<X86_64TargetInfo>(T); + case llvm::Triple::MinGW64: + return new MinGWX86_64TargetInfo(T); + case llvm::Triple::Win32: // This is what Triple.h supports now. + return new VisualStudioWindowsX86_64TargetInfo(T); + default: + return new X86_64TargetInfo(T); + } + } } |