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