[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / lib / Basic / Targets / Hexagon.cpp
blob161369242926eb9b998af2da4627b8d13f3ce408
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.
11 //===----------------------------------------------------------------------===//
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"
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") {
45 DefineHvxDbl = true;
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") {
51 DefineHvxDbl = true;
52 Builder.defineMacro("__HEXAGON_V62__");
53 Builder.defineMacro("__HEXAGON_ARCH__", "62");
54 } else if (CPU == "hexagonv65") {
55 DefineHvxDbl = true;
56 Builder.defineMacro("__HEXAGON_V65__");
57 Builder.defineMacro("__HEXAGON_ARCH__", "65");
58 } else if (CPU == "hexagonv66") {
59 DefineHvxDbl = true;
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");
86 if (DefineHvxDbl)
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 {
101 if (isTinyCore())
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) {
123 HasHVX = true;
124 HVXVersion = F.substr(std::string("+hvxv").length());
125 } else if (F == "-hvx")
126 HasHVX = HasHVX64B = HasHVX128B = false;
127 else if (F == "+long-calls")
128 UseLongCalls = true;
129 else if (F == "-long-calls")
130 UseLongCalls = false;
131 else if (F == "+audio")
132 HasAudio = true;
134 if (CPU.compare("hexagonv68") >= 0) {
135 HasLegalHalfType = true;
136 HasFloat16 = true;
138 return true;
141 const char *const HexagonTargetInfo::GCCRegNames[] = {
142 // Scalar registers:
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",
148 "r31:30",
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",
157 "c31:30",
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",
169 "v31:30",
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[] = {
180 {{"sp"}, "r29"},
181 {{"fp"}, "r30"},
182 {{"lr"}, "r31"},
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;
201 if (Feature == VS)
202 return true;
204 return llvm::StringSwitch<bool>(Feature)
205 .Case("hexagon", true)
206 .Case("hvx", HasHVX)
207 .Case("hvx-length64b", HasHVX64B)
208 .Case("hvx-length128b", HasHVX128B)
209 .Case("long-calls", UseLongCalls)
210 .Case("audio", HasAudio)
211 .Default(false);
214 struct CPUSuffix {
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))
231 return nullptr;
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);