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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Basic/Targets/Hexagon.cpp