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 }
82
83 if (hasFeature("hvx-length64b")) {
84 Builder.defineMacro("__HVX__");
85 Builder.defineMacro("__HVX_ARCH__", HVXVersion);
86 Builder.defineMacro("__HVX_LENGTH__", "64");
87 }
88
89 if (hasFeature("hvx-length128b")) {
90 Builder.defineMacro("__HVX__");
91 Builder.defineMacro("__HVX_ARCH__", HVXVersion);
92 Builder.defineMacro("__HVX_LENGTH__", "128");
93 if (DefineHvxDbl)
94 Builder.defineMacro("__HVXDBL__");
95 }
96
97 if (hasFeature("audio")) {
98 Builder.defineMacro("__HEXAGON_AUDIO__");
99 }
100
101 std::string NumPhySlots = isTinyCore() ? "3" : "4";
102 Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
103
104 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
105 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
106 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
107 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
108}
109
111 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
112 const std::vector<std::string> &FeaturesVec) const {
113 if (isTinyCore())
114 Features["audio"] = true;
115
116 StringRef CPUFeature = CPU;
117 CPUFeature.consume_front("hexagon");
118 CPUFeature.consume_back("t");
119 if (!CPUFeature.empty())
120 Features[CPUFeature] = true;
121
122 Features["long-calls"] = false;
123
124 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
125}
126
127bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
128 DiagnosticsEngine &Diags) {
129 for (auto &F : Features) {
130 if (F == "+hvx-length64b")
131 HasHVX = HasHVX64B = true;
132 else if (F == "+hvx-length128b")
133 HasHVX = HasHVX128B = true;
134 else if (F.find("+hvxv") != std::string::npos) {
135 HasHVX = true;
136 HVXVersion = F.substr(std::string("+hvxv").length());
137 } else if (F == "-hvx")
138 HasHVX = HasHVX64B = HasHVX128B = false;
139 else if (F == "+long-calls")
140 UseLongCalls = true;
141 else if (F == "-long-calls")
142 UseLongCalls = false;
143 else if (F == "+audio")
144 HasAudio = true;
145 }
146 if (CPU.compare("hexagonv68") >= 0) {
147 HasLegalHalfType = true;
148 HasFloat16 = true;
149 }
150 return true;
151}
152
153const 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
188 return llvm::ArrayRef(GCCRegNames);
189}
190
191const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
192 {{"sp"}, "r29"},
193 {{"fp"}, "r30"},
194 {{"lr"}, "r31"},
195};
196
198 return llvm::ArrayRef(GCCRegAliases);
199}
200
201static 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
211bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
212 std::string VS = "hvxv" + HVXVersion;
213 if (Feature == VS)
214 return true;
215
216 return llvm::StringSwitch<bool>(Feature)
217 .Case("hexagon", true)
218 .Case("hvx", HasHVX)
219 .Case("hvx-length64b", HasHVX64B)
220 .Case("hvx-length128b", HasHVX128B)
221 .Case("long-calls", UseLongCalls)
222 .Case("audio", HasAudio)
223 .Default(false);
224}
225
226struct CPUSuffix {
227 llvm::StringLiteral Name;
228 llvm::StringLiteral Suffix;
229};
230
231static 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
241std::optional<unsigned> HexagonTargetInfo::getHexagonCPURev(StringRef Name) {
242 StringRef Arch = Name;
243 Arch.consume_front("hexagonv");
244 Arch.consume_back("t");
245
246 unsigned Val;
247 if (!Arch.getAsInteger(0, Val))
248 return Val;
249
250 return std::nullopt;
251}
252
253const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
254 const CPUSuffix *Item = llvm::find_if(
255 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
256 if (Item == std::end(Suffixes))
257 return nullptr;
258 return Item->Suffix.data();
259}
260
262 SmallVectorImpl<StringRef> &Values) const {
263 for (const CPUSuffix &Suffix : Suffixes)
264 Values.push_back(Suffix.Name);
265}
266
270}
static constexpr CPUSuffix Suffixes[]
Definition: Hexagon.cpp:231
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:192
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:476
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:532
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:127
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:110
static std::optional< unsigned > getHexagonCPURev(StringRef Name)
Definition: Hexagon.cpp:241
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: Hexagon.cpp:197
static const char * getHexagonCPUSuffix(StringRef Name)
Definition: Hexagon.cpp:253
ArrayRef< const char * > getGCCRegNames() const override
Definition: Hexagon.cpp:187
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Hexagon.cpp:261
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:267
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: Hexagon.cpp:211
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:228
llvm::StringLiteral Name
Definition: Hexagon.cpp:227