/src/llvm-project/clang/lib/Basic/Targets/Sparc.cpp
Line | Count | Source (jump to first uncovered line) |
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. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "Sparc.h" |
14 | | #include "Targets.h" |
15 | | #include "clang/Basic/MacroBuilder.h" |
16 | | #include "llvm/ADT/StringSwitch.h" |
17 | | |
18 | | using namespace clang; |
19 | | using namespace clang::targets; |
20 | | |
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", |
26 | | |
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", |
33 | | }; |
34 | | |
35 | 0 | ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { |
36 | 0 | return llvm::ArrayRef(GCCRegNames); |
37 | 0 | } |
38 | | |
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"}, |
48 | | }; |
49 | | |
50 | 0 | ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { |
51 | 0 | return llvm::ArrayRef(GCCRegAliases); |
52 | 0 | } |
53 | | |
54 | 0 | bool SparcTargetInfo::hasFeature(StringRef Feature) const { |
55 | 0 | return llvm::StringSwitch<bool>(Feature) |
56 | 0 | .Case("softfloat", SoftFloat) |
57 | 0 | .Case("sparc", true) |
58 | 0 | .Default(false); |
59 | 0 | } |
60 | | |
61 | | struct SparcCPUInfo { |
62 | | llvm::StringLiteral Name; |
63 | | SparcTargetInfo::CPUKind Kind; |
64 | | SparcTargetInfo::CPUGeneration Generation; |
65 | | }; |
66 | | |
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 | | {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, |
97 | | {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, |
98 | | {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, |
99 | | {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, |
100 | | {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, |
101 | | {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, |
102 | | {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, |
103 | | {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, |
104 | | }; |
105 | | |
106 | | SparcTargetInfo::CPUGeneration |
107 | 0 | SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { |
108 | 0 | if (Kind == CK_GENERIC) |
109 | 0 | return CG_V8; |
110 | 0 | const SparcCPUInfo *Item = llvm::find_if( |
111 | 0 | CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); |
112 | 0 | if (Item == std::end(CPUInfo)) |
113 | 0 | llvm_unreachable("Unexpected CPU kind"); |
114 | 0 | return Item->Generation; |
115 | 0 | } |
116 | | |
117 | 0 | SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { |
118 | 0 | const SparcCPUInfo *Item = llvm::find_if( |
119 | 0 | CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); |
120 | |
|
121 | 0 | if (Item == std::end(CPUInfo)) |
122 | 0 | return CK_GENERIC; |
123 | 0 | return Item->Kind; |
124 | 0 | } |
125 | | |
126 | | void SparcTargetInfo::fillValidCPUList( |
127 | 0 | SmallVectorImpl<StringRef> &Values) const { |
128 | 0 | for (const SparcCPUInfo &Info : CPUInfo) |
129 | 0 | Values.push_back(Info.Name); |
130 | 0 | } |
131 | | |
132 | | void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, |
133 | 0 | MacroBuilder &Builder) const { |
134 | 0 | DefineStd(Builder, "sparc", Opts); |
135 | 0 | Builder.defineMacro("__REGISTER_PREFIX__", ""); |
136 | |
|
137 | 0 | if (SoftFloat) |
138 | 0 | Builder.defineMacro("SOFT_FLOAT", "1"); |
139 | 0 | } |
140 | | |
141 | | void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, |
142 | 0 | MacroBuilder &Builder) const { |
143 | 0 | SparcTargetInfo::getTargetDefines(Opts, Builder); |
144 | 0 | if (getTriple().isOSSolaris()) |
145 | 0 | Builder.defineMacro("__sparcv8"); |
146 | 0 | else { |
147 | 0 | switch (getCPUGeneration(CPU)) { |
148 | 0 | case CG_V8: |
149 | 0 | Builder.defineMacro("__sparcv8"); |
150 | 0 | Builder.defineMacro("__sparcv8__"); |
151 | 0 | break; |
152 | 0 | case CG_V9: |
153 | 0 | Builder.defineMacro("__sparc_v9__"); |
154 | 0 | break; |
155 | 0 | } |
156 | 0 | } |
157 | 0 | if (getCPUGeneration(CPU) == CG_V9) { |
158 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
159 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
160 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
161 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
162 | 0 | } |
163 | 0 | } |
164 | | |
165 | | void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, |
166 | 0 | MacroBuilder &Builder) const { |
167 | 0 | SparcTargetInfo::getTargetDefines(Opts, Builder); |
168 | 0 | Builder.defineMacro("__sparcv9"); |
169 | 0 | Builder.defineMacro("__arch64__"); |
170 | | // Solaris doesn't need these variants, but the BSDs do. |
171 | 0 | if (!getTriple().isOSSolaris()) { |
172 | 0 | Builder.defineMacro("__sparc64__"); |
173 | 0 | Builder.defineMacro("__sparc_v9__"); |
174 | 0 | Builder.defineMacro("__sparcv9__"); |
175 | 0 | } |
176 | |
|
177 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
178 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
179 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
180 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
181 | 0 | } |
182 | | |
183 | | void SparcV9TargetInfo::fillValidCPUList( |
184 | 0 | SmallVectorImpl<StringRef> &Values) const { |
185 | 0 | for (const SparcCPUInfo &Info : CPUInfo) |
186 | 0 | if (Info.Generation == CG_V9) |
187 | 0 | Values.push_back(Info.Name); |
188 | 0 | } |