summaryrefslogtreecommitdiff
path: root/lib/Basic/Targets
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Basic/Targets
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
Notes
Diffstat (limited to 'lib/Basic/Targets')
-rw-r--r--lib/Basic/Targets/AArch64.cpp64
-rw-r--r--lib/Basic/Targets/AArch64.h9
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp309
-rw-r--r--lib/Basic/Targets/AMDGPU.h234
-rw-r--r--lib/Basic/Targets/ARM.cpp34
-rw-r--r--lib/Basic/Targets/ARM.h8
-rw-r--r--lib/Basic/Targets/AVR.cpp48
-rw-r--r--lib/Basic/Targets/AVR.h3
-rw-r--r--lib/Basic/Targets/BPF.cpp12
-rw-r--r--lib/Basic/Targets/BPF.h19
-rw-r--r--lib/Basic/Targets/Hexagon.cpp35
-rw-r--r--lib/Basic/Targets/Hexagon.h2
-rw-r--r--lib/Basic/Targets/Lanai.cpp4
-rw-r--r--lib/Basic/Targets/Lanai.h2
-rw-r--r--lib/Basic/Targets/Mips.cpp43
-rw-r--r--lib/Basic/Targets/Mips.h16
-rw-r--r--lib/Basic/Targets/NVPTX.cpp37
-rw-r--r--lib/Basic/Targets/NVPTX.h10
-rw-r--r--lib/Basic/Targets/Nios2.h4
-rw-r--r--lib/Basic/Targets/OSTargets.h46
-rw-r--r--lib/Basic/Targets/PPC.cpp185
-rw-r--r--lib/Basic/Targets/PPC.h135
-rw-r--r--lib/Basic/Targets/RISCV.cpp104
-rw-r--r--lib/Basic/Targets/RISCV.h114
-rw-r--r--lib/Basic/Targets/SPIR.h5
-rw-r--r--lib/Basic/Targets/Sparc.cpp140
-rw-r--r--lib/Basic/Targets/Sparc.h49
-rw-r--r--lib/Basic/Targets/SystemZ.cpp56
-rw-r--r--lib/Basic/Targets/SystemZ.h6
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp32
-rw-r--r--lib/Basic/Targets/WebAssembly.h18
-rw-r--r--lib/Basic/Targets/X86.cpp231
-rw-r--r--lib/Basic/Targets/X86.h64
33 files changed, 1424 insertions, 654 deletions
diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp
index 4d3cd121f7057..3444591ac5933 100644
--- a/lib/Basic/Targets/AArch64.cpp
+++ b/lib/Basic/Targets/AArch64.cpp
@@ -29,26 +29,27 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
{#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
+#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
+ {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
#include "clang/Basic/BuiltinsAArch64.def"
};
AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple), ABI("aapcs") {
- if (getTriple().getOS() == llvm::Triple::NetBSD ||
- getTriple().getOS() == llvm::Triple::OpenBSD) {
- // NetBSD apparently prefers consistency across ARM targets to
- // consistency across 64-bit targets.
+ if (getTriple().getOS() == llvm::Triple::OpenBSD) {
Int64Type = SignedLongLong;
IntMaxType = SignedLongLong;
} else {
- if (!getTriple().isOSDarwin())
+ if (!getTriple().isOSDarwin() && getTriple().getOS() != llvm::Triple::NetBSD)
WCharType = UnsignedInt;
Int64Type = SignedLong;
IntMaxType = SignedLong;
}
+ // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
+ HasLegalHalfType = true;
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
MaxVectorAlign = 128;
@@ -101,6 +102,11 @@ bool AArch64TargetInfo::setCPU(const std::string &Name) {
return isValidCPUName(Name);
}
+void AArch64TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::AArch64::fillValidCPUArchList(Values);
+}
+
void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
@@ -183,6 +189,11 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if ((FPU & NeonMode) && HasFullFP16)
Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
+ if (HasFullFP16)
+ Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
+
+ if (HasDotProd)
+ Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
switch (ArchKind) {
default:
@@ -220,6 +231,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
Crypto = 0;
Unaligned = 1;
HasFullFP16 = 0;
+ HasDotProd = 0;
ArchKind = llvm::AArch64::ArchKind::ARMV8A;
for (const auto &Feature : Features) {
@@ -239,6 +251,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
if (Feature == "+fullfp16")
HasFullFP16 = 1;
+ if (Feature == "+dotprod")
+ HasDotProd = 1;
}
setDataLayout();
@@ -299,7 +313,40 @@ ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
}
const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
- {{"w31"}, "wsp"}, {{"x29"}, "fp"}, {{"x30"}, "lr"}, {{"x31"}, "sp"},
+ {{"w31"}, "wsp"},
+ {{"x31"}, "sp"},
+ // GCC rN registers are aliases of xN registers.
+ {{"r0"}, "x0"},
+ {{"r1"}, "x1"},
+ {{"r2"}, "x2"},
+ {{"r3"}, "x3"},
+ {{"r4"}, "x4"},
+ {{"r5"}, "x5"},
+ {{"r6"}, "x6"},
+ {{"r7"}, "x7"},
+ {{"r8"}, "x8"},
+ {{"r9"}, "x9"},
+ {{"r10"}, "x10"},
+ {{"r11"}, "x11"},
+ {{"r12"}, "x12"},
+ {{"r13"}, "x13"},
+ {{"r14"}, "x14"},
+ {{"r15"}, "x15"},
+ {{"r16"}, "x16"},
+ {{"r17"}, "x17"},
+ {{"r18"}, "x18"},
+ {{"r19"}, "x19"},
+ {{"r20"}, "x20"},
+ {{"r21"}, "x21"},
+ {{"r22"}, "x22"},
+ {{"r23"}, "x23"},
+ {{"r24"}, "x24"},
+ {{"r25"}, "x25"},
+ {{"r26"}, "x26"},
+ {{"r27"}, "x27"},
+ {{"r28"}, "x28"},
+ {{"r29", "x29"}, "fp"},
+ {{"r30", "x30"}, "lr"},
// The S/D/Q and W/X registers overlap, but aren't really aliases; we
// don't want to substitute one of these for a different-sized one.
};
@@ -486,6 +533,11 @@ void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
getVisualStudioDefines(Opts, Builder);
}
+TargetInfo::CallingConvKind
+MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
+ return CCK_MicrosoftWin64;
+}
+
MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsARM64TargetInfo(Triple, Opts) {
diff --git a/lib/Basic/Targets/AArch64.h b/lib/Basic/Targets/AArch64.h
index 33268f0f8d990..a9df895e4dad3 100644
--- a/lib/Basic/Targets/AArch64.h
+++ b/lib/Basic/Targets/AArch64.h
@@ -33,6 +33,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
unsigned Crypto;
unsigned Unaligned;
unsigned HasFullFP16;
+ unsigned HasDotProd;
llvm::AArch64::ArchKind ArchKind;
static const Builtin::Info BuiltinInfo[];
@@ -46,6 +47,7 @@ public:
bool setABI(const std::string &Name) override;
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override;
bool useFP16ConversionIntrinsics() const override {
@@ -80,6 +82,11 @@ public:
std::string &SuggestedModifier) const override;
const char *getClobbers() const override;
+ StringRef getConstraintRegister(StringRef Constraint,
+ StringRef Expression) const override {
+ return Expression;
+ }
+
int getEHDataRegisterNumber(unsigned RegNo) const override;
};
@@ -119,6 +126,8 @@ public:
MacroBuilder &Builder) const;
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
+ TargetInfo::CallingConvKind
+ getCallingConvKind(bool ClangABICompat4) const override;
};
// ARM64 MinGW target
diff --git a/lib/Basic/Targets/AMDGPU.cpp b/lib/Basic/Targets/AMDGPU.cpp
index 4c510e47379f5..b6b9aa2f1244c 100644
--- a/lib/Basic/Targets/AMDGPU.cpp
+++ b/lib/Basic/Targets/AMDGPU.cpp
@@ -30,64 +30,35 @@ namespace targets {
static const char *const DataLayoutStringR600 =
"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";
+ "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5";
-static const char *const DataLayoutStringSIPrivateIsZero =
- "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32"
+static const char *const DataLayoutStringAMDGCN =
+ "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6: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";
-
-static const char *const DataLayoutStringSIGenericIsZero =
- "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5: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-A5";
-
-static const LangASMap AMDGPUPrivIsZeroDefIsGenMap = {
- 4, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_private
- 4, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+ "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5";
+
+const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
+ Generic, // Default
+ Global, // opencl_global
+ Local, // opencl_local
+ Constant, // opencl_constant
+ Private, // opencl_private
+ Generic, // opencl_generic
+ Global, // cuda_device
+ Constant, // cuda_constant
+ Local // cuda_shared
};
-static const LangASMap AMDGPUGenIsZeroDefIsGenMap = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 5, // opencl_private
- 0, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
-};
-
-static const LangASMap AMDGPUPrivIsZeroDefIsPrivMap = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_private
- 4, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
-};
-
-static const LangASMap AMDGPUGenIsZeroDefIsPrivMap = {
- 5, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 5, // opencl_private
- 0, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
+ Private, // Default
+ Global, // opencl_global
+ Local, // opencl_local
+ Constant, // opencl_constant
+ Private, // opencl_private
+ Generic, // opencl_generic
+ Global, // cuda_device
+ Constant, // cuda_constant
+ Local // cuda_shared
};
} // namespace targets
} // namespace clang
@@ -144,7 +115,7 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = {
"s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",
"s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",
"s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",
- "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",
+ "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",
"flat_scratch_lo", "flat_scratch_hi"
};
@@ -157,49 +128,66 @@ bool AMDGPUTargetInfo::initFeatureMap(
const std::vector<std::string> &FeatureVec) const {
// XXX - What does the member GPU mean if device name string passed here?
- if (getTriple().getArch() == llvm::Triple::amdgcn) {
+ if (isAMDGCN(getTriple())) {
if (CPU.empty())
- CPU = "tahiti";
-
- switch (parseAMDGCNName(CPU)) {
- case GK_GFX6:
- case GK_GFX7:
- break;
+ CPU = "gfx600";
- case GK_GFX9:
+ switch (parseAMDGCNName(CPU).Kind) {
+ case GK_GFX906:
+ Features["dl-insts"] = true;
+ LLVM_FALLTHROUGH;
+ case GK_GFX904:
+ case GK_GFX902:
+ case GK_GFX900:
Features["gfx9-insts"] = true;
LLVM_FALLTHROUGH;
- case GK_GFX8:
- Features["s-memrealtime"] = true;
+ case GK_GFX810:
+ case GK_GFX803:
+ case GK_GFX802:
+ case GK_GFX801:
Features["16-bit-insts"] = true;
Features["dpp"] = true;
+ Features["s-memrealtime"] = true;
+ break;
+ case GK_GFX704:
+ case GK_GFX703:
+ case GK_GFX702:
+ case GK_GFX701:
+ case GK_GFX700:
+ case GK_GFX601:
+ case GK_GFX600:
break;
-
case GK_NONE:
return false;
default:
- llvm_unreachable("unhandled subtarget");
+ llvm_unreachable("Unhandled GPU!");
}
} else {
if (CPU.empty())
CPU = "r600";
- switch (parseR600Name(CPU)) {
- case GK_R600:
- case GK_R700:
- case GK_EVERGREEN:
- case GK_NORTHERN_ISLANDS:
- break;
- case GK_R600_DOUBLE_OPS:
- case GK_R700_DOUBLE_OPS:
- case GK_EVERGREEN_DOUBLE_OPS:
+ switch (parseR600Name(CPU).Kind) {
case GK_CAYMAN:
+ case GK_CYPRESS:
+ case GK_RV770:
+ case GK_RV670:
// TODO: Add fp64 when implemented.
break;
- case GK_NONE:
- return false;
+ case GK_TURKS:
+ case GK_CAICOS:
+ case GK_BARTS:
+ case GK_SUMO:
+ case GK_REDWOOD:
+ case GK_JUNIPER:
+ case GK_CEDAR:
+ case GK_RV730:
+ case GK_RV710:
+ case GK_RS880:
+ case GK_R630:
+ case GK_R600:
+ break;
default:
- llvm_unreachable("unhandled subtarget");
+ llvm_unreachable("Unhandled GPU!");
}
}
@@ -210,6 +198,7 @@ void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts,
TargetOptions &TargetOpts) const {
bool hasFP32Denormals = false;
bool hasFP64Denormals = false;
+ GPUInfo CGOptsGPU = parseGPUName(TargetOpts.CPU);
for (auto &I : TargetOpts.FeaturesAsWritten) {
if (I == "+fp32-denormals" || I == "-fp32-denormals")
hasFP32Denormals = true;
@@ -218,120 +207,68 @@ void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts,
}
if (!hasFP32Denormals)
TargetOpts.Features.push_back(
- (Twine(hasFullSpeedFMAF32(TargetOpts.CPU) && !CGOpts.FlushDenorm
+ (Twine(CGOptsGPU.HasFastFMAF && !CGOpts.FlushDenorm
? '+'
: '-') +
Twine("fp32-denormals"))
.str());
// Always do not flush fp64 or fp16 denorms.
- if (!hasFP64Denormals && hasFP64)
+ if (!hasFP64Denormals && CGOptsGPU.HasFP64)
TargetOpts.Features.push_back("+fp64-fp16-denormals");
}
-AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseR600Name(StringRef Name) {
- return llvm::StringSwitch<GPUKind>(Name)
- .Case("r600", GK_R600)
- .Case("rv610", GK_R600)
- .Case("rv620", GK_R600)
- .Case("rv630", GK_R600)
- .Case("rv635", GK_R600)
- .Case("rs780", GK_R600)
- .Case("rs880", GK_R600)
- .Case("rv670", GK_R600_DOUBLE_OPS)
- .Case("rv710", GK_R700)
- .Case("rv730", GK_R700)
- .Case("rv740", GK_R700_DOUBLE_OPS)
- .Case("rv770", GK_R700_DOUBLE_OPS)
- .Case("palm", GK_EVERGREEN)
- .Case("cedar", GK_EVERGREEN)
- .Case("sumo", GK_EVERGREEN)
- .Case("sumo2", GK_EVERGREEN)
- .Case("redwood", GK_EVERGREEN)
- .Case("juniper", GK_EVERGREEN)
- .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS)
- .Case("cypress", GK_EVERGREEN_DOUBLE_OPS)
- .Case("barts", GK_NORTHERN_ISLANDS)
- .Case("turks", GK_NORTHERN_ISLANDS)
- .Case("caicos", GK_NORTHERN_ISLANDS)
- .Case("cayman", GK_CAYMAN)
- .Case("aruba", GK_CAYMAN)
- .Default(GK_NONE);
+constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::InvalidGPU;
+constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::R600GPUs[];
+constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::AMDGCNGPUs[];
+
+AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseR600Name(StringRef Name) {
+ const auto *Result = llvm::find_if(
+ R600GPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
+
+ if (Result == std::end(R600GPUs))
+ return InvalidGPU;
+ return *Result;
}
-AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) {
- return llvm::StringSwitch<GPUKind>(Name)
- .Case("gfx600", GK_GFX6)
- .Case("tahiti", GK_GFX6)
- .Case("gfx601", GK_GFX6)
- .Case("pitcairn", GK_GFX6)
- .Case("verde", GK_GFX6)
- .Case("oland", GK_GFX6)
- .Case("hainan", GK_GFX6)
- .Case("gfx700", GK_GFX7)
- .Case("bonaire", GK_GFX7)
- .Case("kaveri", GK_GFX7)
- .Case("gfx701", GK_GFX7)
- .Case("hawaii", GK_GFX7)
- .Case("gfx702", GK_GFX7)
- .Case("gfx703", GK_GFX7)
- .Case("kabini", GK_GFX7)
- .Case("mullins", GK_GFX7)
- .Case("gfx800", GK_GFX8)
- .Case("iceland", GK_GFX8)
- .Case("gfx801", GK_GFX8)
- .Case("carrizo", GK_GFX8)
- .Case("gfx802", GK_GFX8)
- .Case("tonga", GK_GFX8)
- .Case("gfx803", GK_GFX8)
- .Case("fiji", GK_GFX8)
- .Case("polaris10", GK_GFX8)
- .Case("polaris11", GK_GFX8)
- .Case("gfx804", GK_GFX8)
- .Case("gfx810", GK_GFX8)
- .Case("stoney", GK_GFX8)
- .Case("gfx900", GK_GFX9)
- .Case("gfx901", GK_GFX9)
- .Case("gfx902", GK_GFX9)
- .Case("gfx903", GK_GFX9)
- .Default(GK_NONE);
+AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) {
+ const auto *Result = llvm::find_if(
+ AMDGCNGPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
+
+ if (Result == std::end(AMDGCNGPUs))
+ return InvalidGPU;
+ return *Result;
+}
+
+AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseGPUName(StringRef Name) const {
+ if (isAMDGCN(getTriple()))
+ return parseAMDGCNName(Name);
+ else
+ return parseR600Name(Name);
+}
+
+void AMDGPUTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ if (isAMDGCN(getTriple()))
+ llvm::for_each(AMDGCNGPUs, [&Values](const GPUInfo &GPU) {
+ Values.emplace_back(GPU.Name);});
+ else
+ llvm::for_each(R600GPUs, [&Values](const GPUInfo &GPU) {
+ Values.emplace_back(GPU.Name);});
}
void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) {
- if (isGenericZero(getTriple())) {
- AddrSpaceMap = DefaultIsPrivate ? &AMDGPUGenIsZeroDefIsPrivMap
- : &AMDGPUGenIsZeroDefIsGenMap;
- } else {
- AddrSpaceMap = DefaultIsPrivate ? &AMDGPUPrivIsZeroDefIsPrivMap
- : &AMDGPUPrivIsZeroDefIsGenMap;
- }
+ AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap;
}
AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple),
- GPU(isAMDGCN(Triple) ? GK_GFX6 : parseR600Name(Opts.CPU)),
- hasFP64(false), hasFMAF(false), hasLDEXPF(false),
- AS(isGenericZero(Triple)) {
- if (getTriple().getArch() == llvm::Triple::amdgcn) {
- hasFP64 = true;
- hasFMAF = true;
- hasLDEXPF = true;
- }
- if (getTriple().getArch() == llvm::Triple::r600) {
- if (GPU == GK_EVERGREEN_DOUBLE_OPS || GPU == GK_CAYMAN) {
- hasFMAF = true;
- }
- }
- auto IsGenericZero = isGenericZero(Triple);
- resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn
- ? (IsGenericZero ? DataLayoutStringSIGenericIsZero
- : DataLayoutStringSIPrivateIsZero)
- : DataLayoutStringR600);
- assert(DataLayout->getAllocaAddrSpace() == AS.Private);
+ GPU(isAMDGCN(Triple) ? AMDGCNGPUs[0] : parseR600Name(Opts.CPU)) {
+ resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN
+ : DataLayoutStringR600);
+ assert(DataLayout->getAllocaAddrSpace() == Private);
setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||
- Triple.getEnvironment() == llvm::Triple::OpenCL ||
- Triple.getEnvironmentName() == "amdgizcl" ||
!isAMDGCN(Triple));
UseAddrSpaceMapMangling = true;
@@ -349,7 +286,11 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
void AMDGPUTargetInfo::adjust(LangOptions &Opts) {
TargetInfo::adjust(Opts);
- setAddressSpaceMap(Opts.OpenCL || !isAMDGCN(getTriple()));
+ // ToDo: There are still a few places using default address space as private
+ // address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL
+ // can be removed from the following line.
+ setAddressSpaceMap(/*DefaultIsPrivate=*/Opts.OpenCL ||
+ !isAMDGCN(getTriple()));
}
ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
@@ -359,15 +300,27 @@ ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
- if (getTriple().getArch() == llvm::Triple::amdgcn)
+ Builder.defineMacro("__AMD__");
+ Builder.defineMacro("__AMDGPU__");
+
+ if (isAMDGCN(getTriple()))
Builder.defineMacro("__AMDGCN__");
else
Builder.defineMacro("__R600__");
- if (hasFMAF)
+ if (GPU.Kind != GK_NONE)
+ Builder.defineMacro(Twine("__") + Twine(GPU.CanonicalName) + Twine("__"));
+
+ // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be
+ // removed in the near future.
+ if (GPU.HasFMAF)
Builder.defineMacro("__HAS_FMAF__");
- if (hasLDEXPF)
+ if (GPU.HasFastFMAF)
+ Builder.defineMacro("FP_FAST_FMAF");
+ if (GPU.HasLDEXPF)
Builder.defineMacro("__HAS_LDEXPF__");
- if (hasFP64)
+ if (GPU.HasFP64)
Builder.defineMacro("__HAS_FP64__");
+ if (GPU.HasFastFMA)
+ Builder.defineMacro("FP_FAST_FMA");
}
diff --git a/lib/Basic/Targets/AMDGPU.h b/lib/Basic/Targets/AMDGPU.h
index a4e070f1cb12e..b0221031addf2 100644
--- a/lib/Basic/Targets/AMDGPU.h
+++ b/lib/Basic/Targets/AMDGPU.h
@@ -28,60 +28,157 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
static const Builtin::Info BuiltinInfo[];
static const char *const GCCRegNames[];
- struct LLVM_LIBRARY_VISIBILITY AddrSpace {
- unsigned Generic, Global, Local, Constant, Private;
- AddrSpace(bool IsGenericZero_ = false) {
- if (IsGenericZero_) {
- Generic = 0;
- Global = 1;
- Local = 3;
- Constant = 2;
- Private = 5;
- } else {
- Generic = 4;
- Global = 1;
- Local = 3;
- Constant = 2;
- Private = 0;
- }
- }
+ enum AddrSpace {
+ Generic = 0,
+ Global = 1,
+ Local = 3,
+ Constant = 4,
+ Private = 5
};
+ static const LangASMap AMDGPUDefIsGenMap;
+ static const LangASMap AMDGPUDefIsPrivMap;
+
+ /// GPU kinds supported by the AMDGPU target.
+ enum GPUKind : uint32_t {
+ // Not specified processor.
+ GK_NONE = 0,
- /// \brief The GPU profiles supported by the AMDGPU target.
- enum GPUKind {
- GK_NONE,
+ // R600-based processors.
GK_R600,
- GK_R600_DOUBLE_OPS,
- GK_R700,
- GK_R700_DOUBLE_OPS,
- GK_EVERGREEN,
- GK_EVERGREEN_DOUBLE_OPS,
- GK_NORTHERN_ISLANDS,
+ GK_R630,
+ GK_RS880,
+ GK_RV670,
+ GK_RV710,
+ GK_RV730,
+ GK_RV770,
+ GK_CEDAR,
+ GK_CYPRESS,
+ GK_JUNIPER,
+ GK_REDWOOD,
+ GK_SUMO,
+ GK_BARTS,
+ GK_CAICOS,
GK_CAYMAN,
- GK_GFX6,
- GK_GFX7,
- GK_GFX8,
- GK_GFX9
- } GPU;
-
- bool hasFP64 : 1;
- bool hasFMAF : 1;
- bool hasLDEXPF : 1;
- const AddrSpace AS;
-
- static bool hasFullSpeedFMAF32(StringRef GPUName) {
- return parseAMDGCNName(GPUName) >= GK_GFX9;
- }
+ GK_TURKS,
+
+ GK_R600_FIRST = GK_R600,
+ GK_R600_LAST = GK_TURKS,
+
+ // AMDGCN-based processors.
+ GK_GFX600,
+ GK_GFX601,
+ GK_GFX700,
+ GK_GFX701,
+ GK_GFX702,
+ GK_GFX703,
+ GK_GFX704,
+ GK_GFX801,
+ GK_GFX802,
+ GK_GFX803,
+ GK_GFX810,
+ GK_GFX900,
+ GK_GFX902,
+ GK_GFX904,
+ GK_GFX906,
+
+ GK_AMDGCN_FIRST = GK_GFX600,
+ GK_AMDGCN_LAST = GK_GFX906,
+ };
+
+ struct GPUInfo {
+ llvm::StringLiteral Name;
+ llvm::StringLiteral CanonicalName;
+ AMDGPUTargetInfo::GPUKind Kind;
+ bool HasFMAF;
+ bool HasFastFMAF;
+ bool HasLDEXPF;
+ bool HasFP64;
+ bool HasFastFMA;
+ };
+
+ static constexpr GPUInfo InvalidGPU =
+ {{""}, {""}, GK_NONE, false, false, false, false, false};
+ static constexpr GPUInfo R600GPUs[26] = {
+ // Name Canonical Kind Has Has Has Has Has
+ // Name FMAF Fast LDEXPF FP64 Fast
+ // FMAF FMA
+ {{"r600"}, {"r600"}, GK_R600, false, false, false, false, false},
+ {{"rv630"}, {"r600"}, GK_R600, false, false, false, false, false},
+ {{"rv635"}, {"r600"}, GK_R600, false, false, false, false, false},
+ {{"r630"}, {"r630"}, GK_R630, false, false, false, false, false},
+ {{"rs780"}, {"rs880"}, GK_RS880, false, false, false, false, false},
+ {{"rs880"}, {"rs880"}, GK_RS880, false, false, false, false, false},
+ {{"rv610"}, {"rs880"}, GK_RS880, false, false, false, false, false},
+ {{"rv620"}, {"rs880"}, GK_RS880, false, false, false, false, false},
+ {{"rv670"}, {"rv670"}, GK_RV670, false, false, false, false, false},
+ {{"rv710"}, {"rv710"}, GK_RV710, false, false, false, false, false},
+ {{"rv730"}, {"rv730"}, GK_RV730, false, false, false, false, false},
+ {{"rv740"}, {"rv770"}, GK_RV770, false, false, false, false, false},
+ {{"rv770"}, {"rv770"}, GK_RV770, false, false, false, false, false},
+ {{"cedar"}, {"cedar"}, GK_CEDAR, false, false, false, false, false},
+ {{"palm"}, {"cedar"}, GK_CEDAR, false, false, false, false, false},
+ {{"cypress"}, {"cypress"}, GK_CYPRESS, true, false, false, false, false},
+ {{"hemlock"}, {"cypress"}, GK_CYPRESS, true, false, false, false, false},
+ {{"juniper"}, {"juniper"}, GK_JUNIPER, false, false, false, false, false},
+ {{"redwood"}, {"redwood"}, GK_REDWOOD, false, false, false, false, false},
+ {{"sumo"}, {"sumo"}, GK_SUMO, false, false, false, false, false},
+ {{"sumo2"}, {"sumo"}, GK_SUMO, false, false, false, false, false},
+ {{"barts"}, {"barts"}, GK_BARTS, false, false, false, false, false},
+ {{"caicos"}, {"caicos"}, GK_BARTS, false, false, false, false, false},
+ {{"aruba"}, {"cayman"}, GK_CAYMAN, true, false, false, false, false},
+ {{"cayman"}, {"cayman"}, GK_CAYMAN, true, false, false, false, false},
+ {{"turks"}, {"turks"}, GK_TURKS, false, false, false, false, false},
+ };
+ static constexpr GPUInfo AMDGCNGPUs[32] = {
+ // Name Canonical Kind Has Has Has Has Has
+ // Name FMAF Fast LDEXPF FP64 Fast
+ // FMAF FMA
+ {{"gfx600"}, {"gfx600"}, GK_GFX600, true, true, true, true, true},
+ {{"tahiti"}, {"gfx600"}, GK_GFX600, true, true, true, true, true},
+ {{"gfx601"}, {"gfx601"}, GK_GFX601, true, false, true, true, true},
+ {{"hainan"}, {"gfx601"}, GK_GFX601, true, false, true, true, true},
+ {{"oland"}, {"gfx601"}, GK_GFX601, true, false, true, true, true},
+ {{"pitcairn"}, {"gfx601"}, GK_GFX601, true, false, true, true, true},
+ {{"verde"}, {"gfx601"}, GK_GFX601, true, false, true, true, true},
+ {{"gfx700"}, {"gfx700"}, GK_GFX700, true, false, true, true, true},
+ {{"kaveri"}, {"gfx700"}, GK_GFX700, true, false, true, true, true},
+ {{"gfx701"}, {"gfx701"}, GK_GFX701, true, true, true, true, true},
+ {{"hawaii"}, {"gfx701"}, GK_GFX701, true, true, true, true, true},
+ {{"gfx702"}, {"gfx702"}, GK_GFX702, true, true, true, true, true},
+ {{"gfx703"}, {"gfx703"}, GK_GFX703, true, false, true, true, true},
+ {{"kabini"}, {"gfx703"}, GK_GFX703, true, false, true, true, true},
+ {{"mullins"}, {"gfx703"}, GK_GFX703, true, false, true, true, true},
+ {{"gfx704"}, {"gfx704"}, GK_GFX704, true, false, true, true, true},
+ {{"bonaire"}, {"gfx704"}, GK_GFX704, true, false, true, true, true},
+ {{"gfx801"}, {"gfx801"}, GK_GFX801, true, true, true, true, true},
+ {{"carrizo"}, {"gfx801"}, GK_GFX801, true, true, true, true, true},
+ {{"gfx802"}, {"gfx802"}, GK_GFX802, true, false, true, true, true},
+ {{"iceland"}, {"gfx802"}, GK_GFX802, true, false, true, true, true},
+ {{"tonga"}, {"gfx802"}, GK_GFX802, true, false, true, true, true},
+ {{"gfx803"}, {"gfx803"}, GK_GFX803, true, false, true, true, true},
+ {{"fiji"}, {"gfx803"}, GK_GFX803, true, false, true, true, true},
+ {{"polaris10"}, {"gfx803"}, GK_GFX803, true, false, true, true, true},
+ {{"polaris11"}, {"gfx803"}, GK_GFX803, true, false, true, true, true},
+ {{"gfx810"}, {"gfx810"}, GK_GFX810, true, false, true, true, true},
+ {{"stoney"}, {"gfx810"}, GK_GFX810, true, false, true, true, true},
+ {{"gfx900"}, {"gfx900"}, GK_GFX900, true, true, true, true, true},
+ {{"gfx902"}, {"gfx902"}, GK_GFX900, true, true, true, true, true},
+ {{"gfx904"}, {"gfx904"}, GK_GFX904, true, true, true, true, true},
+ {{"gfx906"}, {"gfx906"}, GK_GFX906, true, true, true, true, true},
+ };
+
+ static GPUInfo parseR600Name(StringRef Name);
+
+ static GPUInfo parseAMDGCNName(StringRef Name);
+
+ GPUInfo parseGPUName(StringRef Name) const;
+
+ GPUInfo GPU;
static bool isAMDGCN(const llvm::Triple &TT) {
return TT.getArch() == llvm::Triple::amdgcn;
}
- static bool isGenericZero(const llvm::Triple &TT) {
- return TT.getEnvironmentName() == "amdgiz" ||
- TT.getEnvironmentName() == "amdgizcl";
- }
-
public:
AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
@@ -90,12 +187,10 @@ public:
void adjust(LangOptions &Opts) override;
uint64_t getPointerWidthV(unsigned AddrSpace) const override {
- if (GPU <= GK_CAYMAN)
+ if (GPU.Kind <= GK_R600_LAST)
return 32;
-
- if (AddrSpace == AS.Private || AddrSpace == AS.Local) {
+ if (AddrSpace == Private || AddrSpace == Local)
return 32;
- }
return 64;
}
@@ -194,6 +289,19 @@ public:
return true;
}
+ // \p Constraint will be left pointing at the last character of
+ // the constraint. In practice, it won't be changed unless the
+ // constraint is longer than one character.
+ std::string convertConstraint(const char *&Constraint) const override {
+ const char *Begin = Constraint;
+ TargetInfo::ConstraintInfo Info("", "");
+ if (validateAsmConstraint(Constraint, Info))
+ return std::string(Begin).substr(0, Constraint - Begin + 1);
+
+ Constraint = Begin;
+ return std::string(1, *Constraint);
+ }
+
bool
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
StringRef CPU,
@@ -211,24 +319,22 @@ public:
return TargetInfo::CharPtrBuiltinVaList;
}
- static GPUKind parseR600Name(StringRef Name);
-
- static GPUKind parseAMDGCNName(StringRef Name);
-
bool isValidCPUName(StringRef Name) const override {
if (getTriple().getArch() == llvm::Triple::amdgcn)
- return GK_NONE != parseAMDGCNName(Name);
+ return GK_NONE != parseAMDGCNName(Name).Kind;
else
- return GK_NONE != parseR600Name(Name);
+ return GK_NONE != parseR600Name(Name).Kind;
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
if (getTriple().getArch() == llvm::Triple::amdgcn)
GPU = parseAMDGCNName(Name);
else
GPU = parseR600Name(Name);
- return GPU != GK_NONE;
+ return GK_NONE != GPU.Kind;
}
void setSupportedOpenCLOpts() override {
@@ -236,16 +342,16 @@ public:
Opts.support("cl_clang_storage_class_specifiers");
Opts.support("cl_khr_icd");
- if (hasFP64)
+ if (GPU.HasFP64)
Opts.support("cl_khr_fp64");
- if (GPU >= GK_EVERGREEN) {
+ if (GPU.Kind >= GK_CEDAR) {
Opts.support("cl_khr_byte_addressable_store");
Opts.support("cl_khr_global_int32_base_atomics");
Opts.support("cl_khr_global_int32_extended_atomics");
Opts.support("cl_khr_local_int32_base_atomics");
Opts.support("cl_khr_local_int32_extended_atomics");
}
- if (GPU >= GK_GFX6) {
+ if (GPU.Kind >= GK_AMDGCN_FIRST) {
Opts.support("cl_khr_fp16");
Opts.support("cl_khr_int64_base_atomics");
Opts.support("cl_khr_int64_extended_atomics");
@@ -273,11 +379,13 @@ public:
}
llvm::Optional<LangAS> getConstantAddressSpace() const override {
- return getLangASFromTargetAS(AS.Constant);
+ return getLangASFromTargetAS(Constant);
}
/// \returns Target specific vtbl ptr address space.
- unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
+ unsigned getVtblPtrAddressSpace() const override {
+ return static_cast<unsigned>(Constant);
+ }
/// \returns If a target requires an address within a target specific address
/// space \p AddressSpace to be converted in order to be used, then return the
@@ -289,9 +397,9 @@ public:
getDWARFAddressSpace(unsigned AddressSpace) const override {
const unsigned DWARF_Private = 1;
const unsigned DWARF_Local = 2;
- if (AddressSpace == AS.Private) {
+ if (AddressSpace == Private) {
return DWARF_Private;
- } else if (AddressSpace == AS.Local) {
+ } else if (AddressSpace == Local) {
return DWARF_Local;
} else {
return None;
diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp
index 6fb0ab41ff5bf..efed9b096d563 100644
--- a/lib/Basic/Targets/ARM.cpp
+++ b/lib/Basic/Targets/ARM.cpp
@@ -334,9 +334,20 @@ bool ARMTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
+ std::string ArchFeature;
std::vector<StringRef> TargetFeatures;
llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
+ // Map the base architecture to an appropriate target feature, so we don't
+ // rely on the target triple.
+ llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ CPUArch = Arch;
+ if (CPUArch != llvm::ARM::ArchKind::INVALID) {
+ ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
+ TargetFeatures.push_back(ArchFeature);
+ }
+
// get default FPU features
unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
@@ -379,6 +390,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
Unaligned = 1;
SoftFloat = SoftFloatABI = false;
HWDiv = 0;
+ DotProd = 0;
// This does not diagnose illegal cases like having both
// "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
@@ -419,6 +431,10 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
Unaligned = 0;
} else if (Feature == "+fp16") {
HW_FP |= HW_FP_HP;
+ } else if (Feature == "+fullfp16") {
+ HasLegalHalfType = true;
+ } else if (Feature == "+dotprod") {
+ DotProd = true;
}
}
HW_FP &= ~HW_FP_remove;
@@ -478,6 +494,10 @@ bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
}
+void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
+ llvm::ARM::fillValidCPUArchList(Values);
+}
+
bool ARMTargetInfo::setCPU(const std::string &Name) {
if (Name != "generic")
setArchInfo(llvm::ARM::parseCPUArch(Name));
@@ -706,6 +726,18 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.UnsafeFPMath)
Builder.defineMacro("__ARM_FP_FAST", "1");
+ // Armv8.2-A FP16 vector intrinsic
+ if ((FPU & NeonFPU) && HasLegalHalfType)
+ Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
+
+ // Armv8.2-A FP16 scalar intrinsics
+ if (HasLegalHalfType)
+ Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
+
+ // Armv8.2-A dot product intrinsics
+ if (DotProd)
+ Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
+
switch (ArchKind) {
default:
break;
@@ -956,6 +988,8 @@ WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
return CCCR_Ignore;
case CC_C:
case CC_OpenCLKernel:
+ case CC_PreserveMost:
+ case CC_PreserveAll:
return CCCR_OK;
default:
return CCCR_Warning;
diff --git a/lib/Basic/Targets/ARM.h b/lib/Basic/Targets/ARM.h
index fb0e7e66bea38..9c72c3387f7a9 100644
--- a/lib/Basic/Targets/ARM.h
+++ b/lib/Basic/Targets/ARM.h
@@ -69,6 +69,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
unsigned Crypto : 1;
unsigned DSP : 1;
unsigned Unaligned : 1;
+ unsigned DotProd : 1;
enum {
LDREX_B = (1 << 0), /// byte (8-bit)
@@ -122,6 +123,8 @@ public:
bool hasFeature(StringRef Feature) const override;
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override;
bool setFPMath(StringRef Name) override;
@@ -153,6 +156,11 @@ public:
std::string &SuggestedModifier) const override;
const char *getClobbers() const override;
+ StringRef getConstraintRegister(StringRef Constraint,
+ StringRef Expression) const override {
+ return Expression;
+ }
+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
int getEHDataRegisterNumber(unsigned RegNo) const override;
diff --git a/lib/Basic/Targets/AVR.cpp b/lib/Basic/Targets/AVR.cpp
index 3022fe33d76cc..9b66449cbca63 100644
--- a/lib/Basic/Targets/AVR.cpp
+++ b/lib/Basic/Targets/AVR.cpp
@@ -28,7 +28,7 @@ struct LLVM_LIBRARY_VISIBILITY MCUInfo {
};
// This list should be kept up-to-date with AVRDevices.td in LLVM.
-static ArrayRef<MCUInfo> AVRMcus = {
+static MCUInfo AVRMcus[] = {
{"at90s1200", "__AVR_AT90S1200__"},
{"attiny11", "__AVR_ATtiny11__"},
{"attiny12", "__AVR_ATtiny12__"},
@@ -273,35 +273,29 @@ static ArrayRef<MCUInfo> AVRMcus = {
} // namespace targets
} // namespace clang
+static constexpr llvm::StringLiteral ValidFamilyNames[] = {
+ "avr1", "avr2", "avr25", "avr3", "avr31",
+ "avr35", "avr4", "avr5", "avr51", "avr6",
+ "avrxmega1", "avrxmega2", "avrxmega3", "avrxmega4", "avrxmega5",
+ "avrxmega6", "avrxmega7", "avrtiny"};
+
bool AVRTargetInfo::isValidCPUName(StringRef Name) const {
- bool IsFamily = llvm::StringSwitch<bool>(Name)
- .Case("avr1", true)
- .Case("avr2", true)
- .Case("avr25", true)
- .Case("avr3", true)
- .Case("avr31", true)
- .Case("avr35", true)
- .Case("avr4", true)
- .Case("avr5", true)
- .Case("avr51", true)
- .Case("avr6", true)
- .Case("avrxmega1", true)
- .Case("avrxmega2", true)
- .Case("avrxmega3", true)
- .Case("avrxmega4", true)
- .Case("avrxmega5", true)
- .Case("avrxmega6", true)
- .Case("avrxmega7", true)
- .Case("avrtiny", true)
- .Default(false);
+ bool IsFamily =
+ llvm::find(ValidFamilyNames, Name) != std::end(ValidFamilyNames);
bool IsMCU =
- std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) {
+ llvm::find_if(AVRMcus, [&](const MCUInfo &Info) {
return Info.Name == Name;
- }) != AVRMcus.end();
+ }) != std::end(AVRMcus);
return IsFamily || IsMCU;
}
+void AVRTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
+ Values.append(std::begin(ValidFamilyNames), std::end(ValidFamilyNames));
+ for (const MCUInfo &Info : AVRMcus)
+ Values.push_back(Info.Name);
+}
+
void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("AVR");
@@ -309,12 +303,10 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVR__");
if (!this->CPU.empty()) {
- auto It =
- std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) {
- return Info.Name == this->CPU;
- });
+ auto It = llvm::find_if(
+ AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; });
- if (It != AVRMcus.end())
+ if (It != std::end(AVRMcus))
Builder.defineMacro(It->DefineName);
}
}
diff --git a/lib/Basic/Targets/AVR.h b/lib/Basic/Targets/AVR.h
index 3dfb84f756684..d595f48e8ef7c 100644
--- a/lib/Basic/Targets/AVR.h
+++ b/lib/Basic/Targets/AVR.h
@@ -55,7 +55,7 @@ public:
WIntType = SignedInt;
Char32Type = UnsignedLong;
SigAtomicType = SignedChar;
- resetDataLayout("e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
+ resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
}
void getTargetDefines(const LangOptions &Opts,
@@ -167,6 +167,7 @@ public:
}
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override {
bool isValid = isValidCPUName(Name);
if (isValid)
diff --git a/lib/Basic/Targets/BPF.cpp b/lib/Basic/Targets/BPF.cpp
index 54e34f15532da..cf41a09d76f5f 100644
--- a/lib/Basic/Targets/BPF.cpp
+++ b/lib/Basic/Targets/BPF.cpp
@@ -14,6 +14,7 @@
#include "BPF.h"
#include "Targets.h"
#include "clang/Basic/MacroBuilder.h"
+#include "llvm/ADT/StringRef.h"
using namespace clang;
using namespace clang::targets;
@@ -23,3 +24,14 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
DefineStd(Builder, "bpf", Opts);
Builder.defineMacro("__BPF__");
}
+
+static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",
+ "probe"};
+
+bool BPFTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+}
+
+void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
+ Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
+}
diff --git a/lib/Basic/Targets/BPF.h b/lib/Basic/Targets/BPF.h
index 4dd9cbd9d2219..7f97f81891459 100644
--- a/lib/Basic/Targets/BPF.h
+++ b/lib/Basic/Targets/BPF.h
@@ -46,7 +46,14 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
- bool hasFeature(StringRef Feature) const override { return Feature == "bpf"; }
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "bpf" || Feature == "alu32" || Feature == "dwarfris";
+ }
+
+ void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
+ bool Enabled) const override {
+ Features[Name] = Enabled;
+ }
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
@@ -56,6 +63,7 @@ public:
return TargetInfo::VoidPtrBuiltinVaList;
}
+ bool isValidGCCRegisterName(StringRef Name) const override { return true; }
ArrayRef<const char *> getGCCRegNames() const override { return None; }
bool validateAsmConstraint(const char *&Name,
@@ -77,12 +85,9 @@ public:
}
}
- bool isValidCPUName(StringRef Name) const override {
- if (Name == "generic" || Name == "v1" ||
- Name == "v2" || Name == "probe")
- return true;
- return false;
- }
+ bool isValidCPUName(StringRef Name) const override;
+
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override {
StringRef CPUName(Name);
diff --git a/lib/Basic/Targets/Hexagon.cpp b/lib/Basic/Targets/Hexagon.cpp
index 71d4c1e0f1611..0ef1f6db281ea 100644
--- a/lib/Basic/Targets/Hexagon.cpp
+++ b/lib/Basic/Targets/Hexagon.cpp
@@ -75,7 +75,6 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
bool HexagonTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
- Features["hvx-double"] = false;
Features["long-calls"] = false;
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
@@ -132,6 +131,10 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
};
bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
+ std::string VS = "hvxv" + HVXVersion;
+ if (Feature == VS)
+ return true;
+
return llvm::StringSwitch<bool>(Feature)
.Case("hexagon", true)
.Case("hvx", HasHVX)
@@ -141,15 +144,29 @@ bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
.Default(false);
}
+struct CPUSuffix {
+ llvm::StringLiteral Name;
+ llvm::StringLiteral Suffix;
+};
+
+static constexpr CPUSuffix Suffixes[] = {
+ {{"hexagonv4"}, {"4"}}, {{"hexagonv5"}, {"5"}},
+ {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}},
+ {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}},
+};
+
const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
- return llvm::StringSwitch<const char *>(Name)
- .Case("hexagonv4", "4")
- .Case("hexagonv5", "5")
- .Case("hexagonv55", "55")
- .Case("hexagonv60", "60")
- .Case("hexagonv62", "62")
- .Case("hexagonv65", "65")
- .Default(nullptr);
+ const CPUSuffix *Item = llvm::find_if(
+ Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
+ if (Item == std::end(Suffixes))
+ return nullptr;
+ return Item->Suffix.data();
+}
+
+void HexagonTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ for (const CPUSuffix &Suffix : Suffixes)
+ Values.push_back(Suffix.Name);
}
ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
diff --git a/lib/Basic/Targets/Hexagon.h b/lib/Basic/Targets/Hexagon.h
index 7b0966457c4bf..fb4956a9e53d8 100644
--- a/lib/Basic/Targets/Hexagon.h
+++ b/lib/Basic/Targets/Hexagon.h
@@ -112,6 +112,8 @@ public:
return getHexagonCPUSuffix(Name);
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
if (!isValidCPUName(Name))
return false;
diff --git a/lib/Basic/Targets/Lanai.cpp b/lib/Basic/Targets/Lanai.cpp
index 1d8314af99fbe..0e8030c04e5c8 100644
--- a/lib/Basic/Targets/Lanai.cpp
+++ b/lib/Basic/Targets/Lanai.cpp
@@ -40,6 +40,10 @@ ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const {
bool LanaiTargetInfo::isValidCPUName(StringRef Name) const {
return llvm::StringSwitch<bool>(Name).Case("v11", true).Default(false);
}
+void LanaiTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ Values.emplace_back("v11");
+}
bool LanaiTargetInfo::setCPU(const std::string &Name) {
CPU = llvm::StringSwitch<CPUKind>(Name).Case("v11", CK_V11).Default(CK_NONE);
diff --git a/lib/Basic/Targets/Lanai.h b/lib/Basic/Targets/Lanai.h
index 5f99c17a53447..b9e6dbe04433f 100644
--- a/lib/Basic/Targets/Lanai.h
+++ b/lib/Basic/Targets/Lanai.h
@@ -65,6 +65,8 @@ public:
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override;
bool hasFeature(StringRef Feature) const override;
diff --git a/lib/Basic/Targets/Mips.cpp b/lib/Basic/Targets/Mips.cpp
index a8a1bcc363618..cbd5a01c3da8c 100644
--- a/lib/Basic/Targets/Mips.cpp
+++ b/lib/Basic/Targets/Mips.cpp
@@ -44,26 +44,19 @@ bool MipsTargetInfo::processorSupportsGPR64() const {
return false;
}
+static constexpr llvm::StringLiteral ValidCPUNames[] = {
+ {"mips1"}, {"mips2"}, {"mips3"}, {"mips4"}, {"mips5"},
+ {"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"},
+ {"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"},
+ {"octeon"}, {"p5600"}};
+
bool MipsTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- .Case("mips1", true)
- .Case("mips2", true)
- .Case("mips3", true)
- .Case("mips4", true)
- .Case("mips5", true)
- .Case("mips32", true)
- .Case("mips32r2", true)
- .Case("mips32r3", true)
- .Case("mips32r5", true)
- .Case("mips32r6", true)
- .Case("mips64", true)
- .Case("mips64r2", true)
- .Case("mips64r3", true)
- .Case("mips64r5", true)
- .Case("mips64r6", true)
- .Case("octeon", true)
- .Case("p5600", true)
- .Default(false);
+ return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+}
+
+void MipsTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}
void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -207,9 +200,7 @@ ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
// microMIPS64R6 backend was removed.
- if ((getTriple().getArch() == llvm::Triple::mips64 ||
- getTriple().getArch() == llvm::Triple::mips64el) &&
- IsMicromips && (ABI == "n32" || ABI == "n64")) {
+ if (getTriple().isMIPS64() && IsMicromips && (ABI == "n32" || ABI == "n64")) {
Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU;
return false;
}
@@ -229,9 +220,7 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
// FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend
// can't handle this yet. It's better to fail here than on the
// backend assertion.
- if ((getTriple().getArch() == llvm::Triple::mips64 ||
- getTriple().getArch() == llvm::Triple::mips64el) &&
- ABI == "o32") {
+ if (getTriple().isMIPS64() && ABI == "o32") {
Diags.Report(diag::err_target_unsupported_abi_for_triple)
<< ABI << getTriple().str();
return false;
@@ -240,9 +229,7 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
// FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend
// can't handle this yet. It's better to fail here than on the
// backend assertion.
- if ((getTriple().getArch() == llvm::Triple::mips ||
- getTriple().getArch() == llvm::Triple::mipsel) &&
- (ABI == "n32" || ABI == "n64")) {
+ if (getTriple().isMIPS32() && (ABI == "n32" || ABI == "n64")) {
Diags.Report(diag::err_target_unsupported_abi_for_triple)
<< ABI << getTriple().str();
return false;
diff --git a/lib/Basic/Targets/Mips.h b/lib/Basic/Targets/Mips.h
index 28900f21f86ba..11e9ac914430e 100644
--- a/lib/Basic/Targets/Mips.h
+++ b/lib/Basic/Targets/Mips.h
@@ -54,6 +54,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev;
bool HasMSA;
bool DisableMadd4;
+ bool UseIndirectJumpHazard;
protected:
bool HasFP64;
@@ -64,13 +65,11 @@ public:
: TargetInfo(Triple), IsMips16(false), IsMicromips(false),
IsNan2008(false), IsAbs2008(false), IsSingleFloat(false),
IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat),
- DspRev(NoDSP), HasMSA(false), DisableMadd4(false), HasFP64(false) {
+ DspRev(NoDSP), HasMSA(false), DisableMadd4(false),
+ UseIndirectJumpHazard(false), HasFP64(false) {
TheCXXABI.set(TargetCXXABI::GenericMIPS);
- setABI((getTriple().getArch() == llvm::Triple::mips ||
- getTriple().getArch() == llvm::Triple::mipsel)
- ? "o32"
- : "n64");
+ setABI(getTriple().isMIPS32() ? "o32" : "n64");
CPU = ABI == "o32" ? "mips32r2" : "mips64r2";
@@ -161,6 +160,7 @@ public:
}
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override {
CPU = Name;
@@ -338,6 +338,8 @@ public:
IsAbs2008 = false;
else if (Feature == "+noabicalls")
IsNoABICalls = true;
+ else if (Feature == "+use-indirect-jump-hazard")
+ UseIndirectJumpHazard = true;
}
setDataLayout();
@@ -387,7 +389,9 @@ public:
return llvm::makeArrayRef(NewABIRegAliases);
}
- bool hasInt128Type() const override { return ABI == "n32" || ABI == "n64"; }
+ bool hasInt128Type() const override {
+ return (ABI == "n32" || ABI == "n64") || getTargetOpts().ForceEnableInt128;
+ }
bool validateTarget(DiagnosticsEngine &Diags) const override;
};
diff --git a/lib/Basic/Targets/NVPTX.cpp b/lib/Basic/Targets/NVPTX.cpp
index add3b318aeb6d..fd4ee16060611 100644
--- a/lib/Basic/Targets/NVPTX.cpp
+++ b/lib/Basic/Targets/NVPTX.cpp
@@ -40,6 +40,22 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
"NVPTX only supports 32- and 64-bit modes.");
+ PTXVersion = 32;
+ for (const StringRef Feature : Opts.FeaturesAsWritten) {
+ if (!Feature.startswith("+ptx"))
+ continue;
+ PTXVersion = llvm::StringSwitch<unsigned>(Feature)
+ .Case("+ptx61", 61)
+ .Case("+ptx60", 60)
+ .Case("+ptx50", 50)
+ .Case("+ptx43", 43)
+ .Case("+ptx42", 42)
+ .Case("+ptx41", 41)
+ .Case("+ptx40", 40)
+ .Case("+ptx32", 32)
+ .Default(32);
+ }
+
TLSSupported = false;
VLASupported = false;
AddrSpaceMap = &NVPTXAddrSpaceMap;
@@ -52,6 +68,9 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
if (TargetPointerWidth == 32)
resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
+ else if (Opts.NVPTXUseShortPointers)
+ resetDataLayout(
+ "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
else
resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
@@ -145,7 +164,6 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Cases("ptx", "nvptx", true)
- .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope.
.Default(false);
}
@@ -157,6 +175,21 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
// Set __CUDA_ARCH__ for the GPU specified.
std::string CUDAArchCode = [this] {
switch (GPU) {
+ case CudaArch::GFX600:
+ case CudaArch::GFX601:
+ case CudaArch::GFX700:
+ case CudaArch::GFX701:
+ case CudaArch::GFX702:
+ case CudaArch::GFX703:
+ case CudaArch::GFX704:
+ case CudaArch::GFX801:
+ case CudaArch::GFX802:
+ case CudaArch::GFX803:
+ case CudaArch::GFX810:
+ case CudaArch::GFX900:
+ case CudaArch::GFX902:
+ case CudaArch::LAST:
+ break;
case CudaArch::UNKNOWN:
assert(false && "No GPU arch when compiling CUDA device code.");
return "";
@@ -186,6 +219,8 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
return "620";
case CudaArch::SM_70:
return "700";
+ case CudaArch::SM_72:
+ return "720";
}
llvm_unreachable("unhandled CudaArch");
}();
diff --git a/lib/Basic/Targets/NVPTX.h b/lib/Basic/Targets/NVPTX.h
index a84870763f545..84d466d2f49f2 100644
--- a/lib/Basic/Targets/NVPTX.h
+++ b/lib/Basic/Targets/NVPTX.h
@@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
CudaArch GPU;
+ uint32_t PTXVersion;
std::unique_ptr<TargetInfo> HostTarget;
public:
@@ -55,7 +56,8 @@ public:
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
StringRef CPU,
const std::vector<std::string> &FeaturesVec) const override {
- Features["satom"] = GPU >= CudaArch::SM_60;
+ Features[CudaArchToString(GPU)] = true;
+ Features["ptx" + std::to_string(PTXVersion)] = true;
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -98,6 +100,12 @@ public:
return StringToCudaArch(Name) != CudaArch::UNKNOWN;
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
+ for (int i = static_cast<int>(CudaArch::SM_20);
+ i < static_cast<int>(CudaArch::LAST); ++i)
+ Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i)));
+ }
+
bool setCPU(const std::string &Name) override {
GPU = StringToCudaArch(Name);
return GPU != CudaArch::UNKNOWN;
diff --git a/lib/Basic/Targets/Nios2.h b/lib/Basic/Targets/Nios2.h
index aa02f8f6262fe..ffeb414d47789 100644
--- a/lib/Basic/Targets/Nios2.h
+++ b/lib/Basic/Targets/Nios2.h
@@ -56,6 +56,10 @@ public:
return Name == "nios2r1" || Name == "nios2r2";
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
+ Values.append({"nios2r1", "nios2r2"});
+ }
+
bool setCPU(const std::string &Name) override {
if (isValidCPUName(Name)) {
CPU = Name;
diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h
index 5af63615dc5ec..d0354784acf9b 100644
--- a/lib/Basic/Targets/OSTargets.h
+++ b/lib/Basic/Targets/OSTargets.h
@@ -95,16 +95,22 @@ public:
if (Triple.isMacOSX())
this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
else if (Triple.isiOS()) {
- // 64-bit iOS supported it from 8 onwards, 32-bit from 9 onwards.
- if (Triple.getArch() == llvm::Triple::x86_64 ||
- Triple.getArch() == llvm::Triple::aarch64)
+ // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
+ // 32-bit simulator from 10 onwards.
+ if (Triple.isArch64Bit())
this->TLSSupported = !Triple.isOSVersionLT(8);
- else if (Triple.getArch() == llvm::Triple::x86 ||
- Triple.getArch() == llvm::Triple::arm ||
- Triple.getArch() == llvm::Triple::thumb)
- this->TLSSupported = !Triple.isOSVersionLT(9);
- } else if (Triple.isWatchOS())
- this->TLSSupported = !Triple.isOSVersionLT(2);
+ else if (Triple.isArch32Bit()) {
+ if (!Triple.isSimulatorEnvironment())
+ this->TLSSupported = !Triple.isOSVersionLT(9);
+ else
+ this->TLSSupported = !Triple.isOSVersionLT(10);
+ }
+ } else if (Triple.isWatchOS()) {
+ if (!Triple.isSimulatorEnvironment())
+ this->TLSSupported = !Triple.isOSVersionLT(2);
+ else
+ this->TLSSupported = !Triple.isOSVersionLT(3);
+ }
this->MCountName = "\01mcount";
}
@@ -363,7 +369,7 @@ protected:
public:
NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
- this->MCountName = "_mcount";
+ this->MCountName = "__mcount";
}
};
@@ -479,6 +485,7 @@ public:
default:
case llvm::Triple::x86_64:
this->MCountName = ".mcount";
+ this->NewAlign = 256;
break;
}
}
@@ -544,13 +551,24 @@ protected:
Builder.defineMacro("_LARGEFILE_SOURCE");
Builder.defineMacro("_LARGEFILE64_SOURCE");
Builder.defineMacro("__EXTENSIONS__");
- Builder.defineMacro("_REENTRANT");
+ if (Opts.POSIXThreads)
+ Builder.defineMacro("_REENTRANT");
+ if (this->HasFloat128)
+ Builder.defineMacro("__FLOAT128__");
}
public:
SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
// FIXME: WIntType should be SignedLong
+ switch (Triple.getArch()) {
+ default:
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->HasFloat128 = true;
+ break;
+ }
}
};
@@ -599,8 +617,10 @@ protected:
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
- if (Opts.CPlusPlus17)
- Builder.defineMacro("_MSVC_LANG", "201403L");
+ if (Opts.CPlusPlus2a)
+ Builder.defineMacro("_MSVC_LANG", "201704L");
+ else if (Opts.CPlusPlus17)
+ Builder.defineMacro("_MSVC_LANG", "201703L");
else if (Opts.CPlusPlus14)
Builder.defineMacro("_MSVC_LANG", "201402L");
}
diff --git a/lib/Basic/Targets/PPC.cpp b/lib/Basic/Targets/PPC.cpp
index a44aa0cd96f06..b4eb3b1b97b78 100644
--- a/lib/Basic/Targets/PPC.cpp
+++ b/lib/Basic/Targets/PPC.cpp
@@ -15,7 +15,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
-#include "llvm/ADT/StringSwitch.h"
using namespace clang;
using namespace clang::targets;
@@ -96,7 +95,7 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("_CALL_ELF", "2");
// This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but
- // our suppport post-dates this and it should work on all 64-bit ppc linux
+ // our support post-dates this and it should work on all 64-bit ppc linux
// platforms. It is guaranteed to work on all elfv2 platforms.
if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64)
Builder.defineMacro("_CALL_LINUX", "1");
@@ -116,111 +115,37 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
(getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
- // CPU identification.
- ArchDefineTypes defs =
- (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
- .Case("440", ArchDefineName)
- .Case("450", ArchDefineName | ArchDefine440)
- .Case("601", ArchDefineName)
- .Case("602", ArchDefineName | ArchDefinePpcgr)
- .Case("603", ArchDefineName | ArchDefinePpcgr)
- .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
- .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
- .Case("604", ArchDefineName | ArchDefinePpcgr)
- .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
- .Case("620", ArchDefineName | ArchDefinePpcgr)
- .Case("630", ArchDefineName | ArchDefinePpcgr)
- .Case("7400", ArchDefineName | ArchDefinePpcgr)
- .Case("7450", ArchDefineName | ArchDefinePpcgr)
- .Case("750", ArchDefineName | ArchDefinePpcgr)
- .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("a2", ArchDefineA2)
- .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
- .Case("pwr3", ArchDefinePpcgr)
- .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 |
- ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x |
- ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 |
- ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("power3", ArchDefinePpcgr)
- .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 |
- ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
- ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Case("power9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 |
- ArchDefinePwr6x | ArchDefinePwr6 |
- ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
- // powerpc64le automatically defaults to at least power8.
- .Case("ppc64le", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
- ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
- .Default(ArchDefineNone);
-
- if (defs & ArchDefineName)
+ if (ArchDefs & ArchDefineName)
Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
- if (defs & ArchDefinePpcgr)
+ if (ArchDefs & ArchDefinePpcgr)
Builder.defineMacro("_ARCH_PPCGR");
- if (defs & ArchDefinePpcsq)
+ if (ArchDefs & ArchDefinePpcsq)
Builder.defineMacro("_ARCH_PPCSQ");
- if (defs & ArchDefine440)
+ if (ArchDefs & ArchDefine440)
Builder.defineMacro("_ARCH_440");
- if (defs & ArchDefine603)
+ if (ArchDefs & ArchDefine603)
Builder.defineMacro("_ARCH_603");
- if (defs & ArchDefine604)
+ if (ArchDefs & ArchDefine604)
Builder.defineMacro("_ARCH_604");
- if (defs & ArchDefinePwr4)
+ if (ArchDefs & ArchDefinePwr4)
Builder.defineMacro("_ARCH_PWR4");
- if (defs & ArchDefinePwr5)
+ if (ArchDefs & ArchDefinePwr5)
Builder.defineMacro("_ARCH_PWR5");
- if (defs & ArchDefinePwr5x)
+ if (ArchDefs & ArchDefinePwr5x)
Builder.defineMacro("_ARCH_PWR5X");
- if (defs & ArchDefinePwr6)
+ if (ArchDefs & ArchDefinePwr6)
Builder.defineMacro("_ARCH_PWR6");
- if (defs & ArchDefinePwr6x)
+ if (ArchDefs & ArchDefinePwr6x)
Builder.defineMacro("_ARCH_PWR6X");
- if (defs & ArchDefinePwr7)
+ if (ArchDefs & ArchDefinePwr7)
Builder.defineMacro("_ARCH_PWR7");
- if (defs & ArchDefinePwr8)
+ if (ArchDefs & ArchDefinePwr8)
Builder.defineMacro("_ARCH_PWR8");
- if (defs & ArchDefinePwr9)
+ if (ArchDefs & ArchDefinePwr9)
Builder.defineMacro("_ARCH_PWR9");
- if (defs & ArchDefineA2)
+ if (ArchDefs & ArchDefineA2)
Builder.defineMacro("_ARCH_A2");
- if (defs & ArchDefineA2q) {
+ if (ArchDefs & ArchDefineA2q) {
Builder.defineMacro("_ARCH_A2Q");
Builder.defineMacro("_ARCH_QP");
}
@@ -384,6 +309,14 @@ bool PPCTargetInfo::initFeatureMap(
if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
return false;
+ if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
+ std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
+ FeaturesVec.end()) {
+ // We have __float128 on PPC but not power 9 and above.
+ Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
+ return false;
+ }
+
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -479,57 +412,25 @@ ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
return llvm::makeArrayRef(GCCRegAliases);
}
+static constexpr llvm::StringLiteral ValidCPUNames[] = {
+ {"generic"}, {"440"}, {"450"}, {"601"}, {"602"},
+ {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},
+ {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},
+ {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"},
+ {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"},
+ {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"},
+ {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"},
+ {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"},
+ {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"},
+ {"ppc64"}, {"powerpc64le"}, {"ppc64le"},
+};
+
bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- .Case("generic", true)
- .Case("440", true)
- .Case("450", true)
- .Case("601", true)
- .Case("602", true)
- .Case("603", true)
- .Case("603e", true)
- .Case("603ev", true)
- .Case("604", true)
- .Case("604e", true)
- .Case("620", true)
- .Case("630", true)
- .Case("g3", true)
- .Case("7400", true)
- .Case("g4", true)
- .Case("7450", true)
- .Case("g4+", true)
- .Case("750", true)
- .Case("970", true)
- .Case("g5", true)
- .Case("a2", true)
- .Case("a2q", true)
- .Case("e500mc", true)
- .Case("e5500", true)
- .Case("power3", true)
- .Case("pwr3", true)
- .Case("power4", true)
- .Case("pwr4", true)
- .Case("power5", true)
- .Case("pwr5", true)
- .Case("power5x", true)
- .Case("pwr5x", true)
- .Case("power6", true)
- .Case("pwr6", true)
- .Case("power6x", true)
- .Case("pwr6x", true)
- .Case("power7", true)
- .Case("pwr7", true)
- .Case("power8", true)
- .Case("pwr8", true)
- .Case("power9", true)
- .Case("pwr9", true)
- .Case("powerpc", true)
- .Case("ppc", true)
- .Case("powerpc64", true)
- .Case("ppc64", true)
- .Case("powerpc64le", true)
- .Case("ppc64le", true)
- .Default(false);
+ return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+}
+
+void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
+ Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}
void PPCTargetInfo::adjust(LangOptions &Opts) {
diff --git a/lib/Basic/Targets/PPC.h b/lib/Basic/Targets/PPC.h
index 04bef258e3865..439c73a0e3264 100644
--- a/lib/Basic/Targets/PPC.h
+++ b/lib/Basic/Targets/PPC.h
@@ -18,6 +18,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -25,39 +26,8 @@ namespace targets {
// PPC abstract base class
class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
- static const char *const GCCRegNames[];
- static const TargetInfo::GCCRegAlias GCCRegAliases[];
- std::string CPU;
-
- // Target cpu features.
- bool HasAltivec;
- bool HasVSX;
- bool HasP8Vector;
- bool HasP8Crypto;
- bool HasDirectMove;
- bool HasQPX;
- bool HasHTM;
- bool HasBPERMD;
- bool HasExtDiv;
- bool HasP9Vector;
-
-protected:
- std::string ABI;
-
-public:
- PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
- : TargetInfo(Triple), HasAltivec(false), HasVSX(false),
- HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false),
- HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false),
- HasP9Vector(false) {
- SuitableAlign = 128;
- SimdDefaultAlign = 128;
- LongDoubleWidth = LongDoubleAlign = 128;
- LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
- }
- /// \brief Flags for architecture specific defines.
+ /// Flags for architecture specific defines.
typedef enum {
ArchDefineNone = 0,
ArchDefineName = 1 << 0, // <name> is substituted for arch name.
@@ -78,6 +48,37 @@ public:
ArchDefineA2q = 1 << 15
} ArchDefineTypes;
+
+ ArchDefineTypes ArchDefs = ArchDefineNone;
+ static const Builtin::Info BuiltinInfo[];
+ static const char *const GCCRegNames[];
+ static const TargetInfo::GCCRegAlias GCCRegAliases[];
+ std::string CPU;
+
+ // Target cpu features.
+ bool HasAltivec = false;
+ bool HasVSX = false;
+ bool HasP8Vector = false;
+ bool HasP8Crypto = false;
+ bool HasDirectMove = false;
+ bool HasQPX = false;
+ bool HasHTM = false;
+ bool HasBPERMD = false;
+ bool HasExtDiv = false;
+ bool HasP9Vector = false;
+
+protected:
+ std::string ABI;
+
+public:
+ PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple) {
+ SuitableAlign = 128;
+ SimdDefaultAlign = 128;
+ LongDoubleWidth = LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
+ }
+
// Set the language option for altivec based on our value.
void adjust(LangOptions &Opts) override;
@@ -86,11 +87,66 @@ public:
// 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
// titan, rs64.
bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override {
bool CPUKnown = isValidCPUName(Name);
- if (CPUKnown)
+ if (CPUKnown) {
CPU = Name;
+
+ // CPU identification.
+ ArchDefs =
+ (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
+ .Case("440", ArchDefineName)
+ .Case("450", ArchDefineName | ArchDefine440)
+ .Case("601", ArchDefineName)
+ .Case("602", ArchDefineName | ArchDefinePpcgr)
+ .Case("603", ArchDefineName | ArchDefinePpcgr)
+ .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
+ .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
+ .Case("604", ArchDefineName | ArchDefinePpcgr)
+ .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
+ .Case("620", ArchDefineName | ArchDefinePpcgr)
+ .Case("630", ArchDefineName | ArchDefinePpcgr)
+ .Case("7400", ArchDefineName | ArchDefinePpcgr)
+ .Case("7450", ArchDefineName | ArchDefinePpcgr)
+ .Case("750", ArchDefineName | ArchDefinePpcgr)
+ .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
+ .Case("a2", ArchDefineA2)
+ .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
+ .Cases("power3", "pwr3", ArchDefinePpcgr)
+ .Cases("power4", "pwr4",
+ ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
+ .Cases("power5", "pwr5",
+ ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
+ .Cases("power5x", "pwr5x",
+ ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
+ ArchDefinePpcgr | ArchDefinePpcsq)
+ .Cases("power6", "pwr6",
+ ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
+ ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
+ .Cases("power6x", "pwr6x",
+ ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
+ ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
+ .Cases("power7", "pwr7",
+ ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 |
+ ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
+ ArchDefinePpcgr | ArchDefinePpcsq)
+ // powerpc64le automatically defaults to at least power8.
+ .Cases("power8", "pwr8", "ppc64le",
+ ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
+ ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
+ ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
+ .Cases("power9", "pwr9",
+ ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 |
+ ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
+ ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
+ .Default(ArchDefineNone);
+ }
return CPUKnown;
}
@@ -310,10 +366,6 @@ public:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
break;
- case llvm::Triple::NetBSD:
- IntMaxType = SignedLongLong;
- Int64Type = SignedLongLong;
- break;
default:
break;
}
@@ -334,6 +386,15 @@ public:
}
return false;
}
+
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+ switch (CC) {
+ case CC_Swift:
+ return CCCR_OK;
+ default:
+ return CCCR_Warning;
+ }
+ }
};
class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo
diff --git a/lib/Basic/Targets/RISCV.cpp b/lib/Basic/Targets/RISCV.cpp
new file mode 100644
index 0000000000000..7eb5e6a686a9a
--- /dev/null
+++ b/lib/Basic/Targets/RISCV.cpp
@@ -0,0 +1,104 @@
+//===--- RISCV.cpp - Implement RISCV target feature support ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements RISCV TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
+ static const char *const GCCRegNames[] = {
+ "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
+ "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"};
+ return llvm::makeArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"},
+ {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"},
+ {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"},
+ {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x15"}, {{"a5"}, "x15"},
+ {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"},
+ {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"},
+ {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"},
+ {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"}};
+ return llvm::makeArrayRef(GCCRegAliases);
+}
+
+void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__ELF__");
+ Builder.defineMacro("__riscv");
+ bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
+ Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
+ // TODO: modify when more code models and ABIs are supported.
+ Builder.defineMacro("__riscv_cmodel_medlow");
+ Builder.defineMacro("__riscv_float_abi_soft");
+
+ if (HasM) {
+ Builder.defineMacro("__riscv_mul");
+ Builder.defineMacro("__riscv_div");
+ Builder.defineMacro("__riscv_muldiv");
+ }
+
+ if (HasA)
+ Builder.defineMacro("__riscv_atomic");
+
+ if (HasF || HasD) {
+ Builder.defineMacro("__riscv_flen", HasD ? "64" : "32");
+ Builder.defineMacro("__riscv_fdiv");
+ Builder.defineMacro("__riscv_fsqrt");
+ }
+
+ if (HasC)
+ Builder.defineMacro("__riscv_compressed");
+}
+
+/// Return true if has this feature, need to sync with handleTargetFeatures.
+bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
+ bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("riscv", true)
+ .Case("riscv32", !Is64Bit)
+ .Case("riscv64", Is64Bit)
+ .Case("m", HasM)
+ .Case("a", HasA)
+ .Case("f", HasF)
+ .Case("d", HasD)
+ .Case("c", HasC)
+ .Default(false);
+}
+
+/// Perform initialization based on the user configured set of features.
+bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ for (const auto &Feature : Features) {
+ if (Feature == "+m")
+ HasM = true;
+ else if (Feature == "+a")
+ HasA = true;
+ else if (Feature == "+f")
+ HasF = true;
+ else if (Feature == "+d")
+ HasD = true;
+ else if (Feature == "+c")
+ HasC = true;
+ }
+
+ return true;
+}
diff --git a/lib/Basic/Targets/RISCV.h b/lib/Basic/Targets/RISCV.h
new file mode 100644
index 0000000000000..f83aae5393919
--- /dev/null
+++ b/lib/Basic/Targets/RISCV.h
@@ -0,0 +1,114 @@
+//===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares RISCV TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace targets {
+
+// RISC-V Target
+class RISCVTargetInfo : public TargetInfo {
+protected:
+ std::string ABI;
+ bool HasM;
+ bool HasA;
+ bool HasF;
+ bool HasD;
+ bool HasC;
+
+public:
+ RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple), HasM(false), HasA(false), HasF(false),
+ HasD(false), HasC(false) {
+ TLSSupported = false;
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ SuitableAlign = 128;
+ WCharType = SignedInt;
+ WIntType = UnsignedInt;
+ }
+
+ StringRef getABI() const override { return ABI; }
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::VoidPtrBuiltinVaList;
+ }
+
+ const char *getClobbers() const override { return ""; }
+
+ ArrayRef<const char *> getGCCRegNames() const override;
+
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override {
+ return false;
+ }
+
+ bool hasFeature(StringRef Feature) const override;
+
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override;
+};
+class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
+public:
+ RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : RISCVTargetInfo(Triple, Opts) {
+ IntPtrType = SignedInt;
+ PtrDiffType = SignedInt;
+ SizeType = UnsignedInt;
+ resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
+ }
+
+ bool setABI(const std::string &Name) override {
+ // TODO: support ilp32f and ilp32d ABIs.
+ if (Name == "ilp32") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
+};
+class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
+public:
+ RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : RISCVTargetInfo(Triple, Opts) {
+ LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ IntMaxType = Int64Type = SignedLong;
+ resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
+ }
+
+ bool setABI(const std::string &Name) override {
+ // TODO: support lp64f and lp64d ABIs.
+ if (Name == "lp64") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
+};
+} // namespace targets
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
diff --git a/lib/Basic/Targets/SPIR.h b/lib/Basic/Targets/SPIR.h
index c384d4260ca9e..9815292fc276d 100644
--- a/lib/Basic/Targets/SPIR.h
+++ b/lib/Basic/Targets/SPIR.h
@@ -47,6 +47,7 @@ public:
LongWidth = LongAlign = 64;
AddrSpaceMap = &SPIRAddrSpaceMap;
UseAddrSpaceMapMangling = true;
+ HasLegalHalfType = true;
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
@@ -59,6 +60,10 @@ public:
return Feature == "spir";
}
+ // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
+ // memcpy as per section 3 of the SPIR spec.
+ bool useFP16ConversionIntrinsics() const override { return false; }
+
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
const char *getClobbers() const override { return ""; }
diff --git a/lib/Basic/Targets/Sparc.cpp b/lib/Basic/Targets/Sparc.cpp
index 429c1ee3a23c5..ee4f309363af4 100644
--- a/lib/Basic/Targets/Sparc.cpp
+++ b/lib/Basic/Targets/Sparc.cpp
@@ -20,9 +20,17 @@ using namespace clang;
using namespace clang::targets;
const char *const SparcTargetInfo::GCCRegNames[] = {
+ // Integer registers
"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"
+ "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ // Floating-point registers
+ "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", "f32",
+ "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
+ "f56", "f58", "f60", "f62",
};
ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
@@ -51,49 +59,81 @@ bool SparcTargetInfo::hasFeature(StringRef Feature) const {
.Default(false);
}
+struct SparcCPUInfo {
+ llvm::StringLiteral Name;
+ SparcTargetInfo::CPUKind Kind;
+ SparcTargetInfo::CPUGeneration Generation;
+};
+
+static constexpr SparcCPUInfo CPUInfo[] = {
+ {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
+ {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
+ {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
+ {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
+ {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
+ {{"sparclite86x"},
+ SparcTargetInfo::CK_SPARCLITE86X,
+ SparcTargetInfo::CG_V8},
+ {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
+ {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
+ {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
+ {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
+ {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
+ {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
+ {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
+ {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
+ {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
+ {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
+ {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
+ {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
+ {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
+ {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
+ {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
+ {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
+ {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
+ {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
+ {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
+ {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
+ // FIXME: the myriad2[.n] spellings are obsolete,
+ // but a grace period is needed to allow updating dependent builds.
+ {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
+ {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
+ {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
+ {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
+ {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
+ {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
+ {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
+ {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
+ {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
+ {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
+ {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
+ {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
+};
+
+SparcTargetInfo::CPUGeneration
+SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
+ if (Kind == CK_GENERIC)
+ return CG_V8;
+ const SparcCPUInfo *Item = llvm::find_if(
+ CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
+ if (Item == std::end(CPUInfo))
+ llvm_unreachable("Unexpected CPU kind");
+ return Item->Generation;
+}
+
SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
- return llvm::StringSwitch<CPUKind>(Name)
- .Case("v8", CK_V8)
- .Case("supersparc", CK_SUPERSPARC)
- .Case("sparclite", CK_SPARCLITE)
- .Case("f934", CK_F934)
- .Case("hypersparc", CK_HYPERSPARC)
- .Case("sparclite86x", CK_SPARCLITE86X)
- .Case("sparclet", CK_SPARCLET)
- .Case("tsc701", CK_TSC701)
- .Case("v9", CK_V9)
- .Case("ultrasparc", CK_ULTRASPARC)
- .Case("ultrasparc3", CK_ULTRASPARC3)
- .Case("niagara", CK_NIAGARA)
- .Case("niagara2", CK_NIAGARA2)
- .Case("niagara3", CK_NIAGARA3)
- .Case("niagara4", CK_NIAGARA4)
- .Case("ma2100", CK_MYRIAD2100)
- .Case("ma2150", CK_MYRIAD2150)
- .Case("ma2155", CK_MYRIAD2155)
- .Case("ma2450", CK_MYRIAD2450)
- .Case("ma2455", CK_MYRIAD2455)
- .Case("ma2x5x", CK_MYRIAD2x5x)
- .Case("ma2080", CK_MYRIAD2080)
- .Case("ma2085", CK_MYRIAD2085)
- .Case("ma2480", CK_MYRIAD2480)
- .Case("ma2485", CK_MYRIAD2485)
- .Case("ma2x8x", CK_MYRIAD2x8x)
- // FIXME: the myriad2[.n] spellings are obsolete,
- // but a grace period is needed to allow updating dependent builds.
- .Case("myriad2", CK_MYRIAD2x5x)
- .Case("myriad2.1", CK_MYRIAD2100)
- .Case("myriad2.2", CK_MYRIAD2x5x)
- .Case("myriad2.3", CK_MYRIAD2x8x)
- .Case("leon2", CK_LEON2)
- .Case("at697e", CK_LEON2_AT697E)
- .Case("at697f", CK_LEON2_AT697F)
- .Case("leon3", CK_LEON3)
- .Case("ut699", CK_LEON3_UT699)
- .Case("gr712rc", CK_LEON3_GR712RC)
- .Case("leon4", CK_LEON4)
- .Case("gr740", CK_LEON4_GR740)
- .Default(CK_GENERIC);
+ const SparcCPUInfo *Item = llvm::find_if(
+ CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
+
+ if (Item == std::end(CPUInfo))
+ return CK_GENERIC;
+ return Item->Kind;
+}
+
+void SparcTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ for (const SparcCPUInfo &Info : CPUInfo)
+ Values.push_back(Info.Name);
}
void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -178,6 +218,13 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro(MyriadArchValue, "1");
Builder.defineMacro(MyriadArchValue + "__", "1");
}
+ if (Myriad2Value == "2") {
+ Builder.defineMacro("__ma2x5x", "1");
+ Builder.defineMacro("__ma2x5x__", "1");
+ } else if (Myriad2Value == "3") {
+ Builder.defineMacro("__ma2x8x", "1");
+ Builder.defineMacro("__ma2x8x__", "1");
+ }
Builder.defineMacro("__myriad2__", Myriad2Value);
Builder.defineMacro("__myriad2", Myriad2Value);
}
@@ -195,3 +242,10 @@ void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__sparcv9__");
}
}
+
+void SparcV9TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ for (const SparcCPUInfo &Info : CPUInfo)
+ if (Info.Generation == CG_V9)
+ Values.push_back(Info.Name);
+}
diff --git a/lib/Basic/Targets/Sparc.h b/lib/Basic/Targets/Sparc.h
index aacc26119dfbd..af2189f214687 100644
--- a/lib/Basic/Targets/Sparc.h
+++ b/lib/Basic/Targets/Sparc.h
@@ -1,4 +1,4 @@
-//===--- Sparc.h - Declare Sparc target feature support -------------------===//
+//===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -131,48 +131,7 @@ public:
CG_V9,
};
- CPUGeneration getCPUGeneration(CPUKind Kind) const {
- switch (Kind) {
- case CK_GENERIC:
- case CK_V8:
- case CK_SUPERSPARC:
- case CK_SPARCLITE:
- case CK_F934:
- case CK_HYPERSPARC:
- case CK_SPARCLITE86X:
- case CK_SPARCLET:
- case CK_TSC701:
- case CK_MYRIAD2100:
- case CK_MYRIAD2150:
- case CK_MYRIAD2155:
- case CK_MYRIAD2450:
- case CK_MYRIAD2455:
- case CK_MYRIAD2x5x:
- case CK_MYRIAD2080:
- case CK_MYRIAD2085:
- case CK_MYRIAD2480:
- case CK_MYRIAD2485:
- case CK_MYRIAD2x8x:
- case CK_LEON2:
- case CK_LEON2_AT697E:
- case CK_LEON2_AT697F:
- case CK_LEON3:
- case CK_LEON3_UT699:
- case CK_LEON3_GR712RC:
- case CK_LEON4:
- case CK_LEON4_GR740:
- return CG_V8;
- case CK_V9:
- case CK_ULTRASPARC:
- case CK_ULTRASPARC3:
- case CK_NIAGARA:
- case CK_NIAGARA2:
- case CK_NIAGARA3:
- case CK_NIAGARA4:
- return CG_V9;
- }
- llvm_unreachable("Unexpected CPU kind");
- }
+ CPUGeneration getCPUGeneration(CPUKind Kind) const;
CPUKind getCPUKind(StringRef Name) const;
@@ -180,6 +139,8 @@ public:
return getCPUKind(Name) != CK_GENERIC;
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
CPU = getCPUKind(Name);
return CPU != CK_GENERIC;
@@ -259,6 +220,8 @@ public:
return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
if (!SparcTargetInfo::setCPU(Name))
return false;
diff --git a/lib/Basic/Targets/SystemZ.cpp b/lib/Basic/Targets/SystemZ.cpp
index 98f3ae2f72b47..6f06f1fc760c6 100644
--- a/lib/Basic/Targets/SystemZ.cpp
+++ b/lib/Basic/Targets/SystemZ.cpp
@@ -30,15 +30,30 @@ const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = {
};
const char *const SystemZTargetInfo::GCCRegNames[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
- "r11", "r12", "r13", "r14", "r15", "f0", "f2", "f4", "f6", "f1", "f3",
- "f5", "f7", "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15"
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",
+ "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15",
+ /*ap*/"", "cc", /*fp*/"", /*rp*/"", "a0", "a1",
+ "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23",
+ "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31"
+};
+
+const TargetInfo::AddlRegName GCCAddlRegNames[] = {
+ {{"v0"}, 16}, {{"v2"}, 17}, {{"v4"}, 18}, {{"v6"}, 19},
+ {{"v1"}, 20}, {{"v3"}, 21}, {{"v5"}, 22}, {{"v7"}, 23},
+ {{"v8"}, 24}, {{"v10"}, 25}, {{"v12"}, 26}, {{"v14"}, 27},
+ {{"v9"}, 28}, {{"v11"}, 29}, {{"v13"}, 30}, {{"v15"}, 31}
};
ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
+ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const {
+ return llvm::makeArrayRef(GCCAddlRegNames);
+}
+
bool SystemZTargetInfo::validateAsmConstraint(
const char *&Name, TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
@@ -48,6 +63,7 @@ bool SystemZTargetInfo::validateAsmConstraint(
case 'a': // Address register
case 'd': // Data register (equivalent to 'r')
case 'f': // Floating-point register
+ case 'v': // Vector register
Info.setAllowsRegister();
return true;
@@ -67,14 +83,32 @@ bool SystemZTargetInfo::validateAsmConstraint(
}
}
-int SystemZTargetInfo::getISARevision(const StringRef &Name) const {
- return llvm::StringSwitch<int>(Name)
- .Cases("arch8", "z10", 8)
- .Cases("arch9", "z196", 9)
- .Cases("arch10", "zEC12", 10)
- .Cases("arch11", "z13", 11)
- .Cases("arch12", "z14", 12)
- .Default(-1);
+struct ISANameRevision {
+ llvm::StringLiteral Name;
+ int ISARevisionID;
+};
+static constexpr ISANameRevision ISARevisions[] = {
+ {{"arch8"}, 8}, {{"z10"}, 8},
+ {{"arch9"}, 9}, {{"z196"}, 9},
+ {{"arch10"}, 10}, {{"zEC12"}, 10},
+ {{"arch11"}, 11}, {{"z13"}, 11},
+ {{"arch12"}, 12}, {{"z14"}, 12}
+};
+
+int SystemZTargetInfo::getISARevision(StringRef Name) const {
+ const auto Rev =
+ llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) {
+ return CR.Name == Name;
+ });
+ if (Rev == std::end(ISARevisions))
+ return -1;
+ return Rev->ISARevisionID;
+}
+
+void SystemZTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ for (const ISANameRevision &Rev : ISARevisions)
+ Values.push_back(Rev.Name);
}
bool SystemZTargetInfo::hasFeature(StringRef Feature) const {
diff --git a/lib/Basic/Targets/SystemZ.h b/lib/Basic/Targets/SystemZ.h
index 3023c1d2ea262..842316005ed97 100644
--- a/lib/Basic/Targets/SystemZ.h
+++ b/lib/Basic/Targets/SystemZ.h
@@ -62,6 +62,8 @@ public:
return None;
}
+ ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
+
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
@@ -74,12 +76,14 @@ public:
return TargetInfo::SystemZBuiltinVaList;
}
- int getISARevision(const StringRef &Name) const;
+ int getISARevision(StringRef Name) const;
bool isValidCPUName(StringRef Name) const override {
return getISARevision(Name) != -1;
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
CPU = Name;
ISARevision = getISARevision(CPU);
diff --git a/lib/Basic/Targets/WebAssembly.cpp b/lib/Basic/Targets/WebAssembly.cpp
index 915aad4b563b4..b8a2a092aff4a 100644
--- a/lib/Basic/Targets/WebAssembly.cpp
+++ b/lib/Basic/Targets/WebAssembly.cpp
@@ -29,19 +29,25 @@ const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
#include "clang/Basic/BuiltinsWebAssembly.def"
};
+static constexpr llvm::StringLiteral ValidCPUNames[] = {
+ {"mvp"}, {"bleeding-edge"}, {"generic"}};
+
bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("simd128", SIMDLevel >= SIMD128)
.Case("nontrapping-fptoint", HasNontrappingFPToInt)
+ .Case("sign-ext", HasSignExt)
+ .Case("exception-handling", HasExceptionHandling)
.Default(false);
}
bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- .Case("mvp", true)
- .Case("bleeding-edge", true)
- .Case("generic", true)
- .Default(false);
+ return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+}
+
+void WebAssemblyTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}
void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -70,6 +76,22 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
HasNontrappingFPToInt = false;
continue;
}
+ if (Feature == "+sign-ext") {
+ HasSignExt = true;
+ continue;
+ }
+ if (Feature == "-sign-ext") {
+ HasSignExt = false;
+ continue;
+ }
+ if (Feature == "+exception-handling") {
+ HasExceptionHandling = true;
+ continue;
+ }
+ if (Feature == "-exception-handling") {
+ HasExceptionHandling = false;
+ continue;
+ }
Diags.Report(diag::err_opt_not_valid_with_opt)
<< Feature << "-target-feature";
diff --git a/lib/Basic/Targets/WebAssembly.h b/lib/Basic/Targets/WebAssembly.h
index ee0073d081e0a..c04c5cb6fb3a9 100644
--- a/lib/Basic/Targets/WebAssembly.h
+++ b/lib/Basic/Targets/WebAssembly.h
@@ -31,10 +31,13 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
} SIMDLevel;
bool HasNontrappingFPToInt;
+ bool HasSignExt;
+ bool HasExceptionHandling;
public:
explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
- : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false) {
+ : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false),
+ HasSignExt(false), HasExceptionHandling(false) {
NoAsmVariants = true;
SuitableAlign = 128;
LargeArrayMinWidth = 128;
@@ -43,9 +46,12 @@ public:
SigAtomicType = SignedLong;
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
- SizeType = UnsignedInt;
- PtrDiffType = SignedInt;
- IntPtrType = SignedInt;
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
+ // more consistent between the two.
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ IntPtrType = SignedLong;
}
protected:
@@ -60,6 +66,7 @@ private:
if (CPU == "bleeding-edge") {
Features["simd128"] = true;
Features["nontrapping-fptoint"] = true;
+ Features["sign-ext"] = true;
}
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -70,6 +77,7 @@ private:
DiagnosticsEngine &Diags) final;
bool isValidCPUName(StringRef Name) const final;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
@@ -115,7 +123,6 @@ public:
explicit WebAssembly32TargetInfo(const llvm::Triple &T,
const TargetOptions &Opts)
: WebAssemblyTargetInfo(T, Opts) {
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
}
@@ -132,7 +139,6 @@ public:
: WebAssemblyTargetInfo(T, Opts) {
LongAlign = LongWidth = 64;
PointerAlign = PointerWidth = 64;
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
SizeType = UnsignedLong;
PtrDiffType = SignedLong;
IntPtrType = SignedLong;
diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp
index 3efba26a83731..7ae0696ce7e7b 100644
--- a/lib/Basic/Targets/X86.cpp
+++ b/lib/Basic/Targets/X86.cpp
@@ -15,8 +15,10 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/TargetParser.h"
namespace clang {
namespace targets {
@@ -131,7 +133,11 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "mmx", true);
break;
- case CK_Icelake:
+ case CK_IcelakeServer:
+ setFeatureEnabledImpl(Features, "pconfig", true);
+ setFeatureEnabledImpl(Features, "wbnoinvd", true);
+ LLVM_FALLTHROUGH;
+ case CK_IcelakeClient:
setFeatureEnabledImpl(Features, "vaes", true);
setFeatureEnabledImpl(Features, "gfni", true);
setFeatureEnabledImpl(Features, "vpclmulqdq", true);
@@ -139,7 +145,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "avx512vnni", true);
setFeatureEnabledImpl(Features, "avx512vbmi2", true);
setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
- setFeatureEnabledImpl(Features, "clwb", true);
+ setFeatureEnabledImpl(Features, "rdpid", true);
LLVM_FALLTHROUGH;
case CK_Cannonlake:
setFeatureEnabledImpl(Features, "avx512ifma", true);
@@ -152,16 +158,16 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "avx512dq", true);
setFeatureEnabledImpl(Features, "avx512bw", true);
setFeatureEnabledImpl(Features, "avx512vl", true);
- if (Kind == CK_SkylakeServer) {
- setFeatureEnabledImpl(Features, "pku", true);
+ setFeatureEnabledImpl(Features, "pku", true);
+ if (Kind != CK_Cannonlake) // CNL inherits all SKX features, except CLWB
setFeatureEnabledImpl(Features, "clwb", true);
- }
LLVM_FALLTHROUGH;
case CK_SkylakeClient:
setFeatureEnabledImpl(Features, "xsavec", true);
setFeatureEnabledImpl(Features, "xsaves", true);
setFeatureEnabledImpl(Features, "mpx", true);
- setFeatureEnabledImpl(Features, "sgx", true);
+ if (Kind != CK_SkylakeServer) // SKX inherits all SKL features, except SGX
+ setFeatureEnabledImpl(Features, "sgx", true);
setFeatureEnabledImpl(Features, "clflushopt", true);
setFeatureEnabledImpl(Features, "rtm", true);
LLVM_FALLTHROUGH;
@@ -176,6 +182,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "bmi", true);
setFeatureEnabledImpl(Features, "bmi2", true);
setFeatureEnabledImpl(Features, "fma", true);
+ setFeatureEnabledImpl(Features, "invpcid", true);
setFeatureEnabledImpl(Features, "movbe", true);
LLVM_FALLTHROUGH;
case CK_IvyBridge:
@@ -200,6 +207,7 @@ bool X86TargetInfo::initFeatureMap(
LLVM_FALLTHROUGH;
case CK_Core2:
setFeatureEnabledImpl(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
LLVM_FALLTHROUGH;
case CK_Yonah:
case CK_Prescott:
@@ -218,9 +226,20 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "fxsr", true);
break;
+ case CK_Tremont:
+ setFeatureEnabledImpl(Features, "cldemote", true);
+ setFeatureEnabledImpl(Features, "movdiri", true);
+ setFeatureEnabledImpl(Features, "movdir64b", true);
+ setFeatureEnabledImpl(Features, "gfni", true);
+ setFeatureEnabledImpl(Features, "waitpkg", true);
+ LLVM_FALLTHROUGH;
+ case CK_GoldmontPlus:
+ setFeatureEnabledImpl(Features, "ptwrite", true);
+ setFeatureEnabledImpl(Features, "rdpid", true);
+ setFeatureEnabledImpl(Features, "sgx", true);
+ LLVM_FALLTHROUGH;
case CK_Goldmont:
setFeatureEnabledImpl(Features, "sha", true);
- setFeatureEnabledImpl(Features, "rdrnd", true);
setFeatureEnabledImpl(Features, "rdseed", true);
setFeatureEnabledImpl(Features, "xsave", true);
setFeatureEnabledImpl(Features, "xsaveopt", true);
@@ -231,6 +250,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "fsgsbase", true);
LLVM_FALLTHROUGH;
case CK_Silvermont:
+ setFeatureEnabledImpl(Features, "rdrnd", true);
setFeatureEnabledImpl(Features, "aes", true);
setFeatureEnabledImpl(Features, "pclmul", true);
setFeatureEnabledImpl(Features, "sse4.2", true);
@@ -241,6 +261,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "ssse3", true);
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "cx16", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
break;
case CK_KNM:
@@ -271,6 +292,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "xsaveopt", true);
setFeatureEnabledImpl(Features, "xsave", true);
setFeatureEnabledImpl(Features, "movbe", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
break;
case CK_K6_2:
@@ -284,6 +306,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "sse4a", true);
setFeatureEnabledImpl(Features, "lzcnt", true);
setFeatureEnabledImpl(Features, "popcnt", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
LLVM_FALLTHROUGH;
case CK_K8SSE3:
setFeatureEnabledImpl(Features, "sse3", true);
@@ -317,6 +340,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "prfchw", true);
setFeatureEnabledImpl(Features, "cx16", true);
setFeatureEnabledImpl(Features, "fxsr", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
break;
case CK_ZNVER1:
@@ -340,6 +364,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "prfchw", true);
setFeatureEnabledImpl(Features, "rdrnd", true);
setFeatureEnabledImpl(Features, "rdseed", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
setFeatureEnabledImpl(Features, "sha", true);
setFeatureEnabledImpl(Features, "sse4a", true);
setFeatureEnabledImpl(Features, "xsave", true);
@@ -374,6 +399,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "cx16", true);
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "xsave", true);
+ setFeatureEnabledImpl(Features, "sahf", true);
break;
}
if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
@@ -412,7 +438,7 @@ void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
if (Enabled) {
switch (Level) {
case AVX512F:
- Features["avx512f"] = true;
+ Features["avx512f"] = Features["fma"] = Features["f16c"] = true;
LLVM_FALLTHROUGH;
case AVX2:
Features["avx2"] = true;
@@ -626,6 +652,8 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
} else if (Name == "fma") {
if (Enabled)
setSSELevel(Features, AVX, Enabled);
+ else
+ setSSELevel(Features, AVX512F, Enabled);
} else if (Name == "fma4") {
setXOPLevel(Features, FMA4, Enabled);
} else if (Name == "xop") {
@@ -635,6 +663,8 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
} else if (Name == "f16c") {
if (Enabled)
setSSELevel(Features, AVX, Enabled);
+ else
+ setSSELevel(Features, AVX512F, Enabled);
} else if (Name == "sha") {
if (Enabled)
setSSELevel(Features, SSE2, Enabled);
@@ -732,8 +762,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasMPX = true;
} else if (Feature == "+shstk") {
HasSHSTK = true;
- } else if (Feature == "+ibt") {
- HasIBT = true;
} else if (Feature == "+movbe") {
HasMOVBE = true;
} else if (Feature == "+sgx") {
@@ -758,10 +786,34 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasCLFLUSHOPT = true;
} else if (Feature == "+clwb") {
HasCLWB = true;
+ } else if (Feature == "+wbnoinvd") {
+ HasWBNOINVD = true;
} else if (Feature == "+prefetchwt1") {
HasPREFETCHWT1 = true;
} else if (Feature == "+clzero") {
HasCLZERO = true;
+ } else if (Feature == "+cldemote") {
+ HasCLDEMOTE = true;
+ } else if (Feature == "+rdpid") {
+ HasRDPID = true;
+ } else if (Feature == "+retpoline") {
+ HasRetpoline = true;
+ } else if (Feature == "+retpoline-external-thunk") {
+ HasRetpolineExternalThunk = true;
+ } else if (Feature == "+sahf") {
+ HasLAHFSAHF = true;
+ } else if (Feature == "+waitpkg") {
+ HasWAITPKG = true;
+ } else if (Feature == "+movdiri") {
+ HasMOVDIRI = true;
+ } else if (Feature == "+movdir64b") {
+ HasMOVDIR64B = true;
+ } else if (Feature == "+pconfig") {
+ HasPCONFIG = true;
+ } else if (Feature == "+ptwrite") {
+ HasPTWRITE = true;
+ } else if (Feature == "+invpcid") {
+ HasINVPCID = true;
}
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -882,6 +934,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Goldmont:
defineCPUMacros(Builder, "goldmont");
break;
+ case CK_GoldmontPlus:
+ defineCPUMacros(Builder, "goldmont_plus");
+ break;
+ case CK_Tremont:
+ defineCPUMacros(Builder, "tremont");
+ break;
case CK_Nehalem:
case CK_Westmere:
case CK_SandyBridge:
@@ -891,7 +949,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_SkylakeClient:
case CK_SkylakeServer:
case CK_Cannonlake:
- case CK_Icelake:
+ case CK_IcelakeClient:
+ case CK_IcelakeServer:
// 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.
@@ -1087,12 +1146,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__XSAVES__");
if (HasPKU)
Builder.defineMacro("__PKU__");
- if (HasCX16)
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
if (HasCLFLUSHOPT)
Builder.defineMacro("__CLFLUSHOPT__");
if (HasCLWB)
Builder.defineMacro("__CLWB__");
+ if (HasWBNOINVD)
+ Builder.defineMacro("__WBNOINVD__");
if (HasMPX)
Builder.defineMacro("__MPX__");
if (HasSHSTK)
@@ -1103,6 +1162,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__PREFETCHWT1__");
if (HasCLZERO)
Builder.defineMacro("__CLZERO__");
+ if (HasRDPID)
+ Builder.defineMacro("__RDPID__");
+ if (HasCLDEMOTE)
+ Builder.defineMacro("__CLDEMOTE__");
+ if (HasWAITPKG)
+ Builder.defineMacro("__WAITPKG__");
+ if (HasMOVDIRI)
+ Builder.defineMacro("__MOVDIRI__");
+ if (HasMOVDIR64B)
+ Builder.defineMacro("__MOVDIR64B__");
+ if (HasPCONFIG)
+ Builder.defineMacro("__PCONFIG__");
+ if (HasPTWRITE)
+ Builder.defineMacro("__PTWRITE__");
+ if (HasINVPCID)
+ Builder.defineMacro("__INVPCID__");
// Each case falls through to the previous one here.
switch (SSELevel) {
@@ -1182,6 +1257,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
}
if (CPU >= CK_i586)
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ if (HasCX16)
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
if (HasFloat128)
Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
@@ -1210,6 +1287,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("avx512ifma", true)
.Case("bmi", true)
.Case("bmi2", true)
+ .Case("cldemote", true)
.Case("clflushopt", true)
.Case("clwb", true)
.Case("clzero", true)
@@ -1220,20 +1298,27 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("fsgsbase", true)
.Case("fxsr", true)
.Case("gfni", true)
+ .Case("invpcid", true)
.Case("lwp", true)
.Case("lzcnt", true)
.Case("mmx", true)
.Case("movbe", true)
+ .Case("movdiri", true)
+ .Case("movdir64b", true)
.Case("mpx", true)
.Case("mwaitx", true)
.Case("pclmul", true)
+ .Case("pconfig", true)
.Case("pku", true)
.Case("popcnt", true)
.Case("prefetchwt1", true)
.Case("prfchw", true)
+ .Case("ptwrite", true)
+ .Case("rdpid", true)
.Case("rdrnd", true)
.Case("rdseed", true)
.Case("rtm", true)
+ .Case("sahf", true)
.Case("sgx", true)
.Case("sha", true)
.Case("shstk", true)
@@ -1248,6 +1333,8 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("tbm", true)
.Case("vaes", true)
.Case("vpclmulqdq", true)
+ .Case("wbnoinvd", true)
+ .Case("waitpkg", true)
.Case("x87", true)
.Case("xop", true)
.Case("xsave", true)
@@ -1278,6 +1365,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("avx512ifma", HasAVX512IFMA)
.Case("bmi", HasBMI)
.Case("bmi2", HasBMI2)
+ .Case("cldemote", HasCLDEMOTE)
.Case("clflushopt", HasCLFLUSHOPT)
.Case("clwb", HasCLWB)
.Case("clzero", HasCLZERO)
@@ -1288,23 +1376,31 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("fsgsbase", HasFSGSBASE)
.Case("fxsr", HasFXSR)
.Case("gfni", HasGFNI)
- .Case("ibt", HasIBT)
+ .Case("invpcid", HasINVPCID)
.Case("lwp", HasLWP)
.Case("lzcnt", HasLZCNT)
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
.Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
.Case("mmx", MMX3DNowLevel >= MMX)
.Case("movbe", HasMOVBE)
+ .Case("movdiri", HasMOVDIRI)
+ .Case("movdir64b", HasMOVDIR64B)
.Case("mpx", HasMPX)
.Case("mwaitx", HasMWAITX)
.Case("pclmul", HasPCLMUL)
+ .Case("pconfig", HasPCONFIG)
.Case("pku", HasPKU)
.Case("popcnt", HasPOPCNT)
.Case("prefetchwt1", HasPREFETCHWT1)
.Case("prfchw", HasPRFCHW)
+ .Case("ptwrite", HasPTWRITE)
+ .Case("rdpid", HasRDPID)
.Case("rdrnd", HasRDRND)
.Case("rdseed", HasRDSEED)
+ .Case("retpoline", HasRetpoline)
+ .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
.Case("rtm", HasRTM)
+ .Case("sahf", HasLAHFSAHF)
.Case("sgx", HasSGX)
.Case("sha", HasSHA)
.Case("shstk", HasSHSTK)
@@ -1318,6 +1414,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("tbm", HasTBM)
.Case("vaes", HasVAES)
.Case("vpclmulqdq", HasVPCLMULQDQ)
+ .Case("wbnoinvd", HasWBNOINVD)
+ .Case("waitpkg", HasWAITPKG)
.Case("x86", true)
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
@@ -1341,6 +1439,95 @@ bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
.Default(false);
}
+static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
+ return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
+#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM)
+#include "llvm/Support/X86TargetParser.def"
+ ;
+ // Note, this function should only be used after ensuring the value is
+ // correct, so it asserts if the value is out of range.
+}
+
+static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) {
+ enum class FeatPriority {
+#define FEATURE(FEAT) FEAT,
+#include "clang/Basic/X86Target.def"
+ };
+ switch (Feat) {
+#define FEATURE(FEAT) \
+ case llvm::X86::FEAT: \
+ return static_cast<unsigned>(FeatPriority::FEAT);
+#include "clang/Basic/X86Target.def"
+ default:
+ llvm_unreachable("No Feature Priority for non-CPUSupports Features");
+ }
+}
+
+unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
+ // Valid CPUs have a 'key feature' that compares just better than its key
+ // feature.
+ CPUKind Kind = getCPUKind(Name);
+ if (Kind != CK_Generic) {
+ switch (Kind) {
+ default:
+ llvm_unreachable(
+ "CPU Type without a key feature used in 'target' attribute");
+#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \
+ case CK_##ENUM: \
+ return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1;
+#include "clang/Basic/X86Target.def"
+ }
+ }
+
+ // Now we know we have a feature, so get its priority and shift it a few so
+ // that we have sufficient room for the CPUs (above).
+ return getFeaturePriority(getFeature(Name)) << 1;
+}
+
+bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
+ return llvm::StringSwitch<bool>(Name)
+#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true)
+#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true)
+#include "clang/Basic/X86Target.def"
+ .Default(false);
+}
+
+static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
+ return llvm::StringSwitch<StringRef>(Name)
+#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME)
+#include "clang/Basic/X86Target.def"
+ .Default(Name);
+}
+
+char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
+ return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
+#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
+#include "clang/Basic/X86Target.def"
+ .Default(0);
+}
+
+void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
+ StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
+ StringRef WholeList =
+ llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
+#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
+#include "clang/Basic/X86Target.def"
+ .Default("");
+ WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+}
+
+std::string X86TargetInfo::getCPUKindCanonicalName(CPUKind Kind) const {
+ switch (Kind) {
+ case CK_Generic:
+ return "";
+#define PROC(ENUM, STRING, IS64BIT) \
+ case CK_##ENUM: \
+ return STRING;
+#include "clang/Basic/X86Target.def"
+ }
+ llvm_unreachable("Invalid CPUKind");
+}
+
// We can't use a generic validation scheme for the cpus accepted here
// versus subtarget cpus accepted in the target attribute because the
// variables intitialized by the runtime only support the below currently
@@ -1426,7 +1613,7 @@ bool X86TargetInfo::validateAsmConstraint(
case 'y': // Any MMX register.
case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
case 'x': // Any SSE register.
- case 'k': // Any AVX512 mask register (same as Yk, additionaly allows k0
+ case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
// for intermideate k reg operations).
case 'Q': // Any register accessible as [r]h: a, b, c, and d.
case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
@@ -1554,8 +1741,6 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {
// Perform any per-CPU checks necessary to determine if this CPU is
// acceptable.
- // FIXME: This results in terrible diagnostics. Clang just says the CPU is
- // invalid without explaining *why*.
switch (Kind) {
case CK_Generic:
// No processor selected!
@@ -1568,6 +1753,18 @@ bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {
llvm_unreachable("Unhandled CPU kind");
}
+void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
+#define PROC(ENUM, STRING, IS64BIT) \
+ if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \
+ Values.emplace_back(STRING);
+ // Go through CPUKind checking to ensure that the alias is de-aliased and
+ // 64 bit-ness is checked.
+#define PROC_ALIAS(ENUM, ALIAS) \
+ if (checkCPUKind(getCPUKind(ALIAS))) \
+ Values.emplace_back(ALIAS);
+#include "clang/Basic/X86Target.def"
+}
+
X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {
return llvm::StringSwitch<CPUKind>(CPU)
#define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM)
diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h
index cbd6a2d24fb51..b6cb27977b69e 100644
--- a/lib/Basic/Targets/X86.h
+++ b/lib/Basic/Targets/X86.h
@@ -81,7 +81,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasSHA = false;
bool HasMPX = false;
bool HasSHSTK = false;
- bool HasIBT = false;
bool HasSGX = false;
bool HasCX16 = false;
bool HasFXSR = false;
@@ -91,13 +90,26 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasXSAVES = false;
bool HasMWAITX = false;
bool HasCLZERO = false;
+ bool HasCLDEMOTE = false;
+ bool HasPCONFIG = false;
bool HasPKU = false;
bool HasCLFLUSHOPT = false;
bool HasCLWB = false;
bool HasMOVBE = false;
bool HasPREFETCHWT1 = false;
-
- /// \brief Enumeration of all of the X86 CPUs supported by Clang.
+ bool HasRDPID = false;
+ bool HasRetpoline = false;
+ bool HasRetpolineExternalThunk = false;
+ bool HasLAHFSAHF = false;
+ bool HasWBNOINVD = false;
+ bool HasWAITPKG = false;
+ bool HasMOVDIRI = false;
+ bool HasMOVDIR64B = false;
+ bool HasPTWRITE = false;
+ bool HasINVPCID = false;
+
+protected:
+ /// Enumeration of all of the X86 CPUs supported by Clang.
///
/// Each enumeration represents a particular CPU supported by Clang. These
/// loosely correspond to the options passed to '-march' or '-mtune' flags.
@@ -111,6 +123,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
CPUKind getCPUKind(StringRef CPU) const;
+ std::string getCPUKindCanonicalName(CPUKind Kind) const;
+
enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
public:
@@ -136,6 +150,14 @@ public:
bool validateCpuIs(StringRef Name) const override;
+ bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
+
+ char CPUSpecificManglingCharacter(StringRef Name) const override;
+
+ void getCPUSpecificCPUDispatchFeatures(
+ StringRef Name,
+ llvm::SmallVectorImpl<StringRef> &Features) const override;
+
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
@@ -156,6 +178,17 @@ public:
bool validateInputSize(StringRef Constraint, unsigned Size) const override;
+ virtual bool
+ checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
+ return true;
+ };
+
+ virtual bool
+ checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
+ return true;
+ };
+
+
virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
std::string convertConstraint(const char *&Constraint) const override;
@@ -163,8 +196,8 @@ public:
return "~{dirflag},~{fpsr},~{flags}";
}
- StringRef getConstraintRegister(const StringRef &Constraint,
- const StringRef &Expression) const override {
+ StringRef getConstraintRegister(StringRef Constraint,
+ StringRef Expression) const override {
StringRef::iterator I, E;
for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
if (isalpha(*I))
@@ -252,10 +285,17 @@ public:
return checkCPUKind(getCPUKind(Name));
}
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
bool setCPU(const std::string &Name) override {
return checkCPUKind(CPU = getCPUKind(Name));
}
+ bool supportsMultiVersioning() const override {
+ return getTriple().isOSBinFormatELF();
+ }
+ unsigned multiVersionSortPriority(StringRef Name) const override;
+
bool setFPMath(StringRef Name) override;
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
@@ -267,6 +307,7 @@ public:
case CC_X86VectorCall:
case CC_X86RegCall:
case CC_C:
+ case CC_PreserveMost:
case CC_Swift:
case CC_X86Pascal:
case CC_IntelOclBicc:
@@ -309,9 +350,11 @@ public:
(1 << TargetInfo::LongDouble));
// x86-32 has atomics up to 8 bytes
- // FIXME: Check that we actually have cmpxchg8b before setting
- // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ CPUKind Kind = getCPUKind(Opts.CPU);
+ if (Kind >= CK_i586 || Kind == CK_Generic)
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ else if (Kind >= CK_i486)
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
@@ -706,6 +749,11 @@ public:
Builder.defineMacro("_M_X64", "100");
Builder.defineMacro("_M_AMD64", "100");
}
+
+ TargetInfo::CallingConvKind
+ getCallingConvKind(bool ClangABICompat4) const override {
+ return CCK_MicrosoftWin64;
+ }
};
// x86-64 MinGW target