xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 {
36bdd1243dSDimitry 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 {
51bdd1243dSDimitry 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     {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
970b57cec5SDimitry Andric     {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
980b57cec5SDimitry Andric     {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
990b57cec5SDimitry Andric     {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
1000b57cec5SDimitry Andric     {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
1010b57cec5SDimitry Andric     {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
1020b57cec5SDimitry Andric     {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
1030b57cec5SDimitry Andric     {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
1040b57cec5SDimitry Andric };
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration
1070b57cec5SDimitry Andric SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
1080b57cec5SDimitry Andric   if (Kind == CK_GENERIC)
1090b57cec5SDimitry Andric     return CG_V8;
1100b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
1110b57cec5SDimitry Andric       CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
1120b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
1130b57cec5SDimitry Andric     llvm_unreachable("Unexpected CPU kind");
1140b57cec5SDimitry Andric   return Item->Generation;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
1180b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
1190b57cec5SDimitry Andric       CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
1220b57cec5SDimitry Andric     return CK_GENERIC;
1230b57cec5SDimitry Andric   return Item->Kind;
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric void SparcTargetInfo::fillValidCPUList(
1270b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
1280b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
1290b57cec5SDimitry Andric     Values.push_back(Info.Name);
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
1330b57cec5SDimitry Andric                                        MacroBuilder &Builder) const {
1340b57cec5SDimitry Andric   DefineStd(Builder, "sparc", Opts);
1350b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   if (SoftFloat)
1380b57cec5SDimitry Andric     Builder.defineMacro("SOFT_FLOAT", "1");
1390b57cec5SDimitry Andric }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
1420b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
1430b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
144*5f757f3fSDimitry Andric   if (getTriple().isOSSolaris())
145e8d8bef9SDimitry Andric     Builder.defineMacro("__sparcv8");
146e8d8bef9SDimitry Andric   else {
1470b57cec5SDimitry Andric     switch (getCPUGeneration(CPU)) {
1480b57cec5SDimitry Andric     case CG_V8:
1490b57cec5SDimitry Andric       Builder.defineMacro("__sparcv8");
1500b57cec5SDimitry Andric       Builder.defineMacro("__sparcv8__");
1510b57cec5SDimitry Andric       break;
1520b57cec5SDimitry Andric     case CG_V9:
1530b57cec5SDimitry Andric       Builder.defineMacro("__sparc_v9__");
1540b57cec5SDimitry Andric       break;
1550b57cec5SDimitry Andric     }
156e8d8bef9SDimitry Andric   }
157e8d8bef9SDimitry Andric   if (getCPUGeneration(CPU) == CG_V9) {
158e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
159e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
160e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
161e8d8bef9SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
162e8d8bef9SDimitry Andric   }
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
1660b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
1670b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
1680b57cec5SDimitry Andric   Builder.defineMacro("__sparcv9");
1690b57cec5SDimitry Andric   Builder.defineMacro("__arch64__");
1700b57cec5SDimitry Andric   // Solaris doesn't need these variants, but the BSDs do.
171*5f757f3fSDimitry Andric   if (!getTriple().isOSSolaris()) {
1720b57cec5SDimitry Andric     Builder.defineMacro("__sparc64__");
1730b57cec5SDimitry Andric     Builder.defineMacro("__sparc_v9__");
1740b57cec5SDimitry Andric     Builder.defineMacro("__sparcv9__");
1750b57cec5SDimitry Andric   }
17675b4d546SDimitry Andric 
17775b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
17875b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
17975b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
18075b4d546SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList(
1840b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
1850b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
1860b57cec5SDimitry Andric     if (Info.Generation == CG_V9)
1870b57cec5SDimitry Andric       Values.push_back(Info.Name);
1880b57cec5SDimitry Andric }
189