clang 20.0.0git
Hexagon.cpp
Go to the documentation of this file.
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"
17#include "llvm/ADT/StringSwitch.h"
18
19using namespace clang;
20using namespace clang::targets;
21
23 MacroBuilder &Builder) const {
24 Builder.defineMacro("__qdsp6__", "1");
25 Builder.defineMacro("__hexagon__", "1");
26
27 // The macro __HVXDBL__ is deprecated.
28 bool DefineHvxDbl = false;
29
30 if (CPU == "hexagonv5") {
31 Builder.defineMacro("__HEXAGON_V5__");
32 Builder.defineMacro("__HEXAGON_ARCH__", "5");
33 if (Opts.HexagonQdsp6Compat) {
34 Builder.defineMacro("__QDSP6_V5__");
35 Builder.defineMacro("__QDSP6_ARCH__", "5");
36 }
37 } else if (CPU == "hexagonv55") {
38 Builder.defineMacro("__HEXAGON_V55__");
39 Builder.defineMacro("__HEXAGON_ARCH__", "55");
40 Builder.defineMacro("__QDSP6_V55__");
41 Builder.defineMacro("__QDSP6_ARCH__", "55");
42 } else if (CPU == "hexagonv60") {
43 DefineHvxDbl = true;
44 Builder.defineMacro("__HEXAGON_V60__");
45 Builder.defineMacro("__HEXAGON_ARCH__", "60");
46 Builder.defineMacro("__QDSP6_V60__");
47 Builder.defineMacro("__QDSP6_ARCH__", "60");
48 } else if (CPU == "hexagonv62") {
49 DefineHvxDbl = true;
50 Builder.defineMacro("__HEXAGON_V62__");
51 Builder.defineMacro("__HEXAGON_ARCH__", "62");
52 } else if (CPU == "hexagonv65") {
53 DefineHvxDbl = true;
54 Builder.defineMacro("__HEXAGON_V65__");
55 Builder.defineMacro("__HEXAGON_ARCH__", "65");
56 } else if (CPU == "hexagonv66") {
57 DefineHvxDbl = true;
58 Builder.defineMacro("__HEXAGON_V66__");
59 Builder.defineMacro("__HEXAGON_ARCH__", "66");
60 } else if (CPU == "hexagonv67") {
61 Builder.defineMacro("__HEXAGON_V67__");
62 Builder.defineMacro("__HEXAGON_ARCH__", "67");
63 } else if (CPU == "hexagonv67t") {
64 Builder.defineMacro("__HEXAGON_V67T__");
65 Builder.defineMacro("__HEXAGON_ARCH__", "67");
66 } else if (CPU == "hexagonv68") {
67 Builder.defineMacro("__HEXAGON_V68__");
68 Builder.defineMacro("__HEXAGON_ARCH__", "68");
69 } else if (CPU == "hexagonv69") {
70 Builder.defineMacro("__HEXAGON_V69__");
71 Builder.defineMacro("__HEXAGON_ARCH__", "69");
72 } else if (CPU == "hexagonv71") {
73 Builder.defineMacro("__HEXAGON_V71__");
74 Builder.defineMacro("__HEXAGON_ARCH__", "71");
75 } else if (CPU == "hexagonv71t") {
76 Builder.defineMacro("__HEXAGON_V71T__");
77 Builder.defineMacro("__HEXAGON_ARCH__", "71");
78 } else if (CPU == "hexagonv73") {
79 Builder.defineMacro("__HEXAGON_V73__");
80 Builder.defineMacro("__HEXAGON_ARCH__", "73");
81 } else if (CPU == "hexagonv75") {
82 Builder.defineMacro("__HEXAGON_V75__");
83 Builder.defineMacro("__HEXAGON_ARCH__", "75");
84 } else if (CPU == "hexagonv79") {
85 Builder.defineMacro("__HEXAGON_V79__");
86 Builder.defineMacro("__HEXAGON_ARCH__", "79");
87 }
88
89 if (hasFeature("hvx-length64b")) {
90 Builder.defineMacro("__HVX__");
91 Builder.defineMacro("__HVX_ARCH__", HVXVersion);
92 Builder.defineMacro("__HVX_LENGTH__", "64");
93 }
94
95 if (hasFeature("hvx-length128b")) {
96 Builder.defineMacro("__HVX__");
97 Builder.defineMacro("__HVX_ARCH__", HVXVersion);
98 Builder.defineMacro("__HVX_LENGTH__", "128");
99 if (DefineHvxDbl)
100 Builder.defineMacro("__HVXDBL__");
101 }
102
103 if (hasFeature("audio")) {
104 Builder.defineMacro("__HEXAGON_AUDIO__");
105 }
106
107 std::string NumPhySlots = isTinyCore() ? "3" : "4";
108 Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
109
110 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
111 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
112 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
113 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
114}
115
117 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
118 const std::vector<std::string> &FeaturesVec) const {
119 if (isTinyCore())
120 Features["audio"] = true;
121
122 StringRef CPUFeature = CPU;
123 CPUFeature.consume_front("hexagon");
124 CPUFeature.consume_back("t");
125 if (!CPUFeature.empty())
126 Features[CPUFeature] = true;
127
128 Features["long-calls"] = false;
129
130 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
131}
132
133bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
134 DiagnosticsEngine &Diags) {
135 for (auto &F : Features) {
136 if (F == "+hvx-length64b")
137 HasHVX = HasHVX64B = true;
138 else if (F == "+hvx-length128b")
139 HasHVX = HasHVX128B = true;
140 else if (F.find("+hvxv") != std::string::npos) {
141 HasHVX = true;
142 HVXVersion = F.substr(std::string("+hvxv").length());
143 } else if (F == "-hvx")
144 HasHVX = HasHVX64B = HasHVX128B = false;
145 else if (F == "+long-calls")
146 UseLongCalls = true;
147 else if (F == "-long-calls")
148 UseLongCalls = false;
149 else if (F == "+audio")
150 HasAudio = true;
151 }
152 if (CPU.compare("hexagonv68") >= 0) {
153 HasLegalHalfType = true;
154 HasFloat16 = true;
155 }
156 return true;
157}
158
159const char *const HexagonTargetInfo::GCCRegNames[] = {
160 // Scalar registers:
161 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
162 "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
163 "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
164 "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
165 "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
166 "r31:30",
167 // Predicate registers:
168 "p0", "p1", "p2", "p3",
169 // Control registers:
170 "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
171 "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
172 "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
173 "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
174 "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
175 "c31:30",
176 // Control register aliases:
177 "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",
178 "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
179 "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
180 "upcycle", "pktcount", "utimer",
181 // HVX vector registers:
182 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
183 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
184 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
185 "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
186 "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
187 "v31:30",
188 "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
189 // HVX vector predicates:
190 "q0", "q1", "q2", "q3",
191};
192
194 return llvm::ArrayRef(GCCRegNames);
195}
196
197const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
198 {{"sp"}, "r29"},
199 {{"fp"}, "r30"},
200 {{"lr"}, "r31"},
201};
202
204 return llvm::ArrayRef(GCCRegAliases);
205}
206
207static constexpr Builtin::Info BuiltinInfo[] = {
208#define BUILTIN(ID, TYPE, ATTRS) \
209 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
210#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
211 {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
212#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
213 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
214#include "clang/Basic/BuiltinsHexagon.def"
215};
216
217bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
218 std::string VS = "hvxv" + HVXVersion;
219 if (Feature == VS)
220 return true;
221
222 return llvm::StringSwitch<bool>(Feature)
223 .Case("hexagon", true)
224 .Case("hvx", HasHVX)
225 .Case("hvx-length64b", HasHVX64B)
226 .Case("hvx-length128b", HasHVX128B)
227 .Case("long-calls", UseLongCalls)
228 .Case("audio", HasAudio)
229 .Default(false);
230}
231
232struct CPUSuffix {
233 llvm::StringLiteral Name;
234 llvm::StringLiteral Suffix;
235};
236
237static constexpr CPUSuffix Suffixes[] = {
238 {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
239 {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
240 {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
241 {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
242 {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},
243 {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},
244 {{"hexagonv73"}, {"73"}}, {{"hexagonv75"}, {"75"}},
245 {{"hexagonv79"}, {"79"}},
246};
247
248std::optional<unsigned> HexagonTargetInfo::getHexagonCPURev(StringRef Name) {
249 StringRef Arch = Name;
250 Arch.consume_front("hexagonv");
251 Arch.consume_back("t");
252
253 unsigned Val;
254 if (!Arch.getAsInteger(0, Val))
255 return Val;
256
257 return std::nullopt;
258}
259
260const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
261 const CPUSuffix *Item = llvm::find_if(
262 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
263 if (Item == std::end(Suffixes))
264 return nullptr;
265 return Item->Suffix.data();
266}
267
269 SmallVectorImpl<StringRef> &Values) const {
270 for (const CPUSuffix &Suffix : Suffixes)
271 Values.push_back(Suffix.Name);
272}
273
277}
static constexpr CPUSuffix Suffixes[]
Definition: Hexagon.cpp:237
static constexpr Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:32
Defines the clang::MacroBuilder utility class.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:231
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: TargetInfo.cpp:549
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
Definition: Hexagon.cpp:133
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: Hexagon.cpp:116
static std::optional< unsigned > getHexagonCPURev(StringRef Name)
Definition: Hexagon.cpp:248
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: Hexagon.cpp:203
static const char * getHexagonCPUSuffix(StringRef Name)
Definition: Hexagon.cpp:260
ArrayRef< const char * > getGCCRegNames() const override
Definition: Hexagon.cpp:193
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Hexagon.cpp:268
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: Hexagon.cpp:22
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: Hexagon.cpp:274
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: Hexagon.cpp:217
The JSON file list parser is used to communicate input to InstallAPI.
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
llvm::StringLiteral Suffix
Definition: Hexagon.cpp:234
llvm::StringLiteral Name
Definition: Hexagon.cpp:233