xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/Hexagon.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements Hexagon TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "Hexagon.h"
14e5dd7070Spatrick #include "Targets.h"
15e5dd7070Spatrick #include "clang/Basic/MacroBuilder.h"
16e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
17e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
18e5dd7070Spatrick 
19e5dd7070Spatrick using namespace clang;
20e5dd7070Spatrick using namespace clang::targets;
21e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const22e5dd7070Spatrick void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
23e5dd7070Spatrick                                          MacroBuilder &Builder) const {
24e5dd7070Spatrick   Builder.defineMacro("__qdsp6__", "1");
25e5dd7070Spatrick   Builder.defineMacro("__hexagon__", "1");
26e5dd7070Spatrick 
27ec727ea7Spatrick   Builder.defineMacro("__ELF__");
28ec727ea7Spatrick 
29ec727ea7Spatrick   // The macro __HVXDBL__ is deprecated.
30ec727ea7Spatrick   bool DefineHvxDbl = false;
31ec727ea7Spatrick 
32e5dd7070Spatrick   if (CPU == "hexagonv5") {
33e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V5__");
34e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "5");
35e5dd7070Spatrick     if (Opts.HexagonQdsp6Compat) {
36e5dd7070Spatrick       Builder.defineMacro("__QDSP6_V5__");
37e5dd7070Spatrick       Builder.defineMacro("__QDSP6_ARCH__", "5");
38e5dd7070Spatrick     }
39e5dd7070Spatrick   } else if (CPU == "hexagonv55") {
40e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V55__");
41e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "55");
42e5dd7070Spatrick     Builder.defineMacro("__QDSP6_V55__");
43e5dd7070Spatrick     Builder.defineMacro("__QDSP6_ARCH__", "55");
44e5dd7070Spatrick   } else if (CPU == "hexagonv60") {
45ec727ea7Spatrick     DefineHvxDbl = true;
46e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V60__");
47e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "60");
48e5dd7070Spatrick     Builder.defineMacro("__QDSP6_V60__");
49e5dd7070Spatrick     Builder.defineMacro("__QDSP6_ARCH__", "60");
50e5dd7070Spatrick   } else if (CPU == "hexagonv62") {
51ec727ea7Spatrick     DefineHvxDbl = true;
52e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V62__");
53e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "62");
54e5dd7070Spatrick   } else if (CPU == "hexagonv65") {
55ec727ea7Spatrick     DefineHvxDbl = true;
56e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V65__");
57e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "65");
58e5dd7070Spatrick   } else if (CPU == "hexagonv66") {
59ec727ea7Spatrick     DefineHvxDbl = true;
60e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_V66__");
61e5dd7070Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "66");
62ec727ea7Spatrick   } else if (CPU == "hexagonv67") {
63ec727ea7Spatrick     Builder.defineMacro("__HEXAGON_V67__");
64ec727ea7Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "67");
65ec727ea7Spatrick   } else if (CPU == "hexagonv67t") {
66ec727ea7Spatrick     Builder.defineMacro("__HEXAGON_V67T__");
67ec727ea7Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "67");
68a9ac8606Spatrick   } else if (CPU == "hexagonv68") {
69a9ac8606Spatrick     Builder.defineMacro("__HEXAGON_V68__");
70a9ac8606Spatrick     Builder.defineMacro("__HEXAGON_ARCH__", "68");
71*12c85518Srobert   } else if (CPU == "hexagonv69") {
72*12c85518Srobert     Builder.defineMacro("__HEXAGON_V69__");
73*12c85518Srobert     Builder.defineMacro("__HEXAGON_ARCH__", "69");
74*12c85518Srobert   } else if (CPU == "hexagonv71") {
75*12c85518Srobert     Builder.defineMacro("__HEXAGON_V71__");
76*12c85518Srobert     Builder.defineMacro("__HEXAGON_ARCH__", "71");
77*12c85518Srobert   } else if (CPU == "hexagonv71t") {
78*12c85518Srobert     Builder.defineMacro("__HEXAGON_V71T__");
79*12c85518Srobert     Builder.defineMacro("__HEXAGON_ARCH__", "71");
80*12c85518Srobert   } else if (CPU == "hexagonv73") {
81*12c85518Srobert     Builder.defineMacro("__HEXAGON_V73__");
82*12c85518Srobert     Builder.defineMacro("__HEXAGON_ARCH__", "73");
83e5dd7070Spatrick   }
84e5dd7070Spatrick 
85e5dd7070Spatrick   if (hasFeature("hvx-length64b")) {
86e5dd7070Spatrick     Builder.defineMacro("__HVX__");
87e5dd7070Spatrick     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
88e5dd7070Spatrick     Builder.defineMacro("__HVX_LENGTH__", "64");
89e5dd7070Spatrick   }
90e5dd7070Spatrick 
91e5dd7070Spatrick   if (hasFeature("hvx-length128b")) {
92e5dd7070Spatrick     Builder.defineMacro("__HVX__");
93e5dd7070Spatrick     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
94e5dd7070Spatrick     Builder.defineMacro("__HVX_LENGTH__", "128");
95ec727ea7Spatrick     if (DefineHvxDbl)
96e5dd7070Spatrick       Builder.defineMacro("__HVXDBL__");
97e5dd7070Spatrick   }
98ec727ea7Spatrick 
99ec727ea7Spatrick   if (hasFeature("audio")) {
100ec727ea7Spatrick     Builder.defineMacro("__HEXAGON_AUDIO__");
101ec727ea7Spatrick   }
102ec727ea7Spatrick 
103ec727ea7Spatrick   std::string NumPhySlots = isTinyCore() ? "3" : "4";
104ec727ea7Spatrick   Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
105*12c85518Srobert 
106*12c85518Srobert   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
107*12c85518Srobert   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
108*12c85518Srobert   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
109*12c85518Srobert   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
110e5dd7070Spatrick }
111e5dd7070Spatrick 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const112e5dd7070Spatrick bool HexagonTargetInfo::initFeatureMap(
113e5dd7070Spatrick     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
114e5dd7070Spatrick     const std::vector<std::string> &FeaturesVec) const {
115ec727ea7Spatrick   if (isTinyCore())
116ec727ea7Spatrick     Features["audio"] = true;
117ec727ea7Spatrick 
118ec727ea7Spatrick   StringRef CPUFeature = CPU;
119ec727ea7Spatrick   CPUFeature.consume_front("hexagon");
120ec727ea7Spatrick   CPUFeature.consume_back("t");
121a9ac8606Spatrick   if (!CPUFeature.empty())
122ec727ea7Spatrick     Features[CPUFeature] = true;
123ec727ea7Spatrick 
124e5dd7070Spatrick   Features["long-calls"] = false;
125e5dd7070Spatrick 
126e5dd7070Spatrick   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
127e5dd7070Spatrick }
128e5dd7070Spatrick 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)129e5dd7070Spatrick bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
130e5dd7070Spatrick                                              DiagnosticsEngine &Diags) {
131e5dd7070Spatrick   for (auto &F : Features) {
132e5dd7070Spatrick     if (F == "+hvx-length64b")
133e5dd7070Spatrick       HasHVX = HasHVX64B = true;
134e5dd7070Spatrick     else if (F == "+hvx-length128b")
135e5dd7070Spatrick       HasHVX = HasHVX128B = true;
136e5dd7070Spatrick     else if (F.find("+hvxv") != std::string::npos) {
137e5dd7070Spatrick       HasHVX = true;
138e5dd7070Spatrick       HVXVersion = F.substr(std::string("+hvxv").length());
139e5dd7070Spatrick     } else if (F == "-hvx")
140e5dd7070Spatrick       HasHVX = HasHVX64B = HasHVX128B = false;
141e5dd7070Spatrick     else if (F == "+long-calls")
142e5dd7070Spatrick       UseLongCalls = true;
143e5dd7070Spatrick     else if (F == "-long-calls")
144e5dd7070Spatrick       UseLongCalls = false;
145ec727ea7Spatrick     else if (F == "+audio")
146ec727ea7Spatrick       HasAudio = true;
147e5dd7070Spatrick   }
148*12c85518Srobert   if (CPU.compare("hexagonv68") >= 0) {
149*12c85518Srobert     HasLegalHalfType = true;
150*12c85518Srobert     HasFloat16 = true;
151*12c85518Srobert   }
152e5dd7070Spatrick   return true;
153e5dd7070Spatrick }
154e5dd7070Spatrick 
155e5dd7070Spatrick const char *const HexagonTargetInfo::GCCRegNames[] = {
156a9ac8606Spatrick     // Scalar registers:
157a9ac8606Spatrick     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
158a9ac8606Spatrick     "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
159a9ac8606Spatrick     "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
160e5dd7070Spatrick     "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
161e5dd7070Spatrick     "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
162a9ac8606Spatrick     "r31:30",
163a9ac8606Spatrick     // Predicate registers:
164a9ac8606Spatrick     "p0", "p1", "p2", "p3",
165a9ac8606Spatrick     // Control registers:
166a9ac8606Spatrick     "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
167a9ac8606Spatrick     "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
168a9ac8606Spatrick     "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
169a9ac8606Spatrick     "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
170a9ac8606Spatrick     "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
171a9ac8606Spatrick     "c31:30",
172a9ac8606Spatrick     // Control register aliases:
173a9ac8606Spatrick     "sa0", "lc0", "sa1", "lc1", "p3:0", "m0",  "m1",  "usr", "pc", "ugp",
174a9ac8606Spatrick     "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
175a9ac8606Spatrick     "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
176a9ac8606Spatrick     "upcycle", "pktcount", "utimer",
177a9ac8606Spatrick     // HVX vector registers:
178a9ac8606Spatrick     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
179a9ac8606Spatrick     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
180a9ac8606Spatrick     "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
181a9ac8606Spatrick     "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
182a9ac8606Spatrick     "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
183a9ac8606Spatrick     "v31:30",
184a9ac8606Spatrick     "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
185a9ac8606Spatrick     // HVX vector predicates:
186a9ac8606Spatrick     "q0", "q1", "q2", "q3",
187e5dd7070Spatrick };
188e5dd7070Spatrick 
getGCCRegNames() const189e5dd7070Spatrick ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
190*12c85518Srobert   return llvm::ArrayRef(GCCRegNames);
191e5dd7070Spatrick }
192e5dd7070Spatrick 
193e5dd7070Spatrick const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
194e5dd7070Spatrick     {{"sp"}, "r29"},
195e5dd7070Spatrick     {{"fp"}, "r30"},
196e5dd7070Spatrick     {{"lr"}, "r31"},
197e5dd7070Spatrick };
198e5dd7070Spatrick 
getGCCRegAliases() const199e5dd7070Spatrick ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
200*12c85518Srobert   return llvm::ArrayRef(GCCRegAliases);
201e5dd7070Spatrick }
202e5dd7070Spatrick 
203*12c85518Srobert static constexpr Builtin::Info BuiltinInfo[] = {
204e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
205*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
206e5dd7070Spatrick #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
207*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
208ec727ea7Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
209*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
210e5dd7070Spatrick #include "clang/Basic/BuiltinsHexagon.def"
211e5dd7070Spatrick };
212e5dd7070Spatrick 
hasFeature(StringRef Feature) const213e5dd7070Spatrick bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
214e5dd7070Spatrick   std::string VS = "hvxv" + HVXVersion;
215e5dd7070Spatrick   if (Feature == VS)
216e5dd7070Spatrick     return true;
217e5dd7070Spatrick 
218e5dd7070Spatrick   return llvm::StringSwitch<bool>(Feature)
219e5dd7070Spatrick       .Case("hexagon", true)
220e5dd7070Spatrick       .Case("hvx", HasHVX)
221e5dd7070Spatrick       .Case("hvx-length64b", HasHVX64B)
222e5dd7070Spatrick       .Case("hvx-length128b", HasHVX128B)
223e5dd7070Spatrick       .Case("long-calls", UseLongCalls)
224ec727ea7Spatrick       .Case("audio", HasAudio)
225e5dd7070Spatrick       .Default(false);
226e5dd7070Spatrick }
227e5dd7070Spatrick 
228e5dd7070Spatrick struct CPUSuffix {
229e5dd7070Spatrick   llvm::StringLiteral Name;
230e5dd7070Spatrick   llvm::StringLiteral Suffix;
231e5dd7070Spatrick };
232e5dd7070Spatrick 
233e5dd7070Spatrick static constexpr CPUSuffix Suffixes[] = {
234e5dd7070Spatrick     {{"hexagonv5"},  {"5"}},  {{"hexagonv55"},  {"55"}},
235e5dd7070Spatrick     {{"hexagonv60"}, {"60"}}, {{"hexagonv62"},  {"62"}},
236e5dd7070Spatrick     {{"hexagonv65"}, {"65"}}, {{"hexagonv66"},  {"66"}},
237ec727ea7Spatrick     {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
238*12c85518Srobert     {{"hexagonv68"}, {"68"}}, {{"hexagonv69"},  {"69"}},
239*12c85518Srobert     {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"},  {"71t"}},
240*12c85518Srobert     {{"hexagonv73"}, {"73"}},
241e5dd7070Spatrick };
242e5dd7070Spatrick 
getHexagonCPUSuffix(StringRef Name)243e5dd7070Spatrick const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
244e5dd7070Spatrick   const CPUSuffix *Item = llvm::find_if(
245e5dd7070Spatrick       Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
246e5dd7070Spatrick   if (Item == std::end(Suffixes))
247e5dd7070Spatrick     return nullptr;
248e5dd7070Spatrick   return Item->Suffix.data();
249e5dd7070Spatrick }
250e5dd7070Spatrick 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const251e5dd7070Spatrick void HexagonTargetInfo::fillValidCPUList(
252e5dd7070Spatrick     SmallVectorImpl<StringRef> &Values) const {
253e5dd7070Spatrick   for (const CPUSuffix &Suffix : Suffixes)
254e5dd7070Spatrick     Values.push_back(Suffix.Name);
255e5dd7070Spatrick }
256e5dd7070Spatrick 
getTargetBuiltins() const257e5dd7070Spatrick ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
258*12c85518Srobert   return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
259e5dd7070Spatrick                                          Builtin::FirstTSBuiltin);
260e5dd7070Spatrick }
261