1 //===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements Sparc TargetInfo objects.
11 //===----------------------------------------------------------------------===//
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
[] = {
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::makeArrayRef(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::makeArrayRef(GCCRegAliases
);
54 bool SparcTargetInfo::hasFeature(StringRef Feature
) const {
55 return llvm::StringSwitch
<bool>(Feature
)
56 .Case("softfloat", SoftFloat
)
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
},
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
)
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
))
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__", "");
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");
153 switch (getCPUGeneration(CPU
)) {
155 Builder
.defineMacro("__sparcv8");
156 Builder
.defineMacro("__sparcv8__");
159 Builder
.defineMacro("__sparc_v9__");
163 if (getTriple().getVendor() == llvm::Triple::Myriad
) {
164 std::string MyriadArchValue
, Myriad2Value
;
165 Builder
.defineMacro("__sparc_v8__");
166 Builder
.defineMacro("__leon__");
169 MyriadArchValue
= "__ma2100";
173 MyriadArchValue
= "__ma2150";
177 MyriadArchValue
= "__ma2155";
181 MyriadArchValue
= "__ma2450";
185 MyriadArchValue
= "__ma2455";
192 MyriadArchValue
= "__ma2080";
196 MyriadArchValue
= "__ma2085";
200 MyriadArchValue
= "__ma2480";
204 MyriadArchValue
= "__ma2485";
211 MyriadArchValue
= "__ma2100";
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
);