diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
commit | 36981b17ed939300f6f8fc2355a255f711fcef71 (patch) | |
tree | ee2483e98b09cac943dc93a6969d83ca737ff139 /lib/Basic/Targets.cpp | |
parent | 180abc3db9ae3b4fc63cd65b15697e6ffcc8a657 (diff) | |
download | src-36981b17ed939300f6f8fc2355a255f711fcef71.tar.gz src-36981b17ed939300f6f8fc2355a255f711fcef71.zip |
Notes
Diffstat (limited to 'lib/Basic/Targets.cpp')
-rw-r--r-- | lib/Basic/Targets.cpp | 1102 |
1 files changed, 915 insertions, 187 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 3518ea6f7986..b89ea0c05326 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Type.h" #include <algorithm> using namespace clang; @@ -37,7 +38,7 @@ using namespace clang; /// DefineStd - Define a macro name and standard variants. For example if /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" /// when in GNU mode. -static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName, +static void DefineStd(MacroBuilder &Builder, StringRef MacroName, const LangOptions &Opts) { assert(MacroName[0] != '_' && "Identifier should be in the user's namespace"); @@ -77,7 +78,7 @@ public: static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, - llvm::StringRef &PlatformName, + StringRef &PlatformName, VersionTuple &PlatformMinVersion) { Builder.defineMacro("__APPLE_CC__", "5621"); Builder.defineMacro("__APPLE__"); @@ -89,7 +90,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); // Darwin defines __strong even in C mode (just to nothing). - if (Opts.getGCMode() != LangOptions::NonGC) + if (Opts.getGC() != LangOptions::NonGC) Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); else Builder.defineMacro("__strong", ""); @@ -146,6 +147,14 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, } } + // If -ccc-host-triple arch-pc-win32-macho option specified, we're + // generating code for Win32 ABI. No need to emit + // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. + if (PlatformName == "win32") { + PlatformMinVersion = VersionTuple(Maj, Min, Rev); + return; + } + // Set the appropriate OS version define. if (PlatformName == "ios") { assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); @@ -194,9 +203,9 @@ public: this->MCountName = "\01mcount"; } - virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const { + virtual std::string isValidSectionSpecifier(StringRef SR) const { // Let MCSectionMachO validate this. - llvm::StringRef Segment, Section; + StringRef Segment, Section; unsigned TAA, StubSize; bool HasTAA; return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, @@ -238,11 +247,12 @@ protected: MacroBuilder &Builder) const { // FreeBSD defines; list based off of gcc output - // FIXME: Move version number handling to llvm::Triple. - llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1); + unsigned Release = Triple.getOSMajorVersion(); + if (Release == 0U) + Release = 8; - Builder.defineMacro("__FreeBSD__", Release); - Builder.defineMacro("__FreeBSD_cc_version", Release + "00001"); + Builder.defineMacro("__FreeBSD__", Twine(Release)); + Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U)); Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); DefineStd(Builder, "unix", Opts); Builder.defineMacro("__ELF__"); @@ -495,9 +505,9 @@ protected: Builder.defineMacro("_MT"); if (Opts.MSCVersion != 0) - Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion)); + Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion)); - if (Opts.Microsoft) { + if (Opts.MicrosoftExt) { Builder.defineMacro("_MSC_EXTENSIONS"); if (Opts.CPlusPlus0x) { @@ -869,13 +879,41 @@ public: } // end anonymous namespace. namespace { + static const unsigned PTXAddrSpaceMap[] = { + 0, // opencl_global + 4, // opencl_local + 1 // opencl_constant + }; class PTXTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; + std::vector<llvm::StringRef> AvailableFeatures; public: PTXTargetInfo(const std::string& triple) : TargetInfo(triple) { TLSSupported = false; LongWidth = LongAlign = 64; + AddrSpaceMap = &PTXAddrSpaceMap; + // Define available target features + // These must be defined in sorted order! + AvailableFeatures.push_back("compute10"); + AvailableFeatures.push_back("compute11"); + AvailableFeatures.push_back("compute12"); + AvailableFeatures.push_back("compute13"); + AvailableFeatures.push_back("compute20"); + AvailableFeatures.push_back("double"); + AvailableFeatures.push_back("no-fma"); + AvailableFeatures.push_back("ptx20"); + AvailableFeatures.push_back("ptx21"); + AvailableFeatures.push_back("ptx22"); + AvailableFeatures.push_back("ptx23"); + AvailableFeatures.push_back("sm10"); + AvailableFeatures.push_back("sm11"); + AvailableFeatures.push_back("sm12"); + AvailableFeatures.push_back("sm13"); + AvailableFeatures.push_back("sm20"); + AvailableFeatures.push_back("sm21"); + AvailableFeatures.push_back("sm22"); + AvailableFeatures.push_back("sm23"); } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -908,6 +946,10 @@ namespace { // FIXME: implement return "typedef char* __builtin_va_list;"; } + + virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, + const std::string &Name, + bool Enabled) const; }; const Builtin::Info PTXTargetInfo::BuiltinInfo[] = { @@ -927,6 +969,17 @@ namespace { NumNames = llvm::array_lengthof(GCCRegNames); } + bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + const std::string &Name, + bool Enabled) const { + if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), + Name)) { + Features[Name] = Enabled; + return true; + } else { + return false; + } + } class PTX32TargetInfo : public PTXTargetInfo { public: @@ -1119,10 +1172,134 @@ class X86TargetInfo : public TargetInfo { bool HasAES; bool HasAVX; + /// \brief Enumeration of all of the X86 CPUs supported by Clang. + /// + /// Each enumeration represents a particular CPU supported by Clang. These + /// loosely correspond to the options passed to '-march' or '-mtune' flags. + enum CPUKind { + CK_Generic, + + /// \name i386 + /// i386-generation processors. + //@{ + CK_i386, + //@} + + /// \name i486 + /// i486-generation processors. + //@{ + CK_i486, + CK_WinChipC6, + CK_WinChip2, + CK_C3, + //@} + + /// \name i586 + /// i586-generation processors, P5 microarchitecture based. + //@{ + CK_i586, + CK_Pentium, + CK_PentiumMMX, + //@} + + /// \name i686 + /// i686-generation processors, P6 / Pentium M microarchitecture based. + //@{ + CK_i686, + CK_PentiumPro, + CK_Pentium2, + CK_Pentium3, + CK_Pentium3M, + CK_PentiumM, + CK_C3_2, + + /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah. + /// Clang however has some logic to suport this. + // FIXME: Warn, deprecate, and potentially remove this. + CK_Yonah, + //@} + + /// \name Netburst + /// Netburst microarchitecture based processors. + //@{ + CK_Pentium4, + CK_Pentium4M, + CK_Prescott, + CK_Nocona, + //@} + + /// \name Core + /// Core microarchitecture based processors. + //@{ + CK_Core2, + + /// This enumerator, like \see CK_Yonah, is a bit odd. It is another + /// codename which GCC no longer accepts as an option to -march, but Clang + /// has some logic for recognizing it. + // FIXME: Warn, deprecate, and potentially remove this. + CK_Penryn, + //@} + + /// \name Atom + /// Atom processors + //@{ + CK_Atom, + //@} + + /// \name Nehalem + /// Nehalem microarchitecture based processors. + //@{ + CK_Corei7, + CK_Corei7AVX, + CK_CoreAVXi, + //@} + + /// \name K6 + /// K6 architecture processors. + //@{ + CK_K6, + CK_K6_2, + CK_K6_3, + //@} + + /// \name K7 + /// K7 architecture processors. + //@{ + CK_Athlon, + CK_AthlonThunderbird, + CK_Athlon4, + CK_AthlonXP, + CK_AthlonMP, + //@} + + /// \name K8 + /// K8 architecture processors. + //@{ + CK_Athlon64, + CK_Athlon64SSE3, + CK_AthlonFX, + CK_K8, + CK_K8SSE3, + CK_Opteron, + CK_OpteronSSE3, + + /// This specification is deprecated and will be removed in the future. + /// Users should prefer \see CK_K8. + // FIXME: Warn on this when the CPU is set to it. + CK_x86_64, + //@} + + /// \name Geode + /// Geode processors. + //@{ + CK_Geode + //@} + } CPU; + public: X86TargetInfo(const std::string& triple) : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), - HasAES(false), HasAVX(false) { + HasAES(false), HasAVX(false), CPU(CK_Generic) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } virtual void getTargetBuiltins(const Builtin::Info *&Records, @@ -1156,16 +1333,122 @@ public: virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, const std::string &Name, bool Enabled) const; - virtual void getDefaultFeatures(const std::string &CPU, - llvm::StringMap<bool> &Features) const; + virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; virtual void HandleTargetFeatures(std::vector<std::string> &Features); virtual const char* getABI() const { return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : ""; } + virtual bool setCPU(const std::string &Name) { + CPU = llvm::StringSwitch<CPUKind>(Name) + .Case("i386", CK_i386) + .Case("i486", CK_i486) + .Case("winchip-c6", CK_WinChipC6) + .Case("winchip2", CK_WinChip2) + .Case("c3", CK_C3) + .Case("i586", CK_i586) + .Case("pentium", CK_Pentium) + .Case("pentium-mmx", CK_PentiumMMX) + .Case("i686", CK_i686) + .Case("pentiumpro", CK_PentiumPro) + .Case("pentium2", CK_Pentium2) + .Case("pentium3", CK_Pentium3) + .Case("pentium3m", CK_Pentium3M) + .Case("pentium-m", CK_PentiumM) + .Case("c3-2", CK_C3_2) + .Case("yonah", CK_Yonah) + .Case("pentium4", CK_Pentium4) + .Case("pentium4m", CK_Pentium4M) + .Case("prescott", CK_Prescott) + .Case("nocona", CK_Nocona) + .Case("core2", CK_Core2) + .Case("penryn", CK_Penryn) + .Case("atom", CK_Atom) + .Case("corei7", CK_Corei7) + .Case("corei7-avx", CK_Corei7AVX) + .Case("core-avx-i", CK_CoreAVXi) + .Case("k6", CK_K6) + .Case("k6-2", CK_K6_2) + .Case("k6-3", CK_K6_3) + .Case("athlon", CK_Athlon) + .Case("athlon-tbird", CK_AthlonThunderbird) + .Case("athlon-4", CK_Athlon4) + .Case("athlon-xp", CK_AthlonXP) + .Case("athlon-mp", CK_AthlonMP) + .Case("athlon64", CK_Athlon64) + .Case("athlon64-sse3", CK_Athlon64SSE3) + .Case("athlon-fx", CK_AthlonFX) + .Case("k8", CK_K8) + .Case("k8-sse3", CK_K8SSE3) + .Case("opteron", CK_Opteron) + .Case("opteron-sse3", CK_OpteronSSE3) + .Case("x86-64", CK_x86_64) + .Case("geode", CK_Geode) + .Default(CK_Generic); + + // Perform any per-CPU checks necessary to determine if this CPU is + // acceptable. + // FIXME: This results in terrible diagnostics. Clang just says the CPU is + // invalid without explaining *why*. + switch (CPU) { + case CK_Generic: + // No processor selected! + return false; + + case CK_i386: + case CK_i486: + case CK_WinChipC6: + case CK_WinChip2: + case CK_C3: + case CK_i586: + case CK_Pentium: + case CK_PentiumMMX: + case CK_i686: + case CK_PentiumPro: + case CK_Pentium2: + case CK_Pentium3: + case CK_Pentium3M: + case CK_PentiumM: + case CK_Yonah: + case CK_C3_2: + case CK_Pentium4: + case CK_Pentium4M: + case CK_Prescott: + case CK_K6: + case CK_K6_2: + case CK_K6_3: + case CK_Athlon: + case CK_AthlonThunderbird: + case CK_Athlon4: + case CK_AthlonXP: + case CK_AthlonMP: + case CK_Geode: + // Only accept certain architectures when compiling in 32-bit mode. + if (PointerWidth != 32) + return false; + + // Fallthrough + case CK_Nocona: + case CK_Core2: + case CK_Penryn: + case CK_Atom: + case CK_Corei7: + case CK_Corei7AVX: + case CK_CoreAVXi: + case CK_Athlon64: + case CK_Athlon64SSE3: + case CK_AthlonFX: + case CK_K8: + case CK_K8SSE3: + case CK_Opteron: + case CK_OpteronSSE3: + case CK_x86_64: + return true; + } + llvm_unreachable("Unhandled CPU kind"); + } }; -void X86TargetInfo::getDefaultFeatures(const std::string &CPU, - llvm::StringMap<bool> &Features) const { +void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { // FIXME: This should not be here. Features["3dnow"] = false; Features["3dnowa"] = false; @@ -1188,57 +1471,100 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU, if (PointerWidth == 64) Features["sse2"] = Features["sse"] = Features["mmx"] = true; - if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" || - CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro") - ; - else if (CPU == "pentium-mmx" || CPU == "pentium2") + switch (CPU) { + case CK_Generic: + case CK_i386: + case CK_i486: + case CK_i586: + case CK_Pentium: + case CK_i686: + case CK_PentiumPro: + break; + case CK_PentiumMMX: + case CK_Pentium2: setFeatureEnabled(Features, "mmx", true); - else if (CPU == "pentium3") { + break; + case CK_Pentium3: + case CK_Pentium3M: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); - } else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") { + break; + case CK_PentiumM: + case CK_Pentium4: + case CK_Pentium4M: + case CK_x86_64: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse2", true); - } else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") { + break; + case CK_Yonah: + case CK_Prescott: + case CK_Nocona: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse3", true); - } else if (CPU == "core2") { + break; + case CK_Core2: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "ssse3", true); - } else if (CPU == "penryn") { + break; + case CK_Penryn: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4", true); Features["sse42"] = false; - } else if (CPU == "atom") { + break; + case CK_Atom: setFeatureEnabled(Features, "mmx", true); - setFeatureEnabled(Features, "sse3", true); - } else if (CPU == "corei7") { + setFeatureEnabled(Features, "ssse3", true); + break; + case CK_Corei7: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4", true); setFeatureEnabled(Features, "aes", true); - } else if (CPU == "corei7-avx") { + break; + case CK_Corei7AVX: + case CK_CoreAVXi: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4", true); setFeatureEnabled(Features, "aes", true); //setFeatureEnabled(Features, "avx", true); - } else if (CPU == "k6" || CPU == "winchip-c6") + break; + case CK_K6: + case CK_WinChipC6: setFeatureEnabled(Features, "mmx", true); - else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || - CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") { + break; + case CK_K6_2: + case CK_K6_3: + case CK_WinChip2: + case CK_C3: setFeatureEnabled(Features, "3dnow", true); - } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") { + break; + case CK_Athlon: + case CK_AthlonThunderbird: + case CK_Geode: + setFeatureEnabled(Features, "3dnowa", true); + break; + case CK_Athlon4: + case CK_AthlonXP: + case CK_AthlonMP: setFeatureEnabled(Features, "sse", true); setFeatureEnabled(Features, "3dnowa", true); - } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" || - CPU == "athlon-fx") { + break; + case CK_K8: + case CK_Opteron: + case CK_Athlon64: + case CK_AthlonFX: setFeatureEnabled(Features, "sse2", true); setFeatureEnabled(Features, "3dnowa", true); - } else if (CPU == "k8-sse3") { + break; + case CK_K8SSE3: + case CK_OpteronSSE3: + case CK_Athlon64SSE3: setFeatureEnabled(Features, "sse3", true); setFeatureEnabled(Features, "3dnowa", true); - } else if (CPU == "c3-2") { + break; + case CK_C3_2: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); + break; } } @@ -1276,7 +1602,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "aes") Features["aes"] = true; else if (Name == "avx") - Features["avx"] = true; + Features["avx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; } else { if (Name == "mmx") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; @@ -1358,8 +1685,8 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { Features.erase(it); } -/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines -/// that are not tied to a specific subtarget. +/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro +/// definitions for this particular subtarget. void X86TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. @@ -1374,19 +1701,140 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, DefineStd(Builder, "i386", Opts); } - if (HasAES) - Builder.defineMacro("__AES__"); - - if (HasAVX) - Builder.defineMacro("__AVX__"); + // Subtarget options. + // FIXME: We are hard-coding the tune parameters based on the CPU, but they + // truly should be based on -mtune options. + switch (CPU) { + case CK_Generic: + break; + case CK_i386: + // The rest are coming from the i386 define above. + Builder.defineMacro("__tune_i386__"); + break; + case CK_i486: + case CK_WinChipC6: + case CK_WinChip2: + case CK_C3: + Builder.defineMacro("__i486"); + Builder.defineMacro("__i486__"); + Builder.defineMacro("__tune_i486__"); + break; + case CK_PentiumMMX: + Builder.defineMacro("__pentium_mmx__"); + Builder.defineMacro("__tune_pentium_mmx__"); + // Fallthrough + case CK_i586: + case CK_Pentium: + Builder.defineMacro("__i586"); + Builder.defineMacro("__i586__"); + Builder.defineMacro("__tune_i586__"); + Builder.defineMacro("__pentium"); + Builder.defineMacro("__pentium__"); + Builder.defineMacro("__tune_pentium__"); + break; + case CK_Pentium3: + case CK_Pentium3M: + case CK_PentiumM: + Builder.defineMacro("__tune_pentium3__"); + // Fallthrough + case CK_Pentium2: + case CK_C3_2: + Builder.defineMacro("__tune_pentium2__"); + // Fallthrough + case CK_PentiumPro: + Builder.defineMacro("__tune_i686__"); + Builder.defineMacro("__tune_pentiumpro__"); + // Fallthrough + case CK_i686: + Builder.defineMacro("__i686"); + Builder.defineMacro("__i686__"); + // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686. + Builder.defineMacro("__pentiumpro"); + Builder.defineMacro("__pentiumpro__"); + break; + case CK_Pentium4: + case CK_Pentium4M: + Builder.defineMacro("__pentium4"); + Builder.defineMacro("__pentium4__"); + Builder.defineMacro("__tune_pentium4__"); + break; + case CK_Yonah: + case CK_Prescott: + case CK_Nocona: + Builder.defineMacro("__nocona"); + Builder.defineMacro("__nocona__"); + Builder.defineMacro("__tune_nocona__"); + break; + case CK_Core2: + case CK_Penryn: + Builder.defineMacro("__core2"); + Builder.defineMacro("__core2__"); + Builder.defineMacro("__tune_core2__"); + break; + case CK_Atom: + Builder.defineMacro("__atom"); + Builder.defineMacro("__atom__"); + Builder.defineMacro("__tune_atom__"); + break; + case CK_Corei7: + case CK_Corei7AVX: + case CK_CoreAVXi: + Builder.defineMacro("__corei7"); + Builder.defineMacro("__corei7__"); + Builder.defineMacro("__tune_corei7__"); + break; + case CK_K6_2: + Builder.defineMacro("__k6_2__"); + Builder.defineMacro("__tune_k6_2__"); + // Fallthrough + case CK_K6_3: + if (CPU != CK_K6_2) { // In case of fallthrough + // FIXME: GCC may be enabling these in cases where some other k6 + // architecture is specified but -m3dnow is explicitly provided. The + // exact semantics need to be determined and emulated here. + Builder.defineMacro("__k6_3__"); + Builder.defineMacro("__tune_k6_3__"); + } + // Fallthrough + case CK_K6: + Builder.defineMacro("__k6"); + Builder.defineMacro("__k6__"); + Builder.defineMacro("__tune_k6__"); + break; + case CK_Athlon: + case CK_AthlonThunderbird: + case CK_Athlon4: + case CK_AthlonXP: + case CK_AthlonMP: + Builder.defineMacro("__athlon"); + Builder.defineMacro("__athlon__"); + Builder.defineMacro("__tune_athlon__"); + if (SSELevel != NoSSE) { + Builder.defineMacro("__athlon_sse__"); + Builder.defineMacro("__tune_athlon_sse__"); + } + break; + case CK_K8: + case CK_K8SSE3: + case CK_x86_64: + case CK_Opteron: + case CK_OpteronSSE3: + case CK_Athlon64: + case CK_Athlon64SSE3: + case CK_AthlonFX: + Builder.defineMacro("__k8"); + Builder.defineMacro("__k8__"); + Builder.defineMacro("__tune_k8__"); + break; + case CK_Geode: + Builder.defineMacro("__geode"); + Builder.defineMacro("__geode__"); + Builder.defineMacro("__tune_geode__"); + break; + } // Target properties. Builder.defineMacro("__LITTLE_ENDIAN__"); - - // Subtarget options. - Builder.defineMacro("__nocona"); - Builder.defineMacro("__nocona__"); - Builder.defineMacro("__tune_nocona__"); Builder.defineMacro("__REGISTER_PREFIX__", ""); // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline @@ -1394,6 +1842,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, // backend can't deal with (PR879). Builder.defineMacro("__NO_MATH_INLINES"); + if (HasAES) + Builder.defineMacro("__AES__"); + + if (HasAVX) + Builder.defineMacro("__AVX__"); + // Each case falls through to the previous one here. switch (SSELevel) { case SSE42: @@ -1414,20 +1868,20 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, break; } - if (Opts.Microsoft && PointerWidth == 32) { + if (Opts.MicrosoftExt && PointerWidth == 32) { switch (SSELevel) { case SSE42: case SSE41: case SSSE3: case SSE3: case SSE2: - Builder.defineMacro("_M_IX86_FP", llvm::Twine(2)); + Builder.defineMacro("_M_IX86_FP", Twine(2)); break; case SSE1: - Builder.defineMacro("_M_IX86_FP", llvm::Twine(1)); + Builder.defineMacro("_M_IX86_FP", Twine(1)); break; default: - Builder.defineMacro("_M_IX86_FP", llvm::Twine(0)); + Builder.defineMacro("_M_IX86_FP", Twine(0)); } } @@ -1521,7 +1975,7 @@ public: LongDoubleAlign = 32; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" - "a0:0:64-f80:32:32-n8:16:32"; + "a0:0:64-f80:32:32-n8:16:32-S128"; SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; @@ -1531,6 +1985,11 @@ public: RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) | (1 << TargetInfo::LongDouble)); + + // x86-32 has atomics up to 8 bytes + // FIXME: Check that we actually have cmpxchg8b before setting + // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.) + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; @@ -1567,7 +2026,7 @@ public: IntPtrType = SignedLong; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" - "a0:0:64-f80:128:128-n8:16:32"; + "a0:0:64-f80:128:128-n8:16:32-S128"; HasAlignMac68kSupport = true; } @@ -1585,7 +2044,7 @@ public: 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-f80:128:128-v64:64:64-" - "v128:128:128-a0:0:64-f80:32:32-n8:16:32"; + "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -1634,7 +2093,7 @@ public: // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)). // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions. - if (Opts.Microsoft) + if (Opts.MicrosoftExt) // Provide "as-is" __declspec. Builder.defineMacro("__declspec", "__declspec"); else @@ -1655,7 +2114,7 @@ public: 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-n8:16:32"; + "a0:0:64-f80:32:32-n8:16:32-S32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -1697,9 +2156,6 @@ protected: MacroBuilder &Builder) const { // RTEMS defines; list based off of gcc output - // FIXME: Move version number handling to llvm::Triple. - llvm::StringRef Release = Triple.getOSName().substr(strlen("rtems"), 1); - Builder.defineMacro("__rtems__"); Builder.defineMacro("__ELF__"); } @@ -1765,10 +2221,16 @@ public: DescriptionString = "e-p:64:64:64-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-s0:64:64-f80:128:128-n8:16:32:64"; + "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"; // Use fpret only for long double. RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); + + // x86-64 has atomics up to 16 bytes. + // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128 + // on CPUs with cmpxchg16b + MaxAtomicPromoteWidth = 128; + MaxAtomicInlineWidth = 64; } virtual const char *getVAListDeclaration() const { return "typedef struct __va_list_tag {" @@ -1853,7 +2315,7 @@ public: // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)). // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions. - if (Opts.Microsoft) + if (Opts.MicrosoftExt) // Provide "as-is" __declspec. Builder.defineMacro("__declspec", "__declspec"); else @@ -1932,15 +2394,19 @@ public: // so set preferred for small types to 32. 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:64:128-a0:0:32-n32"); + "v64:64:64-v128:64:128-a0:0:32-n32-S64"); } 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:64:128-a0:0:64-n32"); + "v64:64:64-v128:64:128-a0:0:64-n32-S64"); } // ARM targets default to using the ARM C++ ABI. CXXABI = CXXABI_ARM; + + // ARM has atomics up to 8 bytes + // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e + MaxAtomicPromoteWidth = 64; } virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) { @@ -1958,16 +2424,27 @@ public: // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. UseBitFieldTypeAlignment = false; + /// Do force alignment of members that follow zero length bitfields. If + /// the alignment of the zero-length bitfield is greater than the member + /// that follows it, `bar', `bar' will be aligned as the type of the + /// zero length bitfield. + UseZeroLengthBitfieldAlignment = true; + + /// gcc forces the alignment to 4 bytes, regardless of the type of the + /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in + /// gcc. + ZeroLengthBitfieldBoundary = 32; + if (IsThumb) { // Thumb1 add sp, #imm requires the immediate value be multiple of 4, // so set preferred for small types to 32. DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" "i64:32:64-f32:32:32-f64:32:64-" - "v64:32:64-v128:32:128-a0:0:32-n32"); + "v64:32:64-v128:32:128-a0:0:32-n32-S32"); } else { DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:32:64-f32:32:32-f64:32:64-" - "v64:32:64-v128:32:128-a0:0:32-n32"); + "v64:32:64-v128:32:128-a0:0:32-n32-S32"); } // FIXME: Override "preferred align" for double and long long. @@ -1981,8 +2458,7 @@ public: return true; } - void getDefaultFeatures(const std::string &CPU, - llvm::StringMap<bool> &Features) const { + void getDefaultFeatures(llvm::StringMap<bool> &Features) const { if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") Features["vfp2"] = true; else if (CPU == "cortex-a8" || CPU == "cortex-a9") @@ -2027,7 +2503,7 @@ public: Features.erase(it); } - static const char *getCPUDefineSuffix(llvm::StringRef Name) { + static const char *getCPUDefineSuffix(StringRef Name) { return llvm::StringSwitch<const char*>(Name) .Cases("arm8", "arm810", "4") .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4") @@ -2066,7 +2542,7 @@ public: Builder.defineMacro("__LITTLE_ENDIAN__"); Builder.defineMacro("__REGISTER_PREFIX__", ""); - llvm::StringRef CPUArch = getCPUDefineSuffix(CPU); + StringRef CPUArch = getCPUDefineSuffix(CPU); Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); // Subtarget options. @@ -2129,6 +2605,9 @@ public: case 'P': // VFP Floating point register double precision Info.setAllowsRegister(); return true; + case 'Q': // A memory address that is a single base register. + Info.setAllowsMemory(); + return true; case 'U': // a memory reference... switch (Name[1]) { case 'q': // ...ARMV4 ldrsb @@ -2245,6 +2724,9 @@ public: DarwinARMTargetInfo(const std::string& triple) : DarwinTargetInfo<ARMTargetInfo>(triple) { HasAlignMac68kSupport = true; + // iOS always has 64-bit atomic instructions. + // FIXME: This should be based off of the target features in ARMTargetInfo. + MaxAtomicInlineWidth = 64; } }; } // end anonymous namespace. @@ -2590,6 +3072,12 @@ namespace { // target processor and program binary. TCE co-design environment is // publicly available in http://tce.cs.tut.fi + static const unsigned TCEOpenCLAddrSpaceMap[] = { + 3, // opencl_global + 4, // opencl_local + 5 // opencl_constant + }; + class TCETargetInfo : public TargetInfo{ public: TCETargetInfo(const std::string& triple) : TargetInfo(triple) { @@ -2618,6 +3106,7 @@ namespace { "i16:16:32-i32:32:32-i64:32:32-" "f32:32:32-f64:32:32-v64:32:32-" "v128:32:32-a0:0:32-n32"; + AddrSpaceMap = &TCEOpenCLAddrSpaceMap; } virtual void getTargetDefines(const LangOptions &Opts, @@ -2646,51 +3135,30 @@ namespace { } namespace { -class MipsTargetInfo : public TargetInfo { - std::string ABI, CPU; - static const TargetInfo::GCCRegAlias GCCRegAliases[]; - static const char * const GCCRegNames[]; +class MipsTargetInfoBase : public TargetInfo { + std::string CPU; +protected: + std::string ABI; public: - MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") { - DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr) + : TargetInfo(triple), ABI(ABIStr) { SizeType = UnsignedInt; PtrDiffType = SignedInt; } virtual const char *getABI() const { return ABI.c_str(); } - virtual bool setABI(const std::string &Name) { - - if ((Name == "o32") || (Name == "eabi")) { - ABI = Name; - return true; - } else - return false; - } + virtual bool setABI(const std::string &Name) = 0; virtual bool setCPU(const std::string &Name) { CPU = Name; return true; } - void getDefaultFeatures(const std::string &CPU, - llvm::StringMap<bool> &Features) const { + void getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features[ABI] = true; Features[CPU] = true; } virtual void getArchDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - if (ABI == "o32") - Builder.defineMacro("__mips_o32"); - else if (ABI == "eabi") - Builder.defineMacro("__mips_eabi"); - } + MacroBuilder &Builder) const = 0; virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - DefineStd(Builder, "mips", Opts); - Builder.defineMacro("_mips"); - DefineStd(Builder, "MIPSEB", Opts); - Builder.defineMacro("_MIPSEB"); - Builder.defineMacro("__REGISTER_PREFIX__", ""); - getArchDefines(Opts, Builder); - } + MacroBuilder &Builder) const = 0; virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { // FIXME: Implement! @@ -2699,9 +3167,24 @@ public: return "typedef void* __builtin_va_list;"; } virtual void getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const; + unsigned &NumNames) const { + static const char * const 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", "$sp", "$fp", "$31", + "$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", + "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", + "$fcc5","$fcc6","$fcc7" + }; + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); + } virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const; + unsigned &NumAliases) const = 0; virtual bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const { switch (*Name) { @@ -2722,89 +3205,296 @@ public: } }; -const char * const MipsTargetInfo::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", "$sp", "$fp", "$31", - "$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", - "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", - "$fcc5","$fcc6","$fcc7" +class Mips32TargetInfoBase : public MipsTargetInfoBase { +public: + Mips32TargetInfoBase(const std::string& triple) : + MipsTargetInfoBase(triple, "o32") {} + virtual bool setABI(const std::string &Name) { + if ((Name == "o32") || (Name == "eabi")) { + ABI = Name; + return true; + } else + return false; + } + virtual void getArchDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + if (ABI == "o32") { + Builder.defineMacro("__mips_o32"); + Builder.defineMacro("_ABIO32", "1"); + Builder.defineMacro("_MIPS_SIM", "_ABIO32"); + } + else if (ABI == "eabi") + Builder.defineMacro("__mips_eabi"); + else + llvm_unreachable("Invalid ABI for Mips32."); + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + { { "at" }, "$1" }, + { { "v0" }, "$2" }, + { { "v1" }, "$3" }, + { { "a0" }, "$4" }, + { { "a1" }, "$5" }, + { { "a2" }, "$6" }, + { { "a3" }, "$7" }, + { { "t0" }, "$8" }, + { { "t1" }, "$9" }, + { { "t2" }, "$10" }, + { { "t3" }, "$11" }, + { { "t4" }, "$12" }, + { { "t5" }, "$13" }, + { { "t6" }, "$14" }, + { { "t7" }, "$15" }, + { { "s0" }, "$16" }, + { { "s1" }, "$17" }, + { { "s2" }, "$18" }, + { { "s3" }, "$19" }, + { { "s4" }, "$20" }, + { { "s5" }, "$21" }, + { { "s6" }, "$22" }, + { { "s7" }, "$23" }, + { { "t8" }, "$24" }, + { { "t9" }, "$25" }, + { { "k0" }, "$26" }, + { { "k1" }, "$27" }, + { { "gp" }, "$28" }, + { { "sp" }, "$29" }, + { { "fp" }, "$30" }, + { { "ra" }, "$31" } + }; + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); + } }; -void MipsTargetInfo::getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - Names = GCCRegNames; - NumNames = llvm::array_lengthof(GCCRegNames); -} +class Mips32EBTargetInfo : public Mips32TargetInfoBase { +public: + Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { + DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "mips", Opts); + Builder.defineMacro("_mips"); + DefineStd(Builder, "MIPSEB", Opts); + Builder.defineMacro("_MIPSEB"); + Builder.defineMacro("__REGISTER_PREFIX__", ""); + getArchDefines(Opts, Builder); + } +}; -const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = { - { { "at" }, "$1" }, - { { "v0" }, "$2" }, - { { "v1" }, "$3" }, - { { "a0" }, "$4" }, - { { "a1" }, "$5" }, - { { "a2" }, "$6" }, - { { "a3" }, "$7" }, - { { "t0" }, "$8" }, - { { "t1" }, "$9" }, - { { "t2" }, "$10" }, - { { "t3" }, "$11" }, - { { "t4" }, "$12" }, - { { "t5" }, "$13" }, - { { "t6" }, "$14" }, - { { "t7" }, "$15" }, - { { "s0" }, "$16" }, - { { "s1" }, "$17" }, - { { "s2" }, "$18" }, - { { "s3" }, "$19" }, - { { "s4" }, "$20" }, - { { "s5" }, "$21" }, - { { "s6" }, "$22" }, - { { "s7" }, "$23" }, - { { "t8" }, "$24" }, - { { "t9" }, "$25" }, - { { "k0" }, "$26" }, - { { "k1" }, "$27" }, - { { "gp" }, "$28" }, - { { "sp" }, "$29" }, - { { "fp" }, "$30" }, - { { "ra" }, "$31" } +class Mips32ELTargetInfo : public Mips32TargetInfoBase { +public: + Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { + DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "mips", Opts); + Builder.defineMacro("_mips"); + DefineStd(Builder, "MIPSEL", Opts); + Builder.defineMacro("_MIPSEL"); + Builder.defineMacro("__REGISTER_PREFIX__", ""); + getArchDefines(Opts, Builder); + } }; -void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const { - Aliases = GCCRegAliases; - NumAliases = llvm::array_lengthof(GCCRegAliases); -} +class Mips64TargetInfoBase : public MipsTargetInfoBase { + virtual void SetDescriptionString(const std::string &Name) = 0; +public: + Mips64TargetInfoBase(const std::string& triple) : + MipsTargetInfoBase(triple, "n64") {} + virtual bool setABI(const std::string &Name) { + SetDescriptionString(Name); + if ((Name == "n32") || (Name == "n64")) { + ABI = Name; + return true; + } else + return false; + } + virtual void getArchDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + if (ABI == "n32") { + Builder.defineMacro("__mips_n32"); + Builder.defineMacro("_ABIN32", "2"); + Builder.defineMacro("_MIPS_SIM", "_ABIN32"); + } + else if (ABI == "n64") { + Builder.defineMacro("__mips_n64"); + Builder.defineMacro("_ABI64", "3"); + Builder.defineMacro("_MIPS_SIM", "_ABI64"); + } + else + llvm_unreachable("Invalid ABI for Mips64."); + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + { { "at" }, "$1" }, + { { "v0" }, "$2" }, + { { "v1" }, "$3" }, + { { "a0" }, "$4" }, + { { "a1" }, "$5" }, + { { "a2" }, "$6" }, + { { "a3" }, "$7" }, + { { "a4" }, "$8" }, + { { "a5" }, "$9" }, + { { "a6" }, "$10" }, + { { "a7" }, "$11" }, + { { "t0" }, "$12" }, + { { "t1" }, "$13" }, + { { "t2" }, "$14" }, + { { "t3" }, "$15" }, + { { "s0" }, "$16" }, + { { "s1" }, "$17" }, + { { "s2" }, "$18" }, + { { "s3" }, "$19" }, + { { "s4" }, "$20" }, + { { "s5" }, "$21" }, + { { "s6" }, "$22" }, + { { "s7" }, "$23" }, + { { "t8" }, "$24" }, + { { "t9" }, "$25" }, + { { "k0" }, "$26" }, + { { "k1" }, "$27" }, + { { "gp" }, "$28" }, + { { "sp" }, "$29" }, + { { "fp" }, "$30" }, + { { "ra" }, "$31" } + }; + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); + } +}; + +class Mips64EBTargetInfo : public Mips64TargetInfoBase { + virtual void SetDescriptionString(const std::string &Name) { + // Change DescriptionString only if ABI is n32. + if (Name == "n32") + DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } +public: + Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { + // Default ABI is n64. + DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "mips", Opts); + Builder.defineMacro("_mips"); + DefineStd(Builder, "MIPSEB", Opts); + Builder.defineMacro("_MIPSEB"); + Builder.defineMacro("__REGISTER_PREFIX__", ""); + getArchDefines(Opts, Builder); + } +}; + +class Mips64ELTargetInfo : public Mips64TargetInfoBase { + virtual void SetDescriptionString(const std::string &Name) { + // Change DescriptionString only if ABI is n32. + if (Name == "n32") + DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } +public: + Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { + // Default ABI is n64. + DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "mips", Opts); + Builder.defineMacro("_mips"); + DefineStd(Builder, "MIPSEL", Opts); + Builder.defineMacro("_MIPSEL"); + Builder.defineMacro("__REGISTER_PREFIX__", ""); + getArchDefines(Opts, Builder); + } +}; } // end anonymous namespace. namespace { -class MipselTargetInfo : public MipsTargetInfo { +class PNaClTargetInfo : public TargetInfo { public: - MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) { - DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) { + this->UserLabelPrefix = ""; + this->LongAlign = 32; + this->LongWidth = 32; + this->PointerAlign = 32; + this->PointerWidth = 32; + this->IntMaxType = TargetInfo::SignedLongLong; + this->UIntMaxType = TargetInfo::UnsignedLongLong; + this->Int64Type = TargetInfo::SignedLongLong; + this->DoubleAlign = 64; + this->LongDoubleWidth = 64; + this->LongDoubleAlign = 64; + this->SizeType = TargetInfo::UnsignedInt; + this->PtrDiffType = TargetInfo::SignedInt; + this->IntPtrType = TargetInfo::SignedInt; + this->RegParmMax = 2; + DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" + "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; } + void getDefaultFeatures(llvm::StringMap<bool> &Features) const { + } + virtual void getArchDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__le32__"); + Builder.defineMacro("__pnacl__"); + } virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const; + MacroBuilder &Builder) const { + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + + Builder.defineMacro("__native_client__"); + getArchDefines(Opts, Builder); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + } + virtual const char *getVAListDeclaration() const { + return "typedef int __builtin_va_list[4];"; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const; + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + return false; + } + + virtual const char *getClobbers() const { + return ""; + } }; -void MipselTargetInfo::getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - DefineStd(Builder, "mips", Opts); - Builder.defineMacro("_mips"); - DefineStd(Builder, "MIPSEL", Opts); - Builder.defineMacro("_MIPSEL"); - Builder.defineMacro("__REGISTER_PREFIX__", ""); - getArchDefines(Opts, Builder); +void PNaClTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = NULL; + NumNames = 0; +} + +void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = NULL; + NumAliases = 0; } } // end anonymous namespace. + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// @@ -2845,40 +3535,74 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::mips: switch (os) { - case llvm::Triple::Psp: - return new PSPTargetInfo<MipsTargetInfo>(T); case llvm::Triple::Linux: - return new LinuxTargetInfo<MipsTargetInfo>(T); + return new LinuxTargetInfo<Mips32EBTargetInfo>(T); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipsTargetInfo>(T); + return new RTEMSTargetInfo<Mips32EBTargetInfo>(T); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipsTargetInfo>(T); + return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipsTargetInfo>(T); + return new NetBSDTargetInfo<Mips32EBTargetInfo>(T); default: - return new MipsTargetInfo(T); + return new Mips32EBTargetInfo(T); } case llvm::Triple::mipsel: switch (os) { - case llvm::Triple::Psp: - return new PSPTargetInfo<MipselTargetInfo>(T); case llvm::Triple::Linux: - return new LinuxTargetInfo<MipselTargetInfo>(T); + return new LinuxTargetInfo<Mips32ELTargetInfo>(T); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<MipselTargetInfo>(T); + return new RTEMSTargetInfo<Mips32ELTargetInfo>(T); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<MipselTargetInfo>(T); + return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<MipselTargetInfo>(T); + return new NetBSDTargetInfo<Mips32ELTargetInfo>(T); default: - return new MipsTargetInfo(T); + return new Mips32ELTargetInfo(T); + } + + case llvm::Triple::mips64: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<Mips64EBTargetInfo>(T); + case llvm::Triple::RTEMS: + return new RTEMSTargetInfo<Mips64EBTargetInfo>(T); + case llvm::Triple::FreeBSD: + return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<Mips64EBTargetInfo>(T); + default: + return new Mips64EBTargetInfo(T); + } + + case llvm::Triple::mips64el: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<Mips64ELTargetInfo>(T); + case llvm::Triple::RTEMS: + return new RTEMSTargetInfo<Mips64ELTargetInfo>(T); + case llvm::Triple::FreeBSD: + return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<Mips64ELTargetInfo>(T); + default: + return new Mips64ELTargetInfo(T); + } + + case llvm::Triple::le32: + switch (os) { + case llvm::Triple::NativeClient: + return new PNaClTargetInfo(T); + default: + return NULL; } case llvm::Triple::ppc: if (Triple.isOSDarwin()) return new DarwinPPC32TargetInfo(T); switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<PPC32TargetInfo>(T); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<PPC32TargetInfo>(T); case llvm::Triple::NetBSD: @@ -2893,6 +3617,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { if (Triple.isOSDarwin()) return new DarwinPPC64TargetInfo(T); switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<PPC64TargetInfo>(T); case llvm::Triple::Lv2: return new PS3PPUTargetInfo<PPC64TargetInfo>(T); case llvm::Triple::FreeBSD: @@ -2913,6 +3639,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::sparc: switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<SparcV8TargetInfo>(T); case llvm::Triple::AuroraUX: return new AuroraUXSparcV8TargetInfo(T); case llvm::Triple::Solaris: @@ -3001,7 +3729,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { /// CreateTargetInfo - Return the target info object for the specified target /// triple. -TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, +TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts) { llvm::Triple Triple(Opts.Triple); @@ -3033,7 +3761,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, // Compute the default target features, we need the target to handle this // because features may have dependencies on one another. llvm::StringMap<bool> Features; - Target->getDefaultFeatures(Opts.CPU, Features); + Target->getDefaultFeatures(Features); // Apply the user specified deltas. for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), |