[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / lib / Basic / Targets / Sparc.cpp
blob4548902ca12b9e19c2a0f39fcc004ef474b69d10
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.
11 //===----------------------------------------------------------------------===//
13 #include "Sparc.h"
14 #include "Targets.h"
15 #include "clang/Basic/MacroBuilder.h"
16 #include "llvm/ADT/StringSwitch.h"
18 using namespace clang;
19 using namespace clang::targets;
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",
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",
35 ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36 return llvm::ArrayRef(GCCRegNames);
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"},
50 ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51 return llvm::ArrayRef(GCCRegAliases);
54 bool SparcTargetInfo::hasFeature(StringRef Feature) const {
55 return llvm::StringSwitch<bool>(Feature)
56 .Case("softfloat", SoftFloat)
57 .Case("sparc", true)
58 .Default(false);
61 struct SparcCPUInfo {
62 llvm::StringLiteral Name;
63 SparcTargetInfo::CPUKind Kind;
64 SparcTargetInfo::CPUGeneration Generation;
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},
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;
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; });
127 if (Item == std::end(CPUInfo))
128 return CK_GENERIC;
129 return Item->Kind;
132 void SparcTargetInfo::fillValidCPUList(
133 SmallVectorImpl<StringRef> &Values) const {
134 for (const SparcCPUInfo &Info : CPUInfo)
135 Values.push_back(Info.Name);
138 void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
139 MacroBuilder &Builder) const {
140 DefineStd(Builder, "sparc", Opts);
141 Builder.defineMacro("__REGISTER_PREFIX__", "");
143 if (SoftFloat)
144 Builder.defineMacro("SOFT_FLOAT", "1");
147 void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
148 MacroBuilder &Builder) const {
149 SparcTargetInfo::getTargetDefines(Opts, Builder);
150 if (getTriple().getOS() == llvm::Triple::Solaris)
151 Builder.defineMacro("__sparcv8");
152 else {
153 switch (getCPUGeneration(CPU)) {
154 case CG_V8:
155 Builder.defineMacro("__sparcv8");
156 Builder.defineMacro("__sparcv8__");
157 break;
158 case CG_V9:
159 Builder.defineMacro("__sparc_v9__");
160 break;
163 if (getTriple().getVendor() == llvm::Triple::Myriad) {
164 std::string MyriadArchValue, Myriad2Value;
165 Builder.defineMacro("__sparc_v8__");
166 Builder.defineMacro("__leon__");
167 switch (CPU) {
168 case CK_MYRIAD2100:
169 MyriadArchValue = "__ma2100";
170 Myriad2Value = "1";
171 break;
172 case CK_MYRIAD2150:
173 MyriadArchValue = "__ma2150";
174 Myriad2Value = "2";
175 break;
176 case CK_MYRIAD2155:
177 MyriadArchValue = "__ma2155";
178 Myriad2Value = "2";
179 break;
180 case CK_MYRIAD2450:
181 MyriadArchValue = "__ma2450";
182 Myriad2Value = "2";
183 break;
184 case CK_MYRIAD2455:
185 MyriadArchValue = "__ma2455";
186 Myriad2Value = "2";
187 break;
188 case CK_MYRIAD2x5x:
189 Myriad2Value = "2";
190 break;
191 case CK_MYRIAD2080:
192 MyriadArchValue = "__ma2080";
193 Myriad2Value = "3";
194 break;
195 case CK_MYRIAD2085:
196 MyriadArchValue = "__ma2085";
197 Myriad2Value = "3";
198 break;
199 case CK_MYRIAD2480:
200 MyriadArchValue = "__ma2480";
201 Myriad2Value = "3";
202 break;
203 case CK_MYRIAD2485:
204 MyriadArchValue = "__ma2485";
205 Myriad2Value = "3";
206 break;
207 case CK_MYRIAD2x8x:
208 Myriad2Value = "3";
209 break;
210 default:
211 MyriadArchValue = "__ma2100";
212 Myriad2Value = "1";
213 break;
215 if (!MyriadArchValue.empty()) {
216 Builder.defineMacro(MyriadArchValue, "1");
217 Builder.defineMacro(MyriadArchValue + "__", "1");
219 if (Myriad2Value == "2") {
220 Builder.defineMacro("__ma2x5x", "1");
221 Builder.defineMacro("__ma2x5x__", "1");
222 } else if (Myriad2Value == "3") {
223 Builder.defineMacro("__ma2x8x", "1");
224 Builder.defineMacro("__ma2x8x__", "1");
226 Builder.defineMacro("__myriad2__", Myriad2Value);
227 Builder.defineMacro("__myriad2", Myriad2Value);
229 if (getCPUGeneration(CPU) == CG_V9) {
230 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
231 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
232 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
233 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
237 void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
238 MacroBuilder &Builder) const {
239 SparcTargetInfo::getTargetDefines(Opts, Builder);
240 Builder.defineMacro("__sparcv9");
241 Builder.defineMacro("__arch64__");
242 // Solaris doesn't need these variants, but the BSDs do.
243 if (getTriple().getOS() != llvm::Triple::Solaris) {
244 Builder.defineMacro("__sparc64__");
245 Builder.defineMacro("__sparc_v9__");
246 Builder.defineMacro("__sparcv9__");
249 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
250 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
251 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
252 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
255 void SparcV9TargetInfo::fillValidCPUList(
256 SmallVectorImpl<StringRef> &Values) const {
257 for (const SparcCPUInfo &Info : CPUInfo)
258 if (Info.Generation == CG_V9)
259 Values.push_back(Info.Name);