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