diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Basic/Targets | |
parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) |
Notes
Diffstat (limited to 'lib/Basic/Targets')
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 |