summaryrefslogtreecommitdiffstats
path: root/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic/Targets.cpp')
-rw-r--r--lib/Basic/Targets.cpp1008
1 files changed, 711 insertions, 297 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index b89ea0c..1ad37c4 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -54,6 +54,14 @@ static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
Builder.defineMacro("__" + MacroName + "__");
}
+static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
+ bool Tuning = true) {
+ Builder.defineMacro("__" + CPUName);
+ Builder.defineMacro("__" + CPUName + "__");
+ if (Tuning)
+ Builder.defineMacro("__tune_" + CPUName + "__");
+}
+
//===----------------------------------------------------------------------===//
// Defines specific to certain operating systems.
//===----------------------------------------------------------------------===//
@@ -99,13 +107,6 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
// allow this in C, since one might have block pointers in structs that
// are used in pure C code and in Objective-C ARC.
Builder.defineMacro("__unsafe_unretained", "");
-
- // The Objective-C bridged cast keywords are defined to nothing in non-ARC
- // mode; then they become normal, C-style casts.
- Builder.defineMacro("__bridge", "");
- Builder.defineMacro("__bridge_transfer", "");
- Builder.defineMacro("__bridge_retained", "");
- Builder.defineMacro("__bridge_retain", "");
}
if (Opts.Static)
@@ -118,36 +119,15 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
// Get the platform type and version number from the triple.
unsigned Maj, Min, Rev;
-
- // If no version was given, default to to 10.4.0, for simplifying tests.
- if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") {
+ if (Triple.isMacOSX()) {
+ Triple.getMacOSXVersion(Maj, Min, Rev);
PlatformName = "macosx";
- Min = Rev = 0;
- Maj = 8;
} else {
- // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]",
- // "-osxNNN", and "-iosNNN").
-
- if (Triple.getOS() == llvm::Triple::Darwin) {
- // For historical reasons that make little sense, the version passed here
- // is the "darwin" version, which drops the 10 and offsets by 4.
- Triple.getOSVersion(Maj, Min, Rev);
-
- if (Triple.getEnvironmentName() == "iphoneos") {
- PlatformName = "ios";
- } else {
- PlatformName = "macosx";
- Rev = Min;
- Min = Maj - 4;
- Maj = 10;
- }
- } else {
- Triple.getOSVersion(Maj, Min, Rev);
- PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
- }
+ Triple.getOSVersion(Maj, Min, Rev);
+ PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
}
- // If -ccc-host-triple arch-pc-win32-macho option specified, we're
+ // If -target arch-pc-win32-macho option specified, we're
// generating code for Win32 ABI. No need to emit
// __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
if (PlatformName == "win32") {
@@ -156,7 +136,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
}
// Set the appropriate OS version define.
- if (PlatformName == "ios") {
+ if (Triple.getOS() == llvm::Triple::IOS) {
assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
char Str[6];
Str[0] = '0' + Maj;
@@ -217,6 +197,12 @@ public:
return "__TEXT,__StaticInit,regular,pure_instructions";
}
+ /// Darwin does not support protected visibility. Darwin's "default"
+ /// is very similar to ELF's "protected"; Darwin requires a "weak"
+ /// attribute on declarations that can be dynamically replaced.
+ virtual bool hasProtectedVisibility() const {
+ return false;
+ }
};
@@ -236,7 +222,18 @@ protected:
}
public:
DragonFlyBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {}
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+
+ llvm::Triple Triple(triple);
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->MCountName = ".mcount";
+ break;
+ }
+ }
};
// FreeBSD Target
@@ -298,6 +295,7 @@ protected:
Builder.defineMacro("_EM_LSIZE", "4");
Builder.defineMacro("_EM_FSIZE", "4");
Builder.defineMacro("_EM_DSIZE", "8");
+ Builder.defineMacro("__ELF__");
DefineStd(Builder, "unix", Opts);
}
public:
@@ -329,6 +327,10 @@ public:
this->UserLabelPrefix = "";
this->WIntType = TargetInfo::UnsignedInt;
}
+
+ virtual const char *getStaticInitSectionSpecifier() const {
+ return ".text.startup";
+ }
};
// NetBSD Target
@@ -367,7 +369,26 @@ protected:
}
public:
OpenBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {}
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+
+ llvm::Triple Triple(triple);
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ case llvm::Triple::arm:
+ case llvm::Triple::sparc:
+ this->MCountName = "__mcount";
+ break;
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::ppc:
+ case llvm::Triple::sparcv9:
+ this->MCountName = "_mcount";
+ break;
+ }
+ }
};
// PSP Target
@@ -408,13 +429,14 @@ public:
PS3PPUTargetInfo(const std::string& triple)
: OSTargetInfo<Target>(triple) {
this->UserLabelPrefix = "";
- this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
+ this->LongWidth = this->LongAlign = 32;
+ this->PointerWidth = this->PointerAlign = 32;
this->IntMaxType = TargetInfo::SignedLongLong;
this->UIntMaxType = TargetInfo::UnsignedLongLong;
this->Int64Type = TargetInfo::SignedLongLong;
this->SizeType = TargetInfo::UnsignedInt;
this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
+ "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
}
};
@@ -468,12 +490,26 @@ protected:
Builder.defineMacro("__ELF__");
Builder.defineMacro("__svr4__");
Builder.defineMacro("__SVR4");
+ // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
+ // newer, but to 500 for everything else. feature_test.h has a check to
+ // ensure that you are not using C99 with an old version of X/Open or C89
+ // with a new version.
+ if (Opts.C99 || Opts.C11)
+ Builder.defineMacro("_XOPEN_SOURCE", "600");
+ else
+ Builder.defineMacro("_XOPEN_SOURCE", "500");
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("__C99FEATURES__");
+ Builder.defineMacro("_LARGEFILE_SOURCE");
+ Builder.defineMacro("_LARGEFILE64_SOURCE");
+ Builder.defineMacro("__EXTENSIONS__");
+ Builder.defineMacro("_REENTRANT");
}
public:
SolarisTargetInfo(const std::string& triple)
: OSTargetInfo<Target>(triple) {
this->UserLabelPrefix = "";
- this->WCharType = this->SignedLong;
+ this->WCharType = this->SignedInt;
// FIXME: WIntType should be SignedLong
}
};
@@ -538,7 +574,10 @@ class PPCTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
public:
- PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
+ PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ LongDoubleWidth = LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
+ }
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
@@ -546,9 +585,13 @@ public:
NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
}
+ virtual bool isCLZForZeroUndef() const { return false; }
+
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const;
+ virtual bool hasFeature(StringRef Feature) const;
+
virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const;
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -701,7 +744,11 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
}
}
+bool PPCTargetInfo::hasFeature(StringRef Feature) const {
+ return Feature == "powerpc";
+}
+
const char * const PPCTargetInfo::GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
@@ -814,13 +861,21 @@ public:
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
switch (getTriple().getOS()) {
+ case llvm::Triple::Linux:
case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
break;
default:
break;
}
+
+ if (getTriple().getOS() == llvm::Triple::FreeBSD) {
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+ }
}
virtual const char *getVAListDeclaration() const {
@@ -846,6 +901,11 @@ public:
Int64Type = SignedLong;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
+
+ if (getTriple().getOS() == llvm::Triple::FreeBSD) {
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+ }
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@@ -862,6 +922,10 @@ public:
: DarwinTargetInfo<PPC32TargetInfo>(triple) {
HasAlignMac68kSupport = true;
BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
+ LongLongAlign = 32;
+ SuitableAlign = 128;
+ DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+ "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32";
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@@ -874,6 +938,7 @@ public:
DarwinPPC64TargetInfo(const std::string& triple)
: DarwinTargetInfo<PPC64TargetInfo>(triple) {
HasAlignMac68kSupport = true;
+ SuitableAlign = 128;
}
};
} // end anonymous namespace.
@@ -890,6 +955,7 @@ namespace {
std::vector<llvm::StringRef> AvailableFeatures;
public:
PTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ BigEndian = false;
TLSSupported = false;
LongWidth = LongAlign = 64;
AddrSpaceMap = &PTXAddrSpaceMap;
@@ -924,7 +990,10 @@ namespace {
Records = BuiltinInfo;
NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
}
-
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "ptx";
+ }
+
virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const;
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -948,7 +1017,7 @@ namespace {
}
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const;
};
@@ -970,7 +1039,7 @@ namespace {
}
bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const {
if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(),
Name)) {
@@ -1023,6 +1092,10 @@ public:
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const;
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "mblaze";
+ }
+
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
}
@@ -1146,6 +1219,8 @@ static const char* const GCCRegNames[] = {
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
+ "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
+ "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
};
const TargetInfo::AddlRegName AddlRegNames[] = {
@@ -1163,14 +1238,18 @@ const TargetInfo::AddlRegName AddlRegNames[] = {
// most of the implementation can be shared.
class X86TargetInfo : public TargetInfo {
enum X86SSEEnum {
- NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
+ NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2
} SSELevel;
enum MMX3DNowEnum {
NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
} MMX3DNowLevel;
bool HasAES;
- bool HasAVX;
+ bool HasLZCNT;
+ bool HasBMI;
+ bool HasBMI2;
+ bool HasPOPCNT;
+ bool HasFMA4;
/// \brief Enumeration of all of the X86 CPUs supported by Clang.
///
@@ -1252,6 +1331,7 @@ class X86TargetInfo : public TargetInfo {
CK_Corei7,
CK_Corei7AVX,
CK_CoreAVXi,
+ CK_CoreAVX2,
//@}
/// \name K6
@@ -1282,6 +1362,21 @@ class X86TargetInfo : public TargetInfo {
CK_K8SSE3,
CK_Opteron,
CK_OpteronSSE3,
+ CK_AMDFAM10,
+ //@}
+
+ /// \name Bobcat
+ /// Bobcat architecture processors.
+ //@{
+ CK_BTVER1,
+ //@}
+
+ /// \name Bulldozer
+ /// Bulldozer architecture processors.
+ //@{
+ CK_BDVER1,
+ CK_BDVER2,
+ //@}
/// This specification is deprecated and will be removed in the future.
/// Users should prefer \see CK_K8.
@@ -1299,9 +1394,15 @@ class X86TargetInfo : public TargetInfo {
public:
X86TargetInfo(const std::string& triple)
: TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
- HasAES(false), HasAVX(false), CPU(CK_Generic) {
+ HasAES(false), HasLZCNT(false), HasBMI(false), HasBMI2(false),
+ HasPOPCNT(false), HasFMA4(false), CPU(CK_Generic) {
+ BigEndian = false;
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
+ virtual unsigned getFloatEvalMethod() const {
+ // X87 evaluates with 80 bits "long double" precision.
+ return SSELevel == NoSSE ? 2 : 0;
+ }
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
Records = BuiltinInfo;
@@ -1331,12 +1432,17 @@ public:
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const;
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const;
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
+ virtual bool hasFeature(StringRef Feature) const;
virtual void HandleTargetFeatures(std::vector<std::string> &Features);
virtual const char* getABI() const {
- return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : "";
+ if (PointerWidth == 64 && SSELevel >= AVX)
+ return "avx";
+ else if (PointerWidth == 32 && MMX3DNowLevel == NoMMX3DNow)
+ return "no-mmx";
+ return "";
}
virtual bool setCPU(const std::string &Name) {
CPU = llvm::StringSwitch<CPUKind>(Name)
@@ -1366,6 +1472,7 @@ public:
.Case("corei7", CK_Corei7)
.Case("corei7-avx", CK_Corei7AVX)
.Case("core-avx-i", CK_CoreAVXi)
+ .Case("core-avx2", CK_CoreAVX2)
.Case("k6", CK_K6)
.Case("k6-2", CK_K6_2)
.Case("k6-3", CK_K6_3)
@@ -1381,6 +1488,10 @@ public:
.Case("k8-sse3", CK_K8SSE3)
.Case("opteron", CK_Opteron)
.Case("opteron-sse3", CK_OpteronSSE3)
+ .Case("amdfam10", CK_AMDFAM10)
+ .Case("btver1", CK_BTVER1)
+ .Case("bdver1", CK_BDVER1)
+ .Case("bdver2", CK_BDVER2)
.Case("x86-64", CK_x86_64)
.Case("geode", CK_Geode)
.Default(CK_Generic);
@@ -1434,6 +1545,7 @@ public:
case CK_Corei7:
case CK_Corei7AVX:
case CK_CoreAVXi:
+ case CK_CoreAVX2:
case CK_Athlon64:
case CK_Athlon64SSE3:
case CK_AthlonFX:
@@ -1441,6 +1553,10 @@ public:
case CK_K8SSE3:
case CK_Opteron:
case CK_OpteronSSE3:
+ case CK_AMDFAM10:
+ case CK_BTVER1:
+ case CK_BDVER1:
+ case CK_BDVER2:
case CK_x86_64:
return true;
}
@@ -1459,11 +1575,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
Features["ssse3"] = false;
Features["sse41"] = false;
Features["sse42"] = false;
+ Features["sse4a"] = false;
Features["aes"] = false;
Features["avx"] = false;
-
- // LLVM does not currently recognize this.
- // Features["sse4a"] = false;
+ Features["avx2"] = false;
+ Features["lzcnt"] = false;
+ Features["bmi"] = false;
+ Features["bmi2"] = false;
+ Features["popcnt"] = false;
+ Features["fma4"] = false;
// FIXME: This *really* should not be here.
@@ -1508,8 +1628,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
break;
case CK_Penryn:
setFeatureEnabled(Features, "mmx", true);
- setFeatureEnabled(Features, "sse4", true);
- Features["sse42"] = false;
+ setFeatureEnabled(Features, "sse4.1", true);
break;
case CK_Atom:
setFeatureEnabled(Features, "mmx", true);
@@ -1527,6 +1646,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabled(Features, "aes", true);
//setFeatureEnabled(Features, "avx", true);
break;
+ case CK_CoreAVX2:
+ setFeatureEnabled(Features, "mmx", true);
+ setFeatureEnabled(Features, "sse4", true);
+ setFeatureEnabled(Features, "aes", true);
+ setFeatureEnabled(Features, "lzcnt", true);
+ setFeatureEnabled(Features, "bmi", true);
+ setFeatureEnabled(Features, "bmi2", true);
+ //setFeatureEnabled(Features, "avx2", true);
+ break;
case CK_K6:
case CK_WinChipC6:
setFeatureEnabled(Features, "mmx", true);
@@ -1561,6 +1689,20 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabled(Features, "sse3", true);
setFeatureEnabled(Features, "3dnowa", true);
break;
+ case CK_AMDFAM10:
+ setFeatureEnabled(Features, "sse3", true);
+ setFeatureEnabled(Features, "sse4a", true);
+ setFeatureEnabled(Features, "3dnowa", true);
+ break;
+ case CK_BTVER1:
+ setFeatureEnabled(Features, "ssse3", true);
+ setFeatureEnabled(Features, "sse4a", true);
+ case CK_BDVER1:
+ case CK_BDVER2:
+ setFeatureEnabled(Features, "sse4", true);
+ setFeatureEnabled(Features, "sse4a", true);
+ setFeatureEnabled(Features, "aes", true);
+ break;
case CK_C3_2:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse", true);
@@ -1569,7 +1711,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
}
bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const {
// FIXME: This *really* should not be here. We need some way of translating
// options into llvm subtarget features.
@@ -1577,23 +1719,27 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
(Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
return false;
+ // FIXME: this should probably use a switch with fall through.
+
if (Enabled) {
if (Name == "mmx")
Features["mmx"] = true;
else if (Name == "sse")
- Features["sse"] = true;
+ Features["mmx"] = Features["sse"] = true;
else if (Name == "sse2")
- Features["sse"] = Features["sse2"] = true;
+ Features["mmx"] = Features["sse"] = Features["sse2"] = true;
else if (Name == "sse3")
- Features["sse"] = Features["sse2"] = Features["sse3"] = true;
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ true;
else if (Name == "ssse3")
- Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = true;
else if (Name == "sse4" || Name == "sse4.2")
- Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] =
+ Features["popcnt"] = true;
else if (Name == "sse4.1")
- Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = true;
else if (Name == "3dnow")
Features["mmx"] = Features["3dnow"] = true;
@@ -1602,20 +1748,41 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
else if (Name == "aes")
Features["aes"] = true;
else if (Name == "avx")
- Features["avx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
+ 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 == "fma4")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] =
+ Features["popcnt"] = Features["avx"] = Features["fma4"] = true;
+ else if (Name == "sse4a")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["lzcnt"] = Features["popcnt"] = Features["sse4a"] = true;
+ else if (Name == "lzcnt")
+ Features["lzcnt"] = true;
+ else if (Name == "bmi")
+ Features["bmi"] = true;
+ else if (Name == "bmi2")
+ Features["bmi2"] = true;
+ else if (Name == "popcnt")
+ Features["popcnt"] = true;
} else {
if (Name == "mmx")
Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
else if (Name == "sse")
Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] =
+ Features["sse4a"] = false;
else if (Name == "sse2")
Features["sse2"] = Features["sse3"] = Features["ssse3"] =
- Features["sse41"] = Features["sse42"] = false;
+ Features["sse41"] = Features["sse42"] = Features["sse4a"] = false;
else if (Name == "sse3")
Features["sse3"] = Features["ssse3"] = Features["sse41"] =
- Features["sse42"] = false;
+ Features["sse42"] = Features["sse4a"] = false;
else if (Name == "ssse3")
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
else if (Name == "sse4" || Name == "sse4.1")
@@ -1629,7 +1796,21 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
else if (Name == "aes")
Features["aes"] = false;
else if (Name == "avx")
- Features["avx"] = false;
+ Features["avx"] = Features["avx2"] = Features["fma4"] = false;
+ else if (Name == "avx2")
+ Features["avx2"] = false;
+ else if (Name == "sse4a")
+ Features["sse4a"] = false;
+ else if (Name == "lzcnt")
+ Features["lzcnt"] = false;
+ else if (Name == "bmi")
+ Features["bmi"] = false;
+ else if (Name == "bmi2")
+ Features["bmi2"] = false;
+ else if (Name == "popcnt")
+ Features["popcnt"] = false;
+ else if (Name == "fma4")
+ Features["fma4"] = false;
}
return true;
@@ -1644,20 +1825,42 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
if (Features[i][0] == '-')
continue;
- if (Features[i].substr(1) == "aes") {
+ StringRef Feature = StringRef(Features[i]).substr(1);
+
+ if (Feature == "aes") {
HasAES = true;
continue;
}
- // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
- // For now let it be enabled together with other SSE levels.
- if (Features[i].substr(1) == "avx") {
- HasAVX = true;
+ if (Feature == "lzcnt") {
+ HasLZCNT = true;
+ continue;
+ }
+
+ if (Feature == "bmi") {
+ HasBMI = true;
+ continue;
+ }
+
+ if (Feature == "bmi2") {
+ HasBMI2 = true;
+ continue;
+ }
+
+ if (Feature == "popcnt") {
+ HasPOPCNT = true;
+ continue;
+ }
+
+ if (Feature == "fma4") {
+ HasFMA4 = true;
continue;
}
assert(Features[i][0] == '+' && "Invalid target feature!");
- X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
+ X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
+ .Case("avx2", AVX2)
+ .Case("avx", AVX)
.Case("sse42", SSE42)
.Case("sse41", SSE41)
.Case("ssse3", SSSE3)
@@ -1668,7 +1871,7 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
SSELevel = std::max(SSELevel, Level);
MMX3DNowEnum ThreeDNowLevel =
- llvm::StringSwitch<MMX3DNowEnum>(Features[i].substr(1))
+ llvm::StringSwitch<MMX3DNowEnum>(Feature)
.Case("3dnowa", AMD3DNowAthlon)
.Case("3dnow", AMD3DNow)
.Case("mmx", MMX)
@@ -1691,8 +1894,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Target identification.
if (PointerWidth == 64) {
- Builder.defineMacro("_LP64");
- Builder.defineMacro("__LP64__");
+ if (getLongWidth() == 64) {
+ Builder.defineMacro("_LP64");
+ Builder.defineMacro("__LP64__");
+ }
Builder.defineMacro("__amd64__");
Builder.defineMacro("__amd64");
Builder.defineMacro("__x86_64");
@@ -1715,9 +1920,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_WinChipC6:
case CK_WinChip2:
case CK_C3:
- Builder.defineMacro("__i486");
- Builder.defineMacro("__i486__");
- Builder.defineMacro("__tune_i486__");
+ defineCPUMacros(Builder, "i486");
break;
case CK_PentiumMMX:
Builder.defineMacro("__pentium_mmx__");
@@ -1725,12 +1928,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
// Fallthrough
case CK_i586:
case CK_Pentium:
- Builder.defineMacro("__i586");
- Builder.defineMacro("__i586__");
- Builder.defineMacro("__tune_i586__");
- Builder.defineMacro("__pentium");
- Builder.defineMacro("__pentium__");
- Builder.defineMacro("__tune_pentium__");
+ defineCPUMacros(Builder, "i586");
+ defineCPUMacros(Builder, "pentium");
break;
case CK_Pentium3:
case CK_Pentium3M:
@@ -1754,34 +1953,25 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
break;
case CK_Pentium4:
case CK_Pentium4M:
- Builder.defineMacro("__pentium4");
- Builder.defineMacro("__pentium4__");
- Builder.defineMacro("__tune_pentium4__");
+ defineCPUMacros(Builder, "pentium4");
break;
case CK_Yonah:
case CK_Prescott:
case CK_Nocona:
- Builder.defineMacro("__nocona");
- Builder.defineMacro("__nocona__");
- Builder.defineMacro("__tune_nocona__");
+ defineCPUMacros(Builder, "nocona");
break;
case CK_Core2:
case CK_Penryn:
- Builder.defineMacro("__core2");
- Builder.defineMacro("__core2__");
- Builder.defineMacro("__tune_core2__");
+ defineCPUMacros(Builder, "core2");
break;
case CK_Atom:
- Builder.defineMacro("__atom");
- Builder.defineMacro("__atom__");
- Builder.defineMacro("__tune_atom__");
+ defineCPUMacros(Builder, "atom");
break;
case CK_Corei7:
case CK_Corei7AVX:
case CK_CoreAVXi:
- Builder.defineMacro("__corei7");
- Builder.defineMacro("__corei7__");
- Builder.defineMacro("__tune_corei7__");
+ case CK_CoreAVX2:
+ defineCPUMacros(Builder, "corei7");
break;
case CK_K6_2:
Builder.defineMacro("__k6_2__");
@@ -1797,18 +1987,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
}
// Fallthrough
case CK_K6:
- Builder.defineMacro("__k6");
- Builder.defineMacro("__k6__");
- Builder.defineMacro("__tune_k6__");
+ defineCPUMacros(Builder, "k6");
break;
case CK_Athlon:
case CK_AthlonThunderbird:
case CK_Athlon4:
case CK_AthlonXP:
case CK_AthlonMP:
- Builder.defineMacro("__athlon");
- Builder.defineMacro("__athlon__");
- Builder.defineMacro("__tune_athlon__");
+ defineCPUMacros(Builder, "athlon");
if (SSELevel != NoSSE) {
Builder.defineMacro("__athlon_sse__");
Builder.defineMacro("__tune_athlon_sse__");
@@ -1822,14 +2008,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Athlon64:
case CK_Athlon64SSE3:
case CK_AthlonFX:
- Builder.defineMacro("__k8");
- Builder.defineMacro("__k8__");
- Builder.defineMacro("__tune_k8__");
+ defineCPUMacros(Builder, "k8");
+ break;
+ case CK_AMDFAM10:
+ defineCPUMacros(Builder, "amdfam10");
+ break;
+ case CK_BTVER1:
+ defineCPUMacros(Builder, "btver1");
+ break;
+ case CK_BDVER1:
+ defineCPUMacros(Builder, "bdver1");
+ break;
+ case CK_BDVER2:
+ defineCPUMacros(Builder, "bdver2");
break;
case CK_Geode:
- Builder.defineMacro("__geode");
- Builder.defineMacro("__geode__");
- Builder.defineMacro("__tune_geode__");
+ defineCPUMacros(Builder, "geode");
break;
}
@@ -1845,11 +2039,27 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasAES)
Builder.defineMacro("__AES__");
- if (HasAVX)
- Builder.defineMacro("__AVX__");
+ if (HasLZCNT)
+ Builder.defineMacro("__LZCNT__");
+
+ if (HasBMI)
+ Builder.defineMacro("__BMI__");
+
+ if (HasBMI2)
+ Builder.defineMacro("__BMI2__");
+
+ if (HasPOPCNT)
+ Builder.defineMacro("__POPCNT__");
+
+ if (HasFMA4)
+ Builder.defineMacro("__FMA4__");
// Each case falls through to the previous one here.
switch (SSELevel) {
+ case AVX2:
+ Builder.defineMacro("__AVX2__");
+ case AVX:
+ Builder.defineMacro("__AVX__");
case SSE42:
Builder.defineMacro("__SSE4_2__");
case SSE41:
@@ -1870,6 +2080,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.MicrosoftExt && PointerWidth == 32) {
switch (SSELevel) {
+ case AVX2:
+ case AVX:
case SSE42:
case SSE41:
case SSSE3:
@@ -1898,6 +2110,30 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
}
}
+bool X86TargetInfo::hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("aes", HasAES)
+ .Case("avx", SSELevel >= AVX)
+ .Case("avx2", SSELevel >= AVX2)
+ .Case("bmi", HasBMI)
+ .Case("bmi2", HasBMI2)
+ .Case("fma4", HasFMA4)
+ .Case("lzcnt", HasLZCNT)
+ .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
+ .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
+ .Case("mmx", MMX3DNowLevel >= MMX)
+ .Case("popcnt", HasPOPCNT)
+ .Case("sse", SSELevel >= SSE1)
+ .Case("sse2", SSELevel >= SSE2)
+ .Case("sse3", SSELevel >= SSE3)
+ .Case("ssse3", SSELevel >= SSSE3)
+ .Case("sse41", SSELevel >= SSE41)
+ .Case("sse42", SSELevel >= SSE42)
+ .Case("x86", true)
+ .Case("x86_32", PointerWidth == 32)
+ .Case("x86_64", PointerWidth == 64)
+ .Default(false);
+}
bool
X86TargetInfo::validateAsmConstraint(const char *&Name,
@@ -1940,7 +2176,6 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
// x86_64 instructions.
return true;
}
- return false;
}
@@ -1973,6 +2208,7 @@ public:
DoubleAlign = LongLongAlign = 32;
LongDoubleWidth = 96;
LongDoubleAlign = 32;
+ SuitableAlign = 128;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
"a0:0:64-f80:32:32-n8:16:32-S128";
@@ -2004,6 +2240,20 @@ public:
} // end anonymous namespace
namespace {
+class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
+public:
+ NetBSDI386TargetInfo(const std::string &triple) :
+ NetBSDTargetInfo<X86_32TargetInfo>(triple) {
+ }
+
+ virtual unsigned getFloatEvalMethod() const {
+ // NetBSD defaults to "double" rounding
+ return 1;
+ }
+};
+} // end anonymous namespace
+
+namespace {
class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
public:
OpenBSDI386TargetInfo(const std::string& triple) :
@@ -2022,6 +2272,7 @@ public:
DarwinTargetInfo<X86_32TargetInfo>(triple) {
LongDoubleWidth = 128;
LongDoubleAlign = 128;
+ SuitableAlign = 128;
SizeType = UnsignedLong;
IntPtrType = SignedLong;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -2214,6 +2465,7 @@ public:
LongDoubleAlign = 128;
LargeArrayMinWidth = 128;
LargeArrayAlign = 128;
+ SuitableAlign = 128;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
Int64Type = SignedLong;
@@ -2226,6 +2478,9 @@ public:
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
+ // Use fp2ret for _Complex long double.
+ ComplexLongDoubleUsesFP2Ret = true;
+
// x86-64 has atomics up to 16 bytes.
// FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
// on CPUs with cmpxchg16b
@@ -2380,8 +2635,11 @@ public:
ARMTargetInfo(const std::string &TripleStr)
: TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
{
+ BigEndian = false;
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
+ // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
+ WCharType = UnsignedInt;
// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
@@ -2407,6 +2665,12 @@ public:
// ARM has atomics up to 8 bytes
// FIXME: Set MaxAtomicInlineWidth if we have the feature v6e
MaxAtomicPromoteWidth = 64;
+
+ // Do force alignment of members that follow zero length bitfields. If
+ // the alignment of the zero-length bitfield is greater than the member
+ // that follows it, `bar', `bar' will be aligned as the type of the
+ // zero length bitfield.
+ UseZeroLengthBitfieldAlignment = true;
}
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) {
@@ -2417,19 +2681,16 @@ public:
// FIXME: We need support for -meabi... we could just mangle it into the
// name.
if (Name == "apcs-gnu") {
- DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
+ DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
SizeType = UnsignedLong;
+ // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
+ WCharType = SignedInt;
+
// Do not respect the alignment of bit-field types when laying out
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
UseBitFieldTypeAlignment = false;
- /// Do force alignment of members that follow zero length bitfields. If
- /// the alignment of the zero-length bitfield is greater than the member
- /// that follows it, `bar', `bar' will be aligned as the type of the
- /// zero length bitfield.
- UseZeroLengthBitfieldAlignment = true;
-
/// gcc forces the alignment to 4 bytes, regardless of the type of the
/// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
/// gcc.
@@ -2466,10 +2727,11 @@ public:
}
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const {
if (Name == "soft-float" || Name == "soft-float-abi" ||
- Name == "vfp2" || Name == "vfp3" || Name == "neon") {
+ Name == "vfp2" || Name == "vfp3" || Name == "neon" || Name == "d16" ||
+ Name == "neonfp") {
Features[Name] = Enabled;
} else
return false;
@@ -2503,6 +2765,15 @@ public:
Features.erase(it);
}
+ virtual bool hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("arm", true)
+ .Case("softfloat", SoftFloat)
+ .Case("thumb", IsThumb)
+ .Case("neon", FPU == NeonFPU && !SoftFloat &&
+ StringRef(getCPUDefineSuffix(CPU)).startswith("7"))
+ .Default(false);
+ }
static const char *getCPUDefineSuffix(StringRef Name) {
return llvm::StringSwitch<const char*>(Name)
.Cases("arm8", "arm810", "4")
@@ -2521,6 +2792,7 @@ public:
.Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
.Cases("cortex-a8", "cortex-a9", "7A")
.Case("cortex-m3", "7M")
+ .Case("cortex-m4", "7M")
.Case("cortex-m0", "6M")
.Default(0);
}
@@ -2587,6 +2859,7 @@ public:
Records = BuiltinInfo;
NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
}
+ virtual bool isCLZForZeroUndef() const { return false; }
virtual const char *getVAListDeclaration() const {
return "typedef void* __builtin_va_list;";
}
@@ -2710,7 +2983,6 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
};
} // end anonymous namespace.
-
namespace {
class DarwinARMTargetInfo :
public DarwinTargetInfo<ARMTargetInfo> {
@@ -2731,6 +3003,154 @@ public:
};
} // end anonymous namespace.
+
+namespace {
+// Hexagon abstract base class
+class HexagonTargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+ static const char * const GCCRegNames[];
+ static const TargetInfo::GCCRegAlias GCCRegAliases[];
+ std::string CPU;
+public:
+ HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ BigEndian = false;
+ DescriptionString = ("e-p:32:32:32-"
+ "i64:64:64-i32:32:32-"
+ "i16:16:16-i1:32:32-a:0:0");
+
+ // {} in inline assembly are packet specifiers, not assembly variant
+ // specifiers.
+ NoAsmVariants = true;
+ }
+
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ Records = BuiltinInfo;
+ NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
+ }
+
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const {
+ return true;
+ }
+
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "hexagon";
+ }
+
+ virtual const char *getVAListDeclaration() const {
+ return "typedef char* __builtin_va_list;";
+ }
+ virtual void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const;
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const;
+ virtual const char *getClobbers() const {
+ return "";
+ }
+
+ static const char *getHexagonCPUSuffix(StringRef Name) {
+ return llvm::StringSwitch<const char*>(Name)
+ .Case("hexagonv2", "2")
+ .Case("hexagonv3", "3")
+ .Case("hexagonv4", "4")
+ .Default(0);
+ }
+
+ virtual bool setCPU(const std::string &Name) {
+ if (!getHexagonCPUSuffix(Name))
+ return false;
+
+ CPU = Name;
+ return true;
+ }
+};
+
+void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("qdsp6");
+ Builder.defineMacro("__qdsp6", "1");
+ Builder.defineMacro("__qdsp6__", "1");
+
+ Builder.defineMacro("hexagon");
+ Builder.defineMacro("__hexagon", "1");
+ Builder.defineMacro("__hexagon__", "1");
+
+ if(CPU == "hexagonv1") {
+ Builder.defineMacro("__HEXAGON_V1__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "1");
+ if(Opts.HexagonQdsp6Compat) {
+ Builder.defineMacro("__QDSP6_V1__");
+ Builder.defineMacro("__QDSP6_ARCH__", "1");
+ }
+ }
+ else if(CPU == "hexagonv2") {
+ Builder.defineMacro("__HEXAGON_V2__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "2");
+ if(Opts.HexagonQdsp6Compat) {
+ Builder.defineMacro("__QDSP6_V2__");
+ Builder.defineMacro("__QDSP6_ARCH__", "2");
+ }
+ }
+ else if(CPU == "hexagonv3") {
+ Builder.defineMacro("__HEXAGON_V3__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "3");
+ if(Opts.HexagonQdsp6Compat) {
+ Builder.defineMacro("__QDSP6_V3__");
+ Builder.defineMacro("__QDSP6_ARCH__", "3");
+ }
+ }
+ else if(CPU == "hexagonv4") {
+ Builder.defineMacro("__HEXAGON_V4__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "4");
+ if(Opts.HexagonQdsp6Compat) {
+ Builder.defineMacro("__QDSP6_V4__");
+ Builder.defineMacro("__QDSP6_ARCH__", "4");
+ }
+ }
+}
+
+const char * const HexagonTargetInfo::GCCRegNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "p0", "p1", "p2", "p3",
+ "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
+};
+
+void HexagonTargetInfo::getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const {
+ Names = GCCRegNames;
+ NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+
+const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
+ { { "sp" }, "r29" },
+ { { "fp" }, "r30" },
+ { { "lr" }, "r31" },
+ };
+
+void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ Aliases = GCCRegAliases;
+ NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+
+
+const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
+ ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsHexagon.def"
+};
+}
+
+
namespace {
class SparcV8TargetInfo : public TargetInfo {
static const TargetInfo::GCCRegAlias GCCRegAliases[];
@@ -2739,11 +3159,12 @@ class SparcV8TargetInfo : public TargetInfo {
public:
SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
// FIXME: Support Sparc quad-precision long double?
+ BigEndian = false;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
}
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- const std::string &Name,
+ StringRef Name,
bool Enabled) const {
if (Name == "soft-float")
Features[Name] = Enabled;
@@ -2767,6 +3188,14 @@ public:
if (SoftFloat)
Builder.defineMacro("SOFT_FLOAT", "1");
}
+
+ virtual bool hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("softfloat", SoftFloat)
+ .Case("sparc", true)
+ .Default(false);
+ }
+
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
// FIXME: Implement!
@@ -2868,11 +3297,13 @@ namespace {
static const char * const GCCRegNames[];
public:
MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
+ BigEndian = false;
TLSSupported = false;
IntWidth = 16; IntAlign = 16;
LongWidth = 32; LongLongWidth = 64;
LongAlign = LongLongAlign = 16;
PointerWidth = 16; PointerAlign = 16;
+ SuitableAlign = 16;
SizeType = UnsignedInt;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
@@ -2893,6 +3324,9 @@ namespace {
Records = 0;
NumRecords = 0;
}
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "msp430";
+ }
virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const;
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -2928,140 +3362,6 @@ namespace {
}
}
-
-namespace {
- class SystemZTargetInfo : public TargetInfo {
- static const char * const GCCRegNames[];
- public:
- SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
- TLSSupported = false;
- IntWidth = IntAlign = 32;
- LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
- PointerWidth = PointerAlign = 64;
- DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
- }
- virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- Builder.defineMacro("__s390__");
- Builder.defineMacro("__s390x__");
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- // FIXME: Implement.
- Records = 0;
- NumRecords = 0;
- }
-
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const;
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- // No aliases.
- Aliases = 0;
- NumAliases = 0;
- }
- virtual bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const {
- // FIXME: implement
- return true;
- }
- virtual const char *getClobbers() const {
- // FIXME: Is this really right?
- return "";
- }
- virtual const char *getVAListDeclaration() const {
- // FIXME: implement
- return "typedef char* __builtin_va_list;";
- }
- };
-
- const char * const SystemZTargetInfo::GCCRegNames[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
- };
-
- void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
- }
-}
-
-namespace {
- class BlackfinTargetInfo : public TargetInfo {
- static const char * const GCCRegNames[];
- public:
- BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
- TLSSupported = false;
- DoubleAlign = 32;
- LongLongAlign = 32;
- LongDoubleAlign = 32;
- DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- DefineStd(Builder, "bfin", Opts);
- DefineStd(Builder, "BFIN", Opts);
- Builder.defineMacro("__ADSPBLACKFIN__");
- // FIXME: This one is really dependent on -mcpu
- Builder.defineMacro("__ADSPLPBLACKFIN__");
- // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
- }
-
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- // FIXME: Implement.
- Records = 0;
- NumRecords = 0;
- }
-
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const;
-
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- // No aliases.
- Aliases = 0;
- NumAliases = 0;
- }
-
- virtual bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const {
- if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
- Info.setAllowsRegister();
- return true;
- }
- return false;
- }
-
- virtual const char *getClobbers() const {
- return "";
- }
-
- virtual const char *getVAListDeclaration() const {
- return "typedef char* __builtin_va_list;";
- }
- };
-
- const char * const BlackfinTargetInfo::GCCRegNames[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
- "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
- "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
- "a0", "a1", "cc",
- "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
- "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
- };
-
- void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
- }
-}
-
namespace {
// LLVM and Clang cannot be used directly to output native binaries for
@@ -3088,6 +3388,7 @@ namespace {
IntAlign = 32;
LongAlign = LongLongAlign = 32;
PointerAlign = 32;
+ SuitableAlign = 32;
SizeType = UnsignedInt;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
@@ -3115,6 +3416,10 @@ namespace {
Builder.defineMacro("__TCE__");
Builder.defineMacro("__TCE_V1__");
}
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "tce";
+ }
+
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {}
virtual const char *getClobbers() const {
@@ -3137,14 +3442,22 @@ namespace {
namespace {
class MipsTargetInfoBase : public TargetInfo {
std::string CPU;
+ bool SoftFloat;
+ bool SingleFloat;
+
protected:
std::string ABI;
+
public:
- MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr)
- : TargetInfo(triple), ABI(ABIStr) {
- SizeType = UnsignedInt;
- PtrDiffType = SignedInt;
- }
+ MipsTargetInfoBase(const std::string& triple,
+ const std::string& ABIStr,
+ const std::string& CPUStr)
+ : TargetInfo(triple),
+ CPU(CPUStr),
+ SoftFloat(false), SingleFloat(false),
+ ABI(ABIStr)
+ {}
+
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) = 0;
virtual bool setCPU(const std::string &Name) {
@@ -3155,28 +3468,50 @@ public:
Features[ABI] = true;
Features[CPU] = true;
}
+
virtual void getArchDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const = 0;
+ MacroBuilder &Builder) const {
+ if (SoftFloat)
+ Builder.defineMacro("__mips_soft_float", Twine(1));
+ else if (SingleFloat)
+ Builder.defineMacro("__mips_single_float", Twine(1));
+ else if (!SoftFloat && !SingleFloat)
+ Builder.defineMacro("__mips_hard_float", Twine(1));
+ else
+ llvm_unreachable("Invalid float ABI for Mips.");
+
+ Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
+ Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
+ Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
+ }
+
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const = 0;
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
// FIXME: Implement!
}
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "mips";
+ }
virtual const char *getVAListDeclaration() const {
return "typedef void* __builtin_va_list;";
}
virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const {
static const char * const GCCRegNames[] = {
+ // CPU register names
+ // Must match second column of GCCRegAliases
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
- "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
+ "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
+ // Floating point register names
"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
+ // Hi/lo and condition register names
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
"$fcc5","$fcc6","$fcc7"
};
@@ -3189,26 +3524,64 @@ public:
TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
default:
+ return false;
+
case 'r': // CPU registers.
case 'd': // Equivalent to "r" unless generating MIPS16 code.
case 'y': // Equivalent to "r", backwards compatibility only.
case 'f': // floating-point registers.
+ case 'c': // $25 for indirect jumps
+ case 'l': // lo register
+ case 'x': // hilo register pair
Info.setAllowsRegister();
return true;
}
- return false;
}
virtual const char *getClobbers() const {
// FIXME: Implement!
return "";
}
+
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ StringRef Name,
+ bool Enabled) const {
+ if (Name == "soft-float" || Name == "single-float") {
+ Features[Name] = Enabled;
+ return true;
+ }
+ return false;
+ }
+
+ virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ SoftFloat = false;
+ SingleFloat = false;
+
+ for (std::vector<std::string>::iterator it = Features.begin(),
+ ie = Features.end(); it != ie; ++it) {
+ if (*it == "+single-float") {
+ SingleFloat = true;
+ break;
+ }
+
+ if (*it == "+soft-float") {
+ SoftFloat = true;
+ // This option is front-end specific.
+ // Do not need to pass it to the backend.
+ Features.erase(it);
+ break;
+ }
+ }
+ }
};
class Mips32TargetInfoBase : public MipsTargetInfoBase {
public:
Mips32TargetInfoBase(const std::string& triple) :
- MipsTargetInfoBase(triple, "o32") {}
+ MipsTargetInfoBase(triple, "o32", "mips32") {
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ }
virtual bool setABI(const std::string &Name) {
if ((Name == "o32") || (Name == "eabi")) {
ABI = Name;
@@ -3218,6 +3591,8 @@ public:
}
virtual void getArchDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
+ MipsTargetInfoBase::getArchDefines(Opts, Builder);
+
if (ABI == "o32") {
Builder.defineMacro("__mips_o32");
Builder.defineMacro("_ABIO32", "1");
@@ -3259,8 +3634,8 @@ public:
{ { "k0" }, "$26" },
{ { "k1" }, "$27" },
{ { "gp" }, "$28" },
- { { "sp" }, "$29" },
- { { "fp" }, "$30" },
+ { { "sp","$sp" }, "$29" },
+ { { "fp","$fp" }, "$30" },
{ { "ra" }, "$31" }
};
Aliases = GCCRegAliases;
@@ -3288,6 +3663,7 @@ public:
class Mips32ELTargetInfo : public Mips32TargetInfoBase {
public:
Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
+ BigEndian = false;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
}
@@ -3306,17 +3682,32 @@ class Mips64TargetInfoBase : public MipsTargetInfoBase {
virtual void SetDescriptionString(const std::string &Name) = 0;
public:
Mips64TargetInfoBase(const std::string& triple) :
- MipsTargetInfoBase(triple, "n64") {}
+ MipsTargetInfoBase(triple, "n64", "mips64") {
+ LongWidth = LongAlign = 64;
+ PointerWidth = PointerAlign = 64;
+ LongDoubleWidth = LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad;
+ SuitableAlign = 128;
+ }
virtual bool setABI(const std::string &Name) {
SetDescriptionString(Name);
- if ((Name == "n32") || (Name == "n64")) {
- ABI = Name;
- return true;
- } else
+
+ if (Name != "n32" && Name != "n64")
return false;
+
+ ABI = Name;
+
+ if (Name == "n32") {
+ LongWidth = LongAlign = 32;
+ PointerWidth = PointerAlign = 32;
+ }
+
+ return true;
}
virtual void getArchDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
+ MipsTargetInfoBase::getArchDefines(Opts, Builder);
+
if (ABI == "n32") {
Builder.defineMacro("__mips_n32");
Builder.defineMacro("_ABIN32", "2");
@@ -3361,8 +3752,8 @@ public:
{ { "k0" }, "$26" },
{ { "k1" }, "$27" },
{ { "gp" }, "$28" },
- { { "sp" }, "$29" },
- { { "fp" }, "$30" },
+ { { "sp","$sp" }, "$29" },
+ { { "fp","$fp" }, "$30" },
{ { "ra" }, "$31" }
};
Aliases = GCCRegAliases;
@@ -3375,13 +3766,15 @@ class Mips64EBTargetInfo : public Mips64TargetInfoBase {
// Change DescriptionString only if ABI is n32.
if (Name == "n32")
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
+ "v64:64:64-n32";
}
public:
Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
// Default ABI is n64.
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
+ "v64:64:64-n32";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -3399,13 +3792,16 @@ class Mips64ELTargetInfo : public Mips64TargetInfoBase {
// Change DescriptionString only if ABI is n32.
if (Name == "n32")
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128"
+ "-v64:64:64-n32";
}
public:
Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
- // Default ABI is n64.
+ // Default ABI is n64.
+ BigEndian = false;
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
+ "v64:64:64-n32";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -3423,6 +3819,7 @@ namespace {
class PNaClTargetInfo : public TargetInfo {
public:
PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ BigEndian = false;
this->UserLabelPrefix = "";
this->LongAlign = 32;
this->LongWidth = 32;
@@ -3458,9 +3855,13 @@ public:
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
+ Builder.defineMacro("__LITTLE_ENDIAN__");
Builder.defineMacro("__native_client__");
getArchDefines(Opts, Builder);
}
+ virtual bool hasFeature(StringRef Feature) const {
+ return Feature == "pnacl";
+ }
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
}
@@ -3507,6 +3908,9 @@ static TargetInfo *AllocateTarget(const std::string &T) {
default:
return NULL;
+ case llvm::Triple::hexagon:
+ return new HexagonTargetInfo(T);
+
case llvm::Triple::arm:
case llvm::Triple::thumb:
if (Triple.isOSDarwin())
@@ -3525,11 +3929,6 @@ static TargetInfo *AllocateTarget(const std::string &T) {
return new ARMTargetInfo(T);
}
- case llvm::Triple::bfin:
- if ( os == llvm::Triple::RTEMS )
- return new RTEMSTargetInfo<BlackfinTargetInfo>(T);
- return new BlackfinTargetInfo(T);
-
case llvm::Triple::msp430:
return new MSP430TargetInfo(T);
@@ -3657,9 +4056,6 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::cellspu:
return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
- case llvm::Triple::systemz:
- return new SystemZTargetInfo(T);
-
case llvm::Triple::tce:
return new TCETargetInfo(T);
@@ -3675,7 +4071,7 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::DragonFly:
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<X86_32TargetInfo>(T);
+ return new NetBSDI386TargetInfo(T);
case llvm::Triple::OpenBSD:
return new OpenBSDI386TargetInfo(T);
case llvm::Triple::FreeBSD:
@@ -3734,7 +4130,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
llvm::Triple Triple(Opts.Triple);
// Construct the target
- llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
+ OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
if (!Target) {
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
return 0;
@@ -3764,13 +4160,32 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
Target->getDefaultFeatures(Features);
// Apply the user specified deltas.
+ // First the enables.
+ for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
+ ie = Opts.Features.end(); it != ie; ++it) {
+ const char *Name = it->c_str();
+
+ if (Name[0] != '+')
+ continue;
+
+ // 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.Features.begin(),
ie = Opts.Features.end(); it != ie; ++it) {
const char *Name = it->c_str();
+ if (Name[0] == '+')
+ continue;
+
// Apply the feature via the target.
- if ((Name[0] != '-' && Name[0] != '+') ||
- !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
+ if (Name[0] != '-' ||
+ !Target->setFeatureEnabled(Features, Name + 1, false)) {
Diags.Report(diag::err_target_invalid_feature) << Name;
return 0;
}
@@ -3783,8 +4198,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
Opts.Features.clear();
for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
ie = Features.end(); it != ie; ++it)
- Opts.Features.push_back(std::string(it->second ? "+" : "-") +
- it->first().str());
+ Opts.Features.push_back((it->second ? "+" : "-") + it->first().str());
Target->HandleTargetFeatures(Opts.Features);
return Target.take();
OpenPOWER on IntegriCloud