xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file implements Sparc TargetInfo objects.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "Sparc.h"
14*0b57cec5SDimitry Andric #include "Targets.h"
15*0b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h"
16*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
17*0b57cec5SDimitry Andric 
18*0b57cec5SDimitry Andric using namespace clang;
19*0b57cec5SDimitry Andric using namespace clang::targets;
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric const char *const SparcTargetInfo::GCCRegNames[] = {
22*0b57cec5SDimitry Andric     // Integer registers
23*0b57cec5SDimitry Andric     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
24*0b57cec5SDimitry Andric     "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
25*0b57cec5SDimitry Andric     "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric     // Floating-point registers
28*0b57cec5SDimitry Andric     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10",
29*0b57cec5SDimitry Andric     "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
30*0b57cec5SDimitry Andric     "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
31*0b57cec5SDimitry Andric     "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
32*0b57cec5SDimitry Andric     "f56", "f58", "f60", "f62",
33*0b57cec5SDimitry Andric };
34*0b57cec5SDimitry Andric 
35*0b57cec5SDimitry Andric ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36*0b57cec5SDimitry Andric   return llvm::makeArrayRef(GCCRegNames);
37*0b57cec5SDimitry Andric }
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
40*0b57cec5SDimitry Andric     {{"g0"}, "r0"},  {{"g1"}, "r1"},  {{"g2"}, "r2"},        {{"g3"}, "r3"},
41*0b57cec5SDimitry Andric     {{"g4"}, "r4"},  {{"g5"}, "r5"},  {{"g6"}, "r6"},        {{"g7"}, "r7"},
42*0b57cec5SDimitry Andric     {{"o0"}, "r8"},  {{"o1"}, "r9"},  {{"o2"}, "r10"},       {{"o3"}, "r11"},
43*0b57cec5SDimitry Andric     {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
44*0b57cec5SDimitry Andric     {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"},       {{"l3"}, "r19"},
45*0b57cec5SDimitry Andric     {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"},       {{"l7"}, "r23"},
46*0b57cec5SDimitry Andric     {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"},       {{"i3"}, "r27"},
47*0b57cec5SDimitry Andric     {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
48*0b57cec5SDimitry Andric };
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51*0b57cec5SDimitry Andric   return llvm::makeArrayRef(GCCRegAliases);
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric bool SparcTargetInfo::hasFeature(StringRef Feature) const {
55*0b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
56*0b57cec5SDimitry Andric       .Case("softfloat", SoftFloat)
57*0b57cec5SDimitry Andric       .Case("sparc", true)
58*0b57cec5SDimitry Andric       .Default(false);
59*0b57cec5SDimitry Andric }
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric struct SparcCPUInfo {
62*0b57cec5SDimitry Andric   llvm::StringLiteral Name;
63*0b57cec5SDimitry Andric   SparcTargetInfo::CPUKind Kind;
64*0b57cec5SDimitry Andric   SparcTargetInfo::CPUGeneration Generation;
65*0b57cec5SDimitry Andric };
66*0b57cec5SDimitry Andric 
67*0b57cec5SDimitry Andric static constexpr SparcCPUInfo CPUInfo[] = {
68*0b57cec5SDimitry Andric     {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
69*0b57cec5SDimitry Andric     {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
70*0b57cec5SDimitry Andric     {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
71*0b57cec5SDimitry Andric     {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
72*0b57cec5SDimitry Andric     {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
73*0b57cec5SDimitry Andric     {{"sparclite86x"},
74*0b57cec5SDimitry Andric      SparcTargetInfo::CK_SPARCLITE86X,
75*0b57cec5SDimitry Andric      SparcTargetInfo::CG_V8},
76*0b57cec5SDimitry Andric     {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
77*0b57cec5SDimitry Andric     {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
78*0b57cec5SDimitry Andric     {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
79*0b57cec5SDimitry Andric     {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
80*0b57cec5SDimitry Andric     {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
81*0b57cec5SDimitry Andric     {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
82*0b57cec5SDimitry Andric     {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
83*0b57cec5SDimitry Andric     {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
84*0b57cec5SDimitry Andric     {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
85*0b57cec5SDimitry Andric     {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
86*0b57cec5SDimitry Andric     {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
87*0b57cec5SDimitry Andric     {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
88*0b57cec5SDimitry Andric     {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
89*0b57cec5SDimitry Andric     {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
90*0b57cec5SDimitry Andric     {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
91*0b57cec5SDimitry Andric     {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
92*0b57cec5SDimitry Andric     {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
93*0b57cec5SDimitry Andric     {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
94*0b57cec5SDimitry Andric     {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
95*0b57cec5SDimitry Andric     {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
96*0b57cec5SDimitry Andric     // FIXME: the myriad2[.n] spellings are obsolete,
97*0b57cec5SDimitry Andric     // but a grace period is needed to allow updating dependent builds.
98*0b57cec5SDimitry Andric     {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
99*0b57cec5SDimitry Andric     {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
100*0b57cec5SDimitry Andric     {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
101*0b57cec5SDimitry Andric     {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
102*0b57cec5SDimitry Andric     {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
103*0b57cec5SDimitry Andric     {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
104*0b57cec5SDimitry Andric     {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
105*0b57cec5SDimitry Andric     {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
106*0b57cec5SDimitry Andric     {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
107*0b57cec5SDimitry Andric     {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
108*0b57cec5SDimitry Andric     {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
109*0b57cec5SDimitry Andric     {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
110*0b57cec5SDimitry Andric };
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration
113*0b57cec5SDimitry Andric SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
114*0b57cec5SDimitry Andric   if (Kind == CK_GENERIC)
115*0b57cec5SDimitry Andric     return CG_V8;
116*0b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
117*0b57cec5SDimitry Andric       CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
118*0b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
119*0b57cec5SDimitry Andric     llvm_unreachable("Unexpected CPU kind");
120*0b57cec5SDimitry Andric   return Item->Generation;
121*0b57cec5SDimitry Andric }
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
124*0b57cec5SDimitry Andric   const SparcCPUInfo *Item = llvm::find_if(
125*0b57cec5SDimitry Andric       CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric   if (Item == std::end(CPUInfo))
128*0b57cec5SDimitry Andric     return CK_GENERIC;
129*0b57cec5SDimitry Andric   return Item->Kind;
130*0b57cec5SDimitry Andric }
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric void SparcTargetInfo::fillValidCPUList(
133*0b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
134*0b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
135*0b57cec5SDimitry Andric     Values.push_back(Info.Name);
136*0b57cec5SDimitry Andric }
137*0b57cec5SDimitry Andric 
138*0b57cec5SDimitry Andric void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
139*0b57cec5SDimitry Andric                                        MacroBuilder &Builder) const {
140*0b57cec5SDimitry Andric   DefineStd(Builder, "sparc", Opts);
141*0b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric   if (SoftFloat)
144*0b57cec5SDimitry Andric     Builder.defineMacro("SOFT_FLOAT", "1");
145*0b57cec5SDimitry Andric }
146*0b57cec5SDimitry Andric 
147*0b57cec5SDimitry Andric void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
148*0b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
149*0b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
150*0b57cec5SDimitry Andric   switch (getCPUGeneration(CPU)) {
151*0b57cec5SDimitry Andric   case CG_V8:
152*0b57cec5SDimitry Andric     Builder.defineMacro("__sparcv8");
153*0b57cec5SDimitry Andric     if (getTriple().getOS() != llvm::Triple::Solaris)
154*0b57cec5SDimitry Andric       Builder.defineMacro("__sparcv8__");
155*0b57cec5SDimitry Andric     break;
156*0b57cec5SDimitry Andric   case CG_V9:
157*0b57cec5SDimitry Andric     Builder.defineMacro("__sparcv9");
158*0b57cec5SDimitry Andric     if (getTriple().getOS() != llvm::Triple::Solaris) {
159*0b57cec5SDimitry Andric       Builder.defineMacro("__sparcv9__");
160*0b57cec5SDimitry Andric       Builder.defineMacro("__sparc_v9__");
161*0b57cec5SDimitry Andric     }
162*0b57cec5SDimitry Andric     break;
163*0b57cec5SDimitry Andric   }
164*0b57cec5SDimitry Andric   if (getTriple().getVendor() == llvm::Triple::Myriad) {
165*0b57cec5SDimitry Andric     std::string MyriadArchValue, Myriad2Value;
166*0b57cec5SDimitry Andric     Builder.defineMacro("__sparc_v8__");
167*0b57cec5SDimitry Andric     Builder.defineMacro("__leon__");
168*0b57cec5SDimitry Andric     switch (CPU) {
169*0b57cec5SDimitry Andric     case CK_MYRIAD2100:
170*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2100";
171*0b57cec5SDimitry Andric       Myriad2Value = "1";
172*0b57cec5SDimitry Andric       break;
173*0b57cec5SDimitry Andric     case CK_MYRIAD2150:
174*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2150";
175*0b57cec5SDimitry Andric       Myriad2Value = "2";
176*0b57cec5SDimitry Andric       break;
177*0b57cec5SDimitry Andric     case CK_MYRIAD2155:
178*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2155";
179*0b57cec5SDimitry Andric       Myriad2Value = "2";
180*0b57cec5SDimitry Andric       break;
181*0b57cec5SDimitry Andric     case CK_MYRIAD2450:
182*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2450";
183*0b57cec5SDimitry Andric       Myriad2Value = "2";
184*0b57cec5SDimitry Andric       break;
185*0b57cec5SDimitry Andric     case CK_MYRIAD2455:
186*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2455";
187*0b57cec5SDimitry Andric       Myriad2Value = "2";
188*0b57cec5SDimitry Andric       break;
189*0b57cec5SDimitry Andric     case CK_MYRIAD2x5x:
190*0b57cec5SDimitry Andric       Myriad2Value = "2";
191*0b57cec5SDimitry Andric       break;
192*0b57cec5SDimitry Andric     case CK_MYRIAD2080:
193*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2080";
194*0b57cec5SDimitry Andric       Myriad2Value = "3";
195*0b57cec5SDimitry Andric       break;
196*0b57cec5SDimitry Andric     case CK_MYRIAD2085:
197*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2085";
198*0b57cec5SDimitry Andric       Myriad2Value = "3";
199*0b57cec5SDimitry Andric       break;
200*0b57cec5SDimitry Andric     case CK_MYRIAD2480:
201*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2480";
202*0b57cec5SDimitry Andric       Myriad2Value = "3";
203*0b57cec5SDimitry Andric       break;
204*0b57cec5SDimitry Andric     case CK_MYRIAD2485:
205*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2485";
206*0b57cec5SDimitry Andric       Myriad2Value = "3";
207*0b57cec5SDimitry Andric       break;
208*0b57cec5SDimitry Andric     case CK_MYRIAD2x8x:
209*0b57cec5SDimitry Andric       Myriad2Value = "3";
210*0b57cec5SDimitry Andric       break;
211*0b57cec5SDimitry Andric     default:
212*0b57cec5SDimitry Andric       MyriadArchValue = "__ma2100";
213*0b57cec5SDimitry Andric       Myriad2Value = "1";
214*0b57cec5SDimitry Andric       break;
215*0b57cec5SDimitry Andric     }
216*0b57cec5SDimitry Andric     if (!MyriadArchValue.empty()) {
217*0b57cec5SDimitry Andric       Builder.defineMacro(MyriadArchValue, "1");
218*0b57cec5SDimitry Andric       Builder.defineMacro(MyriadArchValue + "__", "1");
219*0b57cec5SDimitry Andric     }
220*0b57cec5SDimitry Andric     if (Myriad2Value == "2") {
221*0b57cec5SDimitry Andric       Builder.defineMacro("__ma2x5x", "1");
222*0b57cec5SDimitry Andric       Builder.defineMacro("__ma2x5x__", "1");
223*0b57cec5SDimitry Andric     } else if (Myriad2Value == "3") {
224*0b57cec5SDimitry Andric       Builder.defineMacro("__ma2x8x", "1");
225*0b57cec5SDimitry Andric       Builder.defineMacro("__ma2x8x__", "1");
226*0b57cec5SDimitry Andric     }
227*0b57cec5SDimitry Andric     Builder.defineMacro("__myriad2__", Myriad2Value);
228*0b57cec5SDimitry Andric     Builder.defineMacro("__myriad2", Myriad2Value);
229*0b57cec5SDimitry Andric   }
230*0b57cec5SDimitry Andric }
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
233*0b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
234*0b57cec5SDimitry Andric   SparcTargetInfo::getTargetDefines(Opts, Builder);
235*0b57cec5SDimitry Andric   Builder.defineMacro("__sparcv9");
236*0b57cec5SDimitry Andric   Builder.defineMacro("__arch64__");
237*0b57cec5SDimitry Andric   // Solaris doesn't need these variants, but the BSDs do.
238*0b57cec5SDimitry Andric   if (getTriple().getOS() != llvm::Triple::Solaris) {
239*0b57cec5SDimitry Andric     Builder.defineMacro("__sparc64__");
240*0b57cec5SDimitry Andric     Builder.defineMacro("__sparc_v9__");
241*0b57cec5SDimitry Andric     Builder.defineMacro("__sparcv9__");
242*0b57cec5SDimitry Andric   }
243*0b57cec5SDimitry Andric }
244*0b57cec5SDimitry Andric 
245*0b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList(
246*0b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
247*0b57cec5SDimitry Andric   for (const SparcCPUInfo &Info : CPUInfo)
248*0b57cec5SDimitry Andric     if (Info.Generation == CG_V9)
249*0b57cec5SDimitry Andric       Values.push_back(Info.Name);
250*0b57cec5SDimitry Andric }
251