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