17330f729Sjoerg //===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements Sparc TargetInfo objects.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "Sparc.h"
147330f729Sjoerg #include "Targets.h"
157330f729Sjoerg #include "clang/Basic/MacroBuilder.h"
167330f729Sjoerg #include "llvm/ADT/StringSwitch.h"
177330f729Sjoerg
187330f729Sjoerg using namespace clang;
197330f729Sjoerg using namespace clang::targets;
207330f729Sjoerg
217330f729Sjoerg const char *const SparcTargetInfo::GCCRegNames[] = {
227330f729Sjoerg // Integer registers
237330f729Sjoerg "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
247330f729Sjoerg "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
257330f729Sjoerg "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
267330f729Sjoerg
277330f729Sjoerg // Floating-point registers
287330f729Sjoerg "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
297330f729Sjoerg "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
307330f729Sjoerg "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
317330f729Sjoerg "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
327330f729Sjoerg "f56", "f58", "f60", "f62",
337330f729Sjoerg };
347330f729Sjoerg
getGCCRegNames() const357330f729Sjoerg ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
367330f729Sjoerg return llvm::makeArrayRef(GCCRegNames);
377330f729Sjoerg }
387330f729Sjoerg
397330f729Sjoerg const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
407330f729Sjoerg {{"g0"}, "r0"}, {{"g1"}, "r1"}, {{"g2"}, "r2"}, {{"g3"}, "r3"},
417330f729Sjoerg {{"g4"}, "r4"}, {{"g5"}, "r5"}, {{"g6"}, "r6"}, {{"g7"}, "r7"},
427330f729Sjoerg {{"o0"}, "r8"}, {{"o1"}, "r9"}, {{"o2"}, "r10"}, {{"o3"}, "r11"},
437330f729Sjoerg {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
447330f729Sjoerg {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"}, {{"l3"}, "r19"},
457330f729Sjoerg {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"}, {{"l7"}, "r23"},
467330f729Sjoerg {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"}, {{"i3"}, "r27"},
477330f729Sjoerg {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
487330f729Sjoerg };
497330f729Sjoerg
getGCCRegAliases() const507330f729Sjoerg ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
517330f729Sjoerg return llvm::makeArrayRef(GCCRegAliases);
527330f729Sjoerg }
537330f729Sjoerg
hasFeature(StringRef Feature) const547330f729Sjoerg bool SparcTargetInfo::hasFeature(StringRef Feature) const {
557330f729Sjoerg return llvm::StringSwitch<bool>(Feature)
567330f729Sjoerg .Case("softfloat", SoftFloat)
577330f729Sjoerg .Case("sparc", true)
587330f729Sjoerg .Default(false);
597330f729Sjoerg }
607330f729Sjoerg
617330f729Sjoerg struct SparcCPUInfo {
627330f729Sjoerg llvm::StringLiteral Name;
637330f729Sjoerg SparcTargetInfo::CPUKind Kind;
647330f729Sjoerg SparcTargetInfo::CPUGeneration Generation;
657330f729Sjoerg };
667330f729Sjoerg
677330f729Sjoerg static constexpr SparcCPUInfo CPUInfo[] = {
687330f729Sjoerg {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
697330f729Sjoerg {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
707330f729Sjoerg {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
717330f729Sjoerg {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
727330f729Sjoerg {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
737330f729Sjoerg {{"sparclite86x"},
747330f729Sjoerg SparcTargetInfo::CK_SPARCLITE86X,
757330f729Sjoerg SparcTargetInfo::CG_V8},
767330f729Sjoerg {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
777330f729Sjoerg {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
787330f729Sjoerg {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
797330f729Sjoerg {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
807330f729Sjoerg {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
817330f729Sjoerg {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
827330f729Sjoerg {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
837330f729Sjoerg {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
847330f729Sjoerg {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
857330f729Sjoerg {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
867330f729Sjoerg {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
877330f729Sjoerg {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
887330f729Sjoerg {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
897330f729Sjoerg {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
907330f729Sjoerg {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
917330f729Sjoerg {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
927330f729Sjoerg {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
937330f729Sjoerg {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
947330f729Sjoerg {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
957330f729Sjoerg {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
967330f729Sjoerg // FIXME: the myriad2[.n] spellings are obsolete,
977330f729Sjoerg // but a grace period is needed to allow updating dependent builds.
987330f729Sjoerg {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
997330f729Sjoerg {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
1007330f729Sjoerg {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
1017330f729Sjoerg {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
1027330f729Sjoerg {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
1037330f729Sjoerg {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
1047330f729Sjoerg {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
1057330f729Sjoerg {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
1067330f729Sjoerg {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
1077330f729Sjoerg {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
1087330f729Sjoerg {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
1097330f729Sjoerg {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
1107330f729Sjoerg };
1117330f729Sjoerg
1127330f729Sjoerg SparcTargetInfo::CPUGeneration
getCPUGeneration(CPUKind Kind) const1137330f729Sjoerg SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
1147330f729Sjoerg if (Kind == CK_GENERIC)
1157330f729Sjoerg return CG_V8;
1167330f729Sjoerg const SparcCPUInfo *Item = llvm::find_if(
1177330f729Sjoerg CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
1187330f729Sjoerg if (Item == std::end(CPUInfo))
1197330f729Sjoerg llvm_unreachable("Unexpected CPU kind");
1207330f729Sjoerg return Item->Generation;
1217330f729Sjoerg }
1227330f729Sjoerg
getCPUKind(StringRef Name) const1237330f729Sjoerg SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
1247330f729Sjoerg const SparcCPUInfo *Item = llvm::find_if(
1257330f729Sjoerg CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
1267330f729Sjoerg
1277330f729Sjoerg if (Item == std::end(CPUInfo))
1287330f729Sjoerg return CK_GENERIC;
1297330f729Sjoerg return Item->Kind;
1307330f729Sjoerg }
1317330f729Sjoerg
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const1327330f729Sjoerg void SparcTargetInfo::fillValidCPUList(
1337330f729Sjoerg SmallVectorImpl<StringRef> &Values) const {
1347330f729Sjoerg for (const SparcCPUInfo &Info : CPUInfo)
1357330f729Sjoerg Values.push_back(Info.Name);
1367330f729Sjoerg }
1377330f729Sjoerg
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1387330f729Sjoerg void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
1397330f729Sjoerg MacroBuilder &Builder) const {
1407330f729Sjoerg DefineStd(Builder, "sparc", Opts);
1417330f729Sjoerg Builder.defineMacro("__REGISTER_PREFIX__", "");
1427330f729Sjoerg
1437330f729Sjoerg if (SoftFloat)
1447330f729Sjoerg Builder.defineMacro("SOFT_FLOAT", "1");
1457330f729Sjoerg }
1467330f729Sjoerg
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1477330f729Sjoerg void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
1487330f729Sjoerg MacroBuilder &Builder) const {
1497330f729Sjoerg SparcTargetInfo::getTargetDefines(Opts, Builder);
150*e038c9c4Sjoerg if (getTriple().getOS() == llvm::Triple::Solaris)
151*e038c9c4Sjoerg Builder.defineMacro("__sparcv8");
152*e038c9c4Sjoerg else {
1537330f729Sjoerg switch (getCPUGeneration(CPU)) {
1547330f729Sjoerg case CG_V8:
1557330f729Sjoerg Builder.defineMacro("__sparcv8");
1567330f729Sjoerg Builder.defineMacro("__sparcv8__");
1577330f729Sjoerg break;
1587330f729Sjoerg case CG_V9:
1597330f729Sjoerg Builder.defineMacro("__sparcv9");
1607330f729Sjoerg Builder.defineMacro("__sparcv9__");
1617330f729Sjoerg Builder.defineMacro("__sparc_v9__");
1627330f729Sjoerg break;
1637330f729Sjoerg }
164*e038c9c4Sjoerg }
1657330f729Sjoerg if (getTriple().getVendor() == llvm::Triple::Myriad) {
1667330f729Sjoerg std::string MyriadArchValue, Myriad2Value;
1677330f729Sjoerg Builder.defineMacro("__sparc_v8__");
1687330f729Sjoerg Builder.defineMacro("__leon__");
1697330f729Sjoerg switch (CPU) {
1707330f729Sjoerg case CK_MYRIAD2100:
1717330f729Sjoerg MyriadArchValue = "__ma2100";
1727330f729Sjoerg Myriad2Value = "1";
1737330f729Sjoerg break;
1747330f729Sjoerg case CK_MYRIAD2150:
1757330f729Sjoerg MyriadArchValue = "__ma2150";
1767330f729Sjoerg Myriad2Value = "2";
1777330f729Sjoerg break;
1787330f729Sjoerg case CK_MYRIAD2155:
1797330f729Sjoerg MyriadArchValue = "__ma2155";
1807330f729Sjoerg Myriad2Value = "2";
1817330f729Sjoerg break;
1827330f729Sjoerg case CK_MYRIAD2450:
1837330f729Sjoerg MyriadArchValue = "__ma2450";
1847330f729Sjoerg Myriad2Value = "2";
1857330f729Sjoerg break;
1867330f729Sjoerg case CK_MYRIAD2455:
1877330f729Sjoerg MyriadArchValue = "__ma2455";
1887330f729Sjoerg Myriad2Value = "2";
1897330f729Sjoerg break;
1907330f729Sjoerg case CK_MYRIAD2x5x:
1917330f729Sjoerg Myriad2Value = "2";
1927330f729Sjoerg break;
1937330f729Sjoerg case CK_MYRIAD2080:
1947330f729Sjoerg MyriadArchValue = "__ma2080";
1957330f729Sjoerg Myriad2Value = "3";
1967330f729Sjoerg break;
1977330f729Sjoerg case CK_MYRIAD2085:
1987330f729Sjoerg MyriadArchValue = "__ma2085";
1997330f729Sjoerg Myriad2Value = "3";
2007330f729Sjoerg break;
2017330f729Sjoerg case CK_MYRIAD2480:
2027330f729Sjoerg MyriadArchValue = "__ma2480";
2037330f729Sjoerg Myriad2Value = "3";
2047330f729Sjoerg break;
2057330f729Sjoerg case CK_MYRIAD2485:
2067330f729Sjoerg MyriadArchValue = "__ma2485";
2077330f729Sjoerg Myriad2Value = "3";
2087330f729Sjoerg break;
2097330f729Sjoerg case CK_MYRIAD2x8x:
2107330f729Sjoerg Myriad2Value = "3";
2117330f729Sjoerg break;
2127330f729Sjoerg default:
2137330f729Sjoerg MyriadArchValue = "__ma2100";
2147330f729Sjoerg Myriad2Value = "1";
2157330f729Sjoerg break;
2167330f729Sjoerg }
2177330f729Sjoerg if (!MyriadArchValue.empty()) {
2187330f729Sjoerg Builder.defineMacro(MyriadArchValue, "1");
2197330f729Sjoerg Builder.defineMacro(MyriadArchValue + "__", "1");
2207330f729Sjoerg }
2217330f729Sjoerg if (Myriad2Value == "2") {
2227330f729Sjoerg Builder.defineMacro("__ma2x5x", "1");
2237330f729Sjoerg Builder.defineMacro("__ma2x5x__", "1");
2247330f729Sjoerg } else if (Myriad2Value == "3") {
2257330f729Sjoerg Builder.defineMacro("__ma2x8x", "1");
2267330f729Sjoerg Builder.defineMacro("__ma2x8x__", "1");
2277330f729Sjoerg }
2287330f729Sjoerg Builder.defineMacro("__myriad2__", Myriad2Value);
2297330f729Sjoerg Builder.defineMacro("__myriad2", Myriad2Value);
2307330f729Sjoerg }
231*e038c9c4Sjoerg if (getCPUGeneration(CPU) == CG_V9) {
232*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
233*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
234*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
235*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
236*e038c9c4Sjoerg }
2377330f729Sjoerg }
2387330f729Sjoerg
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2397330f729Sjoerg void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
2407330f729Sjoerg MacroBuilder &Builder) const {
2417330f729Sjoerg SparcTargetInfo::getTargetDefines(Opts, Builder);
2427330f729Sjoerg Builder.defineMacro("__sparcv9");
2437330f729Sjoerg Builder.defineMacro("__arch64__");
2447330f729Sjoerg // Solaris doesn't need these variants, but the BSDs do.
2457330f729Sjoerg if (getTriple().getOS() != llvm::Triple::Solaris) {
2467330f729Sjoerg Builder.defineMacro("__sparc64__");
2477330f729Sjoerg Builder.defineMacro("__sparc_v9__");
2487330f729Sjoerg Builder.defineMacro("__sparcv9__");
2497330f729Sjoerg }
250*e038c9c4Sjoerg
251*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
252*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
253*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
254*e038c9c4Sjoerg Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
2557330f729Sjoerg }
2567330f729Sjoerg
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const2577330f729Sjoerg void SparcV9TargetInfo::fillValidCPUList(
2587330f729Sjoerg SmallVectorImpl<StringRef> &Values) const {
2597330f729Sjoerg for (const SparcCPUInfo &Info : CPUInfo)
2607330f729Sjoerg if (Info.Generation == CG_V9)
2617330f729Sjoerg Values.push_back(Info.Name);
2627330f729Sjoerg }
263