diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 2173 |
1 files changed, 1240 insertions, 933 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index f7c8c9c49e84..bccd0d72d8f5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -73,7 +73,7 @@ protected: virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const=0; public: - OSTargetInfo(const std::string& triple) : TgtInfo(triple) {} + OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {} virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { TgtInfo::getTargetDefines(Opts, Builder); @@ -88,7 +88,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, StringRef &PlatformName, VersionTuple &PlatformMinVersion) { - Builder.defineMacro("__APPLE_CC__", "5621"); + Builder.defineMacro("__APPLE_CC__", "6000"); Builder.defineMacro("__APPLE__"); Builder.defineMacro("__MACH__"); Builder.defineMacro("OBJC_NEW_PROPERTIES"); @@ -138,31 +138,37 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, return; } - // Set the appropriate OS version define. - if (Triple.getOS() == llvm::Triple::IOS) { - assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[6]; - Str[0] = '0' + Maj; - Str[1] = '0' + (Min / 10); - Str[2] = '0' + (Min % 10); - Str[3] = '0' + (Rev / 10); - Str[4] = '0' + (Rev % 10); - Str[5] = '\0'; - Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); - } else { - // Note that the Driver allows versions which aren't representable in the - // define (because we only get a single digit for the minor and micro - // revision numbers). So, we limit them to the maximum representable - // version. - assert(Triple.getEnvironmentName().empty() && "Invalid environment!"); - assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[5]; - Str[0] = '0' + (Maj / 10); - Str[1] = '0' + (Maj % 10); - Str[2] = '0' + std::min(Min, 9U); - Str[3] = '0' + std::min(Rev, 9U); - Str[4] = '\0'; - Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); + // If there's an environment specified in the triple, that means we're dealing + // with an embedded variant of some sort and don't want the platform + // version-min defines, so only add them if there's not one. + if (Triple.getEnvironmentName().empty()) { + // Set the appropriate OS version define. + if (Triple.isiOS()) { + assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[6]; + Str[0] = '0' + Maj; + Str[1] = '0' + (Min / 10); + Str[2] = '0' + (Min % 10); + Str[3] = '0' + (Rev / 10); + Str[4] = '0' + (Rev % 10); + Str[5] = '\0'; + Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", + Str); + } else { + // Note that the Driver allows versions which aren't representable in the + // define (because we only get a single digit for the minor and micro + // revision numbers). So, we limit them to the maximum representable + // version. + assert(Triple.getEnvironmentName().empty() && "Invalid environment!"); + assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[5]; + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + std::min(Min, 9U); + Str[3] = '0' + std::min(Rev, 9U); + Str[4] = '\0'; + Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); + } } PlatformMinVersion = VersionTuple(Maj, Min, Rev); @@ -179,12 +185,10 @@ protected: } public: - DarwinTargetInfo(const std::string& triple) : - OSTargetInfo<Target>(triple) { - llvm::Triple T = llvm::Triple(triple); - this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7); - this->MCountName = "\01mcount"; - } + DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->TLSSupported = Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 7); + this->MCountName = "\01mcount"; + } virtual std::string isValidSectionSpecifier(StringRef SR) const { // Let MCSectionMachO validate this. @@ -224,18 +228,17 @@ protected: DefineStd(Builder, "unix", Opts); } public: - DragonFlyBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; + DragonFlyBSDTargetInfo(const llvm::Triple &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; - } + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + } } }; @@ -256,31 +259,57 @@ protected: Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); DefineStd(Builder, "unix", Opts); Builder.defineMacro("__ELF__"); + + // On FreeBSD, wchar_t contains the number of the code point as + // used by the character set of the locale. These character sets are + // not necessarily a superset of ASCII. + Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1"); } public: - FreeBSDTargetInfo(const std::string &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; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - this->MCountName = "_mcount"; - break; - case llvm::Triple::arm: - this->MCountName = "__mcount"; - break; - } + FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + this->MCountName = "_mcount"; + break; + case llvm::Triple::arm: + this->MCountName = "__mcount"; + break; } + } +}; + +// GNU/kFreeBSD Target +template<typename Target> +class KFreeBSDTargetInfo : public OSTargetInfo<Target> { +protected: + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const { + // GNU/kFreeBSD defines; list based off of gcc output + + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__FreeBSD_kernel__"); + Builder.defineMacro("__GLIBC__"); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + } +public: + KFreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + } }; // Minix Target @@ -302,10 +331,9 @@ protected: DefineStd(Builder, "unix", Opts); } public: - MinixTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; - } + MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + } }; // Linux target @@ -327,8 +355,7 @@ protected: Builder.defineMacro("_GNU_SOURCE"); } public: - LinuxTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; this->WIntType = TargetInfo::UnsignedInt; } @@ -352,10 +379,9 @@ protected: Builder.defineMacro("_POSIX_THREADS"); } public: - NetBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; - } + NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + } }; // OpenBSD Target @@ -373,12 +399,10 @@ protected: Builder.defineMacro("_REENTRANT"); } public: - OpenBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; - this->TLSSupported = false; + OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + this->TLSSupported = false; - llvm::Triple Triple(triple); switch (Triple.getArch()) { default: case llvm::Triple::x86: @@ -412,11 +436,10 @@ protected: Builder.defineMacro("_REENTRANT"); } public: - BitrigTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; - this->TLSSupported = false; - this->MCountName = "__mcount"; + BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + this->TLSSupported = false; + this->MCountName = "__mcount"; } }; @@ -433,8 +456,7 @@ protected: Builder.defineMacro("__ELF__"); } public: - PSPTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; } }; @@ -455,8 +477,7 @@ protected: Builder.defineMacro("__powerpc64__"); } public: - PS3PPUTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; this->LongWidth = this->LongAlign = 32; this->PointerWidth = this->PointerAlign = 32; @@ -481,8 +502,7 @@ protected: Builder.defineMacro("__ELF__"); } public: - PS3SPUTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + PS3SPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; } }; @@ -500,8 +520,8 @@ protected: Builder.defineMacro("__SVR4"); } public: - AuroraUXTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + AuroraUXTargetInfo(const llvm::Triple &Triple) + : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; this->WCharType = this->SignedLong; // FIXME: WIntType should be SignedLong @@ -535,8 +555,7 @@ protected: Builder.defineMacro("_REENTRANT"); } public: - SolarisTargetInfo(const std::string& triple) - : OSTargetInfo<Target>(triple) { + SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; this->WCharType = this->SignedInt; // FIXME: WIntType should be SignedLong @@ -586,13 +605,13 @@ protected: } public: - WindowsTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + WindowsTargetInfo(const llvm::Triple &Triple) + : OSTargetInfo<Target>(Triple) {} }; template <typename Target> class NaClTargetInfo : public OSTargetInfo<Target> { - protected: +protected: virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const { if (Opts.POSIXThreads) @@ -604,9 +623,9 @@ class NaClTargetInfo : public OSTargetInfo<Target> { Builder.defineMacro("__ELF__"); Builder.defineMacro("__native_client__"); } - public: - NaClTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { + +public: + NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; this->LongAlign = 32; this->LongWidth = 32; @@ -645,8 +664,14 @@ class PPCTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; + + // Target cpu features. + bool HasVSX; + public: - PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { + PPCTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), HasVSX(false) { + BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; } @@ -718,6 +743,8 @@ public: .Case("ppc", true) .Case("powerpc64", true) .Case("ppc64", true) + .Case("powerpc64le", true) + .Case("ppc64le", true) .Default(false); if (CPUKnown) @@ -739,10 +766,8 @@ public: virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const; - + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags); virtual bool hasFeature(StringRef Feature) const; virtual void getGCCRegNames(const char * const *&Names, @@ -864,6 +889,29 @@ const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { #include "clang/Basic/BuiltinsPPC.def" }; + /// handleTargetFeatures - Perform initialization based on the user +/// configured set of features. +bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + // Remember the maximum enabled sselevel. + for (unsigned i = 0, e = Features.size(); i !=e; ++i) { + // Ignore disabled features. + if (Features[i][0] == '-') + continue; + + StringRef Feature = StringRef(Features[i]).substr(1); + + if (Feature == "vsx") { + HasVSX = true; + continue; + } + + // TODO: Finish this list and add an assert that we've handled them + // all. + } + + return true; +} /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific /// #defines that are not tied to a specific subtarget. @@ -871,6 +919,7 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. Builder.defineMacro("__ppc__"); + Builder.defineMacro("__PPC__"); Builder.defineMacro("_ARCH_PPC"); Builder.defineMacro("__powerpc__"); Builder.defineMacro("__POWERPC__"); @@ -878,22 +927,27 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_ARCH_PPC64"); Builder.defineMacro("__powerpc64__"); Builder.defineMacro("__ppc64__"); - } else { - Builder.defineMacro("__ppc__"); + Builder.defineMacro("__PPC64__"); } // Target properties. - if (getTriple().getOS() != llvm::Triple::NetBSD && - getTriple().getOS() != llvm::Triple::OpenBSD) - Builder.defineMacro("_BIG_ENDIAN"); - Builder.defineMacro("__BIG_ENDIAN__"); + if (getTriple().getArch() == llvm::Triple::ppc64le) { + Builder.defineMacro("_LITTLE_ENDIAN"); + Builder.defineMacro("__LITTLE_ENDIAN__"); + } else { + if (getTriple().getOS() != llvm::Triple::NetBSD && + getTriple().getOS() != llvm::Triple::OpenBSD) + Builder.defineMacro("_BIG_ENDIAN"); + Builder.defineMacro("__BIG_ENDIAN__"); + } // Subtarget options. Builder.defineMacro("__NATURAL_ALIGNMENT__"); Builder.defineMacro("__REGISTER_PREFIX__", ""); // FIXME: Should be controlled by command line option. - Builder.defineMacro("__LONG_DOUBLE_128__"); + if (LongDoubleWidth == 128) + Builder.defineMacro("__LONG_DOUBLE_128__"); if (Opts.AltiVec) { Builder.defineMacro("__VEC__", "10206"); @@ -988,13 +1042,15 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__TOS_BGQ__"); } + if (HasVSX) + Builder.defineMacro("__VSX__"); + // FIXME: The following are not yet generated here by Clang, but are // generated by GCC: // // _SOFT_FLOAT_ // __RECIP_PRECISION__ // __APPLE_ALTIVEC__ - // __VSX__ // __RECIP__ // __RECIPF__ // __RSQRTE__ @@ -1021,23 +1077,12 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { .Case("pwr6", true) .Case("pwr7", true) .Case("ppc64", true) + .Case("ppc64le", true) .Default(false); Features["qpx"] = (CPU == "a2q"); } -bool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" || - Name == "popcntd" || Name == "qpx") { - Features[Name] = Enabled; - return true; - } - - return false; -} - bool PPCTargetInfo::hasFeature(StringRef Feature) const { return Feature == "powerpc"; } @@ -1150,7 +1195,7 @@ void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, namespace { class PPC32TargetInfo : public PPCTargetInfo { public: - PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) { + PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { 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"; @@ -1182,10 +1227,12 @@ public: }; } // end anonymous namespace. +// Note: ABI differences may eventually require us to have a separate +// TargetInfo for little endian. namespace { class PPC64TargetInfo : public PPCTargetInfo { public: - PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { + PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; @@ -1195,7 +1242,7 @@ public: LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; 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-f128:64:64-" + "i64:64:64-f32:32:32-f64:64:64-" "v128:128:128-n32:64"; } else DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -1216,10 +1263,11 @@ namespace { class DarwinPPC32TargetInfo : public DarwinTargetInfo<PPC32TargetInfo> { public: - DarwinPPC32TargetInfo(const std::string& triple) - : DarwinTargetInfo<PPC32TargetInfo>(triple) { + DarwinPPC32TargetInfo(const llvm::Triple &Triple) + : DarwinTargetInfo<PPC32TargetInfo>(Triple) { HasAlignMac68kSupport = true; BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool? + PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 LongLongAlign = 32; SuitableAlign = 128; DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -1233,8 +1281,8 @@ public: class DarwinPPC64TargetInfo : public DarwinTargetInfo<PPC64TargetInfo> { public: - DarwinPPC64TargetInfo(const std::string& triple) - : DarwinTargetInfo<PPC64TargetInfo>(triple) { + DarwinPPC64TargetInfo(const llvm::Triple &Triple) + : DarwinTargetInfo<PPC64TargetInfo>(Triple) { HasAlignMac68kSupport = true; SuitableAlign = 128; DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -1255,13 +1303,13 @@ namespace { class NVPTXTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; - std::vector<StringRef> AvailableFeatures; public: - NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) { + NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &NVPTXAddrSpaceMap; + UseAddrSpaceMapMangling = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; @@ -1289,9 +1337,18 @@ namespace { NumAliases = 0; } virtual bool validateAsmConstraint(const char *&Name, - TargetInfo::ConstraintInfo &info) const { - // FIXME: implement - return true; + TargetInfo::ConstraintInfo &Info) const { + switch (*Name) { + default: return false; + case 'c': + case 'h': + case 'r': + case 'l': + case 'f': + case 'd': + Info.setAllowsRegister(); + return true; + } } virtual const char *getClobbers() const { // FIXME: Is this really right? @@ -1311,9 +1368,6 @@ namespace { return Valid; } - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const; }; const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { @@ -1333,21 +1387,9 @@ namespace { NumNames = llvm::array_lengthof(GCCRegNames); } - bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), - Name)) { - Features[Name] = Enabled; - return true; - } else { - return false; - } - } - class NVPTX32TargetInfo : public NVPTXTargetInfo { public: - NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { + NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { PointerWidth = PointerAlign = 32; SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt; DescriptionString @@ -1359,7 +1401,7 @@ namespace { class NVPTX64TargetInfo : public NVPTXTargetInfo { public: - NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { + NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { PointerWidth = PointerAlign = 64; SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong; DescriptionString @@ -1400,6 +1442,7 @@ static const char *DescriptionStringR600DoubleOps = static const char *DescriptionStringSI = "e" "-p:64:64:64" + "-p3:32:32:32" "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64" "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" @@ -1417,15 +1460,16 @@ class R600TargetInfo : public TargetInfo { GK_EVERGREEN_DOUBLE_OPS, GK_NORTHERN_ISLANDS, GK_CAYMAN, - GK_SOUTHERN_ISLANDS + GK_SOUTHERN_ISLANDS, + GK_SEA_ISLANDS } GPU; public: - R600TargetInfo(const std::string& triple) - : TargetInfo(triple), - GPU(GK_R600) { + R600TargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), GPU(GK_R600) { DescriptionString = DescriptionStringR600; AddrSpaceMap = &R600AddrSpaceMap; + UseAddrSpaceMapMangling = true; } virtual const char * getClobbers() const { @@ -1496,6 +1540,10 @@ public: .Case("pitcairn", GK_SOUTHERN_ISLANDS) .Case("verde", GK_SOUTHERN_ISLANDS) .Case("oland", GK_SOUTHERN_ISLANDS) + .Case("bonaire", GK_SEA_ISLANDS) + .Case("kabini", GK_SEA_ISLANDS) + .Case("kaveri", GK_SEA_ISLANDS) + .Case("hawaii", GK_SEA_ISLANDS) .Default(GK_NONE); if (GPU == GK_NONE) { @@ -1518,6 +1566,7 @@ public: DescriptionString = DescriptionStringR600DoubleOps; break; case GK_SOUTHERN_ISLANDS: + case GK_SEA_ISLANDS: DescriptionString = DescriptionStringSI; break; } @@ -1529,137 +1578,6 @@ public: } // end anonymous namespace namespace { -// MBlaze abstract base class -class MBlazeTargetInfo : public TargetInfo { - static const char * const GCCRegNames[]; - static const TargetInfo::GCCRegAlias GCCRegAliases[]; - -public: - MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) { - DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16"; - } - - virtual void getTargetBuiltins(const Builtin::Info *&Records, - unsigned &NumRecords) const { - // FIXME: Implement. - Records = 0; - NumRecords = 0; - } - - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const; - - virtual bool hasFeature(StringRef Feature) const { - return Feature == "mblaze"; - } - - virtual BuiltinVaListKind getBuiltinVaListKind() const { - return TargetInfo::CharPtrBuiltinVaList; - } - virtual const char *getTargetPrefix() const { - return "mblaze"; - } - 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 { - switch (*Name) { - default: return false; - case 'O': // Zero - return true; - case 'b': // Base register - case 'f': // Floating point register - Info.setAllowsRegister(); - return true; - } - } - virtual const char *getClobbers() const { - return ""; - } -}; - -/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific -/// #defines that are not tied to a specific subtarget. -void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - // Target identification. - Builder.defineMacro("__microblaze__"); - Builder.defineMacro("_ARCH_MICROBLAZE"); - Builder.defineMacro("__MICROBLAZE__"); - - // Target properties. - Builder.defineMacro("_BIG_ENDIAN"); - Builder.defineMacro("__BIG_ENDIAN__"); - - // Subtarget options. - Builder.defineMacro("__REGISTER_PREFIX__", ""); -} - - -const char * const MBlazeTargetInfo::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", - "$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", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4", - "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp" -}; - -void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - Names = GCCRegNames; - NumNames = llvm::array_lengthof(GCCRegNames); -} - -const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = { - { {"f0"}, "r0" }, - { {"f1"}, "r1" }, - { {"f2"}, "r2" }, - { {"f3"}, "r3" }, - { {"f4"}, "r4" }, - { {"f5"}, "r5" }, - { {"f6"}, "r6" }, - { {"f7"}, "r7" }, - { {"f8"}, "r8" }, - { {"f9"}, "r9" }, - { {"f10"}, "r10" }, - { {"f11"}, "r11" }, - { {"f12"}, "r12" }, - { {"f13"}, "r13" }, - { {"f14"}, "r14" }, - { {"f15"}, "r15" }, - { {"f16"}, "r16" }, - { {"f17"}, "r17" }, - { {"f18"}, "r18" }, - { {"f19"}, "r19" }, - { {"f20"}, "r20" }, - { {"f21"}, "r21" }, - { {"f22"}, "r22" }, - { {"f23"}, "r23" }, - { {"f24"}, "r24" }, - { {"f25"}, "r25" }, - { {"f26"}, "r26" }, - { {"f27"}, "r27" }, - { {"f28"}, "r28" }, - { {"f29"}, "r29" }, - { {"f30"}, "r30" }, - { {"f31"}, "r31" }, -}; - -void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const { - Aliases = GCCRegAliases; - NumAliases = llvm::array_lengthof(GCCRegAliases); -} -} // end anonymous namespace. - -namespace { // Namespace for x86 abstract base class const Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, @@ -1695,11 +1613,17 @@ const TargetInfo::AddlRegName AddlRegNames[] = { // most of the implementation can be shared. class X86TargetInfo : public TargetInfo { enum X86SSEEnum { - NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 + NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F } SSELevel; enum MMX3DNowEnum { NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon } MMX3DNowLevel; + enum XOPEnum { + NoXOP, + SSE4A, + FMA4, + XOP + } XOPLevel; bool HasAES; bool HasPCLMUL; @@ -1711,11 +1635,12 @@ class X86TargetInfo : public TargetInfo { bool HasRTM; bool HasPRFCHW; bool HasRDSEED; - bool HasSSE4a; - bool HasFMA4; + bool HasTBM; bool HasFMA; - bool HasXOP; bool HasF16C; + bool HasAVX512CD, HasAVX512ER, HasAVX512PF; + bool HasSHA; + bool HasCX16; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// @@ -1789,6 +1714,7 @@ class X86TargetInfo : public TargetInfo { /// Atom processors //@{ CK_Atom, + CK_Silvermont, //@} /// \name Nehalem @@ -1800,6 +1726,10 @@ class X86TargetInfo : public TargetInfo { CK_CoreAVX2, //@} + /// \name Knights Landing + /// Knights Landing processor. + CK_KNL, + /// \name K6 /// K6 architecture processors. //@{ @@ -1843,6 +1773,7 @@ class X86TargetInfo : public TargetInfo { //@{ CK_BDVER1, CK_BDVER2, + CK_BDVER3, //@} /// This specification is deprecated and will be removed in the future. @@ -1858,13 +1789,21 @@ class X86TargetInfo : public TargetInfo { //@} } CPU; + enum FPMathKind { + FP_Default, + FP_SSE, + FP_387 + } FPMath; + public: - X86TargetInfo(const std::string& triple) - : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), - HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false), - HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false), - HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false), - HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) { + X86TargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), + XOPLevel(NoXOP), HasAES(false), HasPCLMUL(false), HasLZCNT(false), + HasRDRND(false), HasBMI(false), HasBMI2(false), HasPOPCNT(false), + HasRTM(false), HasPRFCHW(false), HasRDSEED(false), HasTBM(false), + HasFMA(false), HasF16C(false), HasAVX512CD(false), HasAVX512ER(false), + HasAVX512PF(false), HasSHA(false), HasCX16(false), CPU(CK_Generic), + FPMath(FP_Default) { BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } @@ -1900,12 +1839,24 @@ public: } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const; + static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, + bool Enabled); + static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level, + bool Enabled); + static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, + bool Enabled); + virtual void setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + setFeatureEnabledImpl(Features, Name, Enabled); + } + // This exists purely to cut down on the number of virtual calls in + // getDefaultFeatures which calls this repeatedly. + static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled); virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; virtual bool hasFeature(StringRef Feature) const; - virtual void HandleTargetFeatures(std::vector<std::string> &Features); + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags); virtual const char* getABI() const { if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) return "avx"; @@ -1939,10 +1890,12 @@ public: .Case("core2", CK_Core2) .Case("penryn", CK_Penryn) .Case("atom", CK_Atom) + .Case("slm", CK_Silvermont) .Case("corei7", CK_Corei7) .Case("corei7-avx", CK_Corei7AVX) .Case("core-avx-i", CK_CoreAVXi) .Case("core-avx2", CK_CoreAVX2) + .Case("knl", CK_KNL) .Case("k6", CK_K6) .Case("k6-2", CK_K6_2) .Case("k6-3", CK_K6_3) @@ -1963,6 +1916,7 @@ public: .Case("btver2", CK_BTVER2) .Case("bdver1", CK_BDVER1) .Case("bdver2", CK_BDVER2) + .Case("bdver3", CK_BDVER3) .Case("x86-64", CK_x86_64) .Case("geode", CK_Geode) .Default(CK_Generic); @@ -2013,10 +1967,12 @@ public: case CK_Core2: case CK_Penryn: case CK_Atom: + case CK_Silvermont: case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: case CK_CoreAVX2: + case CK_KNL: case CK_Athlon64: case CK_Athlon64SSE3: case CK_AthlonFX: @@ -2029,12 +1985,15 @@ public: case CK_BTVER2: case CK_BDVER1: case CK_BDVER2: + case CK_BDVER3: case CK_x86_64: return true; } llvm_unreachable("Unhandled CPU kind"); } + virtual bool setFPMath(StringRef Name); + virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { // We accept all non-ARM calling conventions return (CC == CC_X86ThisCall || @@ -2050,40 +2009,24 @@ public: } }; -void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { - // FIXME: This should not be here. - Features["3dnow"] = false; - Features["3dnowa"] = false; - Features["mmx"] = false; - Features["sse"] = false; - Features["sse2"] = false; - Features["sse3"] = false; - Features["ssse3"] = false; - Features["sse41"] = false; - Features["sse42"] = false; - Features["sse4a"] = false; - Features["aes"] = false; - Features["pclmul"] = false; - Features["avx"] = false; - Features["avx2"] = false; - Features["lzcnt"] = false; - Features["rdrand"] = false; - Features["bmi"] = false; - Features["bmi2"] = false; - Features["popcnt"] = false; - Features["rtm"] = false; - Features["prfchw"] = false; - Features["rdseed"] = false; - Features["fma4"] = false; - Features["fma"] = false; - Features["xop"] = false; - Features["f16c"] = false; +bool X86TargetInfo::setFPMath(StringRef Name) { + if (Name == "387") { + FPMath = FP_387; + return true; + } + if (Name == "sse") { + FPMath = FP_SSE; + return true; + } + return false; +} +void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { // FIXME: This *really* should not be here. // X86_64 always has SSE2. if (getTriple().getArch() == llvm::Triple::x86_64) - setFeatureEnabled(Features, "sse2", true); + setFeatureEnabledImpl(Features, "sse2", true); switch (CPU) { case CK_Generic: @@ -2096,295 +2039,349 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { break; case CK_PentiumMMX: case CK_Pentium2: - setFeatureEnabled(Features, "mmx", true); + setFeatureEnabledImpl(Features, "mmx", true); break; case CK_Pentium3: case CK_Pentium3M: - setFeatureEnabled(Features, "sse", true); + setFeatureEnabledImpl(Features, "sse", true); break; case CK_PentiumM: case CK_Pentium4: case CK_Pentium4M: case CK_x86_64: - setFeatureEnabled(Features, "sse2", true); + setFeatureEnabledImpl(Features, "sse2", true); break; case CK_Yonah: case CK_Prescott: case CK_Nocona: - setFeatureEnabled(Features, "sse3", true); + setFeatureEnabledImpl(Features, "sse3", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_Core2: - setFeatureEnabled(Features, "ssse3", true); + setFeatureEnabledImpl(Features, "ssse3", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_Penryn: - setFeatureEnabled(Features, "sse4.1", true); + setFeatureEnabledImpl(Features, "sse4.1", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_Atom: - setFeatureEnabled(Features, "ssse3", true); + setFeatureEnabledImpl(Features, "ssse3", true); + setFeatureEnabledImpl(Features, "cx16", true); + break; + case CK_Silvermont: + setFeatureEnabledImpl(Features, "sse4.2", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "cx16", true); + setFeatureEnabledImpl(Features, "pclmul", true); break; case CK_Corei7: - setFeatureEnabled(Features, "sse4", true); + setFeatureEnabledImpl(Features, "sse4.2", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_Corei7AVX: - setFeatureEnabled(Features, "avx", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "avx", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "cx16", true); + setFeatureEnabledImpl(Features, "pclmul", true); break; case CK_CoreAVXi: - setFeatureEnabled(Features, "avx", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); - setFeatureEnabled(Features, "rdrnd", true); - setFeatureEnabled(Features, "f16c", true); + setFeatureEnabledImpl(Features, "avx", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "rdrnd", true); + setFeatureEnabledImpl(Features, "f16c", true); break; case CK_CoreAVX2: - setFeatureEnabled(Features, "avx2", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "rdrnd", true); - setFeatureEnabled(Features, "f16c", true); - setFeatureEnabled(Features, "bmi", true); - setFeatureEnabled(Features, "bmi2", true); - setFeatureEnabled(Features, "rtm", true); - setFeatureEnabled(Features, "fma", true); + setFeatureEnabledImpl(Features, "avx2", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "rdrnd", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "bmi2", true); + setFeatureEnabledImpl(Features, "rtm", true); + setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "cx16", true); + break; + case CK_KNL: + setFeatureEnabledImpl(Features, "avx512f", true); + setFeatureEnabledImpl(Features, "avx512cd", true); + setFeatureEnabledImpl(Features, "avx512er", true); + setFeatureEnabledImpl(Features, "avx512pf", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "rdrnd", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "bmi2", true); + setFeatureEnabledImpl(Features, "rtm", true); + setFeatureEnabledImpl(Features, "fma", true); break; case CK_K6: case CK_WinChipC6: - setFeatureEnabled(Features, "mmx", true); + setFeatureEnabledImpl(Features, "mmx", true); break; case CK_K6_2: case CK_K6_3: case CK_WinChip2: case CK_C3: - setFeatureEnabled(Features, "3dnow", true); + setFeatureEnabledImpl(Features, "3dnow", true); break; case CK_Athlon: case CK_AthlonThunderbird: case CK_Geode: - setFeatureEnabled(Features, "3dnowa", true); + setFeatureEnabledImpl(Features, "3dnowa", true); break; case CK_Athlon4: case CK_AthlonXP: case CK_AthlonMP: - setFeatureEnabled(Features, "sse", true); - setFeatureEnabled(Features, "3dnowa", true); + setFeatureEnabledImpl(Features, "sse", true); + setFeatureEnabledImpl(Features, "3dnowa", true); break; case CK_K8: case CK_Opteron: case CK_Athlon64: case CK_AthlonFX: - setFeatureEnabled(Features, "sse2", true); - setFeatureEnabled(Features, "3dnowa", true); + setFeatureEnabledImpl(Features, "sse2", true); + setFeatureEnabledImpl(Features, "3dnowa", true); break; case CK_K8SSE3: case CK_OpteronSSE3: case CK_Athlon64SSE3: - setFeatureEnabled(Features, "sse3", true); - setFeatureEnabled(Features, "3dnowa", true); + setFeatureEnabledImpl(Features, "sse3", true); + setFeatureEnabledImpl(Features, "3dnowa", true); break; case CK_AMDFAM10: - setFeatureEnabled(Features, "sse3", true); - setFeatureEnabled(Features, "sse4a", true); - setFeatureEnabled(Features, "3dnowa", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "popcnt", true); + setFeatureEnabledImpl(Features, "sse3", true); + setFeatureEnabledImpl(Features, "sse4a", true); + setFeatureEnabledImpl(Features, "3dnowa", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "popcnt", true); break; case CK_BTVER1: - setFeatureEnabled(Features, "ssse3", true); - setFeatureEnabled(Features, "sse4a", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "popcnt", true); + setFeatureEnabledImpl(Features, "ssse3", true); + setFeatureEnabledImpl(Features, "sse4a", true); + setFeatureEnabledImpl(Features, "cx16", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "popcnt", true); + setFeatureEnabledImpl(Features, "prfchw", true); break; case CK_BTVER2: - setFeatureEnabled(Features, "avx", true); - setFeatureEnabled(Features, "sse4a", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); - setFeatureEnabled(Features, "bmi", true); - setFeatureEnabled(Features, "f16c", true); + setFeatureEnabledImpl(Features, "avx", true); + setFeatureEnabledImpl(Features, "sse4a", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "prfchw", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_BDVER1: - setFeatureEnabled(Features, "xop", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "xop", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "prfchw", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_BDVER2: - setFeatureEnabled(Features, "xop", true); - setFeatureEnabled(Features, "lzcnt", true); - setFeatureEnabled(Features, "aes", true); - setFeatureEnabled(Features, "pclmul", true); - setFeatureEnabled(Features, "bmi", true); - setFeatureEnabled(Features, "fma", true); - setFeatureEnabled(Features, "f16c", true); + case CK_BDVER3: + setFeatureEnabledImpl(Features, "xop", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "prfchw", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "tbm", true); + setFeatureEnabledImpl(Features, "cx16", true); break; case CK_C3_2: - setFeatureEnabled(Features, "sse", true); + setFeatureEnabledImpl(Features, "sse", true); break; } } -bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - // FIXME: This *really* should not be here. We need some way of translating - // options into llvm subtarget features. - if (!Features.count(Name) && - (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" && - Name != "rdrnd")) - return false; +void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features, + X86SSEEnum Level, bool Enabled) { + if (Enabled) { + switch (Level) { + case AVX512F: + Features["avx512f"] = true; + case AVX2: + Features["avx2"] = true; + case AVX: + Features["avx"] = true; + case SSE42: + Features["sse4.2"] = true; + case SSE41: + Features["sse4.1"] = true; + case SSSE3: + Features["ssse3"] = true; + case SSE3: + Features["sse3"] = true; + case SSE2: + Features["sse2"] = true; + case SSE1: + Features["sse"] = true; + case NoSSE: + break; + } + return; + } - // FIXME: this should probably use a switch with fall through. + switch (Level) { + case NoSSE: + case SSE1: + Features["sse"] = false; + case SSE2: + Features["sse2"] = Features["pclmul"] = Features["aes"] = + Features["sha"] = false; + case SSE3: + Features["sse3"] = false; + setXOPLevel(Features, NoXOP, false); + case SSSE3: + Features["ssse3"] = false; + case SSE41: + Features["sse4.1"] = false; + case SSE42: + Features["sse4.2"] = false; + case AVX: + Features["fma"] = Features["avx"] = Features["f16c"] = false; + setXOPLevel(Features, FMA4, false); + case AVX2: + Features["avx2"] = false; + case AVX512F: + Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = + Features["avx512pf"] = false; + } +} +void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features, + MMX3DNowEnum Level, bool Enabled) { if (Enabled) { - if (Name == "mmx") + switch (Level) { + case AMD3DNowAthlon: + Features["3dnowa"] = true; + case AMD3DNow: + Features["3dnow"] = true; + case MMX: Features["mmx"] = true; - else if (Name == "sse") - Features["mmx"] = Features["sse"] = true; - else if (Name == "sse2") - Features["mmx"] = Features["sse"] = Features["sse2"] = true; - else if (Name == "sse3") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - true; - else if (Name == "ssse3") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = true; - else if (Name == "sse4" || Name == "sse4.2") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - 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; - else if (Name == "3dnow") - Features["mmx"] = Features["3dnow"] = true; - else if (Name == "3dnowa") - Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true; - else if (Name == "aes") - Features["sse"] = Features["sse2"] = Features["aes"] = true; - else if (Name == "pclmul") - Features["sse"] = Features["sse2"] = Features["pclmul"] = true; - else if (Name == "avx") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = - 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 == "fma") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["popcnt"] = Features["avx"] = Features["fma"] = true; - else if (Name == "fma4") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["popcnt"] = Features["avx"] = Features["sse4a"] = - Features["fma4"] = true; - else if (Name == "xop") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["popcnt"] = Features["avx"] = Features["sse4a"] = - Features["fma4"] = Features["xop"] = true; - else if (Name == "sse4a") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["sse4a"] = true; - else if (Name == "lzcnt") - Features["lzcnt"] = true; - else if (Name == "rdrnd") - Features["rdrand"] = 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 == "f16c") - Features["f16c"] = true; - else if (Name == "rtm") - Features["rtm"] = true; - else if (Name == "prfchw") - Features["prfchw"] = true; - else if (Name == "rdseed") - Features["rdseed"] = 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"] = - Features["sse4a"] = Features["avx"] = Features["avx2"] = - Features["fma"] = Features["fma4"] = Features["aes"] = - Features["pclmul"] = Features["xop"] = false; - else if (Name == "sse2") - Features["sse2"] = Features["sse3"] = Features["ssse3"] = - Features["sse41"] = Features["sse42"] = Features["sse4a"] = - Features["avx"] = Features["avx2"] = Features["fma"] = - Features["fma4"] = Features["aes"] = Features["pclmul"] = - Features["xop"] = false; - else if (Name == "sse3") - Features["sse3"] = Features["ssse3"] = Features["sse41"] = - Features["sse42"] = Features["sse4a"] = Features["avx"] = - Features["avx2"] = Features["fma"] = Features["fma4"] = - Features["xop"] = false; - else if (Name == "ssse3") - Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["avx"] = Features["avx2"] = Features["fma"] = false; - else if (Name == "sse4" || Name == "sse4.1") - Features["sse41"] = Features["sse42"] = Features["avx"] = - Features["avx2"] = Features["fma"] = false; - else if (Name == "sse4.2") - Features["sse42"] = Features["avx"] = Features["avx2"] = - Features["fma"] = false; - else if (Name == "3dnow") - Features["3dnow"] = Features["3dnowa"] = false; - else if (Name == "3dnowa") - Features["3dnowa"] = false; - else if (Name == "aes") - Features["aes"] = false; - else if (Name == "pclmul") - Features["pclmul"] = false; - else if (Name == "avx") - Features["avx"] = Features["avx2"] = Features["fma"] = - Features["fma4"] = Features["xop"] = false; - else if (Name == "avx2") - Features["avx2"] = false; - else if (Name == "fma") - Features["fma"] = false; - else if (Name == "sse4a") - Features["sse4a"] = Features["fma4"] = Features["xop"] = false; - else if (Name == "lzcnt") - Features["lzcnt"] = false; - else if (Name == "rdrnd") - Features["rdrand"] = 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"] = Features["xop"] = false; - else if (Name == "xop") - Features["xop"] = false; - else if (Name == "f16c") - Features["f16c"] = false; - else if (Name == "rtm") - Features["rtm"] = false; - else if (Name == "prfchw") - Features["prfchw"] = false; - else if (Name == "rdseed") - Features["rdseed"] = false; + case NoMMX3DNow: + break; + } + return; } - return true; + switch (Level) { + case NoMMX3DNow: + case MMX: + Features["mmx"] = false; + case AMD3DNow: + Features["3dnow"] = false; + case AMD3DNowAthlon: + Features["3dnowa"] = false; + } +} + +void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, + bool Enabled) { + if (Enabled) { + switch (Level) { + case XOP: + Features["xop"] = true; + case FMA4: + Features["fma4"] = true; + setSSELevel(Features, AVX, true); + case SSE4A: + Features["sse4a"] = true; + setSSELevel(Features, SSE3, true); + case NoXOP: + break; + } + return; + } + + switch (Level) { + case NoXOP: + case SSE4A: + Features["sse4a"] = false; + case FMA4: + Features["fma4"] = false; + case XOP: + Features["xop"] = false; + } } -/// HandleTargetOptions - Perform initialization based on the user +void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) { + // FIXME: This *really* should not be here. We need some way of translating + // options into llvm subtarget features. + if (Name == "sse4") + Name = "sse4.2"; + + Features[Name] = Enabled; + + if (Name == "mmx") { + setMMXLevel(Features, MMX, Enabled); + } else if (Name == "sse") { + setSSELevel(Features, SSE1, Enabled); + } else if (Name == "sse2") { + setSSELevel(Features, SSE2, Enabled); + } else if (Name == "sse3") { + setSSELevel(Features, SSE3, Enabled); + } else if (Name == "ssse3") { + setSSELevel(Features, SSSE3, Enabled); + } else if (Name == "sse4.2") { + setSSELevel(Features, SSE42, Enabled); + } else if (Name == "sse4.1") { + setSSELevel(Features, SSE41, Enabled); + } else if (Name == "3dnow") { + setMMXLevel(Features, AMD3DNow, Enabled); + } else if (Name == "3dnowa") { + setMMXLevel(Features, AMD3DNowAthlon, Enabled); + } else if (Name == "aes") { + if (Enabled) + setSSELevel(Features, SSE2, Enabled); + } else if (Name == "pclmul") { + if (Enabled) + setSSELevel(Features, SSE2, Enabled); + } else if (Name == "avx") { + setSSELevel(Features, AVX, Enabled); + } else if (Name == "avx2") { + setSSELevel(Features, AVX2, Enabled); + } else if (Name == "avx512f") { + setSSELevel(Features, AVX512F, Enabled); + } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf") { + if (Enabled) + setSSELevel(Features, AVX512F, Enabled); + } else if (Name == "fma") { + if (Enabled) + setSSELevel(Features, AVX, Enabled); + } else if (Name == "fma4") { + setXOPLevel(Features, FMA4, Enabled); + } else if (Name == "xop") { + setXOPLevel(Features, XOP, Enabled); + } else if (Name == "sse4a") { + setXOPLevel(Features, SSE4A, Enabled); + } else if (Name == "f16c") { + if (Enabled) + setSSELevel(Features, AVX, Enabled); + } else if (Name == "sha") { + if (Enabled) + setSSELevel(Features, SSE2, Enabled); + } +} + +/// handleTargetFeatures - Perform initialization based on the user /// configured set of features. -void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { +bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { // Remember the maximum enabled sselevel. for (unsigned i = 0, e = Features.size(); i !=e; ++i) { // Ignore disabled features. @@ -2408,7 +2405,7 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } - if (Feature == "rdrand") { + if (Feature == "rdrnd") { HasRDRND = true; continue; } @@ -2443,37 +2440,53 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } - if (Feature == "sse4a") { - HasSSE4a = true; + if (Feature == "tbm") { + HasTBM = true; continue; } - if (Feature == "fma4") { - HasFMA4 = true; + if (Feature == "fma") { + HasFMA = true; continue; } - if (Feature == "fma") { - HasFMA = true; + if (Feature == "f16c") { + HasF16C = true; continue; } - if (Feature == "xop") { - HasXOP = true; + if (Feature == "avx512cd") { + HasAVX512CD = true; continue; } - if (Feature == "f16c") { - HasF16C = true; + if (Feature == "avx512er") { + HasAVX512ER = true; + continue; + } + + if (Feature == "avx512pf") { + HasAVX512PF = true; + continue; + } + + if (Feature == "sha") { + HasSHA = true; + continue; + } + + if (Feature == "cx16") { + HasCX16 = true; continue; } assert(Features[i][0] == '+' && "Invalid target feature!"); X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) + .Case("avx512f", AVX512F) .Case("avx2", AVX2) .Case("avx", AVX) - .Case("sse42", SSE42) - .Case("sse41", SSE41) + .Case("sse4.2", SSE42) + .Case("sse4.1", SSE41) .Case("ssse3", SSSE3) .Case("sse3", SSE3) .Case("sse2", SSE2) @@ -2487,16 +2500,53 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { .Case("3dnow", AMD3DNow) .Case("mmx", MMX) .Default(NoMMX3DNow); - MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel); + + XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature) + .Case("xop", XOP) + .Case("fma4", FMA4) + .Case("sse4a", SSE4A) + .Default(NoXOP); + XOPLevel = std::max(XOPLevel, XLevel); + } + + // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled. + // Can't do this earlier because we need to be able to explicitly enable + // popcnt and still disable sse4.2. + if (!HasPOPCNT && SSELevel >= SSE42 && + std::find(Features.begin(), Features.end(), "-popcnt") == Features.end()){ + HasPOPCNT = true; + Features.push_back("+popcnt"); + } + + // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled. + if (!HasPRFCHW && MMX3DNowLevel >= AMD3DNow && + std::find(Features.begin(), Features.end(), "-prfchw") == Features.end()){ + HasPRFCHW = true; + Features.push_back("+prfchw"); + } + + // LLVM doesn't have a separate switch for fpmath, so only accept it if it + // matches the selected sse level. + if (FPMath == FP_SSE && SSELevel < SSE1) { + Diags.Report(diag::err_target_unsupported_fpmath) << "sse"; + return false; + } else if (FPMath == FP_387 && SSELevel >= SSE1) { + Diags.Report(diag::err_target_unsupported_fpmath) << "387"; + return false; } // Don't tell the backend if we're turning off mmx; it will end up disabling // SSE, which we don't want. + // Additionally, if SSE is enabled and mmx is not explicitly disabled, + // then enable MMX. std::vector<std::string>::iterator it; it = std::find(Features.begin(), Features.end(), "-mmx"); if (it != Features.end()) Features.erase(it); + else if (SSELevel > NoSSE) + MMX3DNowLevel = std::max(MMX3DNowLevel, MMX); + return true; } /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro @@ -2574,12 +2624,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Atom: defineCPUMacros(Builder, "atom"); break; + case CK_Silvermont: + defineCPUMacros(Builder, "slm"); + break; case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: case CK_CoreAVX2: defineCPUMacros(Builder, "corei7"); break; + case CK_KNL: + defineCPUMacros(Builder, "knl"); + break; case CK_K6_2: Builder.defineMacro("__k6_2__"); Builder.defineMacro("__tune_k6_2__"); @@ -2632,6 +2688,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_BDVER2: defineCPUMacros(Builder, "bdver2"); break; + case CK_BDVER3: + defineCPUMacros(Builder, "bdver3"); + break; case CK_Geode: defineCPUMacros(Builder, "geode"); break; @@ -2676,23 +2735,43 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasRDSEED) Builder.defineMacro("__RDSEED__"); - if (HasSSE4a) - Builder.defineMacro("__SSE4A__"); + if (HasTBM) + Builder.defineMacro("__TBM__"); - if (HasFMA4) + switch (XOPLevel) { + case XOP: + Builder.defineMacro("__XOP__"); + case FMA4: Builder.defineMacro("__FMA4__"); + case SSE4A: + Builder.defineMacro("__SSE4A__"); + case NoXOP: + break; + } if (HasFMA) Builder.defineMacro("__FMA__"); - if (HasXOP) - Builder.defineMacro("__XOP__"); - if (HasF16C) Builder.defineMacro("__F16C__"); + if (HasAVX512CD) + Builder.defineMacro("__AVX512CD__"); + if (HasAVX512ER) + Builder.defineMacro("__AVX512ER__"); + if (HasAVX512PF) + Builder.defineMacro("__AVX512PF__"); + + if (HasSHA) + Builder.defineMacro("__SHA__"); + + if (HasCX16) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); + // Each case falls through to the previous one here. switch (SSELevel) { + case AVX512F: + Builder.defineMacro("__AVX512F__"); case AVX2: Builder.defineMacro("__AVX2__"); case AVX: @@ -2717,6 +2796,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) { switch (SSELevel) { + case AVX512F: case AVX2: case AVX: case SSE42: @@ -2760,10 +2840,17 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("aes", HasAES) .Case("avx", SSELevel >= AVX) .Case("avx2", SSELevel >= AVX2) + .Case("avx512f", SSELevel >= AVX512F) + .Case("avx512cd", HasAVX512CD) + .Case("avx512er", HasAVX512ER) + .Case("avx512pf", HasAVX512PF) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) + .Case("cx16", HasCX16) + .Case("f16c", HasF16C) .Case("fma", HasFMA) - .Case("fma4", HasFMA4) + .Case("fma4", XOPLevel >= FMA4) + .Case("tbm", HasTBM) .Case("lzcnt", HasLZCNT) .Case("rdrnd", HasRDRND) .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) @@ -2774,18 +2861,18 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("rtm", HasRTM) .Case("prfchw", HasPRFCHW) .Case("rdseed", HasRDSEED) + .Case("sha", HasSHA) .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("sse4a", HasSSE4a) + .Case("sse4.1", SSELevel >= SSE41) + .Case("sse4.2", SSELevel >= SSE42) + .Case("sse4a", XOPLevel >= SSE4A) .Case("x86", true) .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) - .Case("xop", HasXOP) - .Case("f16c", HasF16C) + .Case("xop", XOPLevel >= XOP) .Default(false); } @@ -2858,7 +2945,7 @@ namespace { // X86-32 generic target class X86_32TargetInfo : public X86TargetInfo { public: - X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { + X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) { DoubleAlign = LongLongAlign = 32; LongDoubleWidth = 96; LongDoubleAlign = 32; @@ -2909,12 +2996,16 @@ public: namespace { class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { public: - NetBSDI386TargetInfo(const std::string &triple) : - NetBSDTargetInfo<X86_32TargetInfo>(triple) { - } + NetBSDI386TargetInfo(const llvm::Triple &Triple) + : NetBSDTargetInfo<X86_32TargetInfo>(Triple) {} virtual unsigned getFloatEvalMethod() const { - // NetBSD defaults to "double" rounding + unsigned Major, Minor, Micro; + getTriple().getOSVersion(Major, Minor, Micro); + // New NetBSD uses the default rounding mode. + if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0) + return X86_32TargetInfo::getFloatEvalMethod(); + // NetBSD before 6.99.26 defaults to "double" rounding. return 1; } }; @@ -2923,8 +3014,8 @@ public: namespace { class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { public: - OpenBSDI386TargetInfo(const std::string& triple) : - OpenBSDTargetInfo<X86_32TargetInfo>(triple) { + OpenBSDI386TargetInfo(const llvm::Triple &Triple) + : OpenBSDTargetInfo<X86_32TargetInfo>(Triple) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -2935,8 +3026,8 @@ public: namespace { class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> { public: - BitrigI386TargetInfo(const std::string& triple) : - BitrigTargetInfo<X86_32TargetInfo>(triple) { + BitrigI386TargetInfo(const llvm::Triple &Triple) + : BitrigTargetInfo<X86_32TargetInfo>(Triple) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -2947,8 +3038,8 @@ public: namespace { class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { public: - DarwinI386TargetInfo(const std::string& triple) : - DarwinTargetInfo<X86_32TargetInfo>(triple) { + DarwinI386TargetInfo(const llvm::Triple &Triple) + : DarwinTargetInfo<X86_32TargetInfo>(Triple) { LongDoubleWidth = 128; LongDoubleAlign = 128; SuitableAlign = 128; @@ -2968,8 +3059,8 @@ namespace { // x86-32 Windows target class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> { public: - WindowsX86_32TargetInfo(const std::string& triple) - : WindowsTargetInfo<X86_32TargetInfo>(triple) { + WindowsX86_32TargetInfo(const llvm::Triple &Triple) + : WindowsTargetInfo<X86_32TargetInfo>(Triple) { TLSSupported = false; WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; @@ -2989,8 +3080,8 @@ namespace { // x86-32 Windows Visual Studio target class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { public: - VisualStudioWindowsX86_32TargetInfo(const std::string& triple) - : WindowsX86_32TargetInfo(triple) { + VisualStudioWindowsX86_32TargetInfo(const llvm::Triple &Triple) + : WindowsX86_32TargetInfo(Triple) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; } @@ -3010,9 +3101,8 @@ namespace { // x86-32 MinGW target class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { public: - MinGWX86_32TargetInfo(const std::string& triple) - : WindowsX86_32TargetInfo(triple) { - } + MinGWX86_32TargetInfo(const llvm::Triple &Triple) + : WindowsX86_32TargetInfo(Triple) {} virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); @@ -3038,8 +3128,8 @@ namespace { // x86-32 Cygwin target class CygwinX86_32TargetInfo : public X86_32TargetInfo { public: - CygwinX86_32TargetInfo(const std::string& triple) - : X86_32TargetInfo(triple) { + CygwinX86_32TargetInfo(const llvm::Triple &Triple) + : X86_32TargetInfo(Triple) { TLSSupported = false; WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; @@ -3064,8 +3154,7 @@ namespace { // x86-32 Haiku target class HaikuX86_32TargetInfo : public X86_32TargetInfo { public: - HaikuX86_32TargetInfo(const std::string& triple) - : X86_32TargetInfo(triple) { + HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -3093,37 +3182,35 @@ protected: Builder.defineMacro("__rtems__"); Builder.defineMacro("__ELF__"); } -public: - RTEMSTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) { - this->UserLabelPrefix = ""; - llvm::Triple Triple(triple); - switch (Triple.getArch()) { - default: - case llvm::Triple::x86: - // this->MCountName = ".mcount"; - break; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - // this->MCountName = "_mcount"; - break; - case llvm::Triple::arm: - // this->MCountName = "__mcount"; - break; - } +public: + RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + // this->MCountName = ".mcount"; + break; + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + // this->MCountName = "_mcount"; + break; + case llvm::Triple::arm: + // this->MCountName = "__mcount"; + break; } + } }; namespace { // x86-32 RTEMS target class RTEMSX86_32TargetInfo : public X86_32TargetInfo { public: - RTEMSX86_32TargetInfo(const std::string& triple) - : X86_32TargetInfo(triple) { + RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -3142,7 +3229,7 @@ namespace { // x86-64 generic target class X86_64TargetInfo : public X86TargetInfo { public: - X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { + X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 128; @@ -3181,8 +3268,7 @@ public: } virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { - return (CC == CC_Default || - CC == CC_C || + return (CC == CC_C || CC == CC_IntelOclBicc || CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning; } @@ -3198,8 +3284,8 @@ namespace { // x86-64 Windows target class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> { public: - WindowsX86_64TargetInfo(const std::string& triple) - : WindowsTargetInfo<X86_64TargetInfo>(triple) { + WindowsX86_64TargetInfo(const llvm::Triple &Triple) + : WindowsTargetInfo<X86_64TargetInfo>(Triple) { TLSSupported = false; WCharType = UnsignedShort; LongWidth = LongAlign = 32; @@ -3232,8 +3318,8 @@ namespace { // x86-64 Windows Visual Studio target class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { public: - VisualStudioWindowsX86_64TargetInfo(const std::string& triple) - : WindowsX86_64TargetInfo(triple) { + VisualStudioWindowsX86_64TargetInfo(const llvm::Triple &Triple) + : WindowsX86_64TargetInfo(Triple) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; } @@ -3251,9 +3337,8 @@ namespace { // x86-64 MinGW target class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { public: - MinGWX86_64TargetInfo(const std::string& triple) - : WindowsX86_64TargetInfo(triple) { - } + MinGWX86_64TargetInfo(const llvm::Triple &Triple) + : WindowsX86_64TargetInfo(Triple) {} virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); @@ -3277,8 +3362,8 @@ public: namespace { class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { public: - DarwinX86_64TargetInfo(const std::string& triple) - : DarwinTargetInfo<X86_64TargetInfo>(triple) { + DarwinX86_64TargetInfo(const llvm::Triple &Triple) + : DarwinTargetInfo<X86_64TargetInfo>(Triple) { Int64Type = SignedLongLong; MaxVectorAlign = 256; } @@ -3288,8 +3373,8 @@ public: namespace { class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { public: - OpenBSDX86_64TargetInfo(const std::string& triple) - : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { + OpenBSDX86_64TargetInfo(const llvm::Triple &Triple) + : OpenBSDTargetInfo<X86_64TargetInfo>(Triple) { IntMaxType = SignedLongLong; UIntMaxType = UnsignedLongLong; Int64Type = SignedLongLong; @@ -3300,11 +3385,11 @@ public: namespace { class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> { public: - BitrigX86_64TargetInfo(const std::string& triple) - : BitrigTargetInfo<X86_64TargetInfo>(triple) { - IntMaxType = SignedLongLong; - UIntMaxType = UnsignedLongLong; - Int64Type = SignedLongLong; + BitrigX86_64TargetInfo(const llvm::Triple &Triple) + : BitrigTargetInfo<X86_64TargetInfo>(Triple) { + IntMaxType = SignedLongLong; + UIntMaxType = UnsignedLongLong; + Int64Type = SignedLongLong; } }; } @@ -3314,9 +3399,17 @@ class AArch64TargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; + enum FPUModeEnum { + FPUMode, + NeonMode + }; + + unsigned FPU; + unsigned Crypto; static const Builtin::Info BuiltinInfo[]; + public: - AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) { + AArch64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { BigEndian = false; LongWidth = LongAlign = 64; LongDoubleWidth = LongDoubleAlign = 128; @@ -3342,22 +3435,20 @@ public: Builder.defineMacro("__AARCH64EL__"); // ACLE predefines. Many can only have one possible value on v8 AArch64. - - // FIXME: these were written based on an unreleased version of a 32-bit ACLE - // which was intended to be compatible with a 64-bit implementation. They - // will need updating when a real 64-bit ACLE exists. Particularly pressing - // instances are: __ARM_ARCH_ISA_ARM, __ARM_ARCH_ISA_THUMB, __ARM_PCS. - Builder.defineMacro("__ARM_ACLE", "101"); + Builder.defineMacro("__ARM_ACLE", "200"); Builder.defineMacro("__ARM_ARCH", "8"); Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'"); + Builder.defineMacro("__ARM_64BIT_STATE"); + Builder.defineMacro("__ARM_PCS_AAPCS64"); + Builder.defineMacro("__ARM_ARCH_ISA_A64"); + Builder.defineMacro("__ARM_FEATURE_UNALIGNED"); Builder.defineMacro("__ARM_FEATURE_CLZ"); Builder.defineMacro("__ARM_FEATURE_FMA"); + Builder.defineMacro("__ARM_FEATURE_DIV"); - // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean - // 128-bit LDXP present, at which point this becomes 0x1f. - Builder.defineMacro("__ARM_FEATURE_LDREX", "0xf"); + Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); // 0xe implies support for half, single and double precision operations. Builder.defineMacro("__ARM_FP", "0xe"); @@ -3379,7 +3470,17 @@ public: Opts.ShortEnums ? "1" : "4"); if (BigEndian) - Builder.defineMacro("__ARM_BIG_ENDIAN"); + Builder.defineMacro("__AARCH_BIG_ENDIAN"); + + if (FPU == NeonMode) { + Builder.defineMacro("__ARM_NEON"); + // 64-bit NEON supports half, single and double precision operations. + Builder.defineMacro("__ARM_NEON_FP", "7"); + } + + if (Crypto) { + Builder.defineMacro("__ARM_FEATURE_CRYPTO"); + } } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -3387,9 +3488,30 @@ public: NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin; } virtual bool hasFeature(StringRef Feature) const { - return Feature == "aarch64"; + return Feature == "aarch64" || (Feature == "neon" && FPU == NeonMode); } - virtual void getGCCRegNames(const char * const *&Names, + + virtual bool setCPU(const std::string &Name) { + return llvm::StringSwitch<bool>(Name) + .Case("generic", true) + .Cases("cortex-a53", "cortex-a57", true) + .Default(false); + } + + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + FPU = FPUMode; + Crypto = 0; + for (unsigned i = 0, e = Features.size(); i != e; ++i) { + if (Features[i] == "+neon") + FPU = NeonMode; + if (Features[i] == "+crypto") + Crypto = 1; + } + return true; + } + + virtual void getGCCRegNames(const char *const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, unsigned &NumAliases) const; @@ -3510,11 +3632,18 @@ class ARMTargetInfo : public TargetInfo { VFP2FPU = (1 << 0), VFP3FPU = (1 << 1), VFP4FPU = (1 << 2), - NeonFPU = (1 << 3) + NeonFPU = (1 << 3), + FPARMV8 = (1 << 4) + }; + + // Possible HWDiv features. + enum HWDivMode { + HWDivThumb = (1 << 0), + HWDivARM = (1 << 1) }; static bool FPUModeIsVFP(FPUMode Mode) { - return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU); + return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8); } static const TargetInfo::GCCRegAlias GCCRegAliases[]; @@ -3522,15 +3651,24 @@ class ARMTargetInfo : public TargetInfo { std::string ABI, CPU; - unsigned FPU : 4; + enum { + FP_Default, + FP_VFP, + FP_Neon + } FPMath; + + unsigned FPU : 5; unsigned IsAAPCS : 1; unsigned IsThumb : 1; + unsigned HWDiv : 2; // Initialized via features. unsigned SoftFloat : 1; unsigned SoftFloatABI : 1; + unsigned CRC : 1; + static const Builtin::Info BuiltinInfo[]; static bool shouldUseInlineAtomic(const llvm::Triple &T) { @@ -3539,7 +3677,10 @@ class ARMTargetInfo : public TargetInfo { // the kernel which on armv6 and newer uses ldrex and strex. The net result // is that if we assume the kernel is at least as recent as the hardware, // it is safe to use atomic instructions on armv6 and newer. - if (T.getOS() != llvm::Triple::Linux && T.getOS() != llvm::Triple::FreeBSD) + if (!T.isOSLinux() && + T.getOS() != llvm::Triple::FreeBSD && + T.getOS() != llvm::Triple::NetBSD && + T.getOS() != llvm::Triple::Bitrig) return false; StringRef ArchName = T.getArchName(); if (T.getArch() == llvm::Triple::arm) { @@ -3562,14 +3703,23 @@ class ARMTargetInfo : public TargetInfo { } public: - ARMTargetInfo(const std::string &TripleStr) - : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true) - { + ARMTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), ABI("aapcs-linux"), CPU("arm1136j-s"), + FPMath(FP_Default), IsAAPCS(true) { BigEndian = false; - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int. - WCharType = UnsignedInt; + switch (getTriple().getOS()) { + case llvm::Triple::NetBSD: + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + WCharType = SignedInt; + break; + default: + // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int. + WCharType = UnsignedInt; + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + break; + } // {} in inline assembly are neon specifiers, not assembly variant // specifiers. @@ -3645,6 +3795,9 @@ public: // FIXME: Override "preferred align" for double and long long. } else if (Name == "aapcs" || Name == "aapcs-vfp") { + // size_t is unsigned long on Darwin. + if (getTriple().isOSDarwin()) + SizeType = UnsignedLong; IsAAPCS = true; // FIXME: Enumerated types are variable width in straight AAPCS. } else if (Name == "aapcs-linux") { @@ -3656,33 +3809,45 @@ public: } void getDefaultFeatures(llvm::StringMap<bool> &Features) const { + StringRef ArchName = getTriple().getArchName(); if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") Features["vfp2"] = true; - else if (CPU == "cortex-a8" || CPU == "cortex-a15" || - CPU == "cortex-a9" || CPU == "cortex-a9-mp") + else if (CPU == "cortex-a8" || CPU == "cortex-a9" || + CPU == "cortex-a9-mp") { + Features["vfp3"] = true; Features["neon"] = true; - else if (CPU == "swift" || CPU == "cortex-a7") { + } + else if (CPU == "cortex-a5") { + Features["vfp4"] = true; + Features["neon"] = true; + } else if (CPU == "swift" || CPU == "cortex-a7" || CPU == "cortex-a15") { Features["vfp4"] = true; Features["neon"] = true; + Features["hwdiv"] = true; + Features["hwdiv-arm"] = true; + } else if (CPU == "cortex-a53" || CPU == "cortex-a57") { + Features["fp-armv8"] = true; + Features["neon"] = true; + Features["hwdiv"] = true; + Features["hwdiv-arm"] = true; + Features["crc"] = true; + } else if (CPU == "cortex-r5" || CPU == "cortex-m3" || + CPU == "cortex-m4" || + // Enable the hwdiv extension for all v8a AArch32 cores by + // default. + ArchName == "armv8a" || ArchName == "armv8" || + ArchName == "thumbv8a" || ArchName == "thumbv8") { + Features["hwdiv"] = true; + Features["hwdiv-arm"] = true; } } - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - if (Name == "soft-float" || Name == "soft-float-abi" || - Name == "vfp2" || Name == "vfp3" || Name == "vfp4" || Name == "neon" || - Name == "d16" || Name == "neonfp") { - Features[Name] = Enabled; - } else - return false; - - return true; - } - - virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { FPU = 0; + CRC = 0; SoftFloat = SoftFloatABI = false; + HWDiv = 0; for (unsigned i = 0, e = Features.size(); i != e; ++i) { if (Features[i] == "+soft-float") SoftFloat = true; @@ -3694,10 +3859,28 @@ public: FPU |= VFP3FPU; else if (Features[i] == "+vfp4") FPU |= VFP4FPU; + else if (Features[i] == "+fp-armv8") + FPU |= FPARMV8; else if (Features[i] == "+neon") FPU |= NeonFPU; + else if (Features[i] == "+hwdiv") + HWDiv |= HWDivThumb; + else if (Features[i] == "+hwdiv-arm") + HWDiv |= HWDivARM; + else if (Features[i] == "+crc") + CRC = 1; + } + + if (!(FPU & NeonFPU) && FPMath == FP_Neon) { + Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; + return false; } + if (FPMath == FP_Neon) + Features.push_back("+neonfp"); + else if (FPMath == FP_VFP) + Features.push_back("-neonfp"); + // Remove front-end specific options which the backend handles differently. std::vector<std::string>::iterator it; it = std::find(Features.begin(), Features.end(), "+soft-float"); @@ -3706,6 +3889,7 @@ public: it = std::find(Features.begin(), Features.end(), "+soft-float-abi"); if (it != Features.end()) Features.erase(it); + return true; } virtual bool hasFeature(StringRef Feature) const { @@ -3713,8 +3897,9 @@ public: .Case("arm", true) .Case("softfloat", SoftFloat) .Case("thumb", IsThumb) - .Case("neon", FPU == NeonFPU && !SoftFloat && - StringRef(getCPUDefineSuffix(CPU)).startswith("7")) + .Case("neon", (FPU & NeonFPU) && !SoftFloat) + .Case("hwdiv", HWDiv & HWDivThumb) + .Case("hwdiv-arm", HWDiv & HWDivARM) .Default(false); } // FIXME: Should we actually have some table instead of these switches? @@ -3735,19 +3920,22 @@ public: .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A") - .Cases("cortex-a9", "cortex-a15", "7A") - .Case("cortex-r5", "7R") + .Cases("cortex-a9", "cortex-a12", "cortex-a15", "7A") + .Cases("cortex-r4", "cortex-r5", "7R") .Case("cortex-a9-mp", "7F") .Case("swift", "7S") .Cases("cortex-m3", "cortex-m4", "7M") .Case("cortex-m0", "6M") + .Cases("cortex-a53", "cortex-a57", "8A") .Default(0); } static const char *getCPUProfile(StringRef Name) { return llvm::StringSwitch<const char*>(Name) - .Cases("cortex-a8", "cortex-a9", "A") + .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A") + .Cases("cortex-a9", "cortex-a12", "cortex-a15", "A") + .Cases("cortex-a53", "cortex-a57", "A") .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M") - .Case("cortex-r5", "R") + .Cases("cortex-r4", "cortex-r5", "R") .Default(""); } virtual bool setCPU(const std::string &Name) { @@ -3757,6 +3945,7 @@ public: CPU = Name; return true; } + virtual bool setFPMath(StringRef Name); virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. @@ -3769,6 +3958,10 @@ public: Builder.defineMacro("__REGISTER_PREFIX__", ""); StringRef CPUArch = getCPUDefineSuffix(CPU); + unsigned int CPUArchVer; + if(CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer)) { + llvm_unreachable("Invalid char for architecture version number"); + } Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1)); StringRef CPUProfile = getCPUProfile(CPU); @@ -3779,12 +3972,12 @@ public: // FIXME: It's more complicated than this and we don't really support // interworking. - if ('5' <= CPUArch[0] && CPUArch[0] <= '7') + if (5 <= CPUArchVer && CPUArchVer <= 7) Builder.defineMacro("__THUMB_INTERWORK__"); if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { - // M-class CPUs on Darwin follow AAPCS, but not EABI. - if (!(getTriple().isOSDarwin() && CPUProfile == "M")) + // Embedded targets on Darwin follow AAPCS, but not EABI. + if (!getTriple().isOSDarwin()) Builder.defineMacro("__ARM_EABI__"); Builder.defineMacro("__ARM_PCS", "1"); @@ -3798,13 +3991,14 @@ public: if (CPU == "xscale") Builder.defineMacro("__XSCALE__"); - bool IsARMv7 = CPUArch.startswith("7"); if (IsThumb) { Builder.defineMacro("__THUMBEL__"); Builder.defineMacro("__thumb__"); - if (CPUArch == "6T2" || IsARMv7) + if (CPUArch == "6T2" || CPUArchVer == 7) Builder.defineMacro("__thumb2__"); } + if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb)) + Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1"); // Note, this is always on in gcc, even though it doesn't make sense. Builder.defineMacro("__APCS_32__"); @@ -3823,8 +4017,18 @@ public: // the VFP define, hence the soft float and arch check. This is subtly // different from gcc, we follow the intent which was that it should be set // when Neon instructions are actually available. - if ((FPU & NeonFPU) && !SoftFloat && IsARMv7) + if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) Builder.defineMacro("__ARM_NEON__"); + + if (CRC) + Builder.defineMacro("__ARM_FEATURE_CRC32"); + + if (CPUArchVer >= 6 && CPUArch != "6M") { + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + } } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -3902,8 +4106,7 @@ public: case 'r': { switch (Modifier) { default: - return isInOut || (isOutput && Size >= 32) || - (!isOutput && !isInOut && Size <= 32); + return (isInOut || isOutput || Size <= 64); case 'q': // A register of size 32 cannot fit a vector type. return false; @@ -3929,6 +4132,18 @@ public: } }; +bool ARMTargetInfo::setFPMath(StringRef Name) { + if (Name == "neon") { + FPMath = FP_Neon; + return true; + } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" || + Name == "vfp4") { + FPMath = FP_VFP; + return true; + } + return false; +} + const char * const ARMTargetInfo::GCCRegNames[] = { // Integer registers "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -4002,8 +4217,8 @@ protected: } public: - DarwinARMTargetInfo(const std::string& triple) - : DarwinTargetInfo<ARMTargetInfo>(triple) { + DarwinARMTargetInfo(const llvm::Triple &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. @@ -4024,7 +4239,7 @@ class HexagonTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; public: - HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) { + HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { BigEndian = false; DescriptionString = ("e-p:32:32:32-" "i64:64:64-i32:32:32-i16:16:16-i1:32:32-" @@ -4177,23 +4392,15 @@ class SparcTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; bool SoftFloat; public: - SparcTargetInfo(const std::string &triple) : TargetInfo(triple) {} - - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - if (Name == "soft-float") - Features[Name] = Enabled; - else - return false; + SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {} - return true; - } - virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { SoftFloat = false; for (unsigned i = 0, e = Features.size(); i != e; ++i) if (Features[i] == "+soft-float") SoftFloat = true; + return true; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4290,7 +4497,7 @@ void SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, // SPARC v8 is the 32-bit mode selected by Triple::sparc. class SparcV8TargetInfo : public SparcTargetInfo { public: - SparcV8TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { + SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) { // FIXME: Support Sparc quad-precision long double? 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-S64"; @@ -4306,10 +4513,22 @@ public: // SPARC v9 is the 64-bit mode selected by Triple::sparcv9. class SparcV9TargetInfo : public SparcTargetInfo { public: - SparcV9TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { + SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) { // FIXME: Support Sparc quad-precision long double? 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-n32:64-S128"; + // This is an LP64 platform. + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + + // OpenBSD uses long long for int64_t and intmax_t. + if (getTriple().getOS() == llvm::Triple::OpenBSD) { + IntMaxType = SignedLongLong; + UIntMaxType = UnsignedLongLong; + } else { + IntMaxType = SignedLong; + UIntMaxType = UnsignedLong; + } + Int64Type = IntMaxType; } virtual void getTargetDefines(const LangOptions &Opts, @@ -4333,16 +4552,16 @@ public: namespace { class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> { public: - AuroraUXSparcV8TargetInfo(const std::string& triple) : - AuroraUXTargetInfo<SparcV8TargetInfo>(triple) { + AuroraUXSparcV8TargetInfo(const llvm::Triple &Triple) + : AuroraUXTargetInfo<SparcV8TargetInfo>(Triple) { SizeType = UnsignedInt; PtrDiffType = SignedInt; } }; class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { public: - SolarisSparcV8TargetInfo(const std::string& triple) : - SolarisTargetInfo<SparcV8TargetInfo>(triple) { + SolarisSparcV8TargetInfo(const llvm::Triple &Triple) + : SolarisTargetInfo<SparcV8TargetInfo>(Triple) { SizeType = UnsignedInt; PtrDiffType = SignedInt; } @@ -4354,7 +4573,7 @@ namespace { static const char *const GCCRegNames[]; public: - SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { + SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { TLSSupported = true; IntWidth = IntAlign = 32; LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; @@ -4398,6 +4617,17 @@ namespace { virtual BuiltinVaListKind getBuiltinVaListKind() const { return TargetInfo::SystemZBuiltinVaList; } + virtual bool setCPU(const std::string &Name) { + bool CPUKnown = llvm::StringSwitch<bool>(Name) + .Case("z10", true) + .Case("z196", true) + .Case("zEC12", true) + .Default(false); + + // No need to store the CPU yet. There aren't any CPU-specific + // macros to define. + return CPUKnown; + } }; const char *const SystemZTargetInfo::GCCRegNames[] = { @@ -4447,7 +4677,7 @@ namespace { class MSP430TargetInfo : public TargetInfo { static const char * const GCCRegNames[]; public: - MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { + MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { BigEndian = false; TLSSupported = false; IntWidth = 16; IntAlign = 16; @@ -4456,9 +4686,9 @@ namespace { PointerWidth = 16; PointerAlign = 16; SuitableAlign = 16; SizeType = UnsignedInt; - IntMaxType = SignedLong; - UIntMaxType = UnsignedLong; - IntPtrType = SignedShort; + IntMaxType = SignedLongLong; + UIntMaxType = UnsignedLongLong; + IntPtrType = SignedInt; PtrDiffType = SignedInt; SigAtomicType = SignedLong; DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"; @@ -4534,7 +4764,7 @@ namespace { class TCETargetInfo : public TargetInfo{ public: - TCETargetInfo(const std::string& triple) : TargetInfo(triple) { + TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { TLSSupported = false; IntWidth = 32; LongWidth = LongLongWidth = 32; @@ -4562,6 +4792,7 @@ namespace { "f32:32:32-f64:32:32-v64:32:32-" "v128:32:32-a0:0:32-n32"; AddrSpaceMap = &TCEOpenCLAddrSpaceMap; + UseAddrSpaceMapMangling = true; } virtual void getTargetDefines(const LangOptions &Opts, @@ -4595,10 +4826,13 @@ namespace { namespace { class MipsTargetInfoBase : public TargetInfo { + virtual void setDescriptionString() = 0; + static const Builtin::Info BuiltinInfo[]; std::string CPU; bool IsMips16; bool IsMicromips; + bool IsNan2008; bool IsSingleFloat; enum MipsFloatABI { HardFloat, SoftFloat @@ -4606,23 +4840,18 @@ class MipsTargetInfoBase : public TargetInfo { enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev; + bool HasMSA; protected: + bool HasFP64; std::string ABI; public: - MipsTargetInfoBase(const std::string& triple, - const std::string& ABIStr, - const std::string& CPUStr) - : TargetInfo(triple), - CPU(CPUStr), - IsMips16(false), - IsMicromips(false), - IsSingleFloat(false), - FloatABI(HardFloat), - DspRev(NoDSP), - ABI(ABIStr) - {} + MipsTargetInfoBase(const llvm::Triple &Triple, const std::string &ABIStr, + const std::string &CPUStr) + : TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false), + IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat), + DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {} virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) = 0; @@ -4653,12 +4882,19 @@ public: if (IsSingleFloat) Builder.defineMacro("__mips_single_float", Twine(1)); + Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32)); + Builder.defineMacro("_MIPS_FPSET", + Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2))); + if (IsMips16) Builder.defineMacro("__mips16", Twine(1)); if (IsMicromips) Builder.defineMacro("__mips_micromips", Twine(1)); + if (IsNan2008) + Builder.defineMacro("__mips_nan2008", Twine(1)); + switch (DspRev) { default: break; @@ -4673,6 +4909,9 @@ public: break; } + if (HasMSA) + Builder.defineMacro("__mips_msa", Twine(1)); + Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); @@ -4687,14 +4926,17 @@ public: NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin; } virtual bool hasFeature(StringRef Feature) const { - return Feature == "mips"; + return llvm::StringSwitch<bool>(Feature) + .Case("mips", true) + .Case("fp64", HasFP64) + .Default(false); } virtual BuiltinVaListKind getBuiltinVaListKind() const { return TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { - static const char * const GCCRegNames[] = { + static const char *const GCCRegNames[] = { // CPU register names // Must match second column of GCCRegAliases "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", @@ -4708,7 +4950,15 @@ public: "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", // Hi/lo and condition register names "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", - "$fcc5","$fcc6","$fcc7" + "$fcc5","$fcc6","$fcc7", + // MSA register names + "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", + "$w8", "$w9", "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", + "$w16", "$w17", "$w18", "$w19", "$w20", "$w21", "$w22", "$w23", + "$w24", "$w25", "$w26", "$w27", "$w28", "$w29", "$w30", "$w31", + // MSA control register names + "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify", + "$msarequest", "$msamap", "$msaunmap" }; Names = GCCRegNames; NumNames = llvm::array_lengthof(GCCRegNames); @@ -4741,33 +4991,15 @@ public: return ""; } - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { - if (Name == "soft-float" || Name == "single-float" || - Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" || - Name == "mips32" || Name == "mips32r2" || - Name == "mips64" || Name == "mips64r2" || - Name == "mips16" || Name == "micromips" || - Name == "dsp" || Name == "dspr2") { - Features[Name] = Enabled; - return true; - } else if (Name == "32") { - Features["o32"] = Enabled; - return true; - } else if (Name == "64") { - Features["n64"] = Enabled; - return true; - } - return false; - } - - virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { IsMips16 = false; IsMicromips = false; + IsNan2008 = false; IsSingleFloat = false; FloatABI = HardFloat; DspRev = NoDSP; + HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64"; for (std::vector<std::string>::iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) { @@ -4783,13 +5015,28 @@ public: DspRev = std::max(DspRev, DSP1); else if (*it == "+dspr2") DspRev = std::max(DspRev, DSP2); + else if (*it == "+msa") + HasMSA = true; + else if (*it == "+fp64") + HasFP64 = true; + else if (*it == "-fp64") + HasFP64 = false; + else if (*it == "+nan2008") + IsNan2008 = true; } - // Remove front-end specific option. + // Remove front-end specific options. std::vector<std::string>::iterator it = std::find(Features.begin(), Features.end(), "+soft-float"); if (it != Features.end()) Features.erase(it); + it = std::find(Features.begin(), Features.end(), "+nan2008"); + if (it != Features.end()) + Features.erase(it); + + setDescriptionString(); + + return true; } virtual int getEHDataRegisterNumber(unsigned RegNo) const { @@ -4808,8 +5055,8 @@ const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = { class Mips32TargetInfoBase : public MipsTargetInfoBase { public: - Mips32TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "o32", "mips32") { + Mips32TargetInfoBase(const llvm::Triple &Triple) + : MipsTargetInfoBase(Triple, "o32", "mips32") { SizeType = UnsignedInt; PtrDiffType = SignedInt; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; @@ -4879,11 +5126,15 @@ public: }; class Mips32EBTargetInfo : public Mips32TargetInfoBase { -public: - Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { + virtual void setDescriptionString() { 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-S64"; } + +public: + Mips32EBTargetInfo(const llvm::Triple &Triple) + : Mips32TargetInfoBase(Triple) { + } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "MIPSEB", Opts); @@ -4893,12 +5144,16 @@ public: }; class Mips32ELTargetInfo : public Mips32TargetInfoBase { -public: - Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { - BigEndian = false; + virtual void setDescriptionString() { 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-S64"; } + +public: + Mips32ELTargetInfo(const llvm::Triple &Triple) + : Mips32TargetInfoBase(Triple) { + BigEndian = false; + } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "MIPSEL", Opts); @@ -4908,10 +5163,9 @@ public: }; class Mips64TargetInfoBase : public MipsTargetInfoBase { - virtual void SetDescriptionString(const std::string &Name) = 0; public: - Mips64TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "n64", "mips64") { + Mips64TargetInfoBase(const llvm::Triple &Triple) + : MipsTargetInfoBase(Triple, "n64", "mips64") { LongWidth = LongAlign = 64; PointerWidth = PointerAlign = 64; LongDoubleWidth = LongDoubleAlign = 128; @@ -4924,7 +5178,6 @@ public: MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } virtual bool setABI(const std::string &Name) { - SetDescriptionString(Name); if (Name == "n32") { LongWidth = LongAlign = 32; PointerWidth = PointerAlign = 32; @@ -5000,20 +5253,21 @@ public: }; class Mips64EBTargetInfo : public Mips64TargetInfoBase { - virtual void SetDescriptionString(const std::string &Name) { - // Change DescriptionString only if ABI is n32. - if (Name == "n32") + virtual void setDescriptionString() { + if (ABI == "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-f128:128:128-" "v64:64:64-n32:64-S128"; + else + 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-f128:128:128-" + "v64:64:64-n32:64-S128"; + } + 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-f128:128:128-" - "v64:64:64-n32:64-S128"; - } + Mips64EBTargetInfo(const llvm::Triple &Triple) + : Mips64TargetInfoBase(Triple) {} virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "MIPSEB", Opts); @@ -5023,20 +5277,21 @@ public: }; class Mips64ELTargetInfo : public Mips64TargetInfoBase { - virtual void SetDescriptionString(const std::string &Name) { - // Change DescriptionString only if ABI is n32. - if (Name == "n32") + virtual void setDescriptionString() { + if (ABI == "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-f128:128:128" "-v64:64:64-n32:64-S128"; + else + 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-f128:128:128-" + "v64:64:64-n32:64-S128"; } public: - Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { + Mips64ELTargetInfo(const llvm::Triple &Triple) + : Mips64TargetInfoBase(Triple) { // 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-f128:128:128-" - "v64:64:64-n32:64-S128"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -5050,7 +5305,7 @@ public: namespace { class PNaClTargetInfo : public TargetInfo { public: - PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) { + PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { BigEndian = false; this->UserLabelPrefix = ""; this->LongAlign = 32; @@ -5129,11 +5384,8 @@ namespace { 0 // cuda_shared }; class SPIRTargetInfo : public TargetInfo { - static const char * const GCCRegNames[]; - static const Builtin::Info BuiltinInfo[]; - std::vector<StringRef> AvailableFeatures; public: - SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) { + SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { assert(getTriple().getOS() == llvm::Triple::UnknownOS && "SPIR target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && @@ -5142,6 +5394,7 @@ namespace { TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &SPIRAddrSpaceMap; + UseAddrSpaceMapMangling = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; @@ -5175,7 +5428,7 @@ namespace { class SPIR32TargetInfo : public SPIRTargetInfo { public: - SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { + SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) { PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; @@ -5193,7 +5446,7 @@ namespace { class SPIR64TargetInfo : public SPIRTargetInfo { public: - SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { + SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) { PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; @@ -5210,300 +5463,374 @@ namespace { }; } +namespace { +class XCoreTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; +public: + XCoreTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + BigEndian = false; + NoAsmVariants = true; + LongLongAlign = 32; + SuitableAlign = 32; + DoubleAlign = LongDoubleAlign = 32; + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + WCharType = UnsignedChar; + WIntType = UnsignedInt; + UseZeroLengthBitfieldAlignment = true; + DescriptionString = "e-p:32:32:32-a0:0:32-n32" + "-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32" + "-f16:16:32-f32:32:32-f64:32:32"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__XS1B__"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + Records = BuiltinInfo; + NumRecords = clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin; + } + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; + } + virtual const char *getClobbers() const { + return ""; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + static const char * const GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr" + }; + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = NULL; + NumAliases = 0; + } + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + return false; + } +}; + +const Builtin::Info XCoreTargetInfo::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/BuiltinsXCore.def" +}; +} // end anonymous namespace. + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// -static TargetInfo *AllocateTarget(const std::string &T) { - llvm::Triple Triple(T); +static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { llvm::Triple::OSType os = Triple.getOS(); switch (Triple.getArch()) { default: return NULL; + case llvm::Triple::xcore: + return new XCoreTargetInfo(Triple); + case llvm::Triple::hexagon: - return new HexagonTargetInfo(T); + return new HexagonTargetInfo(Triple); case llvm::Triple::aarch64: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<AArch64TargetInfo>(T); + return new LinuxTargetInfo<AArch64TargetInfo>(Triple); default: - return new AArch64TargetInfo(T); + return new AArch64TargetInfo(Triple); } case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSDarwin()) - return new DarwinARMTargetInfo(T); + return new DarwinARMTargetInfo(Triple); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<ARMTargetInfo>(T); + return new LinuxTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<ARMTargetInfo>(T); + return new FreeBSDTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<ARMTargetInfo>(T); + return new NetBSDTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<ARMTargetInfo>(T); + return new OpenBSDTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::Bitrig: - return new BitrigTargetInfo<ARMTargetInfo>(T); + return new BitrigTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<ARMTargetInfo>(T); + return new RTEMSTargetInfo<ARMTargetInfo>(Triple); case llvm::Triple::NaCl: - return new NaClTargetInfo<ARMTargetInfo>(T); + return new NaClTargetInfo<ARMTargetInfo>(Triple); default: - return new ARMTargetInfo(T); + return new ARMTargetInfo(Triple); } case llvm::Triple::msp430: - return new MSP430TargetInfo(T); + return new MSP430TargetInfo(Triple); case llvm::Triple::mips: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips32EBTargetInfo>(T); + return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips32EBTargetInfo>(T); + return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T); + return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips32EBTargetInfo>(T); + return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple); default: - return new Mips32EBTargetInfo(T); + return new Mips32EBTargetInfo(Triple); } case llvm::Triple::mipsel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips32ELTargetInfo>(T); + return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips32ELTargetInfo>(T); + return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T); + return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips32ELTargetInfo>(T); + return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple); + case llvm::Triple::NaCl: + return new NaClTargetInfo<Mips32ELTargetInfo>(Triple); default: - return new Mips32ELTargetInfo(T); + return new Mips32ELTargetInfo(Triple); } case llvm::Triple::mips64: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips64EBTargetInfo>(T); + return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips64EBTargetInfo>(T); + return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T); + return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips64EBTargetInfo>(T); + return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T); + return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple); default: - return new Mips64EBTargetInfo(T); + return new Mips64EBTargetInfo(Triple); } case llvm::Triple::mips64el: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips64ELTargetInfo>(T); + return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips64ELTargetInfo>(T); + return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T); + return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips64ELTargetInfo>(T); + return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T); + return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple); default: - return new Mips64ELTargetInfo(T); + return new Mips64ELTargetInfo(Triple); } case llvm::Triple::le32: switch (os) { case llvm::Triple::NaCl: - return new NaClTargetInfo<PNaClTargetInfo>(T); + return new NaClTargetInfo<PNaClTargetInfo>(Triple); default: return NULL; } case llvm::Triple::ppc: if (Triple.isOSDarwin()) - return new DarwinPPC32TargetInfo(T); + return new DarwinPPC32TargetInfo(Triple); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC32TargetInfo>(T); + return new LinuxTargetInfo<PPC32TargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC32TargetInfo>(T); + return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC32TargetInfo>(T); + return new NetBSDTargetInfo<PPC32TargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<PPC32TargetInfo>(T); + return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<PPC32TargetInfo>(T); + return new RTEMSTargetInfo<PPC32TargetInfo>(Triple); default: - return new PPC32TargetInfo(T); + return new PPC32TargetInfo(Triple); } case llvm::Triple::ppc64: if (Triple.isOSDarwin()) - return new DarwinPPC64TargetInfo(T); + return new DarwinPPC64TargetInfo(Triple); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC64TargetInfo>(T); + return new LinuxTargetInfo<PPC64TargetInfo>(Triple); case llvm::Triple::Lv2: - return new PS3PPUTargetInfo<PPC64TargetInfo>(T); + return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC64TargetInfo>(T); + return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC64TargetInfo>(T); + return new NetBSDTargetInfo<PPC64TargetInfo>(Triple); + default: + return new PPC64TargetInfo(Triple); + } + + case llvm::Triple::ppc64le: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<PPC64TargetInfo>(Triple); default: - return new PPC64TargetInfo(T); + return new PPC64TargetInfo(Triple); } case llvm::Triple::nvptx: - return new NVPTX32TargetInfo(T); + return new NVPTX32TargetInfo(Triple); case llvm::Triple::nvptx64: - return new NVPTX64TargetInfo(T); - - case llvm::Triple::mblaze: - return new MBlazeTargetInfo(T); + return new NVPTX64TargetInfo(Triple); case llvm::Triple::r600: - return new R600TargetInfo(T); + return new R600TargetInfo(Triple); case llvm::Triple::sparc: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV8TargetInfo>(T); + return new LinuxTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::AuroraUX: - return new AuroraUXSparcV8TargetInfo(T); + return new AuroraUXSparcV8TargetInfo(Triple); case llvm::Triple::Solaris: - return new SolarisSparcV8TargetInfo(T); + return new SolarisSparcV8TargetInfo(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV8TargetInfo>(T); + return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV8TargetInfo>(T); + return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<SparcV8TargetInfo>(T); + return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple); default: - return new SparcV8TargetInfo(T); + return new SparcV8TargetInfo(Triple); } case llvm::Triple::sparcv9: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV9TargetInfo>(T); + return new LinuxTargetInfo<SparcV9TargetInfo>(Triple); case llvm::Triple::AuroraUX: - return new AuroraUXTargetInfo<SparcV9TargetInfo>(T); + return new AuroraUXTargetInfo<SparcV9TargetInfo>(Triple); case llvm::Triple::Solaris: - return new SolarisTargetInfo<SparcV9TargetInfo>(T); + return new SolarisTargetInfo<SparcV9TargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV9TargetInfo>(T); + return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV9TargetInfo>(T); + return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<SparcV9TargetInfo>(T); + return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple); default: - return new SparcV9TargetInfo(T); + return new SparcV9TargetInfo(Triple); } case llvm::Triple::systemz: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SystemZTargetInfo>(T); + return new LinuxTargetInfo<SystemZTargetInfo>(Triple); default: - return new SystemZTargetInfo(T); + return new SystemZTargetInfo(Triple); } case llvm::Triple::tce: - return new TCETargetInfo(T); + return new TCETargetInfo(Triple); case llvm::Triple::x86: if (Triple.isOSDarwin()) - return new DarwinI386TargetInfo(T); + return new DarwinI386TargetInfo(Triple); switch (os) { case llvm::Triple::AuroraUX: - return new AuroraUXTargetInfo<X86_32TargetInfo>(T); + return new AuroraUXTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::Linux: - return new LinuxTargetInfo<X86_32TargetInfo>(T); + return new LinuxTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); + return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDI386TargetInfo(T); + return new NetBSDI386TargetInfo(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDI386TargetInfo(T); + return new OpenBSDI386TargetInfo(Triple); case llvm::Triple::Bitrig: - return new BitrigI386TargetInfo(T); + return new BitrigI386TargetInfo(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_32TargetInfo>(T); + return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple); + case llvm::Triple::KFreeBSD: + return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::Minix: - return new MinixTargetInfo<X86_32TargetInfo>(T); + return new MinixTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_32TargetInfo>(T); + return new SolarisTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::Cygwin: - return new CygwinX86_32TargetInfo(T); + return new CygwinX86_32TargetInfo(Triple); case llvm::Triple::MinGW32: - return new MinGWX86_32TargetInfo(T); + return new MinGWX86_32TargetInfo(Triple); case llvm::Triple::Win32: - return new VisualStudioWindowsX86_32TargetInfo(T); + return new VisualStudioWindowsX86_32TargetInfo(Triple); case llvm::Triple::Haiku: - return new HaikuX86_32TargetInfo(T); + return new HaikuX86_32TargetInfo(Triple); case llvm::Triple::RTEMS: - return new RTEMSX86_32TargetInfo(T); + return new RTEMSX86_32TargetInfo(Triple); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_32TargetInfo>(T); + return new NaClTargetInfo<X86_32TargetInfo>(Triple); default: - return new X86_32TargetInfo(T); + return new X86_32TargetInfo(Triple); } case llvm::Triple::x86_64: if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO) - return new DarwinX86_64TargetInfo(T); + return new DarwinX86_64TargetInfo(Triple); switch (os) { case llvm::Triple::AuroraUX: - return new AuroraUXTargetInfo<X86_64TargetInfo>(T); + return new AuroraUXTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::Linux: - return new LinuxTargetInfo<X86_64TargetInfo>(T); + return new LinuxTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T); + return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<X86_64TargetInfo>(T); + return new NetBSDTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::OpenBSD: - return new OpenBSDX86_64TargetInfo(T); + return new OpenBSDX86_64TargetInfo(Triple); case llvm::Triple::Bitrig: - return new BitrigX86_64TargetInfo(T); + return new BitrigX86_64TargetInfo(Triple); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_64TargetInfo>(T); + return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple); + case llvm::Triple::KFreeBSD: + return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_64TargetInfo>(T); + return new SolarisTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::MinGW32: - return new MinGWX86_64TargetInfo(T); + return new MinGWX86_64TargetInfo(Triple); case llvm::Triple::Win32: // This is what Triple.h supports now. - return new VisualStudioWindowsX86_64TargetInfo(T); + return new VisualStudioWindowsX86_64TargetInfo(Triple); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_64TargetInfo>(T); + return new NaClTargetInfo<X86_64TargetInfo>(Triple); default: - return new X86_64TargetInfo(T); + return new X86_64TargetInfo(Triple); } case llvm::Triple::spir: { - llvm::Triple Triple(T); if (Triple.getOS() != llvm::Triple::UnknownOS || - Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return NULL; - return new SPIR32TargetInfo(T); + return new SPIR32TargetInfo(Triple); } case llvm::Triple::spir64: { - llvm::Triple Triple(T); if (Triple.getOS() != llvm::Triple::UnknownOS || - Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return NULL; - return new SPIR64TargetInfo(T); + return new SPIR64TargetInfo(Triple); } } } @@ -5515,7 +5842,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(Opts->Triple); // Construct the target - OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); + OwningPtr<TargetInfo> Target(AllocateTarget(Triple)); if (!Target) { Diags.Report(diag::err_target_unknown_triple) << Triple.str(); return 0; @@ -5540,45 +5867,24 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, return 0; } + // Set the fp math unit. + if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) { + Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath; + return 0; + } + // 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(Features); // Apply the user specified deltas. - // First the enables. - for (std::vector<std::string>::const_iterator - it = Opts->FeaturesAsWritten.begin(), - ie = Opts->FeaturesAsWritten.end(); - it != ie; ++it) { - const char *Name = it->c_str(); - - if (Name[0] != '+') - continue; - + for (unsigned I = 0, N = Opts->FeaturesAsWritten.size(); + I < N; ++I) { + const char *Name = Opts->FeaturesAsWritten[I].c_str(); // Apply the feature via the target. - if (!Target->setFeatureEnabled(Features, Name + 1, true)) { - Diags.Report(diag::err_target_invalid_feature) << Name; - return 0; - } - } - - // Then the disables. - for (std::vector<std::string>::const_iterator - it = Opts->FeaturesAsWritten.begin(), - ie = Opts->FeaturesAsWritten.end(); - it != ie; ++it) { - const char *Name = it->c_str(); - - if (Name[0] == '+') - continue; - - // Apply the feature via the target. - if (Name[0] != '-' || - !Target->setFeatureEnabled(Features, Name + 1, false)) { - Diags.Report(diag::err_target_invalid_feature) << Name; - return 0; - } + bool Enabled = Name[0] == '+'; + Target->setFeatureEnabled(Features, Name + 1, Enabled); } // Add the features to the compile options. @@ -5589,7 +5895,8 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, for (llvm::StringMap<bool>::const_iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) Opts->Features.push_back((it->second ? "+" : "-") + it->first().str()); - Target->HandleTargetFeatures(Opts->Features); + if (!Target->handleTargetFeatures(Opts->Features, Diags)) + return 0; return Target.take(); } |