xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements Sparc TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "Sparc.h"
140b57cec5SDimitry Andric #include "Targets.h"
150b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace clang;
190b57cec5SDimitry Andric using namespace clang::targets;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric const char *const SparcTargetInfo::GCCRegNames[] = {
220b57cec5SDimitry Andric     // Integer registers
230b57cec5SDimitry Andric     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
240b57cec5SDimitry Andric     "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
250b57cec5SDimitry Andric     "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric     // Floating-point registers
280b57cec5SDimitry Andric     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10",
290b57cec5SDimitry Andric     "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
300b57cec5SDimitry Andric     "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
310b57cec5SDimitry Andric     "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
320b57cec5SDimitry Andric     "f56", "f58", "f60", "f62",
330b57cec5SDimitry Andric };
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36*bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
400b57cec5SDimitry Andric     {{"g0"}, "r0"},  {{"g1"}, "r1"},  {{"g2"}, "r2"},        {{"g3"}, "r3"},
410b57cec5SDimitry Andric     {{"g4"}, "r4"},  {{"g5"}, "r5"},  {{"g6"}, "r6"},        {{"g7"}, "r7"},
420b57cec5SDimitry Andric     {{"o0"}, "r8"},  {{"o1"}, "r9"},  {{"o2"}, "r10"},       {{"o3"}, "r11"},
430b57cec5SDimitry Andric     {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
440b57cec5SDimitry Andric     {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"},       {{"l3"}, "r19"},
450b57cec5SDimitry Andric     {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"},       {{"l7"}, "r23"},
460b57cec5SDimitry Andric     {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"},       {{"i3"}, "r27"},
470b57cec5SDimitry Andric     {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
480b57cec5SDimitry Andric };
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51*bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric bool SparcTargetInfo::hasFeature(StringRef Feature) const {
550b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
560b57cec5SDimitry Andric       .Case("softfloat", SoftFloat)
570b57cec5SDimitry Andric       .Case("sparc", true)
580b57cec5SDimitry Andric       .Default(false);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric struct SparcCPUInfo {
620b57cec5SDimitry Andric   llvm::StringLiteral Name;
630b57cec5SDimitry Andric   SparcTargetInfo::CPUKind Kind;
640b57cec5SDimitry Andric   SparcTargetInfo::CPUGeneration Generation;
650b57cec5SDimitry Andric };
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric static constexpr SparcCPUInfo CPUInfo[] = {
680b57cec5SDimitry Andric     {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
690b57cec5SDimitry Andric     {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
700b57cec5SDimitry Andric     {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
710b57cec5SDimitry Andric     {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
720b57cec5SDimitry Andric     {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
730b57cec5SDimitry Andric     {{"sparclite86x"},
740b57cec5SDimitry Andric      SparcTargetInfo::CK_SPARCLITE86X,
750b57cec5SDimitry Andric      SparcTargetInfo::CG_V8},
760b57cec5SDimitry Andric     {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
770b57cec5SDimitry Andric     {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
780b57cec5SDimitry Andric     {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
790b57cec5SDimitry Andric     {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
800b57cec5SDimitry Andric     {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
810b57cec5SDimitry Andric     {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
820b57cec5SDimitry Andric     {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
830b57cec5SDimitry Andric     {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
840b57cec5SDimitry Andric     {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
850b57cec5SDimitry Andric     {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
860b57cec5SDimitry Andric     {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
870b57cec5SDimitry Andric     {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
880b57cec5SDimitry Andric     {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
890b57cec5SDimitry Andric     {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
900b57cec5SDimitry Andric     {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
910b57cec5SDimitry Andric     {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
920b57cec5SDimitry Andric     {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
930b57cec5SDimitry Andric     {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
940b57cec5SDimitry Andric     {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
950b57cec5SDimitry Andric     {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
960b57cec5SDimitry Andric     // FIXME: the myriad2[.n] spellings are obsolete,
970b57cec5SDimitry Andric     // but a grace period is needed to allow updating dependent builds.
980b57cec5SDimitry Andric     {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
990b57cec5SDimitry Andric     {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
1000b57cec5SDimitry Andric     {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
1010b57cec5SDimitry Andric     {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
1020b57cec5SDimitry Andric     {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
1030b57cec5SDimitry Andric     {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
1040b57cec5SDimitry Andric     {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
1050b57cec5SDimitry Andric     {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
1060b57cec5SDimitry Andric     {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
1070b57cec5SDimitry Andric     {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
1080b57cec5SDimitry Andric     {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
1090b57cec5SDimitry Andric     {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
1100b57cec5SDimitry Andric };
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration
1130b57cec5SDimitry Andric SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
1140b57cec5SDimitry Andric   if (Kind == CK_GENERIC)
1150b57cec5SDimitry Andric     return CG_V8;
1160b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
1170b57cec5SDimitry Andric       CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
1180b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
1190b57cec5SDimitry Andric     llvm_unreachable("Unexpected CPU kind");
1200b57cec5SDimitry Andric   return Item->Generation;
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
1240b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
1250b57cec5SDimitry Andric       CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
1280b57cec5SDimitry Andric     return CK_GENERIC;
1290b57cec5SDimitry Andric   return Item->Kind;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric void SparcTargetInfo::fillValidCPUList(
1330b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
1340b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
1350b57cec5SDimitry Andric     Values.push_back(Info.Name);
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
1390b57cec5SDimitry Andric                                        MacroBuilder &Builder) const {
1400b57cec5SDimitry Andric   DefineStd(Builder, "sparc", Opts);
1410b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   if (SoftFloat)
1440b57cec5SDimitry Andric     Builder.defineMacro("SOFT_FLOAT", "1");
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
1480b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
1490b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
150e8d8bef9SDimitry Andric   if (getTriple().getOS() == llvm::Triple::Solaris)
151e8d8bef9SDimitry Andric     Builder.defineMacro("__sparcv8");
152e8d8bef9SDimitry Andric   else {
1530b57cec5SDimitry Andric     switch (getCPUGeneration(CPU)) {
1540b57cec5SDimitry Andric     case CG_V8:
1550b57cec5SDimitry Andric       Builder.defineMacro("__sparcv8");
1560b57cec5SDimitry Andric       Builder.defineMacro("__sparcv8__");
1570b57cec5SDimitry Andric       break;
1580b57cec5SDimitry Andric     case CG_V9:
1590b57cec5SDimitry Andric       Builder.defineMacro("__sparc_v9__");
1600b57cec5SDimitry Andric       break;
1610b57cec5SDimitry Andric     }
162e8d8bef9SDimitry Andric   }
1630b57cec5SDimitry Andric   if (getTriple().getVendor() == llvm::Triple::Myriad) {
1640b57cec5SDimitry Andric     std::string MyriadArchValue, Myriad2Value;
1650b57cec5SDimitry Andric     Builder.defineMacro("__sparc_v8__");
1660b57cec5SDimitry Andric     Builder.defineMacro("__leon__");
1670b57cec5SDimitry Andric     switch (CPU) {
1680b57cec5SDimitry Andric     case CK_MYRIAD2100:
1690b57cec5SDimitry Andric       MyriadArchValue = "__ma2100";
1700b57cec5SDimitry Andric       Myriad2Value = "1";
1710b57cec5SDimitry Andric       break;
1720b57cec5SDimitry Andric     case CK_MYRIAD2150:
1730b57cec5SDimitry Andric       MyriadArchValue = "__ma2150";
1740b57cec5SDimitry Andric       Myriad2Value = "2";
1750b57cec5SDimitry Andric       break;
1760b57cec5SDimitry Andric     case CK_MYRIAD2155:
1770b57cec5SDimitry Andric       MyriadArchValue = "__ma2155";
1780b57cec5SDimitry Andric       Myriad2Value = "2";
1790b57cec5SDimitry Andric       break;
1800b57cec5SDimitry Andric     case CK_MYRIAD2450:
1810b57cec5SDimitry Andric       MyriadArchValue = "__ma2450";
1820b57cec5SDimitry Andric       Myriad2Value = "2";
1830b57cec5SDimitry Andric       break;
1840b57cec5SDimitry Andric     case CK_MYRIAD2455:
1850b57cec5SDimitry Andric       MyriadArchValue = "__ma2455";
1860b57cec5SDimitry Andric       Myriad2Value = "2";
1870b57cec5SDimitry Andric       break;
1880b57cec5SDimitry Andric     case CK_MYRIAD2x5x:
1890b57cec5SDimitry Andric       Myriad2Value = "2";
1900b57cec5SDimitry Andric       break;
1910b57cec5SDimitry Andric     case CK_MYRIAD2080:
1920b57cec5SDimitry Andric       MyriadArchValue = "__ma2080";
1930b57cec5SDimitry Andric       Myriad2Value = "3";
1940b57cec5SDimitry Andric       break;
1950b57cec5SDimitry Andric     case CK_MYRIAD2085:
1960b57cec5SDimitry Andric       MyriadArchValue = "__ma2085";
1970b57cec5SDimitry Andric       Myriad2Value = "3";
1980b57cec5SDimitry Andric       break;
1990b57cec5SDimitry Andric     case CK_MYRIAD2480:
2000b57cec5SDimitry Andric       MyriadArchValue = "__ma2480";
2010b57cec5SDimitry Andric       Myriad2Value = "3";
2020b57cec5SDimitry Andric       break;
2030b57cec5SDimitry Andric     case CK_MYRIAD2485:
2040b57cec5SDimitry Andric       MyriadArchValue = "__ma2485";
2050b57cec5SDimitry Andric       Myriad2Value = "3";
2060b57cec5SDimitry Andric       break;
2070b57cec5SDimitry Andric     case CK_MYRIAD2x8x:
2080b57cec5SDimitry Andric       Myriad2Value = "3";
2090b57cec5SDimitry Andric       break;
2100b57cec5SDimitry Andric     default:
2110b57cec5SDimitry Andric       MyriadArchValue = "__ma2100";
2120b57cec5SDimitry Andric       Myriad2Value = "1";
2130b57cec5SDimitry Andric       break;
2140b57cec5SDimitry Andric     }
2150b57cec5SDimitry Andric     if (!MyriadArchValue.empty()) {
2160b57cec5SDimitry Andric       Builder.defineMacro(MyriadArchValue, "1");
2170b57cec5SDimitry Andric       Builder.defineMacro(MyriadArchValue + "__", "1");
2180b57cec5SDimitry Andric     }
2190b57cec5SDimitry Andric     if (Myriad2Value == "2") {
2200b57cec5SDimitry Andric       Builder.defineMacro("__ma2x5x", "1");
2210b57cec5SDimitry Andric       Builder.defineMacro("__ma2x5x__", "1");
2220b57cec5SDimitry Andric     } else if (Myriad2Value == "3") {
2230b57cec5SDimitry Andric       Builder.defineMacro("__ma2x8x", "1");
2240b57cec5SDimitry Andric       Builder.defineMacro("__ma2x8x__", "1");
2250b57cec5SDimitry Andric     }
2260b57cec5SDimitry Andric     Builder.defineMacro("__myriad2__", Myriad2Value);
2270b57cec5SDimitry Andric     Builder.defineMacro("__myriad2", Myriad2Value);
2280b57cec5SDimitry Andric   }
229e8d8bef9SDimitry Andric   if (getCPUGeneration(CPU) == CG_V9) {
230e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
231e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
232e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
233e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
234e8d8bef9SDimitry Andric   }
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
2380b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
2390b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
2400b57cec5SDimitry Andric   Builder.defineMacro("__sparcv9");
2410b57cec5SDimitry Andric   Builder.defineMacro("__arch64__");
2420b57cec5SDimitry Andric   // Solaris doesn't need these variants, but the BSDs do.
2430b57cec5SDimitry Andric   if (getTriple().getOS() != llvm::Triple::Solaris) {
2440b57cec5SDimitry Andric     Builder.defineMacro("__sparc64__");
2450b57cec5SDimitry Andric     Builder.defineMacro("__sparc_v9__");
2460b57cec5SDimitry Andric     Builder.defineMacro("__sparcv9__");
2470b57cec5SDimitry Andric   }
24875b4d546SDimitry Andric 
24975b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
25075b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
25175b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
25275b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList(
2560b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
2570b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
2580b57cec5SDimitry Andric     if (Info.Generation == CG_V9)
2590b57cec5SDimitry Andric       Values.push_back(Info.Name);
2600b57cec5SDimitry Andric }
261