diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 956 |
1 files changed, 666 insertions, 290 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index ae5f270..1ad37c4 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -54,6 +54,14 @@ static void DefineStd(MacroBuilder &Builder, StringRef MacroName, Builder.defineMacro("__" + MacroName + "__"); } +static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, + bool Tuning = true) { + Builder.defineMacro("__" + CPUName); + Builder.defineMacro("__" + CPUName + "__"); + if (Tuning) + Builder.defineMacro("__tune_" + CPUName + "__"); +} + //===----------------------------------------------------------------------===// // Defines specific to certain operating systems. //===----------------------------------------------------------------------===// @@ -99,13 +107,6 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // allow this in C, since one might have block pointers in structs that // are used in pure C code and in Objective-C ARC. Builder.defineMacro("__unsafe_unretained", ""); - - // The Objective-C bridged cast keywords are defined to nothing in non-ARC - // mode; then they become normal, C-style casts. - Builder.defineMacro("__bridge", ""); - Builder.defineMacro("__bridge_transfer", ""); - Builder.defineMacro("__bridge_retained", ""); - Builder.defineMacro("__bridge_retain", ""); } if (Opts.Static) @@ -118,36 +119,15 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // Get the platform type and version number from the triple. unsigned Maj, Min, Rev; - - // If no version was given, default to to 10.4.0, for simplifying tests. - if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") { + if (Triple.isMacOSX()) { + Triple.getMacOSXVersion(Maj, Min, Rev); PlatformName = "macosx"; - Min = Rev = 0; - Maj = 8; } else { - // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]", - // "-osxNNN", and "-iosNNN"). - - if (Triple.getOS() == llvm::Triple::Darwin) { - // For historical reasons that make little sense, the version passed here - // is the "darwin" version, which drops the 10 and offsets by 4. - Triple.getOSVersion(Maj, Min, Rev); - - if (Triple.getEnvironmentName() == "iphoneos") { - PlatformName = "ios"; - } else { - PlatformName = "macosx"; - Rev = Min; - Min = Maj - 4; - Maj = 10; - } - } else { - Triple.getOSVersion(Maj, Min, Rev); - PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); - } + Triple.getOSVersion(Maj, Min, Rev); + PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); } - // If -ccc-host-triple arch-pc-win32-macho option specified, we're + // If -target 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") { @@ -156,7 +136,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, } // Set the appropriate OS version define. - if (PlatformName == "ios") { + if (Triple.getOS() == llvm::Triple::IOS) { assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); char Str[6]; Str[0] = '0' + Maj; @@ -217,6 +197,12 @@ public: return "__TEXT,__StaticInit,regular,pure_instructions"; } + /// Darwin does not support protected visibility. Darwin's "default" + /// is very similar to ELF's "protected"; Darwin requires a "weak" + /// attribute on declarations that can be dynamically replaced. + virtual bool hasProtectedVisibility() const { + return false; + } }; @@ -236,7 +222,18 @@ protected: } public: DragonFlyBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + + llvm::Triple Triple(triple); + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + } + } }; // FreeBSD Target @@ -249,7 +246,7 @@ protected: unsigned Release = Triple.getOSMajorVersion(); if (Release == 0U) - Release = 8U; + Release = 8; Builder.defineMacro("__FreeBSD__", Twine(Release)); Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U)); @@ -298,6 +295,7 @@ protected: Builder.defineMacro("_EM_LSIZE", "4"); Builder.defineMacro("_EM_FSIZE", "4"); Builder.defineMacro("_EM_DSIZE", "8"); + Builder.defineMacro("__ELF__"); DefineStd(Builder, "unix", Opts); } public: @@ -329,6 +327,10 @@ public: this->UserLabelPrefix = ""; this->WIntType = TargetInfo::UnsignedInt; } + + virtual const char *getStaticInitSectionSpecifier() const { + return ".text.startup"; + } }; // NetBSD Target @@ -367,7 +369,26 @@ protected: } public: OpenBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + + llvm::Triple Triple(triple); + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::arm: + case llvm::Triple::sparc: + this->MCountName = "__mcount"; + break; + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::ppc: + case llvm::Triple::sparcv9: + this->MCountName = "_mcount"; + break; + } + } }; // PSP Target @@ -408,13 +429,14 @@ public: PS3PPUTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; - this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32; + this->LongWidth = this->LongAlign = 32; + this->PointerWidth = this->PointerAlign = 32; this->IntMaxType = TargetInfo::SignedLongLong; this->UIntMaxType = TargetInfo::UnsignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; this->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-v128:128:128-n32"; + "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; } }; @@ -468,12 +490,26 @@ protected: Builder.defineMacro("__ELF__"); Builder.defineMacro("__svr4__"); Builder.defineMacro("__SVR4"); + // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and + // newer, but to 500 for everything else. feature_test.h has a check to + // ensure that you are not using C99 with an old version of X/Open or C89 + // with a new version. + if (Opts.C99 || Opts.C11) + Builder.defineMacro("_XOPEN_SOURCE", "600"); + else + Builder.defineMacro("_XOPEN_SOURCE", "500"); + if (Opts.CPlusPlus) + Builder.defineMacro("__C99FEATURES__"); + Builder.defineMacro("_LARGEFILE_SOURCE"); + Builder.defineMacro("_LARGEFILE64_SOURCE"); + Builder.defineMacro("__EXTENSIONS__"); + Builder.defineMacro("_REENTRANT"); } public: SolarisTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; - this->WCharType = this->SignedLong; + this->WCharType = this->SignedInt; // FIXME: WIntType should be SignedLong } }; @@ -538,7 +574,10 @@ class PPCTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; public: - PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {} + PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -546,9 +585,13 @@ public: NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin; } + virtual bool isCLZForZeroUndef() const { return false; } + virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; + virtual bool hasFeature(StringRef Feature) const; + virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -701,7 +744,11 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool PPCTargetInfo::hasFeature(StringRef Feature) const { + return Feature == "powerpc"; +} + const char * const PPCTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -814,13 +861,21 @@ public: "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; switch (getTriple().getOS()) { + case llvm::Triple::Linux: case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; break; default: break; } + + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } } virtual const char *getVAListDeclaration() const { @@ -846,6 +901,11 @@ public: Int64Type = SignedLong; 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-v128:128:128-n32:64"; + + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } } virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; @@ -862,6 +922,10 @@ public: : DarwinTargetInfo<PPC32TargetInfo>(triple) { HasAlignMac68kSupport = true; BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool? + LongLongAlign = 32; + SuitableAlign = 128; + 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:64:64-v128:128:128-n32"; } virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; @@ -874,6 +938,7 @@ public: DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo<PPC64TargetInfo>(triple) { HasAlignMac68kSupport = true; + SuitableAlign = 128; } }; } // end anonymous namespace. @@ -890,6 +955,7 @@ namespace { std::vector<llvm::StringRef> AvailableFeatures; public: PTXTargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &PTXAddrSpaceMap; @@ -924,7 +990,10 @@ namespace { Records = BuiltinInfo; NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin; } - + virtual bool hasFeature(StringRef Feature) const { + return Feature == "ptx"; + } + virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -948,7 +1017,7 @@ namespace { } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const; }; @@ -970,7 +1039,7 @@ namespace { } bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), Name)) { @@ -1023,6 +1092,10 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; + virtual bool hasFeature(StringRef Feature) const { + return Feature == "mblaze"; + } + virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; } @@ -1146,6 +1219,8 @@ static const char* const GCCRegNames[] = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -1163,14 +1238,18 @@ const TargetInfo::AddlRegName AddlRegNames[] = { // most of the implementation can be shared. class X86TargetInfo : public TargetInfo { enum X86SSEEnum { - NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 + NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 } SSELevel; enum MMX3DNowEnum { NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon } MMX3DNowLevel; bool HasAES; - bool HasAVX; + bool HasLZCNT; + bool HasBMI; + bool HasBMI2; + bool HasPOPCNT; + bool HasFMA4; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// @@ -1252,6 +1331,7 @@ class X86TargetInfo : public TargetInfo { CK_Corei7, CK_Corei7AVX, CK_CoreAVXi, + CK_CoreAVX2, //@} /// \name K6 @@ -1283,6 +1363,20 @@ class X86TargetInfo : public TargetInfo { CK_Opteron, CK_OpteronSSE3, CK_AMDFAM10, + //@} + + /// \name Bobcat + /// Bobcat architecture processors. + //@{ + CK_BTVER1, + //@} + + /// \name Bulldozer + /// Bulldozer architecture processors. + //@{ + CK_BDVER1, + CK_BDVER2, + //@} /// This specification is deprecated and will be removed in the future. /// Users should prefer \see CK_K8. @@ -1300,9 +1394,15 @@ class X86TargetInfo : public TargetInfo { public: X86TargetInfo(const std::string& triple) : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), - HasAES(false), HasAVX(false), CPU(CK_Generic) { + HasAES(false), HasLZCNT(false), HasBMI(false), HasBMI2(false), + HasPOPCNT(false), HasFMA4(false), CPU(CK_Generic) { + BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } + virtual unsigned getFloatEvalMethod() const { + // X87 evaluates with 80 bits "long double" precision. + return SSELevel == NoSSE ? 2 : 0; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { Records = BuiltinInfo; @@ -1332,12 +1432,17 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const; virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; + virtual bool hasFeature(StringRef Feature) const; virtual void HandleTargetFeatures(std::vector<std::string> &Features); virtual const char* getABI() const { - return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : ""; + if (PointerWidth == 64 && SSELevel >= AVX) + return "avx"; + else if (PointerWidth == 32 && MMX3DNowLevel == NoMMX3DNow) + return "no-mmx"; + return ""; } virtual bool setCPU(const std::string &Name) { CPU = llvm::StringSwitch<CPUKind>(Name) @@ -1367,6 +1472,7 @@ public: .Case("corei7", CK_Corei7) .Case("corei7-avx", CK_Corei7AVX) .Case("core-avx-i", CK_CoreAVXi) + .Case("core-avx2", CK_CoreAVX2) .Case("k6", CK_K6) .Case("k6-2", CK_K6_2) .Case("k6-3", CK_K6_3) @@ -1383,6 +1489,9 @@ public: .Case("opteron", CK_Opteron) .Case("opteron-sse3", CK_OpteronSSE3) .Case("amdfam10", CK_AMDFAM10) + .Case("btver1", CK_BTVER1) + .Case("bdver1", CK_BDVER1) + .Case("bdver2", CK_BDVER2) .Case("x86-64", CK_x86_64) .Case("geode", CK_Geode) .Default(CK_Generic); @@ -1436,6 +1545,7 @@ public: case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: + case CK_CoreAVX2: case CK_Athlon64: case CK_Athlon64SSE3: case CK_AthlonFX: @@ -1444,6 +1554,9 @@ public: case CK_Opteron: case CK_OpteronSSE3: case CK_AMDFAM10: + case CK_BTVER1: + case CK_BDVER1: + case CK_BDVER2: case CK_x86_64: return true; } @@ -1465,6 +1578,12 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features["sse4a"] = false; Features["aes"] = false; Features["avx"] = false; + Features["avx2"] = false; + Features["lzcnt"] = false; + Features["bmi"] = false; + Features["bmi2"] = false; + Features["popcnt"] = false; + Features["fma4"] = false; // FIXME: This *really* should not be here. @@ -1509,8 +1628,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { break; case CK_Penryn: setFeatureEnabled(Features, "mmx", true); - setFeatureEnabled(Features, "sse4", true); - Features["sse42"] = false; + setFeatureEnabled(Features, "sse4.1", true); break; case CK_Atom: setFeatureEnabled(Features, "mmx", true); @@ -1528,6 +1646,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "aes", true); //setFeatureEnabled(Features, "avx", true); break; + case CK_CoreAVX2: + setFeatureEnabled(Features, "mmx", true); + setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "bmi", true); + setFeatureEnabled(Features, "bmi2", true); + //setFeatureEnabled(Features, "avx2", true); + break; case CK_K6: case CK_WinChipC6: setFeatureEnabled(Features, "mmx", true); @@ -1567,6 +1694,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "sse4a", true); setFeatureEnabled(Features, "3dnowa", true); break; + case CK_BTVER1: + setFeatureEnabled(Features, "ssse3", true); + setFeatureEnabled(Features, "sse4a", true); + case CK_BDVER1: + case CK_BDVER2: + setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "sse4a", true); + setFeatureEnabled(Features, "aes", true); + break; case CK_C3_2: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); @@ -1575,7 +1711,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { } bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { // FIXME: This *really* should not be here. We need some way of translating // options into llvm subtarget features. @@ -1600,7 +1736,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["ssse3"] = true; else if (Name == "sse4" || Name == "sse4.2") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = true; else if (Name == "sse4.1") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = true; @@ -1613,21 +1750,39 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "avx") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["avx"] = true; + Features["popcnt"] = Features["avx"] = true; + else if (Name == "avx2") + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = Features["avx"] = Features["avx2"] = true; + else if (Name == "fma4") + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = Features["avx"] = Features["fma4"] = true; else if (Name == "sse4a") - Features["mmx"] = Features["sse4a"] = true; + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["lzcnt"] = Features["popcnt"] = Features["sse4a"] = true; + else if (Name == "lzcnt") + Features["lzcnt"] = true; + else if (Name == "bmi") + Features["bmi"] = true; + else if (Name == "bmi2") + Features["bmi2"] = true; + else if (Name == "popcnt") + Features["popcnt"] = true; } else { if (Name == "mmx") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; else if (Name == "sse") Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["sse4a"] = false; else if (Name == "sse2") Features["sse2"] = Features["sse3"] = Features["ssse3"] = - Features["sse41"] = Features["sse42"] = false; + Features["sse41"] = Features["sse42"] = Features["sse4a"] = false; else if (Name == "sse3") Features["sse3"] = Features["ssse3"] = Features["sse41"] = - Features["sse42"] = false; + Features["sse42"] = Features["sse4a"] = false; else if (Name == "ssse3") Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "sse4" || Name == "sse4.1") @@ -1641,9 +1796,21 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "aes") Features["aes"] = false; else if (Name == "avx") - Features["avx"] = false; + Features["avx"] = Features["avx2"] = Features["fma4"] = false; + else if (Name == "avx2") + Features["avx2"] = false; else if (Name == "sse4a") Features["sse4a"] = false; + else if (Name == "lzcnt") + Features["lzcnt"] = false; + else if (Name == "bmi") + Features["bmi"] = false; + else if (Name == "bmi2") + Features["bmi2"] = false; + else if (Name == "popcnt") + Features["popcnt"] = false; + else if (Name == "fma4") + Features["fma4"] = false; } return true; @@ -1658,20 +1825,42 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { if (Features[i][0] == '-') continue; - if (Features[i].substr(1) == "aes") { + StringRef Feature = StringRef(Features[i]).substr(1); + + if (Feature == "aes") { HasAES = true; continue; } - // FIXME: Not sure yet how to treat AVX in regard to SSE levels. - // For now let it be enabled together with other SSE levels. - if (Features[i].substr(1) == "avx") { - HasAVX = true; + if (Feature == "lzcnt") { + HasLZCNT = true; + continue; + } + + if (Feature == "bmi") { + HasBMI = true; + continue; + } + + if (Feature == "bmi2") { + HasBMI2 = true; + continue; + } + + if (Feature == "popcnt") { + HasPOPCNT = true; + continue; + } + + if (Feature == "fma4") { + HasFMA4 = true; continue; } assert(Features[i][0] == '+' && "Invalid target feature!"); - X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1)) + X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) + .Case("avx2", AVX2) + .Case("avx", AVX) .Case("sse42", SSE42) .Case("sse41", SSE41) .Case("ssse3", SSSE3) @@ -1682,7 +1871,7 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { SSELevel = std::max(SSELevel, Level); MMX3DNowEnum ThreeDNowLevel = - llvm::StringSwitch<MMX3DNowEnum>(Features[i].substr(1)) + llvm::StringSwitch<MMX3DNowEnum>(Feature) .Case("3dnowa", AMD3DNowAthlon) .Case("3dnow", AMD3DNow) .Case("mmx", MMX) @@ -1705,8 +1894,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. if (PointerWidth == 64) { - Builder.defineMacro("_LP64"); - Builder.defineMacro("__LP64__"); + if (getLongWidth() == 64) { + Builder.defineMacro("_LP64"); + Builder.defineMacro("__LP64__"); + } Builder.defineMacro("__amd64__"); Builder.defineMacro("__amd64"); Builder.defineMacro("__x86_64"); @@ -1729,9 +1920,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_WinChipC6: case CK_WinChip2: case CK_C3: - Builder.defineMacro("__i486"); - Builder.defineMacro("__i486__"); - Builder.defineMacro("__tune_i486__"); + defineCPUMacros(Builder, "i486"); break; case CK_PentiumMMX: Builder.defineMacro("__pentium_mmx__"); @@ -1739,12 +1928,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, // 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__"); + defineCPUMacros(Builder, "i586"); + defineCPUMacros(Builder, "pentium"); break; case CK_Pentium3: case CK_Pentium3M: @@ -1768,34 +1953,25 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, break; case CK_Pentium4: case CK_Pentium4M: - Builder.defineMacro("__pentium4"); - Builder.defineMacro("__pentium4__"); - Builder.defineMacro("__tune_pentium4__"); + defineCPUMacros(Builder, "pentium4"); break; case CK_Yonah: case CK_Prescott: case CK_Nocona: - Builder.defineMacro("__nocona"); - Builder.defineMacro("__nocona__"); - Builder.defineMacro("__tune_nocona__"); + defineCPUMacros(Builder, "nocona"); break; case CK_Core2: case CK_Penryn: - Builder.defineMacro("__core2"); - Builder.defineMacro("__core2__"); - Builder.defineMacro("__tune_core2__"); + defineCPUMacros(Builder, "core2"); break; case CK_Atom: - Builder.defineMacro("__atom"); - Builder.defineMacro("__atom__"); - Builder.defineMacro("__tune_atom__"); + defineCPUMacros(Builder, "atom"); break; case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: - Builder.defineMacro("__corei7"); - Builder.defineMacro("__corei7__"); - Builder.defineMacro("__tune_corei7__"); + case CK_CoreAVX2: + defineCPUMacros(Builder, "corei7"); break; case CK_K6_2: Builder.defineMacro("__k6_2__"); @@ -1811,18 +1987,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, } // Fallthrough case CK_K6: - Builder.defineMacro("__k6"); - Builder.defineMacro("__k6__"); - Builder.defineMacro("__tune_k6__"); + defineCPUMacros(Builder, "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__"); + defineCPUMacros(Builder, "athlon"); if (SSELevel != NoSSE) { Builder.defineMacro("__athlon_sse__"); Builder.defineMacro("__tune_athlon_sse__"); @@ -1836,19 +2008,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Athlon64: case CK_Athlon64SSE3: case CK_AthlonFX: - Builder.defineMacro("__k8"); - Builder.defineMacro("__k8__"); - Builder.defineMacro("__tune_k8__"); + defineCPUMacros(Builder, "k8"); break; case CK_AMDFAM10: - Builder.defineMacro("__amdfam10"); - Builder.defineMacro("__amdfam10__"); - Builder.defineMacro("__tune_amdfam10__"); + defineCPUMacros(Builder, "amdfam10"); + break; + case CK_BTVER1: + defineCPUMacros(Builder, "btver1"); + break; + case CK_BDVER1: + defineCPUMacros(Builder, "bdver1"); + break; + case CK_BDVER2: + defineCPUMacros(Builder, "bdver2"); break; case CK_Geode: - Builder.defineMacro("__geode"); - Builder.defineMacro("__geode__"); - Builder.defineMacro("__tune_geode__"); + defineCPUMacros(Builder, "geode"); break; } @@ -1864,11 +2039,27 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasAES) Builder.defineMacro("__AES__"); - if (HasAVX) - Builder.defineMacro("__AVX__"); + if (HasLZCNT) + Builder.defineMacro("__LZCNT__"); + + if (HasBMI) + Builder.defineMacro("__BMI__"); + + if (HasBMI2) + Builder.defineMacro("__BMI2__"); + + if (HasPOPCNT) + Builder.defineMacro("__POPCNT__"); + + if (HasFMA4) + Builder.defineMacro("__FMA4__"); // Each case falls through to the previous one here. switch (SSELevel) { + case AVX2: + Builder.defineMacro("__AVX2__"); + case AVX: + Builder.defineMacro("__AVX__"); case SSE42: Builder.defineMacro("__SSE4_2__"); case SSE41: @@ -1889,6 +2080,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.MicrosoftExt && PointerWidth == 32) { switch (SSELevel) { + case AVX2: + case AVX: case SSE42: case SSE41: case SSSE3: @@ -1917,6 +2110,30 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool X86TargetInfo::hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("aes", HasAES) + .Case("avx", SSELevel >= AVX) + .Case("avx2", SSELevel >= AVX2) + .Case("bmi", HasBMI) + .Case("bmi2", HasBMI2) + .Case("fma4", HasFMA4) + .Case("lzcnt", HasLZCNT) + .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) + .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) + .Case("mmx", MMX3DNowLevel >= MMX) + .Case("popcnt", HasPOPCNT) + .Case("sse", SSELevel >= SSE1) + .Case("sse2", SSELevel >= SSE2) + .Case("sse3", SSELevel >= SSE3) + .Case("ssse3", SSELevel >= SSSE3) + .Case("sse41", SSELevel >= SSE41) + .Case("sse42", SSELevel >= SSE42) + .Case("x86", true) + .Case("x86_32", PointerWidth == 32) + .Case("x86_64", PointerWidth == 64) + .Default(false); +} bool X86TargetInfo::validateAsmConstraint(const char *&Name, @@ -1959,7 +2176,6 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, // x86_64 instructions. return true; } - return false; } @@ -1992,6 +2208,7 @@ public: DoubleAlign = LongLongAlign = 32; LongDoubleWidth = 96; LongDoubleAlign = 32; + SuitableAlign = 128; 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-S128"; @@ -2023,6 +2240,20 @@ public: } // end anonymous namespace namespace { +class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { +public: + NetBSDI386TargetInfo(const std::string &triple) : + NetBSDTargetInfo<X86_32TargetInfo>(triple) { + } + + virtual unsigned getFloatEvalMethod() const { + // NetBSD defaults to "double" rounding + return 1; + } +}; +} // end anonymous namespace + +namespace { class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { public: OpenBSDI386TargetInfo(const std::string& triple) : @@ -2041,6 +2272,7 @@ public: DarwinTargetInfo<X86_32TargetInfo>(triple) { LongDoubleWidth = 128; LongDoubleAlign = 128; + SuitableAlign = 128; SizeType = UnsignedLong; IntPtrType = SignedLong; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -2233,6 +2465,7 @@ public: LongDoubleAlign = 128; LargeArrayMinWidth = 128; LargeArrayAlign = 128; + SuitableAlign = 128; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; Int64Type = SignedLong; @@ -2245,6 +2478,9 @@ public: // Use fpret only for long double. RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); + // Use fp2ret for _Complex long double. + ComplexLongDoubleUsesFP2Ret = true; + // x86-64 has atomics up to 16 bytes. // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128 // on CPUs with cmpxchg16b @@ -2399,8 +2635,11 @@ public: ARMTargetInfo(const std::string &TripleStr) : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s") { + BigEndian = false; SizeType = UnsignedInt; PtrDiffType = SignedInt; + // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int. + WCharType = UnsignedInt; // {} in inline assembly are neon specifiers, not assembly variant // specifiers. @@ -2426,6 +2665,12 @@ public: // ARM has atomics up to 8 bytes // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e MaxAtomicPromoteWidth = 64; + + // 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; } virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) { @@ -2436,19 +2681,16 @@ public: // FIXME: We need support for -meabi... we could just mangle it into the // name. if (Name == "apcs-gnu") { - DoubleAlign = LongLongAlign = LongDoubleAlign = 32; + DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; SizeType = UnsignedLong; + // Revert to using SignedInt on apcs-gnu to comply with existing behaviour. + WCharType = SignedInt; + // Do not respect the alignment of bit-field types when laying out // 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. @@ -2485,10 +2727,11 @@ public: } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if (Name == "soft-float" || Name == "soft-float-abi" || - Name == "vfp2" || Name == "vfp3" || Name == "neon") { + Name == "vfp2" || Name == "vfp3" || Name == "neon" || Name == "d16" || + Name == "neonfp") { Features[Name] = Enabled; } else return false; @@ -2522,6 +2765,15 @@ public: Features.erase(it); } + virtual bool hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("arm", true) + .Case("softfloat", SoftFloat) + .Case("thumb", IsThumb) + .Case("neon", FPU == NeonFPU && !SoftFloat && + StringRef(getCPUDefineSuffix(CPU)).startswith("7")) + .Default(false); + } static const char *getCPUDefineSuffix(StringRef Name) { return llvm::StringSwitch<const char*>(Name) .Cases("arm8", "arm810", "4") @@ -2540,6 +2792,7 @@ public: .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") .Cases("cortex-a8", "cortex-a9", "7A") .Case("cortex-m3", "7M") + .Case("cortex-m4", "7M") .Case("cortex-m0", "6M") .Default(0); } @@ -2606,6 +2859,7 @@ public: Records = BuiltinInfo; NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin; } + virtual bool isCLZForZeroUndef() const { return false; } virtual const char *getVAListDeclaration() const { return "typedef void* __builtin_va_list;"; } @@ -2729,7 +2983,6 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { }; } // end anonymous namespace. - namespace { class DarwinARMTargetInfo : public DarwinTargetInfo<ARMTargetInfo> { @@ -2750,6 +3003,154 @@ public: }; } // end anonymous namespace. + +namespace { +// Hexagon abstract base class +class HexagonTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + static const char * const GCCRegNames[]; + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + std::string CPU; +public: + HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; + DescriptionString = ("e-p:32:32:32-" + "i64:64:64-i32:32:32-" + "i16:16:16-i1:32:32-a:0:0"); + + // {} in inline assembly are packet specifiers, not assembly variant + // specifiers. + NoAsmVariants = true; + } + + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + Records = BuiltinInfo; + NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin; + } + + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + return true; + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const; + + virtual bool hasFeature(StringRef Feature) const { + return Feature == "hexagon"; + } + + virtual const char *getVAListDeclaration() const { + return "typedef char* __builtin_va_list;"; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const; + virtual const char *getClobbers() const { + return ""; + } + + static const char *getHexagonCPUSuffix(StringRef Name) { + return llvm::StringSwitch<const char*>(Name) + .Case("hexagonv2", "2") + .Case("hexagonv3", "3") + .Case("hexagonv4", "4") + .Default(0); + } + + virtual bool setCPU(const std::string &Name) { + if (!getHexagonCPUSuffix(Name)) + return false; + + CPU = Name; + return true; + } +}; + +void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("qdsp6"); + Builder.defineMacro("__qdsp6", "1"); + Builder.defineMacro("__qdsp6__", "1"); + + Builder.defineMacro("hexagon"); + Builder.defineMacro("__hexagon", "1"); + Builder.defineMacro("__hexagon__", "1"); + + if(CPU == "hexagonv1") { + Builder.defineMacro("__HEXAGON_V1__"); + Builder.defineMacro("__HEXAGON_ARCH__", "1"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V1__"); + Builder.defineMacro("__QDSP6_ARCH__", "1"); + } + } + else if(CPU == "hexagonv2") { + Builder.defineMacro("__HEXAGON_V2__"); + Builder.defineMacro("__HEXAGON_ARCH__", "2"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V2__"); + Builder.defineMacro("__QDSP6_ARCH__", "2"); + } + } + else if(CPU == "hexagonv3") { + Builder.defineMacro("__HEXAGON_V3__"); + Builder.defineMacro("__HEXAGON_ARCH__", "3"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V3__"); + Builder.defineMacro("__QDSP6_ARCH__", "3"); + } + } + else if(CPU == "hexagonv4") { + Builder.defineMacro("__HEXAGON_V4__"); + Builder.defineMacro("__HEXAGON_ARCH__", "4"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V4__"); + Builder.defineMacro("__QDSP6_ARCH__", "4"); + } + } +} + +const char * const HexagonTargetInfo::GCCRegNames[] = { + "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", + "p0", "p1", "p2", "p3", + "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" +}; + +void HexagonTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} + + +const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { + { { "sp" }, "r29" }, + { { "fp" }, "r30" }, + { { "lr" }, "r31" }, + }; + +void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); +} + + +const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, +#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ + ALL_LANGUAGES }, +#include "clang/Basic/BuiltinsHexagon.def" +}; +} + + namespace { class SparcV8TargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; @@ -2758,11 +3159,12 @@ class SparcV8TargetInfo : public TargetInfo { public: SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { // FIXME: Support Sparc quad-precision long double? + BigEndian = false; 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-n32"; } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if (Name == "soft-float") Features[Name] = Enabled; @@ -2786,6 +3188,14 @@ public: if (SoftFloat) Builder.defineMacro("SOFT_FLOAT", "1"); } + + virtual bool hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("softfloat", SoftFloat) + .Case("sparc", true) + .Default(false); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { // FIXME: Implement! @@ -2887,11 +3297,13 @@ namespace { static const char * const GCCRegNames[]; public: MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; TLSSupported = false; IntWidth = 16; IntAlign = 16; LongWidth = 32; LongLongWidth = 64; LongAlign = LongLongAlign = 16; PointerWidth = 16; PointerAlign = 16; + SuitableAlign = 16; SizeType = UnsignedInt; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; @@ -2912,6 +3324,9 @@ namespace { Records = 0; NumRecords = 0; } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "msp430"; + } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -2947,140 +3362,6 @@ 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-n32:64"; - } - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - Builder.defineMacro("__s390__"); - Builder.defineMacro("__s390x__"); - } - 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 { - // 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-n32"; - } - - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - DefineStd(Builder, "bfin", Opts); - DefineStd(Builder, "BFIN", Opts); - Builder.defineMacro("__ADSPBLACKFIN__"); - // FIXME: This one is really dependent on -mcpu - Builder.defineMacro("__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 @@ -3107,6 +3388,7 @@ namespace { IntAlign = 32; LongAlign = LongLongAlign = 32; PointerAlign = 32; + SuitableAlign = 32; SizeType = UnsignedInt; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; @@ -3134,6 +3416,10 @@ namespace { Builder.defineMacro("__TCE__"); Builder.defineMacro("__TCE_V1__"); } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "tce"; + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const {} virtual const char *getClobbers() const { @@ -3156,14 +3442,22 @@ namespace { namespace { class MipsTargetInfoBase : public TargetInfo { std::string CPU; + bool SoftFloat; + bool SingleFloat; + protected: std::string ABI; + public: - MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr) - : TargetInfo(triple), ABI(ABIStr) { - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - } + MipsTargetInfoBase(const std::string& triple, + const std::string& ABIStr, + const std::string& CPUStr) + : TargetInfo(triple), + CPU(CPUStr), + SoftFloat(false), SingleFloat(false), + ABI(ABIStr) + {} + virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) = 0; virtual bool setCPU(const std::string &Name) { @@ -3174,28 +3468,50 @@ public: Features[ABI] = true; Features[CPU] = true; } + virtual void getArchDefines(const LangOptions &Opts, - MacroBuilder &Builder) const = 0; + MacroBuilder &Builder) const { + if (SoftFloat) + Builder.defineMacro("__mips_soft_float", Twine(1)); + else if (SingleFloat) + Builder.defineMacro("__mips_single_float", Twine(1)); + else if (!SoftFloat && !SingleFloat) + Builder.defineMacro("__mips_hard_float", Twine(1)); + else + llvm_unreachable("Invalid float ABI for Mips."); + + Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); + Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); + Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); + } + virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { // FIXME: Implement! } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "mips"; + } virtual const char *getVAListDeclaration() const { return "typedef void* __builtin_va_list;"; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { static const char * const GCCRegNames[] = { + // CPU register names + // Must match second column of GCCRegAliases "$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", + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + // Floating point register names "$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 and condition register names "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", "$fcc5","$fcc6","$fcc7" }; @@ -3208,26 +3524,64 @@ public: TargetInfo::ConstraintInfo &Info) const { switch (*Name) { default: + return false; + case 'r': // CPU registers. case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backwards compatibility only. case 'f': // floating-point registers. + case 'c': // $25 for indirect jumps + case 'l': // lo register + case 'x': // hilo register pair Info.setAllowsRegister(); return true; } - return false; } virtual const char *getClobbers() const { // FIXME: Implement! return ""; } + + virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, + bool Enabled) const { + if (Name == "soft-float" || Name == "single-float") { + Features[Name] = Enabled; + return true; + } + return false; + } + + virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + SoftFloat = false; + SingleFloat = false; + + for (std::vector<std::string>::iterator it = Features.begin(), + ie = Features.end(); it != ie; ++it) { + if (*it == "+single-float") { + SingleFloat = true; + break; + } + + if (*it == "+soft-float") { + SoftFloat = true; + // This option is front-end specific. + // Do not need to pass it to the backend. + Features.erase(it); + break; + } + } + } }; class Mips32TargetInfoBase : public MipsTargetInfoBase { public: Mips32TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "o32") {} + MipsTargetInfoBase(triple, "o32", "mips32") { + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + } virtual bool setABI(const std::string &Name) { if ((Name == "o32") || (Name == "eabi")) { ABI = Name; @@ -3237,6 +3591,8 @@ public: } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + if (ABI == "o32") { Builder.defineMacro("__mips_o32"); Builder.defineMacro("_ABIO32", "1"); @@ -3278,8 +3634,8 @@ public: { { "k0" }, "$26" }, { { "k1" }, "$27" }, { { "gp" }, "$28" }, - { { "sp" }, "$29" }, - { { "fp" }, "$30" }, + { { "sp","$sp" }, "$29" }, + { { "fp","$fp" }, "$30" }, { { "ra" }, "$31" } }; Aliases = GCCRegAliases; @@ -3307,6 +3663,7 @@ public: class Mips32ELTargetInfo : public Mips32TargetInfoBase { public: Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { + BigEndian = false; 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"; } @@ -3325,17 +3682,32 @@ class Mips64TargetInfoBase : public MipsTargetInfoBase { virtual void SetDescriptionString(const std::string &Name) = 0; public: Mips64TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "n64") {} + MipsTargetInfoBase(triple, "n64", "mips64") { + LongWidth = LongAlign = 64; + PointerWidth = PointerAlign = 64; + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + SuitableAlign = 128; + } virtual bool setABI(const std::string &Name) { SetDescriptionString(Name); - if ((Name == "n32") || (Name == "n64")) { - ABI = Name; - return true; - } else + + if (Name != "n32" && Name != "n64") return false; + + ABI = Name; + + if (Name == "n32") { + LongWidth = LongAlign = 32; + PointerWidth = PointerAlign = 32; + } + + return true; } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + if (ABI == "n32") { Builder.defineMacro("__mips_n32"); Builder.defineMacro("_ABIN32", "2"); @@ -3380,8 +3752,8 @@ public: { { "k0" }, "$26" }, { { "k1" }, "$27" }, { { "gp" }, "$28" }, - { { "sp" }, "$29" }, - { { "fp" }, "$30" }, + { { "sp","$sp" }, "$29" }, + { { "fp","$fp" }, "$30" }, { { "ra" }, "$31" } }; Aliases = GCCRegAliases; @@ -3394,13 +3766,15 @@ class Mips64EBTargetInfo : public Mips64TargetInfoBase { // 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"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "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"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "v64:64:64-n32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -3418,13 +3792,16 @@ class Mips64ELTargetInfo : public Mips64TargetInfoBase { // 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"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128" + "-v64:64:64-n32"; } public: Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { - // Default ABI is n64. + // Default ABI is n64. + BigEndian = false; 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"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "v64:64:64-n32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -3442,6 +3819,7 @@ namespace { class PNaClTargetInfo : public TargetInfo { public: PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; this->UserLabelPrefix = ""; this->LongAlign = 32; this->LongWidth = 32; @@ -3477,9 +3855,13 @@ public: if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); + Builder.defineMacro("__LITTLE_ENDIAN__"); Builder.defineMacro("__native_client__"); getArchDefines(Opts, Builder); } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "pnacl"; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { } @@ -3526,6 +3908,9 @@ static TargetInfo *AllocateTarget(const std::string &T) { default: return NULL; + case llvm::Triple::hexagon: + return new HexagonTargetInfo(T); + case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSDarwin()) @@ -3544,11 +3929,6 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new ARMTargetInfo(T); } - case llvm::Triple::bfin: - if ( os == llvm::Triple::RTEMS ) - return new RTEMSTargetInfo<BlackfinTargetInfo>(T); - return new BlackfinTargetInfo(T); - case llvm::Triple::msp430: return new MSP430TargetInfo(T); @@ -3676,9 +4056,6 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::cellspu: return new PS3SPUTargetInfo<PPC64TargetInfo>(T); - case llvm::Triple::systemz: - return new SystemZTargetInfo(T); - case llvm::Triple::tce: return new TCETargetInfo(T); @@ -3694,7 +4071,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::DragonFly: return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<X86_32TargetInfo>(T); + return new NetBSDI386TargetInfo(T); case llvm::Triple::OpenBSD: return new OpenBSDI386TargetInfo(T); case llvm::Triple::FreeBSD: @@ -3753,7 +4130,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(Opts.Triple); // Construct the target - llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); + OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); if (!Target) { Diags.Report(diag::err_target_unknown_triple) << Triple.str(); return 0; @@ -3821,8 +4198,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Opts.Features.clear(); for (llvm::StringMap<bool>::const_iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) - Opts.Features.push_back(std::string(it->second ? "+" : "-") + - it->first().str()); + Opts.Features.push_back((it->second ? "+" : "-") + it->first().str()); Target->HandleTargetFeatures(Opts.Features); return Target.take(); |