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 switch (getCPUGeneration(CPU)) {
152 Builder.defineMacro("__sparcv8");
153 if (getTriple().getOS() != llvm::Triple::Solaris)
154 Builder.defineMacro("__sparcv8__");
157 Builder.defineMacro("__sparcv9");
158 if (getTriple().getOS() != llvm::Triple::Solaris) {
159 Builder.defineMacro("__sparcv9__");
160 Builder.defineMacro("__sparc_v9__");
164 if (getTriple().getVendor() == llvm::Triple::Myriad) {
165 std::string MyriadArchValue, Myriad2Value;
166 Builder.defineMacro("__sparc_v8__");
167 Builder.defineMacro("__leon__");
170 MyriadArchValue = "__ma2100";
174 MyriadArchValue = "__ma2150";
178 MyriadArchValue = "__ma2155";
182 MyriadArchValue = "__ma2450";
186 MyriadArchValue = "__ma2455";
193 MyriadArchValue = "__ma2080";
197 MyriadArchValue = "__ma2085";
201 MyriadArchValue = "__ma2480";
205 MyriadArchValue = "__ma2485";
212 MyriadArchValue = "__ma2100";
216 if (!MyriadArchValue.empty()) {
217 Builder.defineMacro(MyriadArchValue, "1");
218 Builder.defineMacro(MyriadArchValue + "__", "1");
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");
227 Builder.defineMacro("__myriad2__", Myriad2Value);
228 Builder.defineMacro("__myriad2", Myriad2Value);
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__");
245 void SparcV9TargetInfo::fillValidCPUList(
246 SmallVectorImpl<StringRef> &Values) const {
247 for (const SparcCPUInfo &Info : CPUInfo)
248 if (Info.Generation == CG_V9)
249 Values.push_back(Info.Name);