diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 19:57:54 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 19:57:54 +0000 |
commit | e123fc8fd8677e4dc86f274cffd069e5d56f4a01 (patch) | |
tree | 806fb806ca9ace304565efd09b494e81ac2aff6f /contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp | |
parent | 54db30ce18663e6c2991958f3b5d18362e8e93c4 (diff) | |
parent | 2298981669bf3bd63335a4be179bc0f96823a8f4 (diff) |
Merge clang trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes:
svn path=/projects/clang900-import/; revision=351350
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp | 156 |
1 files changed, 111 insertions, 45 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp index 23eee34eaa93..c6834b9fac15 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp @@ -1,9 +1,8 @@ //===--- ARM.cpp - Implement ARM target feature support -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -41,13 +40,14 @@ void ARMTargetInfo::setABIAAPCS() { // so set preferred for small types to 32. if (T.isOSBinFormatMachO()) { resetDataLayout(BigEndian - ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" - : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); + ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); } else if (T.isOSWindows()) { assert(!BigEndian && "Windows on ARM does not support big endian"); resetDataLayout("e" "-m:w" "-p:32:32" + "-Fi8" "-i64:64" "-v128:64:128" "-a:0:32" @@ -55,11 +55,11 @@ void ARMTargetInfo::setABIAAPCS() { "-S64"); } else if (T.isOSNaCl()) { assert(!BigEndian && "NaCl on ARM does not support big endian"); - resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"); + resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"); } else { resetDataLayout(BigEndian - ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" - : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); + ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); } // FIXME: Enumerated types are variable width in straight AAPCS. @@ -88,17 +88,17 @@ void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { if (T.isOSBinFormatMachO() && IsAAPCS16) { assert(!BigEndian && "AAPCS16 does not support big-endian"); - resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128"); + resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"); } else if (T.isOSBinFormatMachO()) resetDataLayout( BigEndian - ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" - : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); + ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" + : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); else resetDataLayout( BigEndian - ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" - : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); + ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" + : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); // FIXME: Override "preferred align" for double and long long. } @@ -146,6 +146,14 @@ void ARMTargetInfo::setAtomic() { } } +bool ARMTargetInfo::hasMVE() const { + return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0; +} + +bool ARMTargetInfo::hasMVEFloat() const { + return hasMVE() && (MVE & MVE_FP); +} + bool ARMTargetInfo::isThumb() const { return ArchISA == llvm::ARM::ISAKind::THUMB; } @@ -197,6 +205,8 @@ StringRef ARMTargetInfo::getCPUAttr() const { return "8M_MAIN"; case llvm::ARM::ArchKind::ARMV8R: return "8R"; + case llvm::ARM::ArchKind::ARMV8_1MMainline: + return "8_1M_MAIN"; } } @@ -313,6 +323,8 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, this->MCountName = Opts.EABIVersion == llvm::EABI::GNU ? "\01__gnu_mcount_nc" : "\01mcount"; + + SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi"); } StringRef ARMTargetInfo::getABI() const { return ABI; } @@ -375,12 +387,21 @@ bool ARMTargetInfo::initFeatureMap( // Convert user-provided arm and thumb GNU target attributes to // [-|+]thumb-mode target features respectively. - std::vector<std::string> UpdatedFeaturesVec(FeaturesVec); - for (auto &Feature : UpdatedFeaturesVec) { - if (Feature.compare("+arm") == 0) - Feature = "-thumb-mode"; - else if (Feature.compare("+thumb") == 0) - Feature = "+thumb-mode"; + std::vector<std::string> UpdatedFeaturesVec; + for (const auto &Feature : FeaturesVec) { + // Skip soft-float-abi; it's something we only use to initialize a bit of + // class state, and is otherwise unrecognized. + if (Feature == "+soft-float-abi") + continue; + + StringRef FixedFeature; + if (Feature == "+arm") + FixedFeature = "-thumb-mode"; + else if (Feature == "+thumb") + FixedFeature = "+thumb-mode"; + else + FixedFeature = Feature; + UpdatedFeaturesVec.push_back(FixedFeature.str()); } return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); @@ -390,38 +411,49 @@ bool ARMTargetInfo::initFeatureMap( bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) { FPU = 0; + MVE = 0; CRC = 0; Crypto = 0; DSP = 0; Unaligned = 1; - SoftFloat = SoftFloatABI = false; + SoftFloat = false; + // Note that SoftFloatABI is initialized in our constructor. HWDiv = 0; DotProd = 0; HasFloat16 = true; // This does not diagnose illegal cases like having both - // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". - uint32_t HW_FP_remove = 0; + // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". for (const auto &Feature : Features) { if (Feature == "+soft-float") { SoftFloat = true; - } else if (Feature == "+soft-float-abi") { - SoftFloatABI = true; - } else if (Feature == "+vfp2") { + } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" || + Feature == "+vfp2" || Feature == "+vfp2d16") { FPU |= VFP2FPU; - HW_FP |= HW_FP_SP | HW_FP_DP; - } else if (Feature == "+vfp3") { + HW_FP |= HW_FP_SP; + if (Feature == "+vfp2" || Feature == "+vfp2d16") + HW_FP |= HW_FP_DP; + } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" || + Feature == "+vfp3" || Feature == "+vfp3d16") { FPU |= VFP3FPU; - HW_FP |= HW_FP_SP | HW_FP_DP; - } else if (Feature == "+vfp4") { + HW_FP |= HW_FP_SP; + if (Feature == "+vfp3" || Feature == "+vfp3d16") + HW_FP |= HW_FP_DP; + } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" || + Feature == "+vfp4" || Feature == "+vfp4d16") { FPU |= VFP4FPU; - HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; - } else if (Feature == "+fp-armv8") { + HW_FP |= HW_FP_SP | HW_FP_HP; + if (Feature == "+vfp4" || Feature == "+vfp4d16") + HW_FP |= HW_FP_DP; + } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" || + Feature == "+fp-armv8" || Feature == "+fp-armv8d16") { FPU |= FPARMV8; - HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; + HW_FP |= HW_FP_SP | HW_FP_HP; + if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16") + HW_FP |= HW_FP_DP; } else if (Feature == "+neon") { FPU |= NeonFPU; - HW_FP |= HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP; } else if (Feature == "+hwdiv") { HWDiv |= HWDivThumb; } else if (Feature == "+hwdiv-arm") { @@ -432,8 +464,13 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Crypto = 1; } else if (Feature == "+dsp") { DSP = 1; - } else if (Feature == "+fp-only-sp") { - HW_FP_remove |= HW_FP_DP; + } else if (Feature == "+fp64") { + HW_FP |= HW_FP_DP; + } else if (Feature == "+8msecext") { + if (CPUProfile != "M" || ArchVersion != 8) { + Diags.Report(diag::err_target_unsupported_mcmse) << CPU; + return false; + } } else if (Feature == "+strict-align") { Unaligned = 0; } else if (Feature == "+fp16") { @@ -442,9 +479,17 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasLegalHalfType = true; } else if (Feature == "+dotprod") { DotProd = true; + } else if (Feature == "+mve") { + DSP = 1; + MVE |= MVE_INT; + } else if (Feature == "+mve.fp") { + DSP = 1; + HasLegalHalfType = true; + FPU |= FPARMV8; + MVE |= MVE_INT | MVE_FP; + HW_FP |= HW_FP_SP | HW_FP_HP; } } - HW_FP &= ~HW_FP_remove; switch (ArchVersion) { case 6: @@ -475,11 +520,6 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, else if (FPMath == FP_VFP) Features.push_back("-neonfp"); - // Remove front-end specific options which the backend handles differently. - auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi"); - if (Feature != Features.end()) - Features.erase(Feature); - return true; } @@ -493,6 +533,7 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const { .Case("vfp", FPU && !SoftFloat) .Case("hwdiv", HWDiv & HWDivThumb) .Case("hwdiv-arm", HWDiv & HWDivARM) + .Case("mve", hasMVE()) .Default(false); } @@ -653,6 +694,12 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (SoftFloat) Builder.defineMacro("__SOFTFP__"); + // ACLE position independent code macros. + if (Opts.ROPI) + Builder.defineMacro("__ARM_ROPI", "1"); + if (Opts.RWPI) + Builder.defineMacro("__ARM_RWPI", "1"); + if (ArchKind == llvm::ARM::ArchKind::XSCALE) Builder.defineMacro("__XSCALE__"); @@ -702,11 +749,19 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); } + if (hasMVE()) { + Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); + } + Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Twine(Opts.WCharSize ? Opts.WCharSize : 4)); Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); + // CMSE + if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) + Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); + if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -845,6 +900,17 @@ bool ARMTargetInfo::validateAsmConstraint( case 'Q': // A memory address that is a single base register. Info.setAllowsMemory(); return true; + case 'T': + switch (Name[1]) { + default: + break; + case 'e': // Even general-purpose register + case 'o': // Odd general-purpose register + Info.setAllowsRegister(); + Name++; + return true; + } + break; case 'U': // a memory reference... switch (Name[1]) { case 'q': // ...ARMV4 ldrsb @@ -860,6 +926,7 @@ bool ARMTargetInfo::validateAsmConstraint( Name++; return true; } + break; } return false; } @@ -868,6 +935,7 @@ std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { std::string R; switch (*Constraint) { case 'U': // Two-character constraint; add "^" hint for later parsing. + case 'T': R = std::string("^") + std::string(Constraint, 2); Constraint++; break; @@ -962,8 +1030,6 @@ WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder); - // FIXME: this is invalid for WindowsCE Builder.defineMacro("_M_ARM_NT", "1"); Builder.defineMacro("_M_ARMT", "_M_ARM"); @@ -1050,7 +1116,7 @@ CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, this->WCharType = TargetInfo::UnsignedShort; TLSSupported = false; DoubleAlign = LongLongAlign = 64; - resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); + resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); } void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, |