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