Index: stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp =================================================================== --- stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp (revision 357167) +++ stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp (revision 357168) @@ -1,485 +1,492 @@ //===--- PPC.cpp - Implement PPC target feature support -------------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file implements PPC TargetInfo objects. // //===----------------------------------------------------------------------===// #include "PPC.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" using namespace clang; using namespace clang::targets; const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, #include "clang/Basic/BuiltinsPPC.def" }; /// handleTargetFeatures - Perform initialization based on the user /// configured set of features. bool PPCTargetInfo::handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) { FloatABI = HardFloat; for (const auto &Feature : Features) { if (Feature == "+altivec") { HasAltivec = true; } else if (Feature == "+vsx") { HasVSX = true; } else if (Feature == "+bpermd") { HasBPERMD = true; } else if (Feature == "+extdiv") { HasExtDiv = true; } else if (Feature == "+power8-vector") { HasP8Vector = true; } else if (Feature == "+crypto") { HasP8Crypto = true; } else if (Feature == "+direct-move") { HasDirectMove = true; } else if (Feature == "+qpx") { HasQPX = true; } else if (Feature == "+htm") { HasHTM = true; } else if (Feature == "+float128") { HasFloat128 = true; } else if (Feature == "+power9-vector") { HasP9Vector = true; } else if (Feature == "+spe") { HasSPE = true; LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } else if (Feature == "-hard-float") { FloatABI = SoftFloat; } // TODO: Finish this list and add an assert that we've handled them // all. } return true; } /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific /// #defines that are not tied to a specific subtarget. void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. Builder.defineMacro("__ppc__"); Builder.defineMacro("__PPC__"); Builder.defineMacro("_ARCH_PPC"); Builder.defineMacro("__powerpc__"); Builder.defineMacro("__POWERPC__"); if (PointerWidth == 64) { Builder.defineMacro("_ARCH_PPC64"); Builder.defineMacro("__powerpc64__"); Builder.defineMacro("__ppc64__"); Builder.defineMacro("__PPC64__"); } // Target properties. if (getTriple().getArch() == llvm::Triple::ppc64le) { Builder.defineMacro("_LITTLE_ENDIAN"); } else { if (!getTriple().isOSNetBSD() && !getTriple().isOSOpenBSD()) Builder.defineMacro("_BIG_ENDIAN"); } // ABI options. if (ABI == "elfv1" || ABI == "elfv1-qpx") Builder.defineMacro("_CALL_ELF", "1"); if (ABI == "elfv2") Builder.defineMacro("_CALL_ELF", "2"); // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but // 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"); // Subtarget options. if (!getTriple().isOSAIX()){ Builder.defineMacro("__NATURAL_ALIGNMENT__"); } Builder.defineMacro("__REGISTER_PREFIX__", ""); // FIXME: Should be controlled by command line option. if (LongDoubleWidth == 128) { Builder.defineMacro("__LONG_DOUBLE_128__"); Builder.defineMacro("__LONGDOUBLE128"); } // Define this for elfv2 (64-bit only) or 64-bit darwin. if (ABI == "elfv2" || (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); if (ArchDefs & ArchDefineName) Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); if (ArchDefs & ArchDefinePpcgr) Builder.defineMacro("_ARCH_PPCGR"); if (ArchDefs & ArchDefinePpcsq) Builder.defineMacro("_ARCH_PPCSQ"); if (ArchDefs & ArchDefine440) Builder.defineMacro("_ARCH_440"); if (ArchDefs & ArchDefine603) Builder.defineMacro("_ARCH_603"); if (ArchDefs & ArchDefine604) Builder.defineMacro("_ARCH_604"); if (ArchDefs & ArchDefinePwr4) Builder.defineMacro("_ARCH_PWR4"); if (ArchDefs & ArchDefinePwr5) Builder.defineMacro("_ARCH_PWR5"); if (ArchDefs & ArchDefinePwr5x) Builder.defineMacro("_ARCH_PWR5X"); if (ArchDefs & ArchDefinePwr6) Builder.defineMacro("_ARCH_PWR6"); if (ArchDefs & ArchDefinePwr6x) Builder.defineMacro("_ARCH_PWR6X"); if (ArchDefs & ArchDefinePwr7) Builder.defineMacro("_ARCH_PWR7"); if (ArchDefs & ArchDefinePwr8) Builder.defineMacro("_ARCH_PWR8"); if (ArchDefs & ArchDefinePwr9) Builder.defineMacro("_ARCH_PWR9"); if (ArchDefs & ArchDefineA2) Builder.defineMacro("_ARCH_A2"); if (ArchDefs & ArchDefineA2q) { Builder.defineMacro("_ARCH_A2Q"); Builder.defineMacro("_ARCH_QP"); } + if (ArchDefs & ArchDefineE500) + Builder.defineMacro("__NO_LWSYNC__"); if (getTriple().getVendor() == llvm::Triple::BGQ) { Builder.defineMacro("__bg__"); Builder.defineMacro("__THW_BLUEGENE__"); Builder.defineMacro("__bgq__"); Builder.defineMacro("__TOS_BGQ__"); } if (HasAltivec) { Builder.defineMacro("__VEC__", "10206"); Builder.defineMacro("__ALTIVEC__"); } if (HasSPE) { Builder.defineMacro("__SPE__"); Builder.defineMacro("__NO_FPRS__"); } if (HasVSX) Builder.defineMacro("__VSX__"); if (HasP8Vector) Builder.defineMacro("__POWER8_VECTOR__"); if (HasP8Crypto) Builder.defineMacro("__CRYPTO__"); if (HasHTM) Builder.defineMacro("__HTM__"); if (HasFloat128) Builder.defineMacro("__FLOAT128__"); if (HasP9Vector) Builder.defineMacro("__POWER9_VECTOR__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); if (PointerWidth == 64) Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); // We have support for the bswap intrinsics so we can define this. Builder.defineMacro("__HAVE_BSWAP__", "1"); // FIXME: The following are not yet generated here by Clang, but are // generated by GCC: // // _SOFT_FLOAT_ // __RECIP_PRECISION__ // __APPLE_ALTIVEC__ // __RECIP__ // __RECIPF__ // __RSQRTE__ // __RSQRTEF__ // _SOFT_DOUBLE_ // __NO_LWSYNC__ // __CMODEL_MEDIUM__ // __CMODEL_LARGE__ // _CALL_SYSV // _CALL_DARWIN } // Handle explicit options being passed to the compiler here: if we've // explicitly turned off vsx and turned on any of: // - power8-vector // - direct-move // - float128 // - power9-vector // then go ahead and error since the customer has expressed an incompatible // set of options. static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector &FeaturesVec) { if (llvm::find(FeaturesVec, "-vsx") != FeaturesVec.end()) { if (llvm::find(FeaturesVec, "+power8-vector") != FeaturesVec.end()) { Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector" << "-mno-vsx"; return false; } if (llvm::find(FeaturesVec, "+direct-move") != FeaturesVec.end()) { Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move" << "-mno-vsx"; return false; } if (llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) { Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << "-mno-vsx"; return false; } if (llvm::find(FeaturesVec, "+power9-vector") != FeaturesVec.end()) { Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" << "-mno-vsx"; return false; } } return true; } bool PPCTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const { Features["altivec"] = llvm::StringSwitch(CPU) .Case("7400", true) .Case("g4", true) .Case("7450", true) .Case("g4+", true) .Case("970", true) .Case("g5", true) .Case("pwr6", true) .Case("pwr7", true) .Case("pwr8", true) .Case("pwr9", true) .Case("ppc64", true) .Case("ppc64le", true) .Default(false); Features["qpx"] = (CPU == "a2q"); Features["power9-vector"] = (CPU == "pwr9"); Features["crypto"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["power8-vector"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["bpermd"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); Features["extdiv"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); Features["direct-move"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["vsx"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); Features["htm"] = llvm::StringSwitch(CPU) .Case("ppc64le", true) .Case("pwr9", true) .Case("pwr8", true) .Default(false); + Features["spe"] = llvm::StringSwitch(CPU) + .Case("8548", true) + .Case("e500", true) + .Default(false); + if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && llvm::find(FeaturesVec, "+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); } bool PPCTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("powerpc", true) .Case("altivec", HasAltivec) .Case("vsx", HasVSX) .Case("power8-vector", HasP8Vector) .Case("crypto", HasP8Crypto) .Case("direct-move", HasDirectMove) .Case("qpx", HasQPX) .Case("htm", HasHTM) .Case("bpermd", HasBPERMD) .Case("extdiv", HasExtDiv) .Case("float128", HasFloat128) .Case("power9-vector", HasP9Vector) .Case("spe", HasSPE) .Default(false); } void PPCTargetInfo::setFeatureEnabled(llvm::StringMap &Features, StringRef Name, bool Enabled) const { if (Enabled) { // If we're enabling any of the vsx based features then enable vsx and // altivec. We'll diagnose any problems later. bool FeatureHasVSX = llvm::StringSwitch(Name) .Case("vsx", true) .Case("direct-move", true) .Case("power8-vector", true) .Case("power9-vector", true) .Case("float128", true) .Default(false); if (FeatureHasVSX) Features["vsx"] = Features["altivec"] = true; if (Name == "power9-vector") Features["power8-vector"] = true; Features[Name] = true; } else { // If we're disabling altivec or vsx go ahead and disable all of the vsx // features. if ((Name == "altivec") || (Name == "vsx")) Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = Features["float128"] = Features["power9-vector"] = false; if (Name == "power8-vector") Features["power9-vector"] = false; Features[Name] = false; } } const char *const PPCTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", "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", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" }; ArrayRef PPCTargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { // While some of these aliases do map to different registers // they still share the same register name. {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, {{"cc"}, "cr0"}, }; ArrayRef PPCTargetInfo::getGCCRegAliases() const { return llvm::makeArrayRef(GCCRegAliases); } // PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers". // vs0 ~ vs31 is mapping to 32 - 63, // vs32 ~ vs63 is mapping to 77 - 108. const TargetInfo::AddlRegName GCCAddlRegNames[] = { // Table of additional register names to use in user input. {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35}, {{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39}, {{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43}, {{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47}, {{"vs16"}, 48}, {{"vs17"}, 49}, {{"vs18"}, 50}, {{"vs19"}, 51}, {{"vs20"}, 52}, {{"vs21"}, 53}, {{"vs22"}, 54}, {{"vs23"}, 55}, {{"vs24"}, 56}, {{"vs25"}, 57}, {{"vs26"}, 58}, {{"vs27"}, 59}, {{"vs28"}, 60}, {{"vs29"}, 61}, {{"vs30"}, 62}, {{"vs31"}, 63}, {{"vs32"}, 77}, {{"vs33"}, 78}, {{"vs34"}, 79}, {{"vs35"}, 80}, {{"vs36"}, 81}, {{"vs37"}, 82}, {{"vs38"}, 83}, {{"vs39"}, 84}, {{"vs40"}, 85}, {{"vs41"}, 86}, {{"vs42"}, 87}, {{"vs43"}, 88}, {{"vs44"}, 89}, {{"vs45"}, 90}, {{"vs46"}, 91}, {{"vs47"}, 92}, {{"vs48"}, 93}, {{"vs49"}, 94}, {{"vs50"}, 95}, {{"vs51"}, 96}, {{"vs52"}, 97}, {{"vs53"}, 98}, {{"vs54"}, 99}, {{"vs55"}, 100}, {{"vs56"}, 101}, {{"vs57"}, 102}, {{"vs58"}, 103}, {{"vs59"}, 104}, {{"vs60"}, 105}, {{"vs61"}, 106}, {{"vs62"}, 107}, {{"vs63"}, 108}, }; ArrayRef PPCTargetInfo::getGCCAddlRegNames() const { if (ABI == "elfv2") return llvm::makeArrayRef(GCCAddlRegNames); else return TargetInfo::getGCCAddlRegNames(); } 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"}, + {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, + {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, + {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, + {"7450"}, {"g4+"}, {"750"}, {"8548"}, {"970"}, + {"g5"}, {"a2"}, {"a2q"}, {"e500"}, {"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::find(ValidCPUNames, Name) != std::end(ValidCPUNames); } void PPCTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void PPCTargetInfo::adjust(LangOptions &Opts) { if (HasAltivec) Opts.AltiVec = 1; TargetInfo::adjust(Opts); if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) LongDoubleFormat = Opts.PPCIEEELongDouble ? &llvm::APFloat::IEEEquad() : &llvm::APFloat::PPCDoubleDouble(); } ArrayRef PPCTargetInfo::getTargetBuiltins() const { return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin); } Index: stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h =================================================================== --- stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h (revision 357167) +++ stable/12/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h (revision 357168) @@ -1,483 +1,484 @@ //===--- PPC.h - Declare PPC target feature support -------------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// // // This file declares PPC TargetInfo objects. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H #define LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H #include "OSTargets.h" #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 { namespace targets { // PPC abstract base class class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { /// Flags for architecture specific defines. typedef enum { ArchDefineNone = 0, ArchDefineName = 1 << 0, // is substituted for arch name. ArchDefinePpcgr = 1 << 1, ArchDefinePpcsq = 1 << 2, ArchDefine440 = 1 << 3, ArchDefine603 = 1 << 4, ArchDefine604 = 1 << 5, ArchDefinePwr4 = 1 << 6, ArchDefinePwr5 = 1 << 7, ArchDefinePwr5x = 1 << 8, ArchDefinePwr6 = 1 << 9, ArchDefinePwr6x = 1 << 10, ArchDefinePwr7 = 1 << 11, ArchDefinePwr8 = 1 << 12, ArchDefinePwr9 = 1 << 13, ArchDefineA2 = 1 << 14, - ArchDefineA2q = 1 << 15 + ArchDefineA2q = 1 << 15, + ArchDefineE500 = 1 << 16 } ArchDefineTypes; ArchDefineTypes ArchDefs = ArchDefineNone; static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; enum PPCFloatABI { HardFloat, SoftFloat } FloatABI; // 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; bool HasSPE = 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; // Note: GCC recognizes the following additional cpus: // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, - // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, - // titan, rs64. + // 821, 823, 8540, e300c2, e300c3, e500mc64, e6500, 860, cell, titan, rs64. bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; bool setCPU(const std::string &Name) override { bool CPUKnown = isValidCPUName(Name); if (CPUKnown) { CPU = Name; // CPU identification. ArchDefs = (ArchDefineTypes)llvm::StringSwitch(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 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) // powerpc64le automatically defaults to at least power8. .Cases("power8", "pwr8", "ppc64le", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) .Cases("power9", "pwr9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("8548", "e500", ArchDefineE500) .Default(ArchDefineNone); } return CPUKnown; } StringRef getABI() const override { return ABI; } ArrayRef getTargetBuiltins() const override; bool isCLZForZeroUndef() const override { return false; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const override; bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; bool hasFeature(StringRef Feature) const override; void setFeatureEnabled(llvm::StringMap &Features, StringRef Name, bool Enabled) const override; ArrayRef getGCCRegNames() const override; ArrayRef getGCCRegAliases() const override; ArrayRef getGCCAddlRegNames() const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { switch (*Name) { default: return false; case 'O': // Zero break; case 'f': // Floating point register // Don't use floating point registers on soft float ABI. if (FloatABI == SoftFloat) return false; LLVM_FALLTHROUGH; case 'b': // Base register Info.setAllowsRegister(); break; // FIXME: The following are added to allow parsing. // I just took a guess at what the actions should be. // Also, is more specific checking needed? I.e. specific registers? case 'd': // Floating point register (containing 64-bit value) case 'v': // Altivec vector register // Don't use floating point and altivec vector registers // on soft float ABI if (FloatABI == SoftFloat) return false; Info.setAllowsRegister(); break; case 'w': switch (Name[1]) { case 'd': // VSX vector register to hold vector double data case 'f': // VSX vector register to hold vector float data case 's': // VSX vector register to hold scalar double data case 'w': // VSX vector register to hold scalar double data case 'a': // Any VSX register case 'c': // An individual CR bit case 'i': // FP or VSX register to hold 64-bit integers data break; default: return false; } Info.setAllowsRegister(); Name++; // Skip over 'w'. break; case 'h': // `MQ', `CTR', or `LINK' register case 'q': // `MQ' register case 'c': // `CTR' register case 'l': // `LINK' register case 'x': // `CR' register (condition register) number 0 case 'y': // `CR' register (condition register) case 'z': // `XER[CA]' carry bit (part of the XER register) Info.setAllowsRegister(); break; case 'I': // Signed 16-bit constant case 'J': // Unsigned 16-bit constant shifted left 16 bits // (use `L' instead for SImode constants) case 'K': // Unsigned 16-bit constant case 'L': // Signed 16-bit constant shifted left 16 bits case 'M': // Constant larger than 31 case 'N': // Exact power of 2 case 'P': // Constant whose negation is a signed 16-bit constant case 'G': // Floating point constant that can be loaded into a // register with one instruction per word case 'H': // Integer/Floating point constant that can be loaded // into a register using three instructions break; case 'm': // Memory operand. Note that on PowerPC targets, m can // include addresses that update the base register. It // is therefore only safe to use `m' in an asm statement // if that asm statement accesses the operand exactly once. // The asm statement must also use `%U' as a // placeholder for the "update" flag in the corresponding // load or store instruction. For example: // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val)); // is correct but: // asm ("st %1,%0" : "=m" (mem) : "r" (val)); // is not. Use es rather than m if you don't want the base // register to be updated. case 'e': if (Name[1] != 's') return false; // es: A "stable" memory operand; that is, one which does not // include any automodification of the base register. Unlike // `m', this constraint can be used in asm statements that // might access the operand several times, or that might not // access it at all. Info.setAllowsMemory(); Name++; // Skip over 'e'. break; case 'Q': // Memory operand that is an offset from a register (it is // usually better to use `m' or `es' in asm statements) case 'Z': // Memory operand that is an indexed or indirect from a // register (it is usually better to use `m' or `es' in // asm statements) Info.setAllowsMemory(); Info.setAllowsRegister(); break; case 'R': // AIX TOC entry case 'a': // Address operand that is an indexed or indirect from a // register (`p' is preferable for asm statements) case 'S': // Constant suitable as a 64-bit mask operand case 'T': // Constant suitable as a 32-bit mask operand case 'U': // System V Release 4 small data area reference case 't': // AND masks that can be performed by two rldic{l, r} // instructions case 'W': // Vector constant that does not require memory case 'j': // Vector constant that is all zeros. break; // End FIXME. } return true; } std::string convertConstraint(const char *&Constraint) const override { std::string R; switch (*Constraint) { case 'e': case 'w': // Two-character constraint; add "^" hint for later parsing. R = std::string("^") + std::string(Constraint, 2); Constraint++; break; default: return TargetInfo::convertConstraint(Constraint); } return R; } const char *getClobbers() const override { return ""; } int getEHDataRegisterNumber(unsigned RegNo) const override { if (RegNo == 0) return 3; if (RegNo == 1) return 4; return -1; } bool hasSjLjLowering() const override { return true; } const char *getLongDoubleMangling() const override { if (LongDoubleWidth == 64) return "e"; return LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() ? "g" : "u9__ieee128"; } const char *getFloat128Mangling() const override { return "u9__ieee128"; } }; class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { public: PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { resetDataLayout("E-m:e-p:32:32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; break; case llvm::Triple::AIX: SizeType = UnsignedLong; PtrDiffType = SignedLong; IntPtrType = SignedLong; SuitableAlign = 64; break; default: break; } if (Triple.isOSFreeBSD() || Triple.isOSNetBSD() || Triple.isOSOpenBSD() || Triple.getOS() == llvm::Triple::AIX || Triple.isMusl()) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } // PPC32 supports atomics up to 4 bytes. MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; } BuiltinVaListKind getBuiltinVaListKind() const override { // This is the ELF definition, and is overridden by the Darwin sub-target return TargetInfo::PowerABIBuiltinVaList; } }; // Note: ABI differences may eventually require us to have a separate // TargetInfo for little endian. class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { public: PPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = SignedLong; Int64Type = SignedLong; if (Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) { switch (Triple.getEnvironment()){ case llvm::Triple::ELFv1: ABI = "elfv1"; break; default: ABI = "elfv2"; break; } } else { if ((Triple.getOS() == llvm::Triple::FreeBSD) && (Triple.getOSMajorVersion() < 13)) { ABI = "elfv1"; } else { ABI = "elfv2"; } } if ((Triple.getArch() == llvm::Triple::ppc64le)) { resetDataLayout("e-m:e-i64:64-n32:64"); } else { resetDataLayout("E-m:e-i64:64-n32:64"); } if (Triple.getOS() == llvm::Triple::AIX) SuitableAlign = 64; if (Triple.isOSFreeBSD() || Triple.getOS() == llvm::Triple::AIX || Triple.isMusl()) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } // PPC64 supports atomics up to 8 bytes. MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } // PPC64 Linux-specific ABI options. bool setABI(const std::string &Name) override { if (Name == "elfv1" || Name == "elfv1-qpx" || Name == "elfv2") { ABI = Name; return true; } 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 : public DarwinTargetInfo { public: DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : DarwinTargetInfo(Triple, Opts) { HasAlignMac68kSupport = true; BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 LongLongAlign = 32; resetDataLayout("E-m:o-p:32:32-f64:32:64-n32"); } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } }; class LLVM_LIBRARY_VISIBILITY DarwinPPC64TargetInfo : public DarwinTargetInfo { public: DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : DarwinTargetInfo(Triple, Opts) { HasAlignMac68kSupport = true; resetDataLayout("E-m:o-i64:64-n32:64"); } }; class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo : public AIXTargetInfo { public: using AIXTargetInfo::AIXTargetInfo; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } }; class LLVM_LIBRARY_VISIBILITY AIXPPC64TargetInfo : public AIXTargetInfo { public: using AIXTargetInfo::AIXTargetInfo; }; } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H Index: stable/12/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp =================================================================== --- stable/12/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp (revision 357167) +++ stable/12/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp (revision 357168) @@ -1,157 +1,162 @@ //===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// #include "PPC.h" #include "ToolChains/CommonArgs.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" using namespace clang::driver; using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. std::string ppc::getPPCTargetCPU(const ArgList &Args) { if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { StringRef CPUName = A->getValue(); if (CPUName == "native") { std::string CPU = llvm::sys::getHostCPUName(); if (!CPU.empty() && CPU != "generic") return CPU; else return ""; } return llvm::StringSwitch(CPUName) .Case("common", "generic") .Case("440", "440") .Case("440fp", "440") .Case("450", "450") .Case("601", "601") .Case("602", "602") .Case("603", "603") .Case("603e", "603e") .Case("603ev", "603ev") .Case("604", "604") .Case("604e", "604e") .Case("620", "620") .Case("630", "pwr3") .Case("G3", "g3") .Case("7400", "7400") .Case("G4", "g4") .Case("7450", "7450") .Case("G4+", "g4+") .Case("750", "750") + .Case("8548", "e500") .Case("970", "970") .Case("G5", "g5") .Case("a2", "a2") .Case("a2q", "a2q") + .Case("e500", "e500") .Case("e500mc", "e500mc") .Case("e5500", "e5500") .Case("power3", "pwr3") .Case("power4", "pwr4") .Case("power5", "pwr5") .Case("power5x", "pwr5x") .Case("power6", "pwr6") .Case("power6x", "pwr6x") .Case("power7", "pwr7") .Case("power8", "pwr8") .Case("power9", "pwr9") .Case("pwr3", "pwr3") .Case("pwr4", "pwr4") .Case("pwr5", "pwr5") .Case("pwr5x", "pwr5x") .Case("pwr6", "pwr6") .Case("pwr6x", "pwr6x") .Case("pwr7", "pwr7") .Case("pwr8", "pwr8") .Case("pwr9", "pwr9") .Case("powerpc", "ppc") .Case("powerpc64", "ppc64") .Case("powerpc64le", "ppc64le") .Default(""); } return ""; } const char *ppc::getPPCAsmModeForCPU(StringRef Name) { return llvm::StringSwitch(Name) .Case("pwr7", "-mpower7") .Case("power7", "-mpower7") .Case("pwr8", "-mpower8") .Case("power8", "-mpower8") .Case("ppc64le", "-mpower8") .Case("pwr9", "-mpower9") .Case("power9", "-mpower9") .Default("-many"); } void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector &Features) { + if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe) + Features.push_back("+spe"); + handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group); ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); if (FloatABI == ppc::FloatABI::Soft) Features.push_back("-hard-float"); ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args); if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) Features.push_back("+secure-plt"); } ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) { if (Args.getLastArg(options::OPT_msecure_plt)) return ppc::ReadGOTPtrMode::SecurePlt; if ((Triple.isOSFreeBSD() && Triple.getOSMajorVersion() >= 13) || Triple.isOSNetBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) return ppc::ReadGOTPtrMode::SecurePlt; else return ppc::ReadGOTPtrMode::Bss; } ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) { ppc::FloatABI ABI = ppc::FloatABI::Invalid; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, options::OPT_mfloat_abi_EQ)) { if (A->getOption().matches(options::OPT_msoft_float)) ABI = ppc::FloatABI::Soft; else if (A->getOption().matches(options::OPT_mhard_float)) ABI = ppc::FloatABI::Hard; else { ABI = llvm::StringSwitch(A->getValue()) .Case("soft", ppc::FloatABI::Soft) .Case("hard", ppc::FloatABI::Hard) .Default(ppc::FloatABI::Invalid); if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); ABI = ppc::FloatABI::Hard; } } } // If unspecified, choose the default based on the platform. if (ABI == ppc::FloatABI::Invalid) { ABI = ppc::FloatABI::Hard; } return ABI; } bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) { Arg *A = Args.getLastArg(options::OPT_mabi_EQ); return A && (A->getValue() == StringRef(Value)); } Index: stable/12/contrib/llvm-project/clang =================================================================== --- stable/12/contrib/llvm-project/clang (revision 357167) +++ stable/12/contrib/llvm-project/clang (revision 357168) Property changes on: stable/12/contrib/llvm-project/clang ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/contrib/llvm-project/clang:r356929 Index: stable/12/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h =================================================================== --- stable/12/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h (revision 357167) +++ stable/12/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h (revision 357168) @@ -1,881 +1,883 @@ //===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_TRIPLE_H #define LLVM_ADT_TRIPLE_H #include "llvm/ADT/Twine.h" // Some system headers or GCC predefined macros conflict with identifiers in // this file. Undefine them here. #undef NetBSD #undef mips #undef sparc namespace llvm { /// Triple - Helper class for working with autoconf configuration names. For /// historical reasons, we also call these 'triples' (they used to contain /// exactly three fields). /// /// Configuration names are strings in the canonical form: /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM /// or /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT /// /// This class is used for clients which want to support arbitrary /// configuration names, but also want to implement certain special /// behavior for particular configurations. This class isolates the mapping /// from the components of the configuration name to well known IDs. /// /// At its core the Triple class is designed to be a wrapper for a triple /// string; the constructor does not change or normalize the triple string. /// Clients that need to handle the non-canonical triples that users often /// specify should use the normalize method. /// /// See autoconf/config.guess for a glimpse into what configuration names /// look like in practice. class Triple { public: enum ArchType { UnknownArch, arm, // ARM (little endian): arm, armv.*, xscale armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be aarch64_32, // AArch64 (little endian) ILP32: aarch64_32 arc, // ARC: Synopsys ARC avr, // AVR: Atmel AVR microcontroller bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) hexagon, // Hexagon: hexagon mips, // MIPS: mips, mipsallegrex, mipsr6 mipsel, // MIPSEL: mipsel, mipsallegrexe, mipsr6el mips64, // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6 mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el msp430, // MSP430: msp430 ppc, // PPC: powerpc ppc64, // PPC64: powerpc64, ppu ppc64le, // PPC64LE: powerpc64le r600, // R600: AMD GPUs HD2XXX - HD6XXX amdgcn, // AMDGCN: AMD GCN GPUs riscv32, // RISC-V (32-bit): riscv32 riscv64, // RISC-V (64-bit): riscv64 sparc, // Sparc: sparc sparcv9, // Sparcv9: Sparcv9 sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant systemz, // SystemZ: s390x tce, // TCE (http://tce.cs.tut.fi/): tce tcele, // TCE little endian (http://tce.cs.tut.fi/): tcele thumb, // Thumb (little endian): thumb, thumbv.* thumbeb, // Thumb (big endian): thumbeb x86, // X86: i[3-9]86 x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore nvptx, // NVPTX: 32-bit nvptx64, // NVPTX: 64-bit le32, // le32: generic little-endian 32-bit CPU (PNaCl) le64, // le64: generic little-endian 64-bit CPU (PNaCl) amdil, // AMDIL amdil64, // AMDIL with 64-bit pointers hsail, // AMD HSAIL hsail64, // AMD HSAIL with 64-bit pointers spir, // SPIR: standard portable IR for OpenCL 32-bit version spir64, // SPIR: standard portable IR for OpenCL 64-bit version kalimba, // Kalimba: generic kalimba shave, // SHAVE: Movidius vector VLIW processors lanai, // Lanai: Lanai 32-bit wasm32, // WebAssembly with 32-bit pointers wasm64, // WebAssembly with 64-bit pointers renderscript32, // 32-bit RenderScript renderscript64, // 64-bit RenderScript LastArchType = renderscript64 }; enum SubArchType { NoSubArch, ARMSubArch_v8_5a, ARMSubArch_v8_4a, ARMSubArch_v8_3a, ARMSubArch_v8_2a, ARMSubArch_v8_1a, ARMSubArch_v8, ARMSubArch_v8r, ARMSubArch_v8m_baseline, ARMSubArch_v8m_mainline, ARMSubArch_v8_1m_mainline, ARMSubArch_v7, ARMSubArch_v7em, ARMSubArch_v7m, ARMSubArch_v7s, ARMSubArch_v7k, ARMSubArch_v7ve, ARMSubArch_v6, ARMSubArch_v6m, ARMSubArch_v6k, ARMSubArch_v6t2, ARMSubArch_v5, ARMSubArch_v5te, ARMSubArch_v4t, KalimbaSubArch_v3, KalimbaSubArch_v4, KalimbaSubArch_v5, - MipsSubArch_r6 + MipsSubArch_r6, + + PPCSubArch_spe }; enum VendorType { UnknownVendor, Apple, PC, SCEI, BGP, BGQ, Freescale, IBM, ImaginationTechnologies, MipsTechnologies, NVIDIA, CSR, Myriad, AMD, Mesa, SUSE, OpenEmbedded, LastVendorType = OpenEmbedded }; enum OSType { UnknownOS, Ananas, CloudABI, Darwin, DragonFly, FreeBSD, Fuchsia, IOS, KFreeBSD, Linux, Lv2, // PS3 MacOSX, NetBSD, OpenBSD, Solaris, Win32, Haiku, Minix, RTEMS, NaCl, // Native Client CNK, // BG/P Compute-Node Kernel AIX, CUDA, // NVIDIA CUDA NVCL, // NVIDIA OpenCL AMDHSA, // AMD HSA Runtime PS4, ELFIAMCU, TvOS, // Apple tvOS WatchOS, // Apple watchOS Mesa3D, Contiki, AMDPAL, // AMD PAL Runtime HermitCore, // HermitCore Unikernel/Multikernel Hurd, // GNU/Hurd WASI, // Experimental WebAssembly OS Emscripten, LastOSType = Emscripten }; enum EnvironmentType { UnknownEnvironment, GNU, GNUABIN32, GNUABI64, GNUEABI, GNUEABIHF, GNUX32, CODE16, EABI, EABIHF, ELFv1, ELFv2, Android, Musl, MuslEABI, MuslEABIHF, MSVC, Itanium, Cygnus, CoreCLR, Simulator, // Simulator variants of other systems, e.g., Apple's iOS MacABI, // Mac Catalyst variant of Apple's iOS deployment target. LastEnvironmentType = MacABI }; enum ObjectFormatType { UnknownObjectFormat, COFF, ELF, MachO, Wasm, XCOFF, }; private: std::string Data; /// The parsed arch type. ArchType Arch; /// The parsed subarchitecture type. SubArchType SubArch; /// The parsed vendor type. VendorType Vendor; /// The parsed OS type. OSType OS; /// The parsed Environment type. EnvironmentType Environment; /// The object format type. ObjectFormatType ObjectFormat; public: /// @name Constructors /// @{ /// Default constructor is the same as an empty string and leaves all /// triple fields unknown. Triple() : Data(), Arch(), SubArch(), Vendor(), OS(), Environment(), ObjectFormat() {} explicit Triple(const Twine &Str); Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr); Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, const Twine &EnvironmentStr); bool operator==(const Triple &Other) const { return Arch == Other.Arch && SubArch == Other.SubArch && Vendor == Other.Vendor && OS == Other.OS && Environment == Other.Environment && ObjectFormat == Other.ObjectFormat; } bool operator!=(const Triple &Other) const { return !(*this == Other); } /// @} /// @name Normalization /// @{ /// normalize - Turn an arbitrary machine specification into the canonical /// triple form (or something sensible that the Triple class understands if /// nothing better can reasonably be done). In particular, it handles the /// common case in which otherwise valid components are in the wrong order. static std::string normalize(StringRef Str); /// Return the normalized form of this triple's string. std::string normalize() const { return normalize(Data); } /// @} /// @name Typed Component Access /// @{ /// getArch - Get the parsed architecture type of this triple. ArchType getArch() const { return Arch; } /// getSubArch - get the parsed subarchitecture type for this triple. SubArchType getSubArch() const { return SubArch; } /// getVendor - Get the parsed vendor type of this triple. VendorType getVendor() const { return Vendor; } /// getOS - Get the parsed operating system type of this triple. OSType getOS() const { return OS; } /// hasEnvironment - Does this triple have the optional environment /// (fourth) component? bool hasEnvironment() const { return getEnvironmentName() != ""; } /// getEnvironment - Get the parsed environment type of this triple. EnvironmentType getEnvironment() const { return Environment; } /// Parse the version number from the OS name component of the /// triple, if present. /// /// For example, "fooos1.2.3" would return (1, 2, 3). /// /// If an entry is not defined, it will be returned as 0. void getEnvironmentVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; /// getFormat - Get the object format for this triple. ObjectFormatType getObjectFormat() const { return ObjectFormat; } /// getOSVersion - Parse the version number from the OS name component of the /// triple, if present. /// /// For example, "fooos1.2.3" would return (1, 2, 3). /// /// If an entry is not defined, it will be returned as 0. void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; /// getOSMajorVersion - Return just the major version number, this is /// specialized because it is a common query. unsigned getOSMajorVersion() const { unsigned Maj, Min, Micro; getOSVersion(Maj, Min, Micro); return Maj; } /// getMacOSXVersion - Parse the version number as with getOSVersion and then /// translate generic "darwin" versions to the corresponding OS X versions. /// This may also be called with IOS triples but the OS X version number is /// just set to a constant 10.4.0 in that case. Returns true if successful. bool getMacOSXVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; /// getiOSVersion - Parse the version number as with getOSVersion. This should /// only be called with IOS or generic triples. void getiOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; /// getWatchOSVersion - Parse the version number as with getOSVersion. This /// should only be called with WatchOS or generic triples. void getWatchOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; /// @} /// @name Direct Component Access /// @{ const std::string &str() const { return Data; } const std::string &getTriple() const { return Data; } /// getArchName - Get the architecture (first) component of the /// triple. StringRef getArchName() const; /// getVendorName - Get the vendor (second) component of the triple. StringRef getVendorName() const; /// getOSName - Get the operating system (third) component of the /// triple. StringRef getOSName() const; /// getEnvironmentName - Get the optional environment (fourth) /// component of the triple, or "" if empty. StringRef getEnvironmentName() const; /// getOSAndEnvironmentName - Get the operating system and optional /// environment components as a single string (separated by a '-' /// if the environment component is present). StringRef getOSAndEnvironmentName() const; /// @} /// @name Convenience Predicates /// @{ /// Test whether the architecture is 64-bit /// /// Note that this tests for 64-bit pointer width, and nothing else. Note /// that we intentionally expose only three predicates, 64-bit, 32-bit, and /// 16-bit. The inner details of pointer width for particular architectures /// is not summed up in the triple, and so only a coarse grained predicate /// system is provided. bool isArch64Bit() const; /// Test whether the architecture is 32-bit /// /// Note that this tests for 32-bit pointer width, and nothing else. bool isArch32Bit() const; /// Test whether the architecture is 16-bit /// /// Note that this tests for 16-bit pointer width, and nothing else. bool isArch16Bit() const; /// isOSVersionLT - Helper function for doing comparisons against version /// numbers included in the target triple. bool isOSVersionLT(unsigned Major, unsigned Minor = 0, unsigned Micro = 0) const { unsigned LHS[3]; getOSVersion(LHS[0], LHS[1], LHS[2]); if (LHS[0] != Major) return LHS[0] < Major; if (LHS[1] != Minor) return LHS[1] < Minor; if (LHS[2] != Micro) return LHS[2] < Micro; return false; } bool isOSVersionLT(const Triple &Other) const { unsigned RHS[3]; Other.getOSVersion(RHS[0], RHS[1], RHS[2]); return isOSVersionLT(RHS[0], RHS[1], RHS[2]); } /// isMacOSXVersionLT - Comparison function for checking OS X version /// compatibility, which handles supporting skewed version numbering schemes /// used by the "darwin" triples. bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0, unsigned Micro = 0) const { assert(isMacOSX() && "Not an OS X triple!"); // If this is OS X, expect a sane version number. if (getOS() == Triple::MacOSX) return isOSVersionLT(Major, Minor, Micro); // Otherwise, compare to the "Darwin" number. assert(Major == 10 && "Unexpected major version"); return isOSVersionLT(Minor + 4, Micro, 0); } /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both /// "darwin" and "osx" as OS X triples. bool isMacOSX() const { return getOS() == Triple::Darwin || getOS() == Triple::MacOSX; } /// Is this an iOS triple. /// Note: This identifies tvOS as a variant of iOS. If that ever /// changes, i.e., if the two operating systems diverge or their version /// numbers get out of sync, that will need to be changed. /// watchOS has completely different version numbers so it is not included. bool isiOS() const { return getOS() == Triple::IOS || isTvOS(); } /// Is this an Apple tvOS triple. bool isTvOS() const { return getOS() == Triple::TvOS; } /// Is this an Apple watchOS triple. bool isWatchOS() const { return getOS() == Triple::WatchOS; } bool isWatchABI() const { return getSubArch() == Triple::ARMSubArch_v7k; } /// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS). bool isOSDarwin() const { return isMacOSX() || isiOS() || isWatchOS(); } bool isSimulatorEnvironment() const { return getEnvironment() == Triple::Simulator; } bool isMacCatalystEnvironment() const { return getEnvironment() == Triple::MacABI; } bool isOSNetBSD() const { return getOS() == Triple::NetBSD; } bool isOSOpenBSD() const { return getOS() == Triple::OpenBSD; } bool isOSFreeBSD() const { return getOS() == Triple::FreeBSD; } bool isOSFuchsia() const { return getOS() == Triple::Fuchsia; } bool isOSDragonFly() const { return getOS() == Triple::DragonFly; } bool isOSSolaris() const { return getOS() == Triple::Solaris; } bool isOSIAMCU() const { return getOS() == Triple::ELFIAMCU; } bool isOSUnknown() const { return getOS() == Triple::UnknownOS; } bool isGNUEnvironment() const { EnvironmentType Env = getEnvironment(); return Env == Triple::GNU || Env == Triple::GNUABIN32 || Env == Triple::GNUABI64 || Env == Triple::GNUEABI || Env == Triple::GNUEABIHF || Env == Triple::GNUX32; } bool isOSContiki() const { return getOS() == Triple::Contiki; } /// Tests whether the OS is Haiku. bool isOSHaiku() const { return getOS() == Triple::Haiku; } /// Tests whether the OS is Windows. bool isOSWindows() const { return getOS() == Triple::Win32; } /// Checks if the environment is MSVC. bool isKnownWindowsMSVCEnvironment() const { return isOSWindows() && getEnvironment() == Triple::MSVC; } /// Checks if the environment could be MSVC. bool isWindowsMSVCEnvironment() const { return isKnownWindowsMSVCEnvironment() || (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment); } bool isWindowsCoreCLREnvironment() const { return isOSWindows() && getEnvironment() == Triple::CoreCLR; } bool isWindowsItaniumEnvironment() const { return isOSWindows() && getEnvironment() == Triple::Itanium; } bool isWindowsCygwinEnvironment() const { return isOSWindows() && getEnvironment() == Triple::Cygnus; } bool isWindowsGNUEnvironment() const { return isOSWindows() && getEnvironment() == Triple::GNU; } /// Tests for either Cygwin or MinGW OS bool isOSCygMing() const { return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment(); } /// Is this a "Windows" OS targeting a "MSVCRT.dll" environment. bool isOSMSVCRT() const { return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment() || isWindowsItaniumEnvironment(); } /// Tests whether the OS is NaCl (Native Client) bool isOSNaCl() const { return getOS() == Triple::NaCl; } /// Tests whether the OS is Linux. bool isOSLinux() const { return getOS() == Triple::Linux; } /// Tests whether the OS is kFreeBSD. bool isOSKFreeBSD() const { return getOS() == Triple::KFreeBSD; } /// Tests whether the OS is Hurd. bool isOSHurd() const { return getOS() == Triple::Hurd; } /// Tests whether the OS is WASI. bool isOSWASI() const { return getOS() == Triple::WASI; } /// Tests whether the OS is Emscripten. bool isOSEmscripten() const { return getOS() == Triple::Emscripten; } /// Tests whether the OS uses glibc. bool isOSGlibc() const { return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD || getOS() == Triple::Hurd) && !isAndroid(); } /// Tests whether the OS is AIX. bool isOSAIX() const { return getOS() == Triple::AIX; } /// Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return getObjectFormat() == Triple::ELF; } /// Tests whether the OS uses the COFF binary format. bool isOSBinFormatCOFF() const { return getObjectFormat() == Triple::COFF; } /// Tests whether the environment is MachO. bool isOSBinFormatMachO() const { return getObjectFormat() == Triple::MachO; } /// Tests whether the OS uses the Wasm binary format. bool isOSBinFormatWasm() const { return getObjectFormat() == Triple::Wasm; } /// Tests whether the OS uses the XCOFF binary format. bool isOSBinFormatXCOFF() const { return getObjectFormat() == Triple::XCOFF; } /// Tests whether the target is the PS4 CPU bool isPS4CPU() const { return getArch() == Triple::x86_64 && getVendor() == Triple::SCEI && getOS() == Triple::PS4; } /// Tests whether the target is the PS4 platform bool isPS4() const { return getVendor() == Triple::SCEI && getOS() == Triple::PS4; } /// Tests whether the target is Android bool isAndroid() const { return getEnvironment() == Triple::Android; } bool isAndroidVersionLT(unsigned Major) const { assert(isAndroid() && "Not an Android triple!"); unsigned Env[3]; getEnvironmentVersion(Env[0], Env[1], Env[2]); // 64-bit targets did not exist before API level 21 (Lollipop). if (isArch64Bit() && Env[0] < 21) Env[0] = 21; return Env[0] < Major; } /// Tests whether the environment is musl-libc bool isMusl() const { return getEnvironment() == Triple::Musl || getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::MuslEABIHF; } /// Tests whether the target is SPIR (32- or 64-bit). bool isSPIR() const { return getArch() == Triple::spir || getArch() == Triple::spir64; } /// Tests whether the target is NVPTX (32- or 64-bit). bool isNVPTX() const { return getArch() == Triple::nvptx || getArch() == Triple::nvptx64; } /// Tests whether the target is Thumb (little and big endian). bool isThumb() const { return getArch() == Triple::thumb || getArch() == Triple::thumbeb; } /// Tests whether the target is ARM (little and big endian). bool isARM() const { return getArch() == Triple::arm || getArch() == Triple::armeb; } /// Tests whether the target is AArch64 (little and big endian). bool isAArch64() const { return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be; } /// Tests whether the target is MIPS 32-bit (little and big endian). bool isMIPS32() const { return getArch() == Triple::mips || getArch() == Triple::mipsel; } /// Tests whether the target is MIPS 64-bit (little and big endian). bool isMIPS64() const { return getArch() == Triple::mips64 || getArch() == Triple::mips64el; } /// Tests whether the target is MIPS (little and big endian, 32- or 64-bit). bool isMIPS() const { return isMIPS32() || isMIPS64(); } /// Tests whether the target is 64-bit PowerPC (little and big endian). bool isPPC64() const { return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le; } /// Tests whether the target is RISC-V (32- and 64-bit). bool isRISCV() const { return getArch() == Triple::riscv32 || getArch() == Triple::riscv64; } /// Tests whether the target supports comdat bool supportsCOMDAT() const { return !isOSBinFormatMachO(); } /// Tests whether the target uses emulated TLS as default. bool hasDefaultEmulatedTLS() const { return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); } /// @} /// @name Mutators /// @{ /// setArch - Set the architecture (first) component of the triple /// to a known type. void setArch(ArchType Kind); /// setVendor - Set the vendor (second) component of the triple to a /// known type. void setVendor(VendorType Kind); /// setOS - Set the operating system (third) component of the triple /// to a known type. void setOS(OSType Kind); /// setEnvironment - Set the environment (fourth) component of the triple /// to a known type. void setEnvironment(EnvironmentType Kind); /// setObjectFormat - Set the object file format void setObjectFormat(ObjectFormatType Kind); /// setTriple - Set all components to the new triple \p Str. void setTriple(const Twine &Str); /// setArchName - Set the architecture (first) component of the /// triple by name. void setArchName(StringRef Str); /// setVendorName - Set the vendor (second) component of the triple /// by name. void setVendorName(StringRef Str); /// setOSName - Set the operating system (third) component of the /// triple by name. void setOSName(StringRef Str); /// setEnvironmentName - Set the optional environment (fourth) /// component of the triple by name. void setEnvironmentName(StringRef Str); /// setOSAndEnvironmentName - Set the operating system and optional /// environment components with a single string. void setOSAndEnvironmentName(StringRef Str); /// @} /// @name Helpers to build variants of a particular triple. /// @{ /// Form a triple with a 32-bit variant of the current architecture. /// /// This can be used to move across "families" of architectures where useful. /// /// \returns A new triple with a 32-bit architecture or an unknown /// architecture if no such variant can be found. llvm::Triple get32BitArchVariant() const; /// Form a triple with a 64-bit variant of the current architecture. /// /// This can be used to move across "families" of architectures where useful. /// /// \returns A new triple with a 64-bit architecture or an unknown /// architecture if no such variant can be found. llvm::Triple get64BitArchVariant() const; /// Form a triple with a big endian variant of the current architecture. /// /// This can be used to move across "families" of architectures where useful. /// /// \returns A new triple with a big endian architecture or an unknown /// architecture if no such variant can be found. llvm::Triple getBigEndianArchVariant() const; /// Form a triple with a little endian variant of the current architecture. /// /// This can be used to move across "families" of architectures where useful. /// /// \returns A new triple with a little endian architecture or an unknown /// architecture if no such variant can be found. llvm::Triple getLittleEndianArchVariant() const; /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. /// /// \param Arch the architecture name (e.g., "armv7s"). If it is an empty /// string then the triple's arch name is used. StringRef getARMCPUForArch(StringRef Arch = StringRef()) const; /// Tests whether the target triple is little endian. /// /// \returns true if the triple is little endian, false otherwise. bool isLittleEndian() const; /// Test whether target triples are compatible. bool isCompatibleWith(const Triple &Other) const; /// Merge target triples. std::string merge(const Triple &Other) const; /// @} /// @name Static helpers for IDs. /// @{ /// getArchTypeName - Get the canonical name for the \p Kind architecture. static StringRef getArchTypeName(ArchType Kind); /// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind /// architecture. This is the prefix used by the architecture specific /// builtins, and is suitable for passing to \see /// Intrinsic::getIntrinsicForGCCBuiltin(). /// /// \return - The architecture prefix, or 0 if none is defined. static StringRef getArchTypePrefix(ArchType Kind); /// getVendorTypeName - Get the canonical name for the \p Kind vendor. static StringRef getVendorTypeName(VendorType Kind); /// getOSTypeName - Get the canonical name for the \p Kind operating system. static StringRef getOSTypeName(OSType Kind); /// getEnvironmentTypeName - Get the canonical name for the \p Kind /// environment. static StringRef getEnvironmentTypeName(EnvironmentType Kind); /// @} /// @name Static helpers for converting alternate architecture names. /// @{ /// getArchTypeForLLVMName - The canonical type for the given LLVM /// architecture name (e.g., "x86"). static ArchType getArchTypeForLLVMName(StringRef Str); /// @} }; } // End llvm namespace #endif Index: stable/12/contrib/llvm-project/llvm/lib/Support/Triple.cpp =================================================================== --- stable/12/contrib/llvm-project/llvm/lib/Support/Triple.cpp (revision 357167) +++ stable/12/contrib/llvm-project/llvm/lib/Support/Triple.cpp (revision 357168) @@ -1,1656 +1,1659 @@ //===--- Triple.cpp - Target triple helper class --------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "llvm/ADT/Triple.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetParser.h" #include using namespace llvm; StringRef Triple::getArchTypeName(ArchType Kind) { switch (Kind) { case UnknownArch: return "unknown"; case aarch64: return "aarch64"; case aarch64_be: return "aarch64_be"; case aarch64_32: return "aarch64_32"; case arm: return "arm"; case armeb: return "armeb"; case arc: return "arc"; case avr: return "avr"; case bpfel: return "bpfel"; case bpfeb: return "bpfeb"; case hexagon: return "hexagon"; case mips: return "mips"; case mipsel: return "mipsel"; case mips64: return "mips64"; case mips64el: return "mips64el"; case msp430: return "msp430"; case ppc64: return "powerpc64"; case ppc64le: return "powerpc64le"; case ppc: return "powerpc"; case r600: return "r600"; case amdgcn: return "amdgcn"; case riscv32: return "riscv32"; case riscv64: return "riscv64"; case sparc: return "sparc"; case sparcv9: return "sparcv9"; case sparcel: return "sparcel"; case systemz: return "s390x"; case tce: return "tce"; case tcele: return "tcele"; case thumb: return "thumb"; case thumbeb: return "thumbeb"; case x86: return "i386"; case x86_64: return "x86_64"; case xcore: return "xcore"; case nvptx: return "nvptx"; case nvptx64: return "nvptx64"; case le32: return "le32"; case le64: return "le64"; case amdil: return "amdil"; case amdil64: return "amdil64"; case hsail: return "hsail"; case hsail64: return "hsail64"; case spir: return "spir"; case spir64: return "spir64"; case kalimba: return "kalimba"; case lanai: return "lanai"; case shave: return "shave"; case wasm32: return "wasm32"; case wasm64: return "wasm64"; case renderscript32: return "renderscript32"; case renderscript64: return "renderscript64"; } llvm_unreachable("Invalid ArchType!"); } StringRef Triple::getArchTypePrefix(ArchType Kind) { switch (Kind) { default: return StringRef(); case aarch64: case aarch64_be: case aarch64_32: return "aarch64"; case arc: return "arc"; case arm: case armeb: case thumb: case thumbeb: return "arm"; case avr: return "avr"; case ppc64: case ppc64le: case ppc: return "ppc"; case mips: case mipsel: case mips64: case mips64el: return "mips"; case hexagon: return "hexagon"; case amdgcn: return "amdgcn"; case r600: return "r600"; case bpfel: case bpfeb: return "bpf"; case sparcv9: case sparcel: case sparc: return "sparc"; case systemz: return "s390"; case x86: case x86_64: return "x86"; case xcore: return "xcore"; // NVPTX intrinsics are namespaced under nvvm. case nvptx: return "nvvm"; case nvptx64: return "nvvm"; case le32: return "le32"; case le64: return "le64"; case amdil: case amdil64: return "amdil"; case hsail: case hsail64: return "hsail"; case spir: case spir64: return "spir"; case kalimba: return "kalimba"; case lanai: return "lanai"; case shave: return "shave"; case wasm32: case wasm64: return "wasm"; case riscv32: case riscv64: return "riscv"; } } StringRef Triple::getVendorTypeName(VendorType Kind) { switch (Kind) { case UnknownVendor: return "unknown"; case Apple: return "apple"; case PC: return "pc"; case SCEI: return "scei"; case BGP: return "bgp"; case BGQ: return "bgq"; case Freescale: return "fsl"; case IBM: return "ibm"; case ImaginationTechnologies: return "img"; case MipsTechnologies: return "mti"; case NVIDIA: return "nvidia"; case CSR: return "csr"; case Myriad: return "myriad"; case AMD: return "amd"; case Mesa: return "mesa"; case SUSE: return "suse"; case OpenEmbedded: return "oe"; } llvm_unreachable("Invalid VendorType!"); } StringRef Triple::getOSTypeName(OSType Kind) { switch (Kind) { case UnknownOS: return "unknown"; case Ananas: return "ananas"; case CloudABI: return "cloudabi"; case Darwin: return "darwin"; case DragonFly: return "dragonfly"; case FreeBSD: return "freebsd"; case Fuchsia: return "fuchsia"; case IOS: return "ios"; case KFreeBSD: return "kfreebsd"; case Linux: return "linux"; case Lv2: return "lv2"; case MacOSX: return "macosx"; case NetBSD: return "netbsd"; case OpenBSD: return "openbsd"; case Solaris: return "solaris"; case Win32: return "windows"; case Haiku: return "haiku"; case Minix: return "minix"; case RTEMS: return "rtems"; case NaCl: return "nacl"; case CNK: return "cnk"; case AIX: return "aix"; case CUDA: return "cuda"; case NVCL: return "nvcl"; case AMDHSA: return "amdhsa"; case PS4: return "ps4"; case ELFIAMCU: return "elfiamcu"; case TvOS: return "tvos"; case WatchOS: return "watchos"; case Mesa3D: return "mesa3d"; case Contiki: return "contiki"; case AMDPAL: return "amdpal"; case HermitCore: return "hermit"; case Hurd: return "hurd"; case WASI: return "wasi"; case Emscripten: return "emscripten"; } llvm_unreachable("Invalid OSType"); } StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { switch (Kind) { case UnknownEnvironment: return "unknown"; case GNU: return "gnu"; case GNUABIN32: return "gnuabin32"; case GNUABI64: return "gnuabi64"; case GNUEABIHF: return "gnueabihf"; case GNUEABI: return "gnueabi"; case GNUX32: return "gnux32"; case CODE16: return "code16"; case EABI: return "eabi"; case EABIHF: return "eabihf"; case ELFv1: return "elfv1"; case ELFv2: return "elfv2"; case Android: return "android"; case Musl: return "musl"; case MuslEABI: return "musleabi"; case MuslEABIHF: return "musleabihf"; case MSVC: return "msvc"; case Itanium: return "itanium"; case Cygnus: return "cygnus"; case CoreCLR: return "coreclr"; case Simulator: return "simulator"; case MacABI: return "macabi"; } llvm_unreachable("Invalid EnvironmentType!"); } static Triple::ArchType parseBPFArch(StringRef ArchName) { if (ArchName.equals("bpf")) { if (sys::IsLittleEndianHost) return Triple::bpfel; else return Triple::bpfeb; } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) { return Triple::bpfeb; } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) { return Triple::bpfel; } else { return Triple::UnknownArch; } } Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { Triple::ArchType BPFArch(parseBPFArch(Name)); return StringSwitch(Name) .Case("aarch64", aarch64) .Case("aarch64_be", aarch64_be) .Case("aarch64_32", aarch64_32) .Case("arc", arc) .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" .Case("arm64_32", aarch64_32) .Case("arm", arm) .Case("armeb", armeb) .Case("avr", avr) .StartsWith("bpf", BPFArch) .Case("mips", mips) .Case("mipsel", mipsel) .Case("mips64", mips64) .Case("mips64el", mips64el) .Case("msp430", msp430) .Case("ppc64", ppc64) .Case("ppc32", ppc) .Case("ppc", ppc) .Case("ppc64le", ppc64le) .Case("r600", r600) .Case("amdgcn", amdgcn) .Case("riscv32", riscv32) .Case("riscv64", riscv64) .Case("hexagon", hexagon) .Case("sparc", sparc) .Case("sparcel", sparcel) .Case("sparcv9", sparcv9) .Case("systemz", systemz) .Case("tce", tce) .Case("tcele", tcele) .Case("thumb", thumb) .Case("thumbeb", thumbeb) .Case("x86", x86) .Case("x86-64", x86_64) .Case("xcore", xcore) .Case("nvptx", nvptx) .Case("nvptx64", nvptx64) .Case("le32", le32) .Case("le64", le64) .Case("amdil", amdil) .Case("amdil64", amdil64) .Case("hsail", hsail) .Case("hsail64", hsail64) .Case("spir", spir) .Case("spir64", spir64) .Case("kalimba", kalimba) .Case("lanai", lanai) .Case("shave", shave) .Case("wasm32", wasm32) .Case("wasm64", wasm64) .Case("renderscript32", renderscript32) .Case("renderscript64", renderscript64) .Default(UnknownArch); } static Triple::ArchType parseARMArch(StringRef ArchName) { ARM::ISAKind ISA = ARM::parseArchISA(ArchName); ARM::EndianKind ENDIAN = ARM::parseArchEndian(ArchName); Triple::ArchType arch = Triple::UnknownArch; switch (ENDIAN) { case ARM::EndianKind::LITTLE: { switch (ISA) { case ARM::ISAKind::ARM: arch = Triple::arm; break; case ARM::ISAKind::THUMB: arch = Triple::thumb; break; case ARM::ISAKind::AARCH64: arch = Triple::aarch64; break; case ARM::ISAKind::INVALID: break; } break; } case ARM::EndianKind::BIG: { switch (ISA) { case ARM::ISAKind::ARM: arch = Triple::armeb; break; case ARM::ISAKind::THUMB: arch = Triple::thumbeb; break; case ARM::ISAKind::AARCH64: arch = Triple::aarch64_be; break; case ARM::ISAKind::INVALID: break; } break; } case ARM::EndianKind::INVALID: { break; } } ArchName = ARM::getCanonicalArchName(ArchName); if (ArchName.empty()) return Triple::UnknownArch; // Thumb only exists in v4+ if (ISA == ARM::ISAKind::THUMB && (ArchName.startswith("v2") || ArchName.startswith("v3"))) return Triple::UnknownArch; // Thumb only for v6m ARM::ProfileKind Profile = ARM::parseArchProfile(ArchName); unsigned Version = ARM::parseArchVersion(ArchName); if (Profile == ARM::ProfileKind::M && Version == 6) { if (ENDIAN == ARM::EndianKind::BIG) return Triple::thumbeb; else return Triple::thumb; } return arch; } static Triple::ArchType parseArch(StringRef ArchName) { auto AT = StringSwitch(ArchName) .Cases("i386", "i486", "i586", "i686", Triple::x86) // FIXME: Do we need to support these? .Cases("i786", "i886", "i986", Triple::x86) .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) - .Cases("powerpc", "ppc", "ppc32", Triple::ppc) + .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc) .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64) .Cases("powerpc64le", "ppc64le", Triple::ppc64le) .Case("xscale", Triple::arm) .Case("xscaleeb", Triple::armeb) .Case("aarch64", Triple::aarch64) .Case("aarch64_be", Triple::aarch64_be) .Case("aarch64_32", Triple::aarch64_32) .Case("arc", Triple::arc) .Case("arm64", Triple::aarch64) .Case("arm64_32", Triple::aarch64_32) .Case("arm", Triple::arm) .Case("armeb", Triple::armeb) .Case("thumb", Triple::thumb) .Case("thumbeb", Triple::thumbeb) .Case("avr", Triple::avr) .Case("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6", "mipsr6", Triple::mips) .Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el", Triple::mipsel) .Cases("mips64", "mips64eb", "mipsn32", "mipsisa64r6", "mips64r6", "mipsn32r6", Triple::mips64) .Cases("mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el", "mipsn32r6el", Triple::mips64el) .Case("r600", Triple::r600) .Case("amdgcn", Triple::amdgcn) .Case("riscv32", Triple::riscv32) .Case("riscv64", Triple::riscv64) .Case("hexagon", Triple::hexagon) .Cases("s390x", "systemz", Triple::systemz) .Case("sparc", Triple::sparc) .Case("sparcel", Triple::sparcel) .Cases("sparcv9", "sparc64", Triple::sparcv9) .Case("tce", Triple::tce) .Case("tcele", Triple::tcele) .Case("xcore", Triple::xcore) .Case("nvptx", Triple::nvptx) .Case("nvptx64", Triple::nvptx64) .Case("le32", Triple::le32) .Case("le64", Triple::le64) .Case("amdil", Triple::amdil) .Case("amdil64", Triple::amdil64) .Case("hsail", Triple::hsail) .Case("hsail64", Triple::hsail64) .Case("spir", Triple::spir) .Case("spir64", Triple::spir64) .StartsWith("kalimba", Triple::kalimba) .Case("lanai", Triple::lanai) .Case("shave", Triple::shave) .Case("wasm32", Triple::wasm32) .Case("wasm64", Triple::wasm64) .Case("renderscript32", Triple::renderscript32) .Case("renderscript64", Triple::renderscript64) .Default(Triple::UnknownArch); // Some architectures require special parsing logic just to compute the // ArchType result. if (AT == Triple::UnknownArch) { if (ArchName.startswith("arm") || ArchName.startswith("thumb") || ArchName.startswith("aarch64")) return parseARMArch(ArchName); if (ArchName.startswith("bpf")) return parseBPFArch(ArchName); } return AT; } static Triple::VendorType parseVendor(StringRef VendorName) { return StringSwitch(VendorName) .Case("apple", Triple::Apple) .Case("pc", Triple::PC) .Case("scei", Triple::SCEI) .Case("bgp", Triple::BGP) .Case("bgq", Triple::BGQ) .Case("fsl", Triple::Freescale) .Case("ibm", Triple::IBM) .Case("img", Triple::ImaginationTechnologies) .Case("mti", Triple::MipsTechnologies) .Case("nvidia", Triple::NVIDIA) .Case("csr", Triple::CSR) .Case("myriad", Triple::Myriad) .Case("amd", Triple::AMD) .Case("mesa", Triple::Mesa) .Case("suse", Triple::SUSE) .Case("oe", Triple::OpenEmbedded) .Default(Triple::UnknownVendor); } static Triple::OSType parseOS(StringRef OSName) { return StringSwitch(OSName) .StartsWith("ananas", Triple::Ananas) .StartsWith("cloudabi", Triple::CloudABI) .StartsWith("darwin", Triple::Darwin) .StartsWith("dragonfly", Triple::DragonFly) .StartsWith("freebsd", Triple::FreeBSD) .StartsWith("fuchsia", Triple::Fuchsia) .StartsWith("ios", Triple::IOS) .StartsWith("kfreebsd", Triple::KFreeBSD) .StartsWith("linux", Triple::Linux) .StartsWith("lv2", Triple::Lv2) .StartsWith("macos", Triple::MacOSX) .StartsWith("netbsd", Triple::NetBSD) .StartsWith("openbsd", Triple::OpenBSD) .StartsWith("solaris", Triple::Solaris) .StartsWith("win32", Triple::Win32) .StartsWith("windows", Triple::Win32) .StartsWith("haiku", Triple::Haiku) .StartsWith("minix", Triple::Minix) .StartsWith("rtems", Triple::RTEMS) .StartsWith("nacl", Triple::NaCl) .StartsWith("cnk", Triple::CNK) .StartsWith("aix", Triple::AIX) .StartsWith("cuda", Triple::CUDA) .StartsWith("nvcl", Triple::NVCL) .StartsWith("amdhsa", Triple::AMDHSA) .StartsWith("ps4", Triple::PS4) .StartsWith("elfiamcu", Triple::ELFIAMCU) .StartsWith("tvos", Triple::TvOS) .StartsWith("watchos", Triple::WatchOS) .StartsWith("mesa3d", Triple::Mesa3D) .StartsWith("contiki", Triple::Contiki) .StartsWith("amdpal", Triple::AMDPAL) .StartsWith("hermit", Triple::HermitCore) .StartsWith("hurd", Triple::Hurd) .StartsWith("wasi", Triple::WASI) .StartsWith("emscripten", Triple::Emscripten) .Default(Triple::UnknownOS); } static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { return StringSwitch(EnvironmentName) .StartsWith("eabihf", Triple::EABIHF) .StartsWith("eabi", Triple::EABI) .StartsWith("elfv1", Triple::ELFv1) .StartsWith("elfv2", Triple::ELFv2) .StartsWith("gnuabin32", Triple::GNUABIN32) .StartsWith("gnuabi64", Triple::GNUABI64) .StartsWith("gnueabihf", Triple::GNUEABIHF) .StartsWith("gnueabi", Triple::GNUEABI) .StartsWith("gnux32", Triple::GNUX32) .StartsWith("code16", Triple::CODE16) .StartsWith("gnu", Triple::GNU) .StartsWith("android", Triple::Android) .StartsWith("musleabihf", Triple::MuslEABIHF) .StartsWith("musleabi", Triple::MuslEABI) .StartsWith("musl", Triple::Musl) .StartsWith("msvc", Triple::MSVC) .StartsWith("itanium", Triple::Itanium) .StartsWith("cygnus", Triple::Cygnus) .StartsWith("coreclr", Triple::CoreCLR) .StartsWith("simulator", Triple::Simulator) .StartsWith("macabi", Triple::MacABI) .Default(Triple::UnknownEnvironment); } static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { return StringSwitch(EnvironmentName) // "xcoff" must come before "coff" because of the order-dependendent // pattern matching. .EndsWith("xcoff", Triple::XCOFF) .EndsWith("coff", Triple::COFF) .EndsWith("elf", Triple::ELF) .EndsWith("macho", Triple::MachO) .EndsWith("wasm", Triple::Wasm) .Default(Triple::UnknownObjectFormat); } static Triple::SubArchType parseSubArch(StringRef SubArchName) { if (SubArchName.startswith("mips") && (SubArchName.endswith("r6el") || SubArchName.endswith("r6"))) return Triple::MipsSubArch_r6; + + if (SubArchName == "powerpcspe") + return Triple::PPCSubArch_spe; StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName); // For now, this is the small part. Early return. if (ARMSubArch.empty()) return StringSwitch(SubArchName) .EndsWith("kalimba3", Triple::KalimbaSubArch_v3) .EndsWith("kalimba4", Triple::KalimbaSubArch_v4) .EndsWith("kalimba5", Triple::KalimbaSubArch_v5) .Default(Triple::NoSubArch); // ARM sub arch. switch(ARM::parseArch(ARMSubArch)) { case ARM::ArchKind::ARMV4: return Triple::NoSubArch; case ARM::ArchKind::ARMV4T: return Triple::ARMSubArch_v4t; case ARM::ArchKind::ARMV5T: return Triple::ARMSubArch_v5; case ARM::ArchKind::ARMV5TE: case ARM::ArchKind::IWMMXT: case ARM::ArchKind::IWMMXT2: case ARM::ArchKind::XSCALE: case ARM::ArchKind::ARMV5TEJ: return Triple::ARMSubArch_v5te; case ARM::ArchKind::ARMV6: return Triple::ARMSubArch_v6; case ARM::ArchKind::ARMV6K: case ARM::ArchKind::ARMV6KZ: return Triple::ARMSubArch_v6k; case ARM::ArchKind::ARMV6T2: return Triple::ARMSubArch_v6t2; case ARM::ArchKind::ARMV6M: return Triple::ARMSubArch_v6m; case ARM::ArchKind::ARMV7A: case ARM::ArchKind::ARMV7R: return Triple::ARMSubArch_v7; case ARM::ArchKind::ARMV7VE: return Triple::ARMSubArch_v7ve; case ARM::ArchKind::ARMV7K: return Triple::ARMSubArch_v7k; case ARM::ArchKind::ARMV7M: return Triple::ARMSubArch_v7m; case ARM::ArchKind::ARMV7S: return Triple::ARMSubArch_v7s; case ARM::ArchKind::ARMV7EM: return Triple::ARMSubArch_v7em; case ARM::ArchKind::ARMV8A: return Triple::ARMSubArch_v8; case ARM::ArchKind::ARMV8_1A: return Triple::ARMSubArch_v8_1a; case ARM::ArchKind::ARMV8_2A: return Triple::ARMSubArch_v8_2a; case ARM::ArchKind::ARMV8_3A: return Triple::ARMSubArch_v8_3a; case ARM::ArchKind::ARMV8_4A: return Triple::ARMSubArch_v8_4a; case ARM::ArchKind::ARMV8_5A: return Triple::ARMSubArch_v8_5a; case ARM::ArchKind::ARMV8R: return Triple::ARMSubArch_v8r; case ARM::ArchKind::ARMV8MBaseline: return Triple::ARMSubArch_v8m_baseline; case ARM::ArchKind::ARMV8MMainline: return Triple::ARMSubArch_v8m_mainline; case ARM::ArchKind::ARMV8_1MMainline: return Triple::ARMSubArch_v8_1m_mainline; default: return Triple::NoSubArch; } } static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) { switch (Kind) { case Triple::UnknownObjectFormat: return ""; case Triple::COFF: return "coff"; case Triple::ELF: return "elf"; case Triple::MachO: return "macho"; case Triple::Wasm: return "wasm"; case Triple::XCOFF: return "xcoff"; } llvm_unreachable("unknown object format type"); } static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { switch (T.getArch()) { case Triple::UnknownArch: case Triple::aarch64: case Triple::aarch64_32: case Triple::arm: case Triple::thumb: case Triple::x86: case Triple::x86_64: if (T.isOSDarwin()) return Triple::MachO; else if (T.isOSWindows()) return Triple::COFF; return Triple::ELF; case Triple::aarch64_be: case Triple::arc: case Triple::amdgcn: case Triple::amdil: case Triple::amdil64: case Triple::armeb: case Triple::avr: case Triple::bpfeb: case Triple::bpfel: case Triple::hexagon: case Triple::lanai: case Triple::hsail: case Triple::hsail64: case Triple::kalimba: case Triple::le32: case Triple::le64: case Triple::mips: case Triple::mips64: case Triple::mips64el: case Triple::mipsel: case Triple::msp430: case Triple::nvptx: case Triple::nvptx64: case Triple::ppc64le: case Triple::r600: case Triple::renderscript32: case Triple::renderscript64: case Triple::riscv32: case Triple::riscv64: case Triple::shave: case Triple::sparc: case Triple::sparcel: case Triple::sparcv9: case Triple::spir: case Triple::spir64: case Triple::systemz: case Triple::tce: case Triple::tcele: case Triple::thumbeb: case Triple::xcore: return Triple::ELF; case Triple::ppc: case Triple::ppc64: if (T.isOSDarwin()) return Triple::MachO; else if (T.isOSAIX()) return Triple::XCOFF; return Triple::ELF; case Triple::wasm32: case Triple::wasm64: return Triple::Wasm; } llvm_unreachable("unknown architecture"); } /// Construct a triple from the string representation provided. /// /// This stores the string representation and parses the various pieces into /// enum members. Triple::Triple(const Twine &Str) : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch), Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment), ObjectFormat(UnknownObjectFormat) { // Do minimal parsing by hand here. SmallVector Components; StringRef(Data).split(Components, '-', /*MaxSplit*/ 3); if (Components.size() > 0) { Arch = parseArch(Components[0]); SubArch = parseSubArch(Components[0]); if (Components.size() > 1) { Vendor = parseVendor(Components[1]); if (Components.size() > 2) { OS = parseOS(Components[2]); if (Components.size() > 3) { Environment = parseEnvironment(Components[3]); ObjectFormat = parseFormat(Components[3]); } } } else { Environment = StringSwitch(Components[0]) .StartsWith("mipsn32", Triple::GNUABIN32) .StartsWith("mips64", Triple::GNUABI64) .StartsWith("mipsisa64", Triple::GNUABI64) .StartsWith("mipsisa32", Triple::GNU) .Cases("mips", "mipsel", "mipsr6", "mipsr6el", Triple::GNU) .Default(UnknownEnvironment); } } if (ObjectFormat == UnknownObjectFormat) ObjectFormat = getDefaultFormat(*this); } /// Construct a triple from string representations of the architecture, /// vendor, and OS. /// /// This joins each argument into a canonical string representation and parses /// them into enum members. It leaves the environment unknown and omits it from /// the string representation. Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), Arch(parseArch(ArchStr.str())), SubArch(parseSubArch(ArchStr.str())), Vendor(parseVendor(VendorStr.str())), OS(parseOS(OSStr.str())), Environment(), ObjectFormat(Triple::UnknownObjectFormat) { ObjectFormat = getDefaultFormat(*this); } /// Construct a triple from string representations of the architecture, /// vendor, OS, and environment. /// /// This joins each argument into a canonical string representation and parses /// them into enum members. Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, const Twine &EnvironmentStr) : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + EnvironmentStr).str()), Arch(parseArch(ArchStr.str())), SubArch(parseSubArch(ArchStr.str())), Vendor(parseVendor(VendorStr.str())), OS(parseOS(OSStr.str())), Environment(parseEnvironment(EnvironmentStr.str())), ObjectFormat(parseFormat(EnvironmentStr.str())) { if (ObjectFormat == Triple::UnknownObjectFormat) ObjectFormat = getDefaultFormat(*this); } std::string Triple::normalize(StringRef Str) { bool IsMinGW32 = false; bool IsCygwin = false; // Parse into components. SmallVector Components; Str.split(Components, '-'); // If the first component corresponds to a known architecture, preferentially // use it for the architecture. If the second component corresponds to a // known vendor, preferentially use it for the vendor, etc. This avoids silly // component movement when a component parses as (eg) both a valid arch and a // valid os. ArchType Arch = UnknownArch; if (Components.size() > 0) Arch = parseArch(Components[0]); VendorType Vendor = UnknownVendor; if (Components.size() > 1) Vendor = parseVendor(Components[1]); OSType OS = UnknownOS; if (Components.size() > 2) { OS = parseOS(Components[2]); IsCygwin = Components[2].startswith("cygwin"); IsMinGW32 = Components[2].startswith("mingw"); } EnvironmentType Environment = UnknownEnvironment; if (Components.size() > 3) Environment = parseEnvironment(Components[3]); ObjectFormatType ObjectFormat = UnknownObjectFormat; if (Components.size() > 4) ObjectFormat = parseFormat(Components[4]); // Note which components are already in their final position. These will not // be moved. bool Found[4]; Found[0] = Arch != UnknownArch; Found[1] = Vendor != UnknownVendor; Found[2] = OS != UnknownOS; Found[3] = Environment != UnknownEnvironment; // If they are not there already, permute the components into their canonical // positions by seeing if they parse as a valid architecture, and if so moving // the component to the architecture position etc. for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { if (Found[Pos]) continue; // Already in the canonical position. for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { // Do not reparse any components that already matched. if (Idx < array_lengthof(Found) && Found[Idx]) continue; // Does this component parse as valid for the target position? bool Valid = false; StringRef Comp = Components[Idx]; switch (Pos) { default: llvm_unreachable("unexpected component type!"); case 0: Arch = parseArch(Comp); Valid = Arch != UnknownArch; break; case 1: Vendor = parseVendor(Comp); Valid = Vendor != UnknownVendor; break; case 2: OS = parseOS(Comp); IsCygwin = Comp.startswith("cygwin"); IsMinGW32 = Comp.startswith("mingw"); Valid = OS != UnknownOS || IsCygwin || IsMinGW32; break; case 3: Environment = parseEnvironment(Comp); Valid = Environment != UnknownEnvironment; if (!Valid) { ObjectFormat = parseFormat(Comp); Valid = ObjectFormat != UnknownObjectFormat; } break; } if (!Valid) continue; // Nope, try the next component. // Move the component to the target position, pushing any non-fixed // components that are in the way to the right. This tends to give // good results in the common cases of a forgotten vendor component // or a wrongly positioned environment. if (Pos < Idx) { // Insert left, pushing the existing components to the right. For // example, a-b-i386 -> i386-a-b when moving i386 to the front. StringRef CurrentComponent(""); // The empty component. // Replace the component we are moving with an empty component. std::swap(CurrentComponent, Components[Idx]); // Insert the component being moved at Pos, displacing any existing // components to the right. for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { // Skip over any fixed components. while (i < array_lengthof(Found) && Found[i]) ++i; // Place the component at the new position, getting the component // that was at this position - it will be moved right. std::swap(CurrentComponent, Components[i]); } } else if (Pos > Idx) { // Push right by inserting empty components until the component at Idx // reaches the target position Pos. For example, pc-a -> -pc-a when // moving pc to the second position. do { // Insert one empty component at Idx. StringRef CurrentComponent(""); // The empty component. for (unsigned i = Idx; i < Components.size();) { // Place the component at the new position, getting the component // that was at this position - it will be moved right. std::swap(CurrentComponent, Components[i]); // If it was placed on top of an empty component then we are done. if (CurrentComponent.empty()) break; // Advance to the next component, skipping any fixed components. while (++i < array_lengthof(Found) && Found[i]) ; } // The last component was pushed off the end - append it. if (!CurrentComponent.empty()) Components.push_back(CurrentComponent); // Advance Idx to the component's new position. while (++Idx < array_lengthof(Found) && Found[Idx]) ; } while (Idx < Pos); // Add more until the final position is reached. } assert(Pos < Components.size() && Components[Pos] == Comp && "Component moved wrong!"); Found[Pos] = true; break; } } // Replace empty components with "unknown" value. for (unsigned i = 0, e = Components.size(); i < e; ++i) { if (Components[i].empty()) Components[i] = "unknown"; } // Special case logic goes here. At this point Arch, Vendor and OS have the // correct values for the computed components. std::string NormalizedEnvironment; if (Environment == Triple::Android && Components[3].startswith("androideabi")) { StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi")); if (AndroidVersion.empty()) { Components[3] = "android"; } else { NormalizedEnvironment = Twine("android", AndroidVersion).str(); Components[3] = NormalizedEnvironment; } } // SUSE uses "gnueabi" to mean "gnueabihf" if (Vendor == Triple::SUSE && Environment == llvm::Triple::GNUEABI) Components[3] = "gnueabihf"; if (OS == Triple::Win32) { Components.resize(4); Components[2] = "windows"; if (Environment == UnknownEnvironment) { if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF) Components[3] = "msvc"; else Components[3] = getObjectFormatTypeName(ObjectFormat); } } else if (IsMinGW32) { Components.resize(4); Components[2] = "windows"; Components[3] = "gnu"; } else if (IsCygwin) { Components.resize(4); Components[2] = "windows"; Components[3] = "cygnus"; } if (IsMinGW32 || IsCygwin || (OS == Triple::Win32 && Environment != UnknownEnvironment)) { if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) { Components.resize(5); Components[4] = getObjectFormatTypeName(ObjectFormat); } } // Stick the corrected components back together to form the normalized string. std::string Normalized; for (unsigned i = 0, e = Components.size(); i != e; ++i) { if (i) Normalized += '-'; Normalized += Components[i]; } return Normalized; } StringRef Triple::getArchName() const { return StringRef(Data).split('-').first; // Isolate first component } StringRef Triple::getVendorName() const { StringRef Tmp = StringRef(Data).split('-').second; // Strip first component return Tmp.split('-').first; // Isolate second component } StringRef Triple::getOSName() const { StringRef Tmp = StringRef(Data).split('-').second; // Strip first component Tmp = Tmp.split('-').second; // Strip second component return Tmp.split('-').first; // Isolate third component } StringRef Triple::getEnvironmentName() const { StringRef Tmp = StringRef(Data).split('-').second; // Strip first component Tmp = Tmp.split('-').second; // Strip second component return Tmp.split('-').second; // Strip third component } StringRef Triple::getOSAndEnvironmentName() const { StringRef Tmp = StringRef(Data).split('-').second; // Strip first component return Tmp.split('-').second; // Strip second component } static unsigned EatNumber(StringRef &Str) { assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); unsigned Result = 0; do { // Consume the leading digit. Result = Result*10 + (Str[0] - '0'); // Eat the digit. Str = Str.substr(1); } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); return Result; } static void parseVersionFromName(StringRef Name, unsigned &Major, unsigned &Minor, unsigned &Micro) { // Any unset version defaults to 0. Major = Minor = Micro = 0; // Parse up to three components. unsigned *Components[3] = {&Major, &Minor, &Micro}; for (unsigned i = 0; i != 3; ++i) { if (Name.empty() || Name[0] < '0' || Name[0] > '9') break; // Consume the leading number. *Components[i] = EatNumber(Name); // Consume the separator, if present. if (Name.startswith(".")) Name = Name.substr(1); } } void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { StringRef EnvironmentName = getEnvironmentName(); StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment()); if (EnvironmentName.startswith(EnvironmentTypeName)) EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size()); parseVersionFromName(EnvironmentName, Major, Minor, Micro); } void Triple::getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { StringRef OSName = getOSName(); // Assume that the OS portion of the triple starts with the canonical name. StringRef OSTypeName = getOSTypeName(getOS()); if (OSName.startswith(OSTypeName)) OSName = OSName.substr(OSTypeName.size()); else if (getOS() == MacOSX) OSName.consume_front("macos"); parseVersionFromName(OSName, Major, Minor, Micro); } bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { getOSVersion(Major, Minor, Micro); switch (getOS()) { default: llvm_unreachable("unexpected OS for Darwin triple"); case Darwin: // Default to darwin8, i.e., MacOSX 10.4. if (Major == 0) Major = 8; // Darwin version numbers are skewed from OS X versions. if (Major < 4) return false; Micro = 0; Minor = Major - 4; Major = 10; break; case MacOSX: // Default to 10.4. if (Major == 0) { Major = 10; Minor = 4; } if (Major != 10) return false; break; case IOS: case TvOS: case WatchOS: // Ignore the version from the triple. This is only handled because the // the clang driver combines OS X and IOS support into a common Darwin // toolchain that wants to know the OS X version number even when targeting // IOS. Major = 10; Minor = 4; Micro = 0; break; } return true; } void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { switch (getOS()) { default: llvm_unreachable("unexpected OS for Darwin triple"); case Darwin: case MacOSX: // Ignore the version from the triple. This is only handled because the // the clang driver combines OS X and IOS support into a common Darwin // toolchain that wants to know the iOS version number even when targeting // OS X. Major = 5; Minor = 0; Micro = 0; break; case IOS: case TvOS: getOSVersion(Major, Minor, Micro); // Default to 5.0 (or 7.0 for arm64). if (Major == 0) Major = (getArch() == aarch64) ? 7 : 5; break; case WatchOS: llvm_unreachable("conflicting triple info"); } } void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { switch (getOS()) { default: llvm_unreachable("unexpected OS for Darwin triple"); case Darwin: case MacOSX: // Ignore the version from the triple. This is only handled because the // the clang driver combines OS X and IOS support into a common Darwin // toolchain that wants to know the iOS version number even when targeting // OS X. Major = 2; Minor = 0; Micro = 0; break; case WatchOS: getOSVersion(Major, Minor, Micro); if (Major == 0) Major = 2; break; case IOS: llvm_unreachable("conflicting triple info"); } } void Triple::setTriple(const Twine &Str) { *this = Triple(Str); } void Triple::setArch(ArchType Kind) { setArchName(getArchTypeName(Kind)); } void Triple::setVendor(VendorType Kind) { setVendorName(getVendorTypeName(Kind)); } void Triple::setOS(OSType Kind) { setOSName(getOSTypeName(Kind)); } void Triple::setEnvironment(EnvironmentType Kind) { if (ObjectFormat == getDefaultFormat(*this)) return setEnvironmentName(getEnvironmentTypeName(Kind)); setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") + getObjectFormatTypeName(ObjectFormat)).str()); } void Triple::setObjectFormat(ObjectFormatType Kind) { if (Environment == UnknownEnvironment) return setEnvironmentName(getObjectFormatTypeName(Kind)); setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + getObjectFormatTypeName(Kind)).str()); } void Triple::setArchName(StringRef Str) { // Work around a miscompilation bug for Twines in gcc 4.0.3. SmallString<64> Triple; Triple += Str; Triple += "-"; Triple += getVendorName(); Triple += "-"; Triple += getOSAndEnvironmentName(); setTriple(Triple); } void Triple::setVendorName(StringRef Str) { setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); } void Triple::setOSName(StringRef Str) { if (hasEnvironment()) setTriple(getArchName() + "-" + getVendorName() + "-" + Str + "-" + getEnvironmentName()); else setTriple(getArchName() + "-" + getVendorName() + "-" + Str); } void Triple::setEnvironmentName(StringRef Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + "-" + Str); } void Triple::setOSAndEnvironmentName(StringRef Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + Str); } static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { switch (Arch) { case llvm::Triple::UnknownArch: return 0; case llvm::Triple::avr: case llvm::Triple::msp430: return 16; case llvm::Triple::aarch64_32: case llvm::Triple::arc: case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::hexagon: case llvm::Triple::le32: case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::nvptx: case llvm::Triple::ppc: case llvm::Triple::r600: case llvm::Triple::riscv32: case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::tce: case llvm::Triple::tcele: case llvm::Triple::thumb: case llvm::Triple::thumbeb: case llvm::Triple::x86: case llvm::Triple::xcore: case llvm::Triple::amdil: case llvm::Triple::hsail: case llvm::Triple::spir: case llvm::Triple::kalimba: case llvm::Triple::lanai: case llvm::Triple::shave: case llvm::Triple::wasm32: case llvm::Triple::renderscript32: return 32; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::amdgcn: case llvm::Triple::bpfel: case llvm::Triple::bpfeb: case llvm::Triple::le64: case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::nvptx64: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: case llvm::Triple::riscv64: case llvm::Triple::sparcv9: case llvm::Triple::systemz: case llvm::Triple::x86_64: case llvm::Triple::amdil64: case llvm::Triple::hsail64: case llvm::Triple::spir64: case llvm::Triple::wasm64: case llvm::Triple::renderscript64: return 64; } llvm_unreachable("Invalid architecture value"); } bool Triple::isArch64Bit() const { return getArchPointerBitWidth(getArch()) == 64; } bool Triple::isArch32Bit() const { return getArchPointerBitWidth(getArch()) == 32; } bool Triple::isArch16Bit() const { return getArchPointerBitWidth(getArch()) == 16; } Triple Triple::get32BitArchVariant() const { Triple T(*this); switch (getArch()) { case Triple::UnknownArch: case Triple::amdgcn: case Triple::avr: case Triple::bpfel: case Triple::bpfeb: case Triple::msp430: case Triple::systemz: case Triple::ppc64le: T.setArch(UnknownArch); break; case Triple::aarch64_32: case Triple::amdil: case Triple::hsail: case Triple::spir: case Triple::arc: case Triple::arm: case Triple::armeb: case Triple::hexagon: case Triple::kalimba: case Triple::le32: case Triple::mips: case Triple::mipsel: case Triple::nvptx: case Triple::ppc: case Triple::r600: case Triple::riscv32: case Triple::sparc: case Triple::sparcel: case Triple::tce: case Triple::tcele: case Triple::thumb: case Triple::thumbeb: case Triple::x86: case Triple::xcore: case Triple::lanai: case Triple::shave: case Triple::wasm32: case Triple::renderscript32: // Already 32-bit. break; case Triple::aarch64: T.setArch(Triple::arm); break; case Triple::aarch64_be: T.setArch(Triple::armeb); break; case Triple::le64: T.setArch(Triple::le32); break; case Triple::mips64: T.setArch(Triple::mips); break; case Triple::mips64el: T.setArch(Triple::mipsel); break; case Triple::nvptx64: T.setArch(Triple::nvptx); break; case Triple::ppc64: T.setArch(Triple::ppc); break; case Triple::sparcv9: T.setArch(Triple::sparc); break; case Triple::riscv64: T.setArch(Triple::riscv32); break; case Triple::x86_64: T.setArch(Triple::x86); break; case Triple::amdil64: T.setArch(Triple::amdil); break; case Triple::hsail64: T.setArch(Triple::hsail); break; case Triple::spir64: T.setArch(Triple::spir); break; case Triple::wasm64: T.setArch(Triple::wasm32); break; case Triple::renderscript64: T.setArch(Triple::renderscript32); break; } return T; } Triple Triple::get64BitArchVariant() const { Triple T(*this); switch (getArch()) { case Triple::UnknownArch: case Triple::arc: case Triple::avr: case Triple::hexagon: case Triple::kalimba: case Triple::lanai: case Triple::msp430: case Triple::r600: case Triple::tce: case Triple::tcele: case Triple::xcore: case Triple::sparcel: case Triple::shave: T.setArch(UnknownArch); break; case Triple::aarch64: case Triple::aarch64_be: case Triple::bpfel: case Triple::bpfeb: case Triple::le64: case Triple::amdil64: case Triple::amdgcn: case Triple::hsail64: case Triple::spir64: case Triple::mips64: case Triple::mips64el: case Triple::nvptx64: case Triple::ppc64: case Triple::ppc64le: case Triple::riscv64: case Triple::sparcv9: case Triple::systemz: case Triple::x86_64: case Triple::wasm64: case Triple::renderscript64: // Already 64-bit. break; case Triple::aarch64_32: T.setArch(Triple::aarch64); break; case Triple::arm: T.setArch(Triple::aarch64); break; case Triple::armeb: T.setArch(Triple::aarch64_be); break; case Triple::le32: T.setArch(Triple::le64); break; case Triple::mips: T.setArch(Triple::mips64); break; case Triple::mipsel: T.setArch(Triple::mips64el); break; case Triple::nvptx: T.setArch(Triple::nvptx64); break; case Triple::ppc: T.setArch(Triple::ppc64); break; case Triple::sparc: T.setArch(Triple::sparcv9); break; case Triple::riscv32: T.setArch(Triple::riscv64); break; case Triple::x86: T.setArch(Triple::x86_64); break; case Triple::amdil: T.setArch(Triple::amdil64); break; case Triple::hsail: T.setArch(Triple::hsail64); break; case Triple::spir: T.setArch(Triple::spir64); break; case Triple::thumb: T.setArch(Triple::aarch64); break; case Triple::thumbeb: T.setArch(Triple::aarch64_be); break; case Triple::wasm32: T.setArch(Triple::wasm64); break; case Triple::renderscript32: T.setArch(Triple::renderscript64); break; } return T; } Triple Triple::getBigEndianArchVariant() const { Triple T(*this); // Already big endian. if (!isLittleEndian()) return T; switch (getArch()) { case Triple::UnknownArch: case Triple::amdgcn: case Triple::amdil64: case Triple::amdil: case Triple::avr: case Triple::hexagon: case Triple::hsail64: case Triple::hsail: case Triple::kalimba: case Triple::le32: case Triple::le64: case Triple::msp430: case Triple::nvptx64: case Triple::nvptx: case Triple::r600: case Triple::riscv32: case Triple::riscv64: case Triple::shave: case Triple::spir64: case Triple::spir: case Triple::wasm32: case Triple::wasm64: case Triple::x86: case Triple::x86_64: case Triple::xcore: case Triple::renderscript32: case Triple::renderscript64: // ARM is intentionally unsupported here, changing the architecture would // drop any arch suffixes. case Triple::arm: case Triple::thumb: T.setArch(UnknownArch); break; case Triple::tcele: T.setArch(Triple::tce); break; case Triple::aarch64: T.setArch(Triple::aarch64_be); break; case Triple::bpfel: T.setArch(Triple::bpfeb); break; case Triple::mips64el:T.setArch(Triple::mips64); break; case Triple::mipsel: T.setArch(Triple::mips); break; case Triple::ppc64le: T.setArch(Triple::ppc64); break; case Triple::sparcel: T.setArch(Triple::sparc); break; default: llvm_unreachable("getBigEndianArchVariant: unknown triple."); } return T; } Triple Triple::getLittleEndianArchVariant() const { Triple T(*this); if (isLittleEndian()) return T; switch (getArch()) { case Triple::UnknownArch: case Triple::lanai: case Triple::ppc: case Triple::sparcv9: case Triple::systemz: // ARM is intentionally unsupported here, changing the architecture would // drop any arch suffixes. case Triple::armeb: case Triple::thumbeb: T.setArch(UnknownArch); break; case Triple::tce: T.setArch(Triple::tcele); break; case Triple::aarch64_be: T.setArch(Triple::aarch64); break; case Triple::bpfeb: T.setArch(Triple::bpfel); break; case Triple::mips64: T.setArch(Triple::mips64el); break; case Triple::mips: T.setArch(Triple::mipsel); break; case Triple::ppc64: T.setArch(Triple::ppc64le); break; case Triple::sparc: T.setArch(Triple::sparcel); break; default: llvm_unreachable("getLittleEndianArchVariant: unknown triple."); } return T; } bool Triple::isLittleEndian() const { switch (getArch()) { case Triple::aarch64: case Triple::aarch64_32: case Triple::amdgcn: case Triple::amdil64: case Triple::amdil: case Triple::arm: case Triple::avr: case Triple::bpfel: case Triple::hexagon: case Triple::hsail64: case Triple::hsail: case Triple::kalimba: case Triple::le32: case Triple::le64: case Triple::mips64el: case Triple::mipsel: case Triple::msp430: case Triple::nvptx64: case Triple::nvptx: case Triple::ppc64le: case Triple::r600: case Triple::riscv32: case Triple::riscv64: case Triple::shave: case Triple::sparcel: case Triple::spir64: case Triple::spir: case Triple::thumb: case Triple::wasm32: case Triple::wasm64: case Triple::x86: case Triple::x86_64: case Triple::xcore: case Triple::tcele: case Triple::renderscript32: case Triple::renderscript64: return true; default: return false; } } bool Triple::isCompatibleWith(const Triple &Other) const { // ARM and Thumb triples are compatible, if subarch, vendor and OS match. if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) || (getArch() == Triple::arm && Other.getArch() == Triple::thumb) || (getArch() == Triple::thumbeb && Other.getArch() == Triple::armeb) || (getArch() == Triple::armeb && Other.getArch() == Triple::thumbeb)) { if (getVendor() == Triple::Apple) return getSubArch() == Other.getSubArch() && getVendor() == Other.getVendor() && getOS() == Other.getOS(); else return getSubArch() == Other.getSubArch() && getVendor() == Other.getVendor() && getOS() == Other.getOS() && getEnvironment() == Other.getEnvironment() && getObjectFormat() == Other.getObjectFormat(); } // If vendor is apple, ignore the version number. if (getVendor() == Triple::Apple) return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() && getVendor() == Other.getVendor() && getOS() == Other.getOS(); return *this == Other; } std::string Triple::merge(const Triple &Other) const { // If vendor is apple, pick the triple with the larger version number. if (getVendor() == Triple::Apple) if (Other.isOSVersionLT(*this)) return str(); return Other.str(); } StringRef Triple::getARMCPUForArch(StringRef MArch) const { if (MArch.empty()) MArch = getArchName(); MArch = ARM::getCanonicalArchName(MArch); // Some defaults are forced. switch (getOS()) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: if (!MArch.empty() && MArch == "v6") return "arm1176jzf-s"; break; case llvm::Triple::Win32: // FIXME: this is invalid for WindowsCE return "cortex-a9"; case llvm::Triple::MacOSX: case llvm::Triple::IOS: case llvm::Triple::WatchOS: case llvm::Triple::TvOS: if (MArch == "v7k") return "cortex-a7"; break; default: break; } if (MArch.empty()) return StringRef(); StringRef CPU = ARM::getDefaultCPU(MArch); if (!CPU.empty() && !CPU.equals("invalid")) return CPU; // If no specific architecture version is requested, return the minimum CPU // required by the OS and environment. switch (getOS()) { case llvm::Triple::NetBSD: switch (getEnvironment()) { case llvm::Triple::GNUEABIHF: case llvm::Triple::GNUEABI: case llvm::Triple::EABIHF: case llvm::Triple::EABI: return "arm926ej-s"; default: return "strongarm"; } case llvm::Triple::NaCl: case llvm::Triple::OpenBSD: return "cortex-a8"; default: switch (getEnvironment()) { case llvm::Triple::EABIHF: case llvm::Triple::GNUEABIHF: case llvm::Triple::MuslEABIHF: return "arm1176jzf-s"; default: return "arm7tdmi"; } } llvm_unreachable("invalid arch name"); } Index: stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPC.td =================================================================== --- stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPC.td (revision 357167) +++ stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPC.td (revision 357168) @@ -1,498 +1,498 @@ //===-- PPC.td - Describe the PowerPC Target Machine -------*- tablegen -*-===// // // 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 // //===----------------------------------------------------------------------===// // // This is the top level entry point for the PowerPC target. // //===----------------------------------------------------------------------===// // Get the target-independent interfaces which we are implementing. // include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // PowerPC Subtarget features. // //===----------------------------------------------------------------------===// // CPU Directives // //===----------------------------------------------------------------------===// def Directive440 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_440", "">; def Directive601 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_601", "">; def Directive602 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_602", "">; def Directive603 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_603", "">; def Directive604 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_603", "">; def Directive620 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_603", "">; def Directive7400: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_7400", "">; def Directive750 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_750", "">; def Directive970 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_970", "">; def Directive32 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_32", "">; def Directive64 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_64", "">; def DirectiveA2 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_A2", "">; def DirectiveE500 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_E500", "">; def DirectiveE500mc : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_E500mc", "">; def DirectiveE5500 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_E5500", "">; def DirectivePwr3: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR3", "">; def DirectivePwr4: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR4", "">; def DirectivePwr5: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR5", "">; def DirectivePwr5x : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR5X", "">; def DirectivePwr6: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR6", "">; def DirectivePwr6x : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR6X", "">; def DirectivePwr7: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR7", "">; def DirectivePwr8: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR8", "">; def DirectivePwr9: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR9", "">; def Feature64Bit : SubtargetFeature<"64bit","Has64BitSupport", "true", "Enable 64-bit instructions">; def FeatureHardFloat : SubtargetFeature<"hard-float", "HasHardFloat", "true", "Enable floating-point instructions">; def Feature64BitRegs : SubtargetFeature<"64bitregs","Use64BitRegs", "true", "Enable 64-bit registers usage for ppc32 [beta]">; def FeatureCRBits : SubtargetFeature<"crbits", "UseCRBits", "true", "Use condition-register bits individually">; def FeatureFPU : SubtargetFeature<"fpu","HasFPU","true", "Enable classic FPU instructions", [FeatureHardFloat]>; def FeatureAltivec : SubtargetFeature<"altivec","HasAltivec", "true", "Enable Altivec instructions", [FeatureFPU]>; def FeatureSPE : SubtargetFeature<"spe","HasSPE", "true", "Enable SPE instructions", [FeatureHardFloat]>; def FeatureMFOCRF : SubtargetFeature<"mfocrf","HasMFOCRF", "true", "Enable the MFOCRF instruction">; def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true", "Enable the fsqrt instruction", [FeatureFPU]>; def FeatureFCPSGN : SubtargetFeature<"fcpsgn", "HasFCPSGN", "true", "Enable the fcpsgn instruction", [FeatureFPU]>; def FeatureFRE : SubtargetFeature<"fre", "HasFRE", "true", "Enable the fre instruction", [FeatureFPU]>; def FeatureFRES : SubtargetFeature<"fres", "HasFRES", "true", "Enable the fres instruction", [FeatureFPU]>; def FeatureFRSQRTE : SubtargetFeature<"frsqrte", "HasFRSQRTE", "true", "Enable the frsqrte instruction", [FeatureFPU]>; def FeatureFRSQRTES : SubtargetFeature<"frsqrtes", "HasFRSQRTES", "true", "Enable the frsqrtes instruction", [FeatureFPU]>; def FeatureRecipPrec : SubtargetFeature<"recipprec", "HasRecipPrec", "true", "Assume higher precision reciprocal estimates">; def FeatureSTFIWX : SubtargetFeature<"stfiwx","HasSTFIWX", "true", "Enable the stfiwx instruction", [FeatureFPU]>; def FeatureLFIWAX : SubtargetFeature<"lfiwax","HasLFIWAX", "true", "Enable the lfiwax instruction", [FeatureFPU]>; def FeatureFPRND : SubtargetFeature<"fprnd", "HasFPRND", "true", "Enable the fri[mnpz] instructions", [FeatureFPU]>; def FeatureFPCVT : SubtargetFeature<"fpcvt", "HasFPCVT", "true", "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions", [FeatureFPU]>; def FeatureISEL : SubtargetFeature<"isel","HasISEL", "true", "Enable the isel instruction">; def FeatureBPERMD : SubtargetFeature<"bpermd", "HasBPERMD", "true", "Enable the bpermd instruction">; def FeatureExtDiv : SubtargetFeature<"extdiv", "HasExtDiv", "true", "Enable extended divide instructions">; def FeatureLDBRX : SubtargetFeature<"ldbrx","HasLDBRX", "true", "Enable the ldbrx instruction">; def FeatureCMPB : SubtargetFeature<"cmpb", "HasCMPB", "true", "Enable the cmpb instruction">; def FeatureICBT : SubtargetFeature<"icbt","HasICBT", "true", "Enable icbt instruction">; def FeatureBookE : SubtargetFeature<"booke", "IsBookE", "true", "Enable Book E instructions", [FeatureICBT]>; def FeatureMSYNC : SubtargetFeature<"msync", "HasOnlyMSYNC", "true", "Has only the msync instruction instead of sync", [FeatureBookE]>; def FeatureE500 : SubtargetFeature<"e500", "IsE500", "true", "Enable E500/E500mc instructions">; def FeatureSecurePlt : SubtargetFeature<"secure-plt","SecurePlt", "true", "Enable secure plt mode">; def FeaturePPC4xx : SubtargetFeature<"ppc4xx", "IsPPC4xx", "true", "Enable PPC 4xx instructions">; def FeaturePPC6xx : SubtargetFeature<"ppc6xx", "IsPPC6xx", "true", "Enable PPC 6xx instructions">; def FeatureQPX : SubtargetFeature<"qpx","HasQPX", "true", "Enable QPX instructions", [FeatureFPU]>; def FeatureVSX : SubtargetFeature<"vsx","HasVSX", "true", "Enable VSX instructions", [FeatureAltivec]>; def FeatureTwoConstNR : SubtargetFeature<"two-const-nr", "NeedsTwoConstNR", "true", "Requires two constant Newton-Raphson computation">; def FeatureP8Altivec : SubtargetFeature<"power8-altivec", "HasP8Altivec", "true", "Enable POWER8 Altivec instructions", [FeatureAltivec]>; def FeatureP8Crypto : SubtargetFeature<"crypto", "HasP8Crypto", "true", "Enable POWER8 Crypto instructions", [FeatureP8Altivec]>; def FeatureP8Vector : SubtargetFeature<"power8-vector", "HasP8Vector", "true", "Enable POWER8 vector instructions", [FeatureVSX, FeatureP8Altivec]>; def FeatureDirectMove : SubtargetFeature<"direct-move", "HasDirectMove", "true", "Enable Power8 direct move instructions", [FeatureVSX]>; def FeaturePartwordAtomic : SubtargetFeature<"partword-atomics", "HasPartwordAtomics", "true", "Enable l[bh]arx and st[bh]cx.">; def FeatureInvariantFunctionDescriptors : SubtargetFeature<"invariant-function-descriptors", "HasInvariantFunctionDescriptors", "true", "Assume function descriptors are invariant">; def FeatureLongCall : SubtargetFeature<"longcall", "UseLongCalls", "true", "Always use indirect calls">; def FeatureHTM : SubtargetFeature<"htm", "HasHTM", "true", "Enable Hardware Transactional Memory instructions">; def FeatureMFTB : SubtargetFeature<"", "FeatureMFTB", "true", "Implement mftb using the mfspr instruction">; def FeaturePPCPreRASched: SubtargetFeature<"ppc-prera-sched", "UsePPCPreRASchedStrategy", "true", "Use PowerPC pre-RA scheduling strategy">; def FeaturePPCPostRASched: SubtargetFeature<"ppc-postra-sched", "UsePPCPostRASchedStrategy", "true", "Use PowerPC post-RA scheduling strategy">; def FeatureFloat128 : SubtargetFeature<"float128", "HasFloat128", "true", "Enable the __float128 data type for IEEE-754R Binary128.", [FeatureVSX]>; def FeaturePOPCNTD : SubtargetFeature<"popcntd","HasPOPCNTD", "POPCNTD_Fast", "Enable the popcnt[dw] instructions">; // Note that for the a2/a2q processor models we should not use popcnt[dw] by // default. These processors do support the instructions, but they're // microcoded, and the software emulation is about twice as fast. def FeatureSlowPOPCNTD : SubtargetFeature<"slow-popcntd","HasPOPCNTD", "POPCNTD_Slow", "Has slow popcnt[dw] instructions">; def DeprecatedDST : SubtargetFeature<"", "DeprecatedDST", "true", "Treat vector data stream cache control instructions as deprecated">; def FeatureISA3_0 : SubtargetFeature<"isa-v30-instructions", "IsISA3_0", "true", "Enable instructions added in ISA 3.0.">; def FeatureP9Altivec : SubtargetFeature<"power9-altivec", "HasP9Altivec", "true", "Enable POWER9 Altivec instructions", [FeatureISA3_0, FeatureP8Altivec]>; def FeatureP9Vector : SubtargetFeature<"power9-vector", "HasP9Vector", "true", "Enable POWER9 vector instructions", [FeatureISA3_0, FeatureP8Vector, FeatureP9Altivec]>; // A separate feature for this even though it is equivalent to P9Vector // because this is a feature of the implementation rather than the architecture // and may go away with future CPU's. def FeatureVectorsUseTwoUnits : SubtargetFeature<"vectors-use-two-units", "VectorsUseTwoUnits", "true", "Vectors use two units">; // Since new processors generally contain a superset of features of those that // came before them, the idea is to make implementations of new processors // less error prone and easier to read. // Namely: // list Power8FeatureList = ... // list FutureProcessorSpecificFeatureList = // [ features that Power8 does not support ] // list FutureProcessorFeatureList = // !listconcat(Power8FeatureList, FutureProcessorSpecificFeatureList) // Makes it explicit and obvious what is new in FutureProcesor vs. Power8 as // well as providing a single point of definition if the feature set will be // used elsewhere. def ProcessorFeatures { list Power7FeatureList = [DirectivePwr7, FeatureAltivec, FeatureVSX, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureFPRND, FeatureFPCVT, FeatureISEL, FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX, Feature64Bit /*, Feature64BitRegs */, FeatureBPERMD, FeatureExtDiv, FeatureMFTB, DeprecatedDST, FeatureTwoConstNR]; list Power8SpecificFeatures = [DirectivePwr8, FeatureP8Altivec, FeatureP8Vector, FeatureP8Crypto, FeatureHTM, FeatureDirectMove, FeatureICBT, FeaturePartwordAtomic]; list Power8FeatureList = !listconcat(Power7FeatureList, Power8SpecificFeatures); list Power9SpecificFeatures = [DirectivePwr9, FeatureP9Altivec, FeatureP9Vector, FeatureISA3_0, FeatureVectorsUseTwoUnits, FeaturePPCPreRASched, FeaturePPCPostRASched]; list Power9FeatureList = !listconcat(Power8FeatureList, Power9SpecificFeatures); } // Note: Future features to add when support is extended to more // recent ISA levels: // // DFP p6, p6x, p7 decimal floating-point instructions // POPCNTB p5 through p7 popcntb and related instructions //===----------------------------------------------------------------------===// // Classes used for relation maps. //===----------------------------------------------------------------------===// // RecFormRel - Filter class used to relate non-record-form instructions with // their record-form variants. class RecFormRel; // AltVSXFMARel - Filter class used to relate the primary addend-killing VSX // FMA instruction forms with their corresponding factor-killing forms. class AltVSXFMARel { bit IsVSXFMAAlt = 0; } //===----------------------------------------------------------------------===// // Relation Map Definitions. //===----------------------------------------------------------------------===// def getRecordFormOpcode : InstrMapping { let FilterClass = "RecFormRel"; // Instructions with the same BaseName and Interpretation64Bit values // form a row. let RowFields = ["BaseName", "Interpretation64Bit"]; // Instructions with the same RC value form a column. let ColFields = ["RC"]; // The key column are the non-record-form instructions. let KeyCol = ["0"]; // Value columns RC=1 let ValueCols = [["1"]]; } def getNonRecordFormOpcode : InstrMapping { let FilterClass = "RecFormRel"; // Instructions with the same BaseName and Interpretation64Bit values // form a row. let RowFields = ["BaseName", "Interpretation64Bit"]; // Instructions with the same RC value form a column. let ColFields = ["RC"]; // The key column are the record-form instructions. let KeyCol = ["1"]; // Value columns are RC=0 let ValueCols = [["0"]]; } def getAltVSXFMAOpcode : InstrMapping { let FilterClass = "AltVSXFMARel"; // Instructions with the same BaseName value form a row. let RowFields = ["BaseName"]; // Instructions with the same IsVSXFMAAlt value form a column. let ColFields = ["IsVSXFMAAlt"]; // The key column are the (default) addend-killing instructions. let KeyCol = ["0"]; // Value columns IsVSXFMAAlt=1 let ValueCols = [["1"]]; } //===----------------------------------------------------------------------===// // Register File Description //===----------------------------------------------------------------------===// include "PPCRegisterInfo.td" include "PPCSchedule.td" //===----------------------------------------------------------------------===// // PowerPC processors supported. // def : Processor<"generic", G3Itineraries, [Directive32, FeatureHardFloat, FeatureMFTB]>; def : ProcessorModel<"440", PPC440Model, [Directive440, FeatureISEL, FeatureFRES, FeatureFRSQRTE, FeatureICBT, FeatureBookE, FeatureMSYNC, FeatureMFTB]>; def : ProcessorModel<"450", PPC440Model, [Directive440, FeatureISEL, FeatureFRES, FeatureFRSQRTE, FeatureICBT, FeatureBookE, FeatureMSYNC, FeatureMFTB]>; def : Processor<"601", G3Itineraries, [Directive601, FeatureFPU]>; def : Processor<"602", G3Itineraries, [Directive602, FeatureFPU, FeatureMFTB]>; def : Processor<"603", G3Itineraries, [Directive603, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"603e", G3Itineraries, [Directive603, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"603ev", G3Itineraries, [Directive603, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"604", G3Itineraries, [Directive604, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"604e", G3Itineraries, [Directive604, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"620", G3Itineraries, [Directive620, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"750", G4Itineraries, [Directive750, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"g3", G3Itineraries, [Directive750, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"7400", G4Itineraries, [Directive7400, FeatureAltivec, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"g4", G4Itineraries, [Directive7400, FeatureAltivec, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"7450", G4PlusItineraries, [Directive7400, FeatureAltivec, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : Processor<"g4+", G4PlusItineraries, [Directive7400, FeatureAltivec, FeatureFRES, FeatureFRSQRTE, FeatureMFTB]>; def : ProcessorModel<"970", G5Model, [Directive970, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureFRES, FeatureFRSQRTE, FeatureSTFIWX, Feature64Bit /*, Feature64BitRegs */, FeatureMFTB]>; def : ProcessorModel<"g5", G5Model, [Directive970, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureSTFIWX, FeatureFRES, FeatureFRSQRTE, Feature64Bit /*, Feature64BitRegs */, FeatureMFTB, DeprecatedDST]>; def : ProcessorModel<"e500", PPCE500Model, [DirectiveE500, FeatureICBT, FeatureBookE, - FeatureISEL, FeatureMFTB]>; + FeatureISEL, FeatureMFTB, FeatureSPE]>; def : ProcessorModel<"e500mc", PPCE500mcModel, [DirectiveE500mc, FeatureSTFIWX, FeatureICBT, FeatureBookE, FeatureISEL, FeatureMFTB]>; def : ProcessorModel<"e5500", PPCE5500Model, [DirectiveE5500, FeatureMFOCRF, Feature64Bit, FeatureSTFIWX, FeatureICBT, FeatureBookE, FeatureISEL, FeatureMFTB]>; def : ProcessorModel<"a2", PPCA2Model, [DirectiveA2, FeatureICBT, FeatureBookE, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureFPRND, FeatureFPCVT, FeatureISEL, FeatureSlowPOPCNTD, FeatureCMPB, FeatureLDBRX, Feature64Bit /*, Feature64BitRegs */, FeatureMFTB]>; def : ProcessorModel<"a2q", PPCA2Model, [DirectiveA2, FeatureICBT, FeatureBookE, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureFPRND, FeatureFPCVT, FeatureISEL, FeatureSlowPOPCNTD, FeatureCMPB, FeatureLDBRX, Feature64Bit /*, Feature64BitRegs */, FeatureQPX, FeatureMFTB]>; def : ProcessorModel<"pwr3", G5Model, [DirectivePwr3, FeatureAltivec, FeatureFRES, FeatureFRSQRTE, FeatureMFOCRF, FeatureSTFIWX, Feature64Bit]>; def : ProcessorModel<"pwr4", G5Model, [DirectivePwr4, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureFRES, FeatureFRSQRTE, FeatureSTFIWX, Feature64Bit, FeatureMFTB]>; def : ProcessorModel<"pwr5", G5Model, [DirectivePwr5, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureSTFIWX, Feature64Bit, FeatureMFTB, DeprecatedDST]>; def : ProcessorModel<"pwr5x", G5Model, [DirectivePwr5x, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureSTFIWX, FeatureFPRND, Feature64Bit, FeatureMFTB, DeprecatedDST]>; def : ProcessorModel<"pwr6", G5Model, [DirectivePwr6, FeatureAltivec, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureCMPB, FeatureFPRND, Feature64Bit /*, Feature64BitRegs */, FeatureMFTB, DeprecatedDST]>; def : ProcessorModel<"pwr6x", G5Model, [DirectivePwr5x, FeatureAltivec, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES, FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureCMPB, FeatureFPRND, Feature64Bit, FeatureMFTB, DeprecatedDST]>; def : ProcessorModel<"pwr7", P7Model, ProcessorFeatures.Power7FeatureList>; def : ProcessorModel<"pwr8", P8Model, ProcessorFeatures.Power8FeatureList>; def : ProcessorModel<"pwr9", P9Model, ProcessorFeatures.Power9FeatureList>; def : Processor<"ppc", G3Itineraries, [Directive32, FeatureHardFloat, FeatureMFTB]>; def : Processor<"ppc32", G3Itineraries, [Directive32, FeatureHardFloat, FeatureMFTB]>; def : ProcessorModel<"ppc64", G5Model, [Directive64, FeatureAltivec, FeatureMFOCRF, FeatureFSqrt, FeatureFRES, FeatureFRSQRTE, FeatureSTFIWX, Feature64Bit /*, Feature64BitRegs */, FeatureMFTB]>; def : ProcessorModel<"ppc64le", P8Model, ProcessorFeatures.Power8FeatureList>; //===----------------------------------------------------------------------===// // Calling Conventions //===----------------------------------------------------------------------===// include "PPCCallingConv.td" def PPCInstrInfo : InstrInfo { let isLittleEndianEncoding = 1; // FIXME: Unset this when no longer needed! let decodePositionallyEncodedOperands = 1; let noNamedPositionallyEncodedOperands = 1; } def PPCAsmParser : AsmParser { let ShouldEmitMatchRegisterName = 0; } def PPCAsmParserVariant : AsmParserVariant { int Variant = 0; // We do not use hard coded registers in asm strings. However, some // InstAlias definitions use immediate literals. Set RegisterPrefix // so that those are not misinterpreted as registers. string RegisterPrefix = "%"; string BreakCharacters = "."; } def PPC : Target { // Information about the instructions. let InstructionSet = PPCInstrInfo; let AssemblyParsers = [PPCAsmParser]; let AssemblyParserVariants = [PPCAsmParserVariant]; let AllowRegisterRenaming = 1; } //===----------------------------------------------------------------------===// // Pfm Counters //===----------------------------------------------------------------------===// include "PPCPfmCounters.td" Index: stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.cpp =================================================================== --- stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.cpp (revision 357167) +++ stable/12/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.cpp (revision 357168) @@ -1,247 +1,249 @@ //===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file implements the PPC specific subclass of TargetSubtargetInfo. // //===----------------------------------------------------------------------===// #include "PPCSubtarget.h" #include "PPC.h" #include "PPCRegisterInfo.h" #include "PPCTargetMachine.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineScheduler.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" #include using namespace llvm; #define DEBUG_TYPE "ppc-subtarget" #define GET_SUBTARGETINFO_TARGET_DESC #define GET_SUBTARGETINFO_CTOR #include "PPCGenSubtargetInfo.inc" static cl::opt UseSubRegLiveness("ppc-track-subreg-liveness", cl::desc("Enable subregister liveness tracking for PPC"), cl::Hidden); static cl::opt QPXStackUnaligned("qpx-stack-unaligned", cl::desc("Even when QPX is enabled the stack is not 32-byte aligned"), cl::Hidden); static cl::opt EnableMachinePipeliner("ppc-enable-pipeliner", cl::desc("Enable Machine Pipeliner for PPC"), cl::init(false), cl::Hidden); PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { initializeEnvironment(); initSubtargetFeatures(CPU, FS); return *this; } PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const PPCTargetMachine &TM) : PPCGenSubtargetInfo(TT, CPU, FS), TargetTriple(TT), IsPPC64(TargetTriple.getArch() == Triple::ppc64 || TargetTriple.getArch() == Triple::ppc64le), TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, FS)), InstrInfo(*this), TLInfo(TM, *this) {} void PPCSubtarget::initializeEnvironment() { StackAlignment = 16; DarwinDirective = PPC::DIR_NONE; HasMFOCRF = false; Has64BitSupport = false; Use64BitRegs = false; UseCRBits = false; HasHardFloat = false; HasAltivec = false; HasSPE = false; HasFPU = false; HasQPX = false; HasVSX = false; NeedsTwoConstNR = false; HasP8Vector = false; HasP8Altivec = false; HasP8Crypto = false; HasP9Vector = false; HasP9Altivec = false; HasFCPSGN = false; HasFSQRT = false; HasFRE = false; HasFRES = false; HasFRSQRTE = false; HasFRSQRTES = false; HasRecipPrec = false; HasSTFIWX = false; HasLFIWAX = false; HasFPRND = false; HasFPCVT = false; HasISEL = false; HasBPERMD = false; HasExtDiv = false; HasCMPB = false; HasLDBRX = false; IsBookE = false; HasOnlyMSYNC = false; IsPPC4xx = false; IsPPC6xx = false; IsE500 = false; FeatureMFTB = false; DeprecatedDST = false; HasLazyResolverStubs = false; HasICBT = false; HasInvariantFunctionDescriptors = false; HasPartwordAtomics = false; HasDirectMove = false; IsQPXStackUnaligned = false; HasHTM = false; HasFloat128 = false; IsISA3_0 = false; UseLongCalls = false; SecurePlt = false; VectorsUseTwoUnits = false; UsePPCPreRASchedStrategy = false; UsePPCPostRASchedStrategy = false; HasPOPCNTD = POPCNTD_Unavailable; } void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { // Determine default and user specified characteristics std::string CPUName = CPU; if (CPUName.empty() || CPU == "generic") { // If cross-compiling with -march=ppc64le without -mcpu if (TargetTriple.getArch() == Triple::ppc64le) CPUName = "ppc64le"; + else if (TargetTriple.getSubArch() == Triple::PPCSubArch_spe) + CPUName = "e500"; else CPUName = "generic"; } // Initialize scheduling itinerary for the specified CPU. InstrItins = getInstrItineraryForCPU(CPUName); // Parse features string. ParseSubtargetFeatures(CPUName, FS); // If the user requested use of 64-bit regs, but the cpu selected doesn't // support it, ignore. if (IsPPC64 && has64BitSupport()) Use64BitRegs = true; // Set up darwin-specific properties. if (isDarwin()) HasLazyResolverStubs = true; if ((TargetTriple.isOSFreeBSD() && TargetTriple.getOSMajorVersion() >= 13) || TargetTriple.isOSNetBSD() || TargetTriple.isOSOpenBSD() || TargetTriple.isMusl()) SecurePlt = true; if (HasSPE && IsPPC64) report_fatal_error( "SPE is only supported for 32-bit targets.\n", false); if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU)) report_fatal_error( "SPE and traditional floating point cannot both be enabled.\n", false); // If not SPE, set standard FPU if (!HasSPE) HasFPU = true; // QPX requires a 32-byte aligned stack. Note that we need to do this if // we're compiling for a BG/Q system regardless of whether or not QPX // is enabled because external functions will assume this alignment. IsQPXStackUnaligned = QPXStackUnaligned; StackAlignment = getPlatformStackAlignment(); // Determine endianness. // FIXME: Part of the TargetMachine. IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le); } /// Return true if accesses to the specified global have to go through a dyld /// lazy resolution stub. This means that an extra load is required to get the /// address of the global. bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV) const { if (!HasLazyResolverStubs) return false; if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) return true; // 32 bit macho has no relocation for a-b if a is undefined, even if b is in // the section that is being relocated. This means we have to use o load even // for GVs that are known to be local to the dso. if (GV->isDeclarationForLinker() || GV->hasCommonLinkage()) return true; return false; } bool PPCSubtarget::enableMachineScheduler() const { return true; } bool PPCSubtarget::enableMachinePipeliner() const { return (DarwinDirective == PPC::DIR_PWR9) && EnableMachinePipeliner; } bool PPCSubtarget::useDFAforSMS() const { return false; } // This overrides the PostRAScheduler bit in the SchedModel for each CPU. bool PPCSubtarget::enablePostRAScheduler() const { return true; } PPCGenSubtargetInfo::AntiDepBreakMode PPCSubtarget::getAntiDepBreakMode() const { return TargetSubtargetInfo::ANTIDEP_ALL; } void PPCSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { CriticalPathRCs.clear(); CriticalPathRCs.push_back(isPPC64() ? &PPC::G8RCRegClass : &PPC::GPRCRegClass); } void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const { // The GenericScheduler that we use defaults to scheduling bottom up only. // We want to schedule from both the top and the bottom and so we set // OnlyBottomUp to false. // We want to do bi-directional scheduling since it provides a more balanced // schedule leading to better performance. Policy.OnlyBottomUp = false; // Spilling is generally expensive on all PPC cores, so always enable // register-pressure tracking. Policy.ShouldTrackPressure = true; } bool PPCSubtarget::useAA() const { return true; } bool PPCSubtarget::enableSubRegLiveness() const { return UseSubRegLiveness; } unsigned char PPCSubtarget::classifyGlobalReference(const GlobalValue *GV) const { // Note that currently we don't generate non-pic references. // If a caller wants that, this will have to be updated. // Large code model always uses the TOC even for local symbols. if (TM.getCodeModel() == CodeModel::Large) return PPCII::MO_PIC_FLAG | PPCII::MO_NLP_FLAG; if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) return PPCII::MO_PIC_FLAG; return PPCII::MO_PIC_FLAG | PPCII::MO_NLP_FLAG; } bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); } bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); } Index: stable/12/contrib/llvm-project/llvm =================================================================== --- stable/12/contrib/llvm-project/llvm (revision 357167) +++ stable/12/contrib/llvm-project/llvm (revision 357168) Property changes on: stable/12/contrib/llvm-project/llvm ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/contrib/llvm-project/llvm:r356929 Index: stable/12 =================================================================== --- stable/12 (revision 357167) +++ stable/12 (revision 357168) Property changes on: stable/12 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r356929