1 //===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements Sparc TargetInfo objects.
12 //===----------------------------------------------------------------------===//
16 #include "clang/Basic/MacroBuilder.h"
17 #include "llvm/ADT/StringSwitch.h"
19 using namespace clang;
20 using namespace clang::targets;
22 const char *const SparcTargetInfo::GCCRegNames[] = {
24 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
25 "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
26 "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
28 // Floating-point registers
29 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
30 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
31 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
32 "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
33 "f56", "f58", "f60", "f62",
36 ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
37 return llvm::makeArrayRef(GCCRegNames);
40 const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
41 {{"g0"}, "r0"}, {{"g1"}, "r1"}, {{"g2"}, "r2"}, {{"g3"}, "r3"},
42 {{"g4"}, "r4"}, {{"g5"}, "r5"}, {{"g6"}, "r6"}, {{"g7"}, "r7"},
43 {{"o0"}, "r8"}, {{"o1"}, "r9"}, {{"o2"}, "r10"}, {{"o3"}, "r11"},
44 {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
45 {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"}, {{"l3"}, "r19"},
46 {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"}, {{"l7"}, "r23"},
47 {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"}, {{"i3"}, "r27"},
48 {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
51 ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
52 return llvm::makeArrayRef(GCCRegAliases);
55 bool SparcTargetInfo::hasFeature(StringRef Feature) const {
56 return llvm::StringSwitch<bool>(Feature)
57 .Case("softfloat", SoftFloat)
63 llvm::StringLiteral Name;
64 SparcTargetInfo::CPUKind Kind;
65 SparcTargetInfo::CPUGeneration Generation;
68 static constexpr SparcCPUInfo CPUInfo[] = {
69 {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
70 {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
71 {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
72 {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
73 {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
75 SparcTargetInfo::CK_SPARCLITE86X,
76 SparcTargetInfo::CG_V8},
77 {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
78 {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
79 {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
80 {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
81 {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
82 {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
83 {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
84 {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
85 {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
86 {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
87 {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
88 {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
89 {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
90 {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
91 {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
92 {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
93 {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
94 {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
95 {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
96 {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
97 // FIXME: the myriad2[.n] spellings are obsolete,
98 // but a grace period is needed to allow updating dependent builds.
99 {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
100 {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
101 {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
102 {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
103 {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
104 {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
105 {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
106 {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
107 {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
108 {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
109 {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
110 {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
113 SparcTargetInfo::CPUGeneration
114 SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
115 if (Kind == CK_GENERIC)
117 const SparcCPUInfo *Item = llvm::find_if(
118 CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
119 if (Item == std::end(CPUInfo))
120 llvm_unreachable("Unexpected CPU kind");
121 return Item->Generation;
124 SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
125 const SparcCPUInfo *Item = llvm::find_if(
126 CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
128 if (Item == std::end(CPUInfo))
133 void SparcTargetInfo::fillValidCPUList(
134 SmallVectorImpl<StringRef> &Values) const {
135 for (const SparcCPUInfo &Info : CPUInfo)
136 Values.push_back(Info.Name);
139 void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
140 MacroBuilder &Builder) const {
141 DefineStd(Builder, "sparc", Opts);
142 Builder.defineMacro("__REGISTER_PREFIX__", "");
145 Builder.defineMacro("SOFT_FLOAT", "1");
148 void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
149 MacroBuilder &Builder) const {
150 SparcTargetInfo::getTargetDefines(Opts, Builder);
151 switch (getCPUGeneration(CPU)) {
153 Builder.defineMacro("__sparcv8");
154 if (getTriple().getOS() != llvm::Triple::Solaris)
155 Builder.defineMacro("__sparcv8__");
158 Builder.defineMacro("__sparcv9");
159 if (getTriple().getOS() != llvm::Triple::Solaris) {
160 Builder.defineMacro("__sparcv9__");
161 Builder.defineMacro("__sparc_v9__");
165 if (getTriple().getVendor() == llvm::Triple::Myriad) {
166 std::string MyriadArchValue, Myriad2Value;
167 Builder.defineMacro("__sparc_v8__");
168 Builder.defineMacro("__leon__");
171 MyriadArchValue = "__ma2100";
175 MyriadArchValue = "__ma2150";
179 MyriadArchValue = "__ma2155";
183 MyriadArchValue = "__ma2450";
187 MyriadArchValue = "__ma2455";
194 MyriadArchValue = "__ma2080";
198 MyriadArchValue = "__ma2085";
202 MyriadArchValue = "__ma2480";
206 MyriadArchValue = "__ma2485";
213 MyriadArchValue = "__ma2100";
217 if (!MyriadArchValue.empty()) {
218 Builder.defineMacro(MyriadArchValue, "1");
219 Builder.defineMacro(MyriadArchValue + "__", "1");
221 if (Myriad2Value == "2") {
222 Builder.defineMacro("__ma2x5x", "1");
223 Builder.defineMacro("__ma2x5x__", "1");
224 } else if (Myriad2Value == "3") {
225 Builder.defineMacro("__ma2x8x", "1");
226 Builder.defineMacro("__ma2x8x__", "1");
228 Builder.defineMacro("__myriad2__", Myriad2Value);
229 Builder.defineMacro("__myriad2", Myriad2Value);
233 void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
234 MacroBuilder &Builder) const {
235 SparcTargetInfo::getTargetDefines(Opts, Builder);
236 Builder.defineMacro("__sparcv9");
237 Builder.defineMacro("__arch64__");
238 // Solaris doesn't need these variants, but the BSDs do.
239 if (getTriple().getOS() != llvm::Triple::Solaris) {
240 Builder.defineMacro("__sparc64__");
241 Builder.defineMacro("__sparc_v9__");
242 Builder.defineMacro("__sparcv9__");
246 void SparcV9TargetInfo::fillValidCPUList(
247 SmallVectorImpl<StringRef> &Values) const {
248 for (const SparcCPUInfo &Info : CPUInfo)
249 if (Info.Generation == CG_V9)
250 Values.push_back(Info.Name);