summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp1112
1 files changed, 765 insertions, 347 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 728e9c0..4c64a02 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -21,6 +21,7 @@
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
@@ -93,7 +94,8 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Builder.defineMacro("OBJC_NEW_PROPERTIES");
// AddressSanitizer doesn't play well with source fortification, which is on
// by default on Darwin.
- if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0");
+ if (Opts.Sanitize.has(SanitizerKind::Address))
+ Builder.defineMacro("_FORTIFY_SOURCE", "0");
if (!Opts.ObjCAutoRefCount) {
// __weak is always defined, for use in blocks and with objc pointers.
@@ -271,6 +273,12 @@ protected:
// 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.
+ //
+ // FIXME: This is wrong; the macro refers to the numerical values
+ // of wchar_t *literals*, which are not locale-dependent. However,
+ // FreeBSD systems apparently depend on us getting this wrong, and
+ // setting this to 1 is conforming even if all the basic source
+ // character literals have the same encoding as char and wchar_t.
Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
}
public:
@@ -315,7 +323,8 @@ protected:
Builder.defineMacro("_GNU_SOURCE");
}
public:
- KFreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ KFreeBSDTargetInfo(const llvm::Triple &Triple)
+ : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
}
};
@@ -516,27 +525,6 @@ public:
}
};
-// AuroraUX target
-template<typename Target>
-class AuroraUXTargetInfo : public OSTargetInfo<Target> {
-protected:
- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const override {
- DefineStd(Builder, "sun", Opts);
- DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
- Builder.defineMacro("__svr4__");
- Builder.defineMacro("__SVR4");
- }
-public:
- AuroraUXTargetInfo(const llvm::Triple &Triple)
- : OSTargetInfo<Target>(Triple) {
- this->UserLabelPrefix = "";
- this->WCharType = this->SignedLong;
- // FIXME: WIntType should be SignedLong
- }
-};
-
// Solaris target
template<typename Target>
class SolarisTargetInfo : public OSTargetInfo<Target> {
@@ -551,8 +539,8 @@ protected:
// 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)
+ // with a new version.
+ if (Opts.C99)
Builder.defineMacro("_XOPEN_SOURCE", "600");
else
Builder.defineMacro("_XOPEN_SOURCE", "500");
@@ -658,7 +646,8 @@ public:
// RegParmMax is inherited from the underlying architecture
this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
if (Triple.getArch() == llvm::Triple::arm) {
- this->DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S128";
+ this->DescriptionString =
+ "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128";
} else if (Triple.getArch() == llvm::Triple::x86) {
this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32-S128";
} else if (Triple.getArch() == llvm::Triple::x86_64) {
@@ -692,10 +681,14 @@ class PPCTargetInfo : public TargetInfo {
// Target cpu features.
bool HasVSX;
+ bool HasP8Vector;
+
+protected:
+ std::string ABI;
public:
PPCTargetInfo(const llvm::Triple &Triple)
- : TargetInfo(Triple), HasVSX(false) {
+ : TargetInfo(Triple), HasVSX(false), HasP8Vector(false) {
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
@@ -781,6 +774,9 @@ public:
return CPUKnown;
}
+
+ StringRef getABI() const override { return ABI; }
+
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {
Records = BuiltinInfo;
@@ -932,11 +928,10 @@ const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
#include "clang/Basic/BuiltinsPPC.def"
};
- /// handleTargetFeatures - Perform initialization based on the user
+/// 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] == '-')
@@ -949,6 +944,11 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "power8-vector") {
+ HasP8Vector = true;
+ continue;
+ }
+
// TODO: Finish this list and add an assert that we've handled them
// all.
}
@@ -976,13 +976,18 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
// Target properties.
if (getTriple().getArch() == llvm::Triple::ppc64le) {
Builder.defineMacro("_LITTLE_ENDIAN");
- Builder.defineMacro("_CALL_ELF","2");
} else {
if (getTriple().getOS() != llvm::Triple::NetBSD &&
getTriple().getOS() != llvm::Triple::OpenBSD)
Builder.defineMacro("_BIG_ENDIAN");
}
+ // ABI options.
+ if (ABI == "elfv1")
+ Builder.defineMacro("_CALL_ELF", "1");
+ if (ABI == "elfv2")
+ Builder.defineMacro("_CALL_ELF", "2");
+
// Subtarget options.
Builder.defineMacro("__NATURAL_ALIGNMENT__");
Builder.defineMacro("__REGISTER_PREFIX__", "");
@@ -1094,6 +1099,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasVSX)
Builder.defineMacro("__VSX__");
+ if (HasP8Vector)
+ Builder.defineMacro("__POWER8_VECTOR__");
// FIXME: The following are not yet generated here by Clang, but are
// generated by GCC:
@@ -1132,13 +1139,19 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
.Default(false);
Features["qpx"] = (CPU == "a2q");
+
+ if (!ABI.empty())
+ Features[ABI] = true;
}
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
- return Feature == "powerpc";
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("powerpc", true)
+ .Case("vsx", HasVSX)
+ .Case("power8-vector", HasP8Vector)
+ .Default(false);
}
-
const char * const PPCTargetInfo::GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
@@ -1287,17 +1300,26 @@ public:
IntMaxType = SignedLong;
Int64Type = SignedLong;
- if (getTriple().getOS() == llvm::Triple::FreeBSD) {
+ if ((Triple.getArch() == llvm::Triple::ppc64le)) {
+ DescriptionString = "e-m:e-i64:64-n32:64";
+ ABI = "elfv2";
+ } else {
+ DescriptionString = "E-m:e-i64:64-n32:64";
+ ABI = "elfv1";
+ }
+
+ switch (getTriple().getOS()) {
+ case llvm::Triple::FreeBSD:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
- DescriptionString = "E-m:e-i64:64-n32:64";
- } else {
- if ((Triple.getArch() == llvm::Triple::ppc64le)) {
- DescriptionString = "e-m:e-i64:64-n32:64";
- } else {
- DescriptionString = "E-m:e-i64:64-n32:64";
- }
-}
+ break;
+ case llvm::Triple::NetBSD:
+ IntMaxType = SignedLongLong;
+ Int64Type = SignedLongLong;
+ break;
+ default:
+ break;
+ }
// PPC64 supports atomics up to 8 bytes.
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
@@ -1305,6 +1327,14 @@ public:
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}
+ // PPC64 Linux-specifc ABI options.
+ bool setABI(const std::string &Name) override {
+ if (Name == "elfv1" || Name == "elfv2") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
};
} // end anonymous namespace.
@@ -1317,7 +1347,7 @@ public:
: 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
+ PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
LongLongAlign = 32;
SuitableAlign = 128;
DescriptionString = "E-m:o-p:32:32-f64:32:64-n32";
@@ -1344,6 +1374,8 @@ namespace {
1, // opencl_global
3, // opencl_local
4, // opencl_constant
+ // FIXME: generic has to be added to the target
+ 0, // opencl_generic
1, // cuda_device
4, // cuda_constant
3, // cuda_shared
@@ -1351,6 +1383,16 @@ namespace {
class NVPTXTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
+
+ // The GPU profiles supported by the NVPTX backend
+ enum GPUKind {
+ GK_NONE,
+ GK_SM20,
+ GK_SM21,
+ GK_SM30,
+ GK_SM35,
+ } GPU;
+
public:
NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
@@ -1361,11 +1403,34 @@ namespace {
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
+ // Set the default GPU to sm20
+ GPU = GK_SM20;
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
Builder.defineMacro("__PTX__");
Builder.defineMacro("__NVPTX__");
+ if (Opts.CUDAIsDevice) {
+ // Set __CUDA_ARCH__ for the GPU specified.
+ std::string CUDAArchCode;
+ switch (GPU) {
+ case GK_SM20:
+ CUDAArchCode = "200";
+ break;
+ case GK_SM21:
+ CUDAArchCode = "210";
+ break;
+ case GK_SM30:
+ CUDAArchCode = "300";
+ break;
+ case GK_SM35:
+ CUDAArchCode = "350";
+ break;
+ default:
+ llvm_unreachable("Unhandled target CPU");
+ }
+ Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
+ }
}
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {
@@ -1384,8 +1449,9 @@ namespace {
Aliases = nullptr;
NumAliases = 0;
}
- bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ bool
+ validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override {
switch (*Name) {
default: return false;
case 'c':
@@ -1407,14 +1473,14 @@ namespace {
return TargetInfo::CharPtrBuiltinVaList;
}
bool setCPU(const std::string &Name) override {
- bool Valid = llvm::StringSwitch<bool>(Name)
- .Case("sm_20", true)
- .Case("sm_21", true)
- .Case("sm_30", true)
- .Case("sm_35", true)
- .Default(false);
+ GPU = llvm::StringSwitch<GPUKind>(Name)
+ .Case("sm_20", GK_SM20)
+ .Case("sm_21", GK_SM21)
+ .Case("sm_30", GK_SM30)
+ .Case("sm_35", GK_SM35)
+ .Default(GK_NONE);
- return Valid;
+ return GPU != GK_NONE;
}
};
@@ -1462,11 +1528,15 @@ static const unsigned R600AddrSpaceMap[] = {
1, // opencl_global
3, // opencl_local
2, // opencl_constant
+ 4, // opencl_generic
1, // cuda_device
2, // cuda_constant
3 // cuda_shared
};
+// If you edit the description strings, make sure you update
+// getPointerWidthV().
+
static const char *DescriptionStringR600 =
"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
@@ -1506,6 +1576,20 @@ public:
UseAddrSpaceMapMangling = true;
}
+ uint64_t getPointerWidthV(unsigned AddrSpace) const override {
+ if (GPU <= GK_CAYMAN)
+ return 32;
+
+ switch(AddrSpace) {
+ default:
+ return 64;
+ case 0:
+ case 3:
+ case 5:
+ return 32;
+ }
+ }
+
const char * getClobbers() const override {
return "";
}
@@ -1573,6 +1657,7 @@ public:
.Case("pitcairn", GK_SOUTHERN_ISLANDS)
.Case("verde", GK_SOUTHERN_ISLANDS)
.Case("oland", GK_SOUTHERN_ISLANDS)
+ .Case("hainan", GK_SOUTHERN_ISLANDS)
.Case("bonaire", GK_SEA_ISLANDS)
.Case("kabini", GK_SEA_ISLANDS)
.Case("kaveri", GK_SEA_ISLANDS)
@@ -1669,16 +1754,19 @@ class X86TargetInfo : public TargetInfo {
bool HasPCLMUL;
bool HasLZCNT;
bool HasRDRND;
+ bool HasFSGSBASE;
bool HasBMI;
bool HasBMI2;
bool HasPOPCNT;
bool HasRTM;
bool HasPRFCHW;
bool HasRDSEED;
+ bool HasADX;
bool HasTBM;
bool HasFMA;
bool HasF16C;
- bool HasAVX512CD, HasAVX512ER, HasAVX512PF;
+ bool HasAVX512CD, HasAVX512ER, HasAVX512PF, HasAVX512DQ, HasAVX512BW,
+ HasAVX512VL;
bool HasSHA;
bool HasCX16;
@@ -1753,18 +1841,37 @@ class X86TargetInfo : public TargetInfo {
/// \name Atom
/// Atom processors
//@{
- CK_Atom,
+ CK_Bonnell,
CK_Silvermont,
//@}
/// \name Nehalem
/// Nehalem microarchitecture based processors.
- //@{
- CK_Corei7,
- CK_Corei7AVX,
- CK_CoreAVXi,
- CK_CoreAVX2,
- //@}
+ CK_Nehalem,
+
+ /// \name Westmere
+ /// Westmere microarchitecture based processors.
+ CK_Westmere,
+
+ /// \name Sandy Bridge
+ /// Sandy Bridge microarchitecture based processors.
+ CK_SandyBridge,
+
+ /// \name Ivy Bridge
+ /// Ivy Bridge microarchitecture based processors.
+ CK_IvyBridge,
+
+ /// \name Haswell
+ /// Haswell microarchitecture based processors.
+ CK_Haswell,
+
+ /// \name Broadwell
+ /// Broadwell microarchitecture based processors.
+ CK_Broadwell,
+
+ /// \name Skylake
+ /// Skylake microarchitecture based processors.
+ CK_Skylake,
/// \name Knights Landing
/// Knights Landing processor.
@@ -1820,6 +1927,7 @@ class X86TargetInfo : public TargetInfo {
/// This specification is deprecated and will be removed in the future.
/// Users should prefer \see CK_K8.
// FIXME: Warn on this when the CPU is set to it.
+ //@{
CK_x86_64,
//@}
@@ -1840,11 +1948,12 @@ public:
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) {
+ HasRDRND(false), HasFSGSBASE(false), HasBMI(false), HasBMI2(false),
+ HasPOPCNT(false), HasRTM(false), HasPRFCHW(false), HasRDSEED(false),
+ HasADX(false), HasTBM(false), HasFMA(false), HasF16C(false),
+ HasAVX512CD(false), HasAVX512ER(false), HasAVX512PF(false),
+ HasAVX512DQ(false), HasAVX512BW(false), HasAVX512VL(false),
+ HasSHA(false), HasCX16(false), CPU(CK_Generic), FPMath(FP_Default) {
BigEndian = false;
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
@@ -1873,7 +1982,14 @@ public:
NumNames = llvm::array_lengthof(AddlRegNames);
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override;
+ TargetInfo::ConstraintInfo &info) const override;
+
+ bool validateOutputSize(StringRef Constraint, unsigned Size) const override;
+
+ bool validateInputSize(StringRef Constraint, unsigned Size) const override;
+
+ virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
+
std::string convertConstraint(const char *&Constraint) const override;
const char *getClobbers() const override {
return "~{dirflag},~{fpsr},~{flags}";
@@ -1930,12 +2046,22 @@ public:
.Case("nocona", CK_Nocona)
.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("bonnell", CK_Bonnell)
+ .Case("atom", CK_Bonnell) // Legacy name.
+ .Case("silvermont", CK_Silvermont)
+ .Case("slm", CK_Silvermont) // Legacy name.
+ .Case("nehalem", CK_Nehalem)
+ .Case("corei7", CK_Nehalem) // Legacy name.
+ .Case("westmere", CK_Westmere)
+ .Case("sandybridge", CK_SandyBridge)
+ .Case("corei7-avx", CK_SandyBridge) // Legacy name.
+ .Case("ivybridge", CK_IvyBridge)
+ .Case("core-avx-i", CK_IvyBridge) // Legacy name.
+ .Case("haswell", CK_Haswell)
+ .Case("core-avx2", CK_Haswell) // Legacy name.
+ .Case("broadwell", CK_Broadwell)
+ .Case("skylake", CK_Skylake)
+ .Case("skx", CK_Skylake) // Legacy name.
.Case("knl", CK_KNL)
.Case("k6", CK_K6)
.Case("k6-2", CK_K6_2)
@@ -1952,6 +2078,7 @@ public:
.Case("k8-sse3", CK_K8SSE3)
.Case("opteron", CK_Opteron)
.Case("opteron-sse3", CK_OpteronSSE3)
+ .Case("barcelona", CK_AMDFAM10)
.Case("amdfam10", CK_AMDFAM10)
.Case("btver1", CK_BTVER1)
.Case("btver2", CK_BTVER2)
@@ -2008,12 +2135,15 @@ public:
case CK_Nocona:
case CK_Core2:
case CK_Penryn:
- case CK_Atom:
+ case CK_Bonnell:
case CK_Silvermont:
- case CK_Corei7:
- case CK_Corei7AVX:
- case CK_CoreAVXi:
- case CK_CoreAVX2:
+ case CK_Nehalem:
+ case CK_Westmere:
+ case CK_SandyBridge:
+ case CK_IvyBridge:
+ case CK_Haswell:
+ case CK_Broadwell:
+ case CK_Skylake:
case CK_KNL:
case CK_Athlon64:
case CK_Athlon64SSE3:
@@ -2041,8 +2171,9 @@ public:
// We accept all non-ARM calling conventions
return (CC == CC_X86ThisCall ||
CC == CC_X86FastCall ||
- CC == CC_X86StdCall ||
- CC == CC_C ||
+ CC == CC_X86StdCall ||
+ CC == CC_X86VectorCall ||
+ CC == CC_C ||
CC == CC_X86Pascal ||
CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
}
@@ -2082,10 +2213,13 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
break;
case CK_PentiumMMX:
case CK_Pentium2:
+ case CK_K6:
+ case CK_WinChipC6:
setFeatureEnabledImpl(Features, "mmx", true);
break;
case CK_Pentium3:
case CK_Pentium3M:
+ case CK_C3_2:
setFeatureEnabledImpl(Features, "sse", true);
break;
case CK_PentiumM:
@@ -2101,6 +2235,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Core2:
+ case CK_Bonnell:
setFeatureEnabledImpl(Features, "ssse3", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
@@ -2108,44 +2243,40 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabledImpl(Features, "sse4.1", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
- case CK_Atom:
- 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:
- setFeatureEnabledImpl(Features, "sse4.2", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- break;
- case CK_Corei7AVX:
- setFeatureEnabledImpl(Features, "avx", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- break;
- case CK_CoreAVXi:
- setFeatureEnabledImpl(Features, "avx", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "rdrnd", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- break;
- case CK_CoreAVX2:
+ case CK_Skylake:
+ setFeatureEnabledImpl(Features, "avx512f", true);
+ setFeatureEnabledImpl(Features, "avx512cd", true);
+ setFeatureEnabledImpl(Features, "avx512dq", true);
+ setFeatureEnabledImpl(Features, "avx512bw", true);
+ setFeatureEnabledImpl(Features, "avx512vl", true);
+ // FALLTHROUGH
+ case CK_Broadwell:
+ setFeatureEnabledImpl(Features, "rdseed", true);
+ setFeatureEnabledImpl(Features, "adx", true);
+ // FALLTHROUGH
+ case CK_Haswell:
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);
+ // FALLTHROUGH
+ case CK_IvyBridge:
+ setFeatureEnabledImpl(Features, "rdrnd", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "fsgsbase", true);
+ // FALLTHROUGH
+ case CK_SandyBridge:
+ setFeatureEnabledImpl(Features, "avx", true);
+ // FALLTHROUGH
+ case CK_Westmere:
+ case CK_Silvermont:
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ // FALLTHROUGH
+ case CK_Nehalem:
+ setFeatureEnabledImpl(Features, "sse4.2", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_KNL:
@@ -2153,19 +2284,19 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabledImpl(Features, "avx512cd", true);
setFeatureEnabledImpl(Features, "avx512er", true);
setFeatureEnabledImpl(Features, "avx512pf", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "rdseed", true);
+ setFeatureEnabledImpl(Features, "adx", 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:
- setFeatureEnabledImpl(Features, "mmx", true);
+ setFeatureEnabledImpl(Features, "rdrnd", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "fsgsbase", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_K6_2:
case CK_K6_3:
@@ -2191,43 +2322,29 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabledImpl(Features, "sse2", true);
setFeatureEnabledImpl(Features, "3dnowa", true);
break;
+ case CK_AMDFAM10:
+ setFeatureEnabledImpl(Features, "sse4a", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "popcnt", true);
+ // FALLTHROUGH
case CK_K8SSE3:
case CK_OpteronSSE3:
case CK_Athlon64SSE3:
setFeatureEnabledImpl(Features, "sse3", true);
setFeatureEnabledImpl(Features, "3dnowa", true);
break;
- case CK_AMDFAM10:
- setFeatureEnabledImpl(Features, "sse3", true);
- setFeatureEnabledImpl(Features, "sse4a", true);
- setFeatureEnabledImpl(Features, "3dnowa", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "popcnt", true);
- break;
- case CK_BTVER1:
- 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:
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:
- setFeatureEnabledImpl(Features, "xop", true);
+ // FALLTHROUGH
+ case CK_BTVER1:
+ setFeatureEnabledImpl(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "sse4a", true);
setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "popcnt", true);
setFeatureEnabledImpl(Features, "prfchw", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
@@ -2235,22 +2352,24 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
setFeatureEnabledImpl(Features, "avx2", true);
setFeatureEnabledImpl(Features, "bmi2", true);
// FALLTHROUGH
- case CK_BDVER2:
case CK_BDVER3:
+ setFeatureEnabledImpl(Features, "fsgsbase", true);
+ // FALLTHROUGH
+ case CK_BDVER2:
+ setFeatureEnabledImpl(Features, "bmi", true);
+ setFeatureEnabledImpl(Features, "fma", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "tbm", true);
+ // FALLTHROUGH
+ case CK_BDVER1:
+ // xop implies avx, sse4a and fma4.
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:
- setFeatureEnabledImpl(Features, "sse", true);
- break;
}
}
@@ -2305,7 +2424,8 @@ void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
Features["avx2"] = false;
case AVX512F:
Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
- Features["avx512pf"] = false;
+ Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] =
+ Features["avx512vl"] = false;
}
}
@@ -2404,7 +2524,8 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
setSSELevel(Features, AVX2, Enabled);
} else if (Name == "avx512f") {
setSSELevel(Features, AVX512F, Enabled);
- } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf") {
+ } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf"
+ || Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl") {
if (Enabled)
setSSELevel(Features, AVX512F, Enabled);
} else if (Name == "fma") {
@@ -2457,6 +2578,11 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "fsgsbase") {
+ HasFSGSBASE = true;
+ continue;
+ }
+
if (Feature == "bmi") {
HasBMI = true;
continue;
@@ -2487,6 +2613,11 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "adx") {
+ HasADX = true;
+ continue;
+ }
+
if (Feature == "tbm") {
HasTBM = true;
continue;
@@ -2517,6 +2648,21 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "avx512dq") {
+ HasAVX512DQ = true;
+ continue;
+ }
+
+ if (Feature == "avx512bw") {
+ HasAVX512BW = true;
+ continue;
+ }
+
+ if (Feature == "avx512vl") {
+ HasAVX512VL = true;
+ continue;
+ }
+
if (Feature == "sha") {
HasSHA = true;
continue;
@@ -2606,6 +2752,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__amd64");
Builder.defineMacro("__x86_64");
Builder.defineMacro("__x86_64__");
+ if (getTriple().getArchName() == "x86_64h") {
+ Builder.defineMacro("__x86_64h");
+ Builder.defineMacro("__x86_64h__");
+ }
} else {
DefineStd(Builder, "i386", Opts);
}
@@ -2668,18 +2818,30 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Penryn:
defineCPUMacros(Builder, "core2");
break;
- case CK_Atom:
+ case CK_Bonnell:
defineCPUMacros(Builder, "atom");
break;
case CK_Silvermont:
defineCPUMacros(Builder, "slm");
break;
- case CK_Corei7:
- case CK_Corei7AVX:
- case CK_CoreAVXi:
- case CK_CoreAVX2:
+ case CK_Nehalem:
+ case CK_Westmere:
+ case CK_SandyBridge:
+ case CK_IvyBridge:
+ case CK_Haswell:
+ case CK_Broadwell:
+ // FIXME: Historically, we defined this legacy name, it would be nice to
+ // remove it at some point. We've never exposed fine-grained names for
+ // recent primary x86 CPUs, and we should keep it that way.
defineCPUMacros(Builder, "corei7");
break;
+ case CK_Skylake:
+ // FIXME: Historically, we defined this legacy name, it would be nice to
+ // remove it at some point. This is the only fine-grained CPU macro in the
+ // main intel CPU line, and it would be better to not have these and force
+ // people to use ISA macros.
+ defineCPUMacros(Builder, "skx");
+ break;
case CK_KNL:
defineCPUMacros(Builder, "knl");
break;
@@ -2766,6 +2928,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasRDRND)
Builder.defineMacro("__RDRND__");
+ if (HasFSGSBASE)
+ Builder.defineMacro("__FSGSBASE__");
+
if (HasBMI)
Builder.defineMacro("__BMI__");
@@ -2784,6 +2949,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasRDSEED)
Builder.defineMacro("__RDSEED__");
+ if (HasADX)
+ Builder.defineMacro("__ADX__");
+
if (HasTBM)
Builder.defineMacro("__TBM__");
@@ -2810,6 +2978,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVX512ER__");
if (HasAVX512PF)
Builder.defineMacro("__AVX512PF__");
+ if (HasAVX512DQ)
+ Builder.defineMacro("__AVX512DQ__");
+ if (HasAVX512BW)
+ Builder.defineMacro("__AVX512BW__");
+ if (HasAVX512VL)
+ Builder.defineMacro("__AVX512VL__");
if (HasSHA)
Builder.defineMacro("__SHA__");
@@ -2893,23 +3067,26 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("avx512cd", HasAVX512CD)
.Case("avx512er", HasAVX512ER)
.Case("avx512pf", HasAVX512PF)
+ .Case("avx512dq", HasAVX512DQ)
+ .Case("avx512bw", HasAVX512BW)
+ .Case("avx512vl", HasAVX512VL)
.Case("bmi", HasBMI)
.Case("bmi2", HasBMI2)
.Case("cx16", HasCX16)
.Case("f16c", HasF16C)
.Case("fma", HasFMA)
.Case("fma4", XOPLevel >= FMA4)
- .Case("tbm", HasTBM)
+ .Case("fsgsbase", HasFSGSBASE)
.Case("lzcnt", HasLZCNT)
- .Case("rdrnd", HasRDRND)
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
.Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
.Case("mmx", MMX3DNowLevel >= MMX)
.Case("pclmul", HasPCLMUL)
.Case("popcnt", HasPOPCNT)
- .Case("rtm", HasRTM)
.Case("prfchw", HasPRFCHW)
+ .Case("rdrnd", HasRDRND)
.Case("rdseed", HasRDSEED)
+ .Case("rtm", HasRTM)
.Case("sha", HasSHA)
.Case("sse", SSELevel >= SSE1)
.Case("sse2", SSELevel >= SSE2)
@@ -2918,6 +3095,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("sse4.1", SSELevel >= SSE41)
.Case("sse4.2", SSELevel >= SSE42)
.Case("sse4a", XOPLevel >= SSE4A)
+ .Case("tbm", HasTBM)
.Case("x86", true)
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
@@ -2930,6 +3108,28 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
default: return false;
+ case 'I':
+ Info.setRequiresImmediate(0, 31);
+ return true;
+ case 'J':
+ Info.setRequiresImmediate(0, 63);
+ return true;
+ case 'K':
+ Info.setRequiresImmediate(-128, 127);
+ return true;
+ case 'L':
+ // FIXME: properly analyze this constraint:
+ // must be one of 0xff, 0xffff, or 0xffffffff
+ return true;
+ case 'M':
+ Info.setRequiresImmediate(0, 3);
+ return true;
+ case 'N':
+ Info.setRequiresImmediate(0, 255);
+ return true;
+ case 'O':
+ Info.setRequiresImmediate(0, 127);
+ return true;
case 'Y': // first letter of a pair:
switch (*(Name+1)) {
default: return false;
@@ -2974,6 +3174,39 @@ X86TargetInfo::validateAsmConstraint(const char *&Name,
}
}
+bool X86TargetInfo::validateOutputSize(StringRef Constraint,
+ unsigned Size) const {
+ // Strip off constraint modifiers.
+ while (Constraint[0] == '=' ||
+ Constraint[0] == '+' ||
+ Constraint[0] == '&')
+ Constraint = Constraint.substr(1);
+
+ return validateOperandSize(Constraint, Size);
+}
+
+bool X86TargetInfo::validateInputSize(StringRef Constraint,
+ unsigned Size) const {
+ return validateOperandSize(Constraint, Size);
+}
+
+bool X86TargetInfo::validateOperandSize(StringRef Constraint,
+ unsigned Size) const {
+ switch (Constraint[0]) {
+ default: break;
+ case 'y':
+ return Size <= 64;
+ case 'f':
+ case 't':
+ case 'u':
+ return Size <= 128;
+ case 'x':
+ // 256-bit ymm registers can be used if target supports AVX.
+ return Size <= (SSELevel >= AVX ? 256U : 128U);
+ }
+
+ return true;
+}
std::string
X86TargetInfo::convertConstraint(const char *&Constraint) const {
@@ -3030,18 +3263,25 @@ public:
if (RegNo == 1) return 2;
return -1;
}
- bool validateInputSize(StringRef Constraint,
- unsigned Size) const override {
+ bool validateOperandSize(StringRef Constraint,
+ unsigned Size) const override {
switch (Constraint[0]) {
default: break;
+ case 'R':
+ case 'q':
+ case 'Q':
case 'a':
case 'b':
case 'c':
case 'd':
+ case 'S':
+ case 'D':
return Size <= 32;
+ case 'A':
+ return Size <= 64;
}
- return true;
+ return X86TargetInfo::validateOperandSize(Constraint, Size);
}
};
} // end anonymous namespace
@@ -3304,9 +3544,10 @@ public:
Int64Type = IsX32 ? SignedLongLong : SignedLong;
RegParmMax = 6;
+ // Pointers are 32-bit in x32.
DescriptionString = (IsX32)
- ? "e-m:e-" "p:32:32-" "i64:64-f80:128-n8:16:32:64-S128"
- : "e-m:e-" "i64:64-f80:128-n8:16:32:64-S128";
+ ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
+ : "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
@@ -3330,6 +3571,7 @@ public:
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
return (CC == CC_C ||
+ CC == CC_X86VectorCall ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
}
@@ -3338,6 +3580,8 @@ public:
return CC_C;
}
+ // for x32 we need it here explicitly
+ bool hasInt128Type() const override { return true; }
};
} // end anonymous namespace
@@ -3367,6 +3611,7 @@ public:
}
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
return (CC == CC_C ||
+ CC == CC_X86VectorCall ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
}
@@ -3404,6 +3649,10 @@ public:
DefineStd(Builder, "WIN64", Opts);
Builder.defineMacro("__MINGW64__");
addMinGWDefines(Opts, Builder);
+
+ // GCC defines this macro when it is using __gxx_personality_seh0.
+ if (!Opts.SjLjExceptions)
+ Builder.defineMacro("__SEH__");
}
};
} // end anonymous namespace
@@ -3417,7 +3666,7 @@ public:
MaxVectorAlign = 256;
// The 64-bit iOS simulator uses the builtin bool type for Objective-C.
llvm::Triple T = llvm::Triple(Triple);
- if (T.getOS() == llvm::Triple::IOS)
+ if (T.isiOS())
UseSignedCharForObjCBool = false;
DescriptionString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128";
}
@@ -3492,6 +3741,14 @@ class ARMTargetInfo : public TargetInfo {
unsigned CRC : 1;
unsigned Crypto : 1;
+ // ACLE 6.5.1 Hardware floating point
+ enum {
+ HW_FP_HP = (1 << 1), /// half (16-bit)
+ HW_FP_SP = (1 << 2), /// single (32-bit)
+ HW_FP_DP = (1 << 3), /// double (64-bit)
+ };
+ uint32_t HW_FP;
+
static const Builtin::Info BuiltinInfo[];
static bool shouldUseInlineAtomic(const llvm::Triple &T) {
@@ -3531,8 +3788,8 @@ class ARMTargetInfo : public TargetInfo {
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
const llvm::Triple &T = getTriple();
- // size_t is unsigned long on Darwin and NetBSD.
- if (T.isOSDarwin() || T.getOS() == llvm::Triple::NetBSD)
+ // size_t is unsigned long on MachO-derived environments and NetBSD.
+ if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD)
SizeType = UnsignedLong;
else
SizeType = UnsignedInt;
@@ -3555,42 +3812,27 @@ class ARMTargetInfo : public TargetInfo {
ZeroLengthBitfieldBoundary = 0;
- if (IsThumb) {
- // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
- // so set preferred for small types to 32.
- if (T.isOSBinFormatMachO()) {
- DescriptionString = BigEndian ?
- "E-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
- "v128:64:128-a:0:32-n32-S64" :
- "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
- "v128:64:128-a:0:32-n32-S64";
- } else if (T.isOSWindows()) {
- // FIXME: this is invalid for WindowsCE
- assert(!BigEndian && "Windows on ARM does not support big endian");
- DescriptionString = "e"
- "-m:e"
- "-p:32:32"
- "-i1:8:32-i8:8:32-i16:16:32-i64:64"
- "-v128:64:128"
- "-a:0:32"
- "-n32"
- "-S64";
- } else {
- DescriptionString = BigEndian ?
- "E-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
- "v128:64:128-a:0:32-n32-S64" :
- "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
- "v128:64:128-a:0:32-n32-S64";
- }
+ // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
+ // so set preferred for small types to 32.
+ if (T.isOSBinFormatMachO()) {
+ DescriptionString =
+ BigEndian ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+ : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
+ } else if (T.isOSWindows()) {
+ // FIXME: this is invalid for WindowsCE
+ assert(!BigEndian && "Windows on ARM does not support big endian");
+ DescriptionString = "e"
+ "-m:e"
+ "-p:32:32"
+ "-i64:64"
+ "-v128:64:128"
+ "-a:0:32"
+ "-n32"
+ "-S64";
} else {
- if (T.isOSBinFormatMachO())
- DescriptionString = BigEndian ?
- "E-m:o-p:32:32-i64:64-v128:64:128-n32-S64" :
- "e-m:o-p:32:32-i64:64-v128:64:128-n32-S64";
- else
- DescriptionString = BigEndian ?
- "E-m:e-p:32:32-i64:64-v128:64:128-n32-S64" :
- "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64";
+ DescriptionString =
+ BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+ : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
}
// FIXME: Enumerated types are variable width in straight AAPCS.
@@ -3621,31 +3863,16 @@ class ARMTargetInfo : public TargetInfo {
/// gcc.
ZeroLengthBitfieldBoundary = 32;
- if (IsThumb) {
- // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
- // so set preferred for small types to 32.
- if (T.isOSBinFormatMachO())
- DescriptionString = BigEndian ?
- "E-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
- "-v64:32:64-v128:32:128-a:0:32-n32-S32" :
- "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
- "-v64:32:64-v128:32:128-a:0:32-n32-S32";
- else
- DescriptionString = BigEndian ?
- "E-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
- "-v64:32:64-v128:32:128-a:0:32-n32-S32" :
- "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
- "-v64:32:64-v128:32:128-a:0:32-n32-S32";
- } else {
- if (T.isOSBinFormatMachO())
- DescriptionString = BigEndian ?
- "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" :
- "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
- else
- DescriptionString = BigEndian ?
- "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" :
- "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
- }
+ if (T.isOSBinFormatMachO())
+ DescriptionString =
+ BigEndian
+ ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+ : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
+ else
+ DescriptionString =
+ BigEndian
+ ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+ : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
// FIXME: Override "preferred align" for double and long long.
}
@@ -3653,7 +3880,7 @@ class ARMTargetInfo : public TargetInfo {
public:
ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian)
: TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default),
- IsAAPCS(true) {
+ IsAAPCS(true), HW_FP(0) {
BigEndian = IsBigEndian;
switch (getTriple().getOS()) {
@@ -3672,7 +3899,45 @@ public:
// FIXME: Should we just treat this as a feature?
IsThumb = getTriple().getArchName().startswith("thumb");
- setABI("aapcs-linux");
+ // FIXME: This duplicates code from the driver that sets the -target-abi
+ // option - this code is used if -target-abi isn't passed and should
+ // be unified in some way.
+ if (Triple.isOSBinFormatMachO()) {
+ // The backend is hardwired to assume AAPCS for M-class processors, ensure
+ // the frontend matches that.
+ if (Triple.getEnvironment() == llvm::Triple::EABI ||
+ Triple.getOS() == llvm::Triple::UnknownOS ||
+ StringRef(CPU).startswith("cortex-m")) {
+ setABI("aapcs");
+ } else {
+ setABI("apcs-gnu");
+ }
+ } else if (Triple.isOSWindows()) {
+ // FIXME: this is invalid for WindowsCE
+ setABI("aapcs");
+ } else {
+ // Select the default based on the platform.
+ switch (Triple.getEnvironment()) {
+ case llvm::Triple::Android:
+ case llvm::Triple::GNUEABI:
+ case llvm::Triple::GNUEABIHF:
+ setABI("aapcs-linux");
+ break;
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::EABI:
+ setABI("aapcs");
+ break;
+ case llvm::Triple::GNU:
+ setABI("apcs-gnu");
+ break;
+ default:
+ if (Triple.getOS() == llvm::Triple::NetBSD)
+ setABI("apcs-gnu");
+ else
+ setABI("aapcs");
+ break;
+ }
+ }
// ARM targets default to using the ARM C++ ABI.
TheCXXABI.set(TargetCXXABI::GenericARM);
@@ -3683,8 +3948,8 @@ public:
MaxAtomicInlineWidth = 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
+ // 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;
}
@@ -3708,16 +3973,10 @@ public:
}
void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
- if (IsAAPCS)
- Features["aapcs"] = true;
- else
- Features["apcs"] = true;
-
StringRef ArchName = getTriple().getArchName();
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
Features["vfp2"] = true;
- else if (CPU == "cortex-a8" || CPU == "cortex-a9" ||
- CPU == "cortex-a9-mp") {
+ else if (CPU == "cortex-a8" || CPU == "cortex-a9") {
Features["vfp3"] = true;
Features["neon"] = true;
}
@@ -3726,7 +3985,7 @@ public:
Features["neon"] = true;
} else if (CPU == "swift" || CPU == "cortex-a7" ||
CPU == "cortex-a12" || CPU == "cortex-a15" ||
- CPU == "krait") {
+ CPU == "cortex-a17" || CPU == "krait") {
Features["vfp4"] = true;
Features["neon"] = true;
Features["hwdiv"] = true;
@@ -3752,7 +4011,7 @@ public:
ArchName == "thumbebv8a" || ArchName == "thumbebv8") {
Features["hwdiv"] = true;
Features["hwdiv-arm"] = true;
- } else if (CPU == "cortex-m3" || CPU == "cortex-m4") {
+ } else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7") {
Features["hwdiv"] = true;
}
}
@@ -3764,29 +4023,38 @@ public:
Crypto = 0;
SoftFloat = SoftFloatABI = false;
HWDiv = 0;
- for (unsigned i = 0, e = Features.size(); i != e; ++i) {
- if (Features[i] == "+soft-float")
+
+ for (const auto &Feature : Features) {
+ if (Feature == "+soft-float") {
SoftFloat = true;
- else if (Features[i] == "+soft-float-abi")
+ } else if (Feature == "+soft-float-abi") {
SoftFloatABI = true;
- else if (Features[i] == "+vfp2")
+ } else if (Feature == "+vfp2") {
FPU |= VFP2FPU;
- else if (Features[i] == "+vfp3")
+ HW_FP = HW_FP_SP | HW_FP_DP;
+ } else if (Feature == "+vfp3") {
FPU |= VFP3FPU;
- else if (Features[i] == "+vfp4")
+ HW_FP = HW_FP_SP | HW_FP_DP;
+ } else if (Feature == "+vfp4") {
FPU |= VFP4FPU;
- else if (Features[i] == "+fp-armv8")
+ HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP;
+ } else if (Feature == "+fp-armv8") {
FPU |= FPARMV8;
- else if (Features[i] == "+neon")
+ HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP;
+ } else if (Feature == "+neon") {
FPU |= NeonFPU;
- else if (Features[i] == "+hwdiv")
+ HW_FP = HW_FP_SP | HW_FP_DP;
+ } else if (Feature == "+hwdiv") {
HWDiv |= HWDivThumb;
- else if (Features[i] == "+hwdiv-arm")
+ } else if (Feature == "+hwdiv-arm") {
HWDiv |= HWDivARM;
- else if (Features[i] == "+crc")
+ } else if (Feature == "+crc") {
CRC = 1;
- else if (Features[i] == "+crypto")
+ } else if (Feature == "+crypto") {
Crypto = 1;
+ } else if (Feature == "+fp-only-sp") {
+ HW_FP &= ~HW_FP_DP;
+ }
}
if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
@@ -3800,13 +4068,13 @@ public:
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");
- if (it != Features.end())
- Features.erase(it);
- it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
- if (it != Features.end())
- Features.erase(it);
+ const StringRef FrontEndFeatures[] = { "+soft-float", "+soft-float-abi" };
+ for (const auto &FEFeature : FrontEndFeatures) {
+ auto Feature = std::find(Features.begin(), Features.end(), FEFeature);
+ if (Feature != Features.end())
+ Features.erase(Feature);
+ }
+
return true;
}
@@ -3822,40 +4090,43 @@ public:
}
// FIXME: Should we actually have some table instead of these switches?
static const char *getCPUDefineSuffix(StringRef Name) {
- return llvm::StringSwitch<const char*>(Name)
- .Cases("arm8", "arm810", "4")
- .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
- .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
- .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
- .Case("ep9312", "4T")
- .Cases("arm10tdmi", "arm1020t", "5T")
- .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
- .Case("arm926ej-s", "5TEJ")
- .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
- .Cases("xscale", "iwmmxt", "5TE")
- .Case("arm1136j-s", "6J")
- .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
- .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
- .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
- .Cases("cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9-mp", "7A")
- .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "7A")
- .Cases("cortex-r4", "cortex-r5", "7R")
- .Case("swift", "7S")
- .Case("cyclone", "8A")
- .Case("cortex-m3", "7M")
- .Case("cortex-m4", "7EM")
- .Case("cortex-m0", "6M")
- .Cases("cortex-a53", "cortex-a57", "8A")
- .Default(nullptr);
+ return llvm::StringSwitch<const char *>(Name)
+ .Cases("arm8", "arm810", "4")
+ .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110",
+ "4")
+ .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
+ .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
+ .Case("ep9312", "4T")
+ .Cases("arm10tdmi", "arm1020t", "5T")
+ .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
+ .Case("arm926ej-s", "5TEJ")
+ .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
+ .Cases("xscale", "iwmmxt", "5TE")
+ .Case("arm1136j-s", "6J")
+ .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
+ .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
+ .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
+ .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait",
+ "7A")
+ .Cases("cortex-r4", "cortex-r5", "7R")
+ .Case("swift", "7S")
+ .Case("cyclone", "8A")
+ .Case("cortex-m3", "7M")
+ .Cases("cortex-m4", "cortex-m7", "7EM")
+ .Case("cortex-m0", "6M")
+ .Cases("cortex-a53", "cortex-a57", "8A")
+ .Default(nullptr);
}
static const char *getCPUProfile(StringRef Name) {
- return llvm::StringSwitch<const char*>(Name)
- .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
- .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "A")
- .Cases("cortex-a53", "cortex-a57", "A")
- .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
- .Cases("cortex-r4", "cortex-r5", "R")
- .Default("");
+ return llvm::StringSwitch<const char *>(Name)
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
+ .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait",
+ "A")
+ .Cases("cortex-a53", "cortex-a57", "A")
+ .Cases("cortex-m3", "cortex-m4", "cortex-m0", "cortex-m7", "M")
+ .Cases("cortex-r4", "cortex-r5", "R")
+ .Default("");
}
bool setCPU(const std::string &Name) override {
if (!getCPUDefineSuffix(Name))
@@ -3895,9 +4166,8 @@ public:
StringRef CPUArch = getCPUDefineSuffix(CPU);
unsigned int CPUArchVer;
- if(CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer)) {
+ if (CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer))
llvm_unreachable("Invalid char for architecture version number");
- }
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
// ACLE 6.4.1 ARM/Thumb instruction set architecture
@@ -3906,6 +4176,10 @@ public:
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA
Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+ if (CPUArch[0] >= '8') {
+ Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN");
+ Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING");
+ }
// __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
// is not defined for the M-profile.
@@ -3931,6 +4205,10 @@ public:
if (!CPUProfile.empty())
Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
+ // ACLE 6.5.1 Hardware Floating Point
+ if (HW_FP)
+ Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
+
// ACLE predefines.
Builder.defineMacro("__ARM_ACLE", "200");
@@ -4008,6 +4286,13 @@ public:
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
+
+ bool is5EOrAbove = (CPUArchVer >= 6 ||
+ (CPUArchVer == 5 &&
+ CPUArch.find('E') != StringRef::npos));
+ bool is32Bit = (!IsThumb || supportsThumb2(ArchName, CPUArch, CPUArchVer));
+ if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUArch == "7EM"))
+ Builder.defineMacro("__ARM_FEATURE_DSP");
}
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {
@@ -4032,6 +4317,13 @@ public:
case 'P': // VFP Floating point register double precision
Info.setAllowsRegister();
return true;
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ // FIXME
+ return true;
case 'Q': // A memory address that is a single base register.
Info.setAllowsMemory();
return true;
@@ -4068,8 +4360,9 @@ public:
}
return R;
}
- bool validateConstraintModifier(StringRef Constraint, const char Modifier,
- unsigned Size) const override {
+ bool
+ validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
+ std::string &SuggestedModifier) const override {
bool isOutput = (Constraint[0] == '=');
bool isInOut = (Constraint[0] == '+');
@@ -4297,7 +4590,8 @@ public:
: DarwinTargetInfo<ARMleTargetInfo>(Triple) {
HasAlignMac68kSupport = true;
// iOS always has 64-bit atomic instructions.
- // FIXME: This should be based off of the target features in ARMleTargetInfo.
+ // FIXME: This should be based off of the target features in
+ // ARMleTargetInfo.
MaxAtomicInlineWidth = 64;
// Darwin on iOS uses a variant of the ARM C++ ABI.
@@ -4361,7 +4655,7 @@ public:
}
StringRef getABI() const override { return ABI; }
- virtual bool setABI(const std::string &Name) {
+ bool setABI(const std::string &Name) override {
if (Name != "aapcs" && Name != "darwinpcs")
return false;
@@ -4369,7 +4663,7 @@ public:
return true;
}
- virtual bool setCPU(const std::string &Name) {
+ bool setCPU(const std::string &Name) override {
bool CPUKnown = llvm::StringSwitch<bool>(Name)
.Case("generic", true)
.Cases("cortex-a53", "cortex-a57", true)
@@ -4379,7 +4673,7 @@ public:
}
virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
+ MacroBuilder &Builder) const override {
// Target identification.
Builder.defineMacro("__aarch64__");
@@ -4400,6 +4694,10 @@ public:
Builder.defineMacro("__ARM_FEATURE_CLZ");
Builder.defineMacro("__ARM_FEATURE_FMA");
Builder.defineMacro("__ARM_FEATURE_DIV");
+ Builder.defineMacro("__ARM_FEATURE_IDIV"); // As specified in ACLE
+ Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
+ Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN");
+ Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING");
Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
@@ -4413,7 +4711,7 @@ public:
if (Opts.FastMath || Opts.FiniteMathOnly)
Builder.defineMacro("__ARM_FP_FAST");
- if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
+ if (Opts.C99 && !Opts.Freestanding)
Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
@@ -4435,12 +4733,12 @@ public:
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
+ unsigned &NumRecords) const override {
Records = BuiltinInfo;
NumRecords = clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
}
- virtual bool hasFeature(StringRef Feature) const {
+ bool hasFeature(StringRef Feature) const override {
return Feature == "aarch64" ||
Feature == "arm64" ||
(Feature == "neon" && FPU == NeonMode);
@@ -4465,19 +4763,20 @@ public:
return true;
}
- virtual bool isCLZForZeroUndef() const { return false; }
+ bool isCLZForZeroUndef() const override { return false; }
- virtual BuiltinVaListKind getBuiltinVaListKind() const {
+ BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::AArch64ABIBuiltinVaList;
}
virtual void getGCCRegNames(const char *const *&Names,
- unsigned &NumNames) const;
+ unsigned &NumNames) const override;
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const;
+ unsigned &NumAliases) const override;
- virtual bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const {
+ virtual bool
+ validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override {
switch (*Name) {
default:
return false;
@@ -4500,11 +4799,11 @@ public:
Info.setAllowsRegister();
return true;
case 'U':
- // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
- // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
- // Usa: An absolute symbolic address
- // Ush: The high part (bits 32:12) of a pc-relative symbolic address
- llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
+ // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
+ // Utf: A memory address suitable for ldp/stp in TF mode.
+ // Usa: An absolute symbolic address.
+ // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
+ llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
case 'z': // Zero register, wzr or xzr
Info.setAllowsRegister();
return true;
@@ -4515,9 +4814,40 @@ public:
return false;
}
- virtual const char *getClobbers() const { return ""; }
+ bool
+ validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
+ std::string &SuggestedModifier) const override {
+ // Strip off constraint modifiers.
+ while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
+ Constraint = Constraint.substr(1);
+
+ switch (Constraint[0]) {
+ default:
+ return true;
+ case 'z':
+ case 'r': {
+ switch (Modifier) {
+ case 'x':
+ case 'w':
+ // For now assume that the person knows what they're
+ // doing with the modifier.
+ return true;
+ default:
+ // By default an 'r' constraint will be in the 'x'
+ // registers.
+ if (Size == 64)
+ return true;
+
+ SuggestedModifier = "w";
+ return false;
+ }
+ }
+ }
+ }
+
+ const char *getClobbers() const override { return ""; }
- int getEHDataRegisterNumber(unsigned RegNo) const {
+ int getEHDataRegisterNumber(unsigned RegNo) const override {
if (RegNo == 0)
return 0;
if (RegNo == 1)
@@ -4652,7 +4982,7 @@ public:
TheCXXABI.set(TargetCXXABI::iOS64);
}
- virtual BuiltinVaListKind getBuiltinVaListKind() const {
+ BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}
};
@@ -4857,6 +5187,16 @@ public:
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override {
// FIXME: Implement!
+ switch (*Name) {
+ case 'I': // Signed 13-bit constant
+ case 'J': // Zero
+ case 'K': // 32-bit constant with the low 12 bits clear
+ case 'L': // A constant in the range supported by movcc (11-bit signed imm)
+ case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
+ case 'N': // Same as 'K' but zext (required for SIMode)
+ case 'O': // The constant 4096
+ return true;
+ }
return false;
}
const char *getClobbers() const override {
@@ -4962,10 +5302,8 @@ public:
SparcTargetInfo::getTargetDefines(Opts, Builder);
Builder.defineMacro("__sparcv9");
Builder.defineMacro("__arch64__");
- // Solaris and its derivative AuroraUX don't need these variants, but the
- // BSDs do.
- if (getTriple().getOS() != llvm::Triple::Solaris &&
- getTriple().getOS() != llvm::Triple::AuroraUX) {
+ // Solaris doesn't need these variants, but the BSDs do.
+ if (getTriple().getOS() != llvm::Triple::Solaris) {
Builder.defineMacro("__sparc64__");
Builder.defineMacro("__sparc_v9__");
Builder.defineMacro("__sparcv9__");
@@ -4992,14 +5330,6 @@ public:
} // end anonymous namespace.
namespace {
-class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
-public:
- AuroraUXSparcV8TargetInfo(const llvm::Triple &Triple)
- : AuroraUXTargetInfo<SparcV8TargetInfo>(Triple) {
- SizeType = UnsignedInt;
- PtrDiffType = SignedInt;
- }
-};
class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
public:
SolarisSparcV8TargetInfo(const llvm::Triple &Triple)
@@ -5131,7 +5461,7 @@ namespace {
IntPtrType = SignedInt;
PtrDiffType = SignedInt;
SigAtomicType = SignedLong;
- DescriptionString = "e-m:e-p:16:16-i32:16:32-n8:16";
+ DescriptionString = "e-m:e-p:16:16-i32:16:32-a:16-n8:16";
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
@@ -5156,8 +5486,16 @@ namespace {
Aliases = nullptr;
NumAliases = 0;
}
- bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ bool
+ validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override {
+ // FIXME: implement
+ switch (*Name) {
+ case 'K': // the constant 1
+ case 'L': // constant -1^20 .. 1^19
+ case 'M': // constant 1-4:
+ return true;
+ }
// No target constraints for now.
return false;
}
@@ -5197,6 +5535,8 @@ namespace {
3, // opencl_global
4, // opencl_local
5, // opencl_constant
+ // FIXME: generic has to be added to the target
+ 0, // opencl_generic
0, // cuda_device
0, // cuda_constant
0 // cuda_shared
@@ -5443,7 +5783,6 @@ public:
switch (*Name) {
default:
return false;
-
case 'r': // CPU registers.
case 'd': // Equivalent to "r" unless generating MIPS16 code.
case 'y': // Equivalent to "r", backward compatibility only.
@@ -5453,6 +5792,15 @@ public:
case 'x': // hilo register pair
Info.setAllowsRegister();
return true;
+ case 'I': // Signed 16-bit constant
+ case 'J': // Integer 0
+ case 'K': // Unsigned 16-bit constant
+ case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui)
+ case 'M': // Constants not loadable via lui, addiu, or ori
+ case 'N': // Constant -1 to -65535
+ case 'O': // A signed 15-bit constant
+ case 'P': // A constant between 1 go 65535
+ return true;
case 'R': // An address that can be used in a non-macro load or store
Info.setAllowsMemory();
return true;
@@ -5460,8 +5808,28 @@ public:
}
const char *getClobbers() const override {
- // FIXME: Implement!
- return "";
+ // In GCC, $1 is not widely used in generated code (it's used only in a few
+ // specific situations), so there is no real need for users to add it to
+ // the clobbers list if they want to use it in their inline assembly code.
+ //
+ // In LLVM, $1 is treated as a normal GPR and is always allocatable during
+ // code generation, so using it in inline assembly without adding it to the
+ // clobbers list can cause conflicts between the inline assembly code and
+ // the surrounding generated code.
+ //
+ // Another problem is that LLVM is allowed to choose $1 for inline assembly
+ // operands, which will conflict with the ".set at" assembler option (which
+ // we use only for inline assembly, in order to maintain compatibility with
+ // GCC) and will also conflict with the user's usage of $1.
+ //
+ // The easiest way to avoid these conflicts and keep $1 as an allocatable
+ // register for generated code is to automatically clobber $1 for all inline
+ // assembly code.
+ //
+ // FIXME: We should automatically clobber $1 only for inline assembly code
+ // which actually uses it. This would allow LLVM to use $1 for inline
+ // assembly operands if the user's assembly code doesn't use it.
+ return "~{$1}";
}
bool handleTargetFeatures(std::vector<std::string> &Features,
@@ -5863,10 +6231,65 @@ void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
} // end anonymous namespace.
namespace {
+class Le64TargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+
+public:
+ Le64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
+ BigEndian = false;
+ NoAsmVariants = true;
+ LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ DescriptionString =
+ "e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128";
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override {
+ DefineStd(Builder, "unix", Opts);
+ defineCPUMacros(Builder, "le64", /*Tuning=*/false);
+ Builder.defineMacro("__ELF__");
+ }
+ void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const override {
+ Records = BuiltinInfo;
+ NumRecords = clang::Le64::LastTSBuiltin - Builtin::FirstTSBuiltin;
+ }
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::PNaClABIBuiltinVaList;
+ }
+ const char *getClobbers() const override { return ""; }
+ void getGCCRegNames(const char *const *&Names,
+ unsigned &NumNames) const override {
+ Names = nullptr;
+ NumNames = 0;
+ }
+ void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const override {
+ Aliases = nullptr;
+ NumAliases = 0;
+ }
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override {
+ return false;
+ }
+
+ bool hasProtectedVisibility() const override { return false; }
+};
+} // end anonymous namespace.
+
+const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsLe64.def"
+};
+
+namespace {
static const unsigned SPIRAddrSpaceMap[] = {
1, // opencl_global
3, // opencl_local
2, // opencl_constant
+ 4, // opencl_generic
0, // cuda_device
0, // cuda_constant
0 // cuda_shared
@@ -5902,8 +6325,9 @@ namespace {
}
void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const override {}
- bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ bool
+ validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override {
return true;
}
void getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -6031,7 +6455,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
return new HexagonTargetInfo(Triple);
case llvm::Triple::aarch64:
- case llvm::Triple::arm64:
if (Triple.isOSDarwin())
return new DarwinAArch64TargetInfo(Triple);
@@ -6047,7 +6470,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
}
case llvm::Triple::aarch64_be:
- case llvm::Triple::arm64_be:
switch (os) {
case llvm::Triple::FreeBSD:
return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple);
@@ -6189,6 +6611,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
return nullptr;
}
+ case llvm::Triple::le64:
+ return new Le64TargetInfo(Triple);
+
case llvm::Triple::ppc:
if (Triple.isOSDarwin())
return new DarwinPPC32TargetInfo(Triple);
@@ -6236,6 +6661,7 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
case llvm::Triple::nvptx64:
return new NVPTX64TargetInfo(Triple);
+ case llvm::Triple::amdgcn:
case llvm::Triple::r600:
return new R600TargetInfo(Triple);
@@ -6243,8 +6669,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
switch (os) {
case llvm::Triple::Linux:
return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
- case llvm::Triple::AuroraUX:
- return new AuroraUXSparcV8TargetInfo(Triple);
case llvm::Triple::Solaris:
return new SolarisSparcV8TargetInfo(Triple);
case llvm::Triple::NetBSD:
@@ -6261,8 +6685,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
switch (os) {
case llvm::Triple::Linux:
return new LinuxTargetInfo<SparcV9TargetInfo>(Triple);
- case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::Solaris:
return new SolarisTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::NetBSD:
@@ -6291,8 +6713,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
return new DarwinI386TargetInfo(Triple);
switch (os) {
- case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::Linux:
return new LinuxTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::DragonFly:
@@ -6339,8 +6759,6 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
return new DarwinX86_64TargetInfo(Triple);
switch (os) {
- case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::Linux:
return new LinuxTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::DragonFly:
OpenPOWER on IntegriCloud