/src/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Hexagon.cpp - Implement Hexagon 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 Hexagon TargetInfo objects. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "Hexagon.h" |
14 | | #include "Targets.h" |
15 | | #include "clang/Basic/MacroBuilder.h" |
16 | | #include "clang/Basic/TargetBuiltins.h" |
17 | | #include "llvm/ADT/StringSwitch.h" |
18 | | |
19 | | using namespace clang; |
20 | | using namespace clang::targets; |
21 | | |
22 | | void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, |
23 | 0 | MacroBuilder &Builder) const { |
24 | 0 | Builder.defineMacro("__qdsp6__", "1"); |
25 | 0 | Builder.defineMacro("__hexagon__", "1"); |
26 | | |
27 | | // The macro __HVXDBL__ is deprecated. |
28 | 0 | bool DefineHvxDbl = false; |
29 | |
|
30 | 0 | if (CPU == "hexagonv5") { |
31 | 0 | Builder.defineMacro("__HEXAGON_V5__"); |
32 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "5"); |
33 | 0 | if (Opts.HexagonQdsp6Compat) { |
34 | 0 | Builder.defineMacro("__QDSP6_V5__"); |
35 | 0 | Builder.defineMacro("__QDSP6_ARCH__", "5"); |
36 | 0 | } |
37 | 0 | } else if (CPU == "hexagonv55") { |
38 | 0 | Builder.defineMacro("__HEXAGON_V55__"); |
39 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "55"); |
40 | 0 | Builder.defineMacro("__QDSP6_V55__"); |
41 | 0 | Builder.defineMacro("__QDSP6_ARCH__", "55"); |
42 | 0 | } else if (CPU == "hexagonv60") { |
43 | 0 | DefineHvxDbl = true; |
44 | 0 | Builder.defineMacro("__HEXAGON_V60__"); |
45 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "60"); |
46 | 0 | Builder.defineMacro("__QDSP6_V60__"); |
47 | 0 | Builder.defineMacro("__QDSP6_ARCH__", "60"); |
48 | 0 | } else if (CPU == "hexagonv62") { |
49 | 0 | DefineHvxDbl = true; |
50 | 0 | Builder.defineMacro("__HEXAGON_V62__"); |
51 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "62"); |
52 | 0 | } else if (CPU == "hexagonv65") { |
53 | 0 | DefineHvxDbl = true; |
54 | 0 | Builder.defineMacro("__HEXAGON_V65__"); |
55 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "65"); |
56 | 0 | } else if (CPU == "hexagonv66") { |
57 | 0 | DefineHvxDbl = true; |
58 | 0 | Builder.defineMacro("__HEXAGON_V66__"); |
59 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "66"); |
60 | 0 | } else if (CPU == "hexagonv67") { |
61 | 0 | Builder.defineMacro("__HEXAGON_V67__"); |
62 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "67"); |
63 | 0 | } else if (CPU == "hexagonv67t") { |
64 | 0 | Builder.defineMacro("__HEXAGON_V67T__"); |
65 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "67"); |
66 | 0 | } else if (CPU == "hexagonv68") { |
67 | 0 | Builder.defineMacro("__HEXAGON_V68__"); |
68 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "68"); |
69 | 0 | } else if (CPU == "hexagonv69") { |
70 | 0 | Builder.defineMacro("__HEXAGON_V69__"); |
71 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "69"); |
72 | 0 | } else if (CPU == "hexagonv71") { |
73 | 0 | Builder.defineMacro("__HEXAGON_V71__"); |
74 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "71"); |
75 | 0 | } else if (CPU == "hexagonv71t") { |
76 | 0 | Builder.defineMacro("__HEXAGON_V71T__"); |
77 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "71"); |
78 | 0 | } else if (CPU == "hexagonv73") { |
79 | 0 | Builder.defineMacro("__HEXAGON_V73__"); |
80 | 0 | Builder.defineMacro("__HEXAGON_ARCH__", "73"); |
81 | 0 | } |
82 | |
|
83 | 0 | if (hasFeature("hvx-length64b")) { |
84 | 0 | Builder.defineMacro("__HVX__"); |
85 | 0 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
86 | 0 | Builder.defineMacro("__HVX_LENGTH__", "64"); |
87 | 0 | } |
88 | |
|
89 | 0 | if (hasFeature("hvx-length128b")) { |
90 | 0 | Builder.defineMacro("__HVX__"); |
91 | 0 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
92 | 0 | Builder.defineMacro("__HVX_LENGTH__", "128"); |
93 | 0 | if (DefineHvxDbl) |
94 | 0 | Builder.defineMacro("__HVXDBL__"); |
95 | 0 | } |
96 | |
|
97 | 0 | if (hasFeature("audio")) { |
98 | 0 | Builder.defineMacro("__HEXAGON_AUDIO__"); |
99 | 0 | } |
100 | |
|
101 | 0 | std::string NumPhySlots = isTinyCore() ? "3" : "4"; |
102 | 0 | Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots); |
103 | |
|
104 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
105 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
106 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
107 | 0 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
108 | 0 | } |
109 | | |
110 | | bool HexagonTargetInfo::initFeatureMap( |
111 | | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
112 | 0 | const std::vector<std::string> &FeaturesVec) const { |
113 | 0 | if (isTinyCore()) |
114 | 0 | Features["audio"] = true; |
115 | |
|
116 | 0 | StringRef CPUFeature = CPU; |
117 | 0 | CPUFeature.consume_front("hexagon"); |
118 | 0 | CPUFeature.consume_back("t"); |
119 | 0 | if (!CPUFeature.empty()) |
120 | 0 | Features[CPUFeature] = true; |
121 | |
|
122 | 0 | Features["long-calls"] = false; |
123 | |
|
124 | 0 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
125 | 0 | } |
126 | | |
127 | | bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
128 | 0 | DiagnosticsEngine &Diags) { |
129 | 0 | for (auto &F : Features) { |
130 | 0 | if (F == "+hvx-length64b") |
131 | 0 | HasHVX = HasHVX64B = true; |
132 | 0 | else if (F == "+hvx-length128b") |
133 | 0 | HasHVX = HasHVX128B = true; |
134 | 0 | else if (F.find("+hvxv") != std::string::npos) { |
135 | 0 | HasHVX = true; |
136 | 0 | HVXVersion = F.substr(std::string("+hvxv").length()); |
137 | 0 | } else if (F == "-hvx") |
138 | 0 | HasHVX = HasHVX64B = HasHVX128B = false; |
139 | 0 | else if (F == "+long-calls") |
140 | 0 | UseLongCalls = true; |
141 | 0 | else if (F == "-long-calls") |
142 | 0 | UseLongCalls = false; |
143 | 0 | else if (F == "+audio") |
144 | 0 | HasAudio = true; |
145 | 0 | } |
146 | 0 | if (CPU.compare("hexagonv68") >= 0) { |
147 | 0 | HasLegalHalfType = true; |
148 | 0 | HasFloat16 = true; |
149 | 0 | } |
150 | 0 | return true; |
151 | 0 | } |
152 | | |
153 | | const char *const HexagonTargetInfo::GCCRegNames[] = { |
154 | | // Scalar registers: |
155 | | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", |
156 | | "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", |
157 | | "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", |
158 | | "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14", |
159 | | "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28", |
160 | | "r31:30", |
161 | | // Predicate registers: |
162 | | "p0", "p1", "p2", "p3", |
163 | | // Control registers: |
164 | | "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", |
165 | | "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21", |
166 | | "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", |
167 | | "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14", |
168 | | "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28", |
169 | | "c31:30", |
170 | | // Control register aliases: |
171 | | "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp", |
172 | | "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey", |
173 | | "pktcountlo", "pktcounthi", "utimerlo", "utimerhi", |
174 | | "upcycle", "pktcount", "utimer", |
175 | | // HVX vector registers: |
176 | | "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", |
177 | | "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", |
178 | | "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", |
179 | | "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14", |
180 | | "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28", |
181 | | "v31:30", |
182 | | "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28", |
183 | | // HVX vector predicates: |
184 | | "q0", "q1", "q2", "q3", |
185 | | }; |
186 | | |
187 | 0 | ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { |
188 | 0 | return llvm::ArrayRef(GCCRegNames); |
189 | 0 | } |
190 | | |
191 | | const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { |
192 | | {{"sp"}, "r29"}, |
193 | | {{"fp"}, "r30"}, |
194 | | {{"lr"}, "r31"}, |
195 | | }; |
196 | | |
197 | 0 | ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { |
198 | 0 | return llvm::ArrayRef(GCCRegAliases); |
199 | 0 | } |
200 | | |
201 | | static constexpr Builtin::Info BuiltinInfo[] = { |
202 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
203 | | {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, |
204 | | #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ |
205 | | {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES}, |
206 | | #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ |
207 | | {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, |
208 | | #include "clang/Basic/BuiltinsHexagon.def" |
209 | | }; |
210 | | |
211 | 0 | bool HexagonTargetInfo::hasFeature(StringRef Feature) const { |
212 | 0 | std::string VS = "hvxv" + HVXVersion; |
213 | 0 | if (Feature == VS) |
214 | 0 | return true; |
215 | | |
216 | 0 | return llvm::StringSwitch<bool>(Feature) |
217 | 0 | .Case("hexagon", true) |
218 | 0 | .Case("hvx", HasHVX) |
219 | 0 | .Case("hvx-length64b", HasHVX64B) |
220 | 0 | .Case("hvx-length128b", HasHVX128B) |
221 | 0 | .Case("long-calls", UseLongCalls) |
222 | 0 | .Case("audio", HasAudio) |
223 | 0 | .Default(false); |
224 | 0 | } |
225 | | |
226 | | struct CPUSuffix { |
227 | | llvm::StringLiteral Name; |
228 | | llvm::StringLiteral Suffix; |
229 | | }; |
230 | | |
231 | | static constexpr CPUSuffix Suffixes[] = { |
232 | | {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, |
233 | | {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, |
234 | | {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, |
235 | | {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}}, |
236 | | {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}}, |
237 | | {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}}, |
238 | | {{"hexagonv73"}, {"73"}}, |
239 | | }; |
240 | | |
241 | 0 | const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { |
242 | 0 | const CPUSuffix *Item = llvm::find_if( |
243 | 0 | Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); |
244 | 0 | if (Item == std::end(Suffixes)) |
245 | 0 | return nullptr; |
246 | 0 | return Item->Suffix.data(); |
247 | 0 | } |
248 | | |
249 | | void HexagonTargetInfo::fillValidCPUList( |
250 | 0 | SmallVectorImpl<StringRef> &Values) const { |
251 | 0 | for (const CPUSuffix &Suffix : Suffixes) |
252 | 0 | Values.push_back(Suffix.Name); |
253 | 0 | } |
254 | | |
255 | 0 | ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { |
256 | 0 | return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - |
257 | 0 | Builtin::FirstTSBuiltin); |
258 | 0 | } |