xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements Hexagon TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "Hexagon.h"
140b57cec5SDimitry Andric #include "Targets.h"
150b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace clang;
200b57cec5SDimitry Andric using namespace clang::targets;
210b57cec5SDimitry Andric 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const220b57cec5SDimitry Andric void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
230b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
240b57cec5SDimitry Andric   Builder.defineMacro("__qdsp6__", "1");
250b57cec5SDimitry Andric   Builder.defineMacro("__hexagon__", "1");
260b57cec5SDimitry Andric 
275ffd83dbSDimitry Andric   // The macro __HVXDBL__ is deprecated.
285ffd83dbSDimitry Andric   bool DefineHvxDbl = false;
295ffd83dbSDimitry Andric 
300b57cec5SDimitry Andric   if (CPU == "hexagonv5") {
310b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V5__");
320b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "5");
330b57cec5SDimitry Andric     if (Opts.HexagonQdsp6Compat) {
340b57cec5SDimitry Andric       Builder.defineMacro("__QDSP6_V5__");
350b57cec5SDimitry Andric       Builder.defineMacro("__QDSP6_ARCH__", "5");
360b57cec5SDimitry Andric     }
370b57cec5SDimitry Andric   } else if (CPU == "hexagonv55") {
380b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V55__");
390b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "55");
400b57cec5SDimitry Andric     Builder.defineMacro("__QDSP6_V55__");
410b57cec5SDimitry Andric     Builder.defineMacro("__QDSP6_ARCH__", "55");
420b57cec5SDimitry Andric   } else if (CPU == "hexagonv60") {
435ffd83dbSDimitry Andric     DefineHvxDbl = true;
440b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V60__");
450b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "60");
460b57cec5SDimitry Andric     Builder.defineMacro("__QDSP6_V60__");
470b57cec5SDimitry Andric     Builder.defineMacro("__QDSP6_ARCH__", "60");
480b57cec5SDimitry Andric   } else if (CPU == "hexagonv62") {
495ffd83dbSDimitry Andric     DefineHvxDbl = true;
500b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V62__");
510b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "62");
520b57cec5SDimitry Andric   } else if (CPU == "hexagonv65") {
535ffd83dbSDimitry Andric     DefineHvxDbl = true;
540b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V65__");
550b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "65");
560b57cec5SDimitry Andric   } else if (CPU == "hexagonv66") {
575ffd83dbSDimitry Andric     DefineHvxDbl = true;
580b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_V66__");
590b57cec5SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "66");
605ffd83dbSDimitry Andric   } else if (CPU == "hexagonv67") {
615ffd83dbSDimitry Andric     Builder.defineMacro("__HEXAGON_V67__");
625ffd83dbSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "67");
635ffd83dbSDimitry Andric   } else if (CPU == "hexagonv67t") {
645ffd83dbSDimitry Andric     Builder.defineMacro("__HEXAGON_V67T__");
655ffd83dbSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "67");
66fe6060f1SDimitry Andric   } else if (CPU == "hexagonv68") {
67fe6060f1SDimitry Andric     Builder.defineMacro("__HEXAGON_V68__");
68fe6060f1SDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "68");
690eae32dcSDimitry Andric   } else if (CPU == "hexagonv69") {
700eae32dcSDimitry Andric     Builder.defineMacro("__HEXAGON_V69__");
710eae32dcSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "69");
72bdd1243dSDimitry Andric   } else if (CPU == "hexagonv71") {
73bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_V71__");
74bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "71");
75bdd1243dSDimitry Andric   } else if (CPU == "hexagonv71t") {
76bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_V71T__");
77bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "71");
78bdd1243dSDimitry Andric   } else if (CPU == "hexagonv73") {
79bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_V73__");
80bdd1243dSDimitry Andric     Builder.defineMacro("__HEXAGON_ARCH__", "73");
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   if (hasFeature("hvx-length64b")) {
840b57cec5SDimitry Andric     Builder.defineMacro("__HVX__");
850b57cec5SDimitry Andric     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
860b57cec5SDimitry Andric     Builder.defineMacro("__HVX_LENGTH__", "64");
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   if (hasFeature("hvx-length128b")) {
900b57cec5SDimitry Andric     Builder.defineMacro("__HVX__");
910b57cec5SDimitry Andric     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
920b57cec5SDimitry Andric     Builder.defineMacro("__HVX_LENGTH__", "128");
935ffd83dbSDimitry Andric     if (DefineHvxDbl)
940b57cec5SDimitry Andric       Builder.defineMacro("__HVXDBL__");
950b57cec5SDimitry Andric   }
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric   if (hasFeature("audio")) {
985ffd83dbSDimitry Andric     Builder.defineMacro("__HEXAGON_AUDIO__");
995ffd83dbSDimitry Andric   }
1005ffd83dbSDimitry Andric 
1015ffd83dbSDimitry Andric   std::string NumPhySlots = isTinyCore() ? "3" : "4";
1025ffd83dbSDimitry Andric   Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
103bdd1243dSDimitry Andric 
104bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
105bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
106bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
107bdd1243dSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const1100b57cec5SDimitry Andric bool HexagonTargetInfo::initFeatureMap(
1110b57cec5SDimitry Andric     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1120b57cec5SDimitry Andric     const std::vector<std::string> &FeaturesVec) const {
1135ffd83dbSDimitry Andric   if (isTinyCore())
1145ffd83dbSDimitry Andric     Features["audio"] = true;
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric   StringRef CPUFeature = CPU;
1175ffd83dbSDimitry Andric   CPUFeature.consume_front("hexagon");
1185ffd83dbSDimitry Andric   CPUFeature.consume_back("t");
119e8d8bef9SDimitry Andric   if (!CPUFeature.empty())
1205ffd83dbSDimitry Andric     Features[CPUFeature] = true;
1215ffd83dbSDimitry Andric 
1220b57cec5SDimitry Andric   Features["long-calls"] = false;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)1270b57cec5SDimitry Andric bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1280b57cec5SDimitry Andric                                              DiagnosticsEngine &Diags) {
1290b57cec5SDimitry Andric   for (auto &F : Features) {
1300b57cec5SDimitry Andric     if (F == "+hvx-length64b")
1310b57cec5SDimitry Andric       HasHVX = HasHVX64B = true;
1320b57cec5SDimitry Andric     else if (F == "+hvx-length128b")
1330b57cec5SDimitry Andric       HasHVX = HasHVX128B = true;
1340b57cec5SDimitry Andric     else if (F.find("+hvxv") != std::string::npos) {
1350b57cec5SDimitry Andric       HasHVX = true;
1360b57cec5SDimitry Andric       HVXVersion = F.substr(std::string("+hvxv").length());
1370b57cec5SDimitry Andric     } else if (F == "-hvx")
1380b57cec5SDimitry Andric       HasHVX = HasHVX64B = HasHVX128B = false;
1390b57cec5SDimitry Andric     else if (F == "+long-calls")
1400b57cec5SDimitry Andric       UseLongCalls = true;
1410b57cec5SDimitry Andric     else if (F == "-long-calls")
1420b57cec5SDimitry Andric       UseLongCalls = false;
1435ffd83dbSDimitry Andric     else if (F == "+audio")
1445ffd83dbSDimitry Andric       HasAudio = true;
1450b57cec5SDimitry Andric   }
1460eae32dcSDimitry Andric   if (CPU.compare("hexagonv68") >= 0) {
1470eae32dcSDimitry Andric     HasLegalHalfType = true;
1480eae32dcSDimitry Andric     HasFloat16 = true;
1490eae32dcSDimitry Andric   }
1500b57cec5SDimitry Andric   return true;
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric const char *const HexagonTargetInfo::GCCRegNames[] = {
154fe6060f1SDimitry Andric     // Scalar registers:
155fe6060f1SDimitry Andric     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
156fe6060f1SDimitry Andric     "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
157fe6060f1SDimitry Andric     "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
158480093f4SDimitry Andric     "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
159480093f4SDimitry Andric     "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
160fe6060f1SDimitry Andric     "r31:30",
161fe6060f1SDimitry Andric     // Predicate registers:
162fe6060f1SDimitry Andric     "p0", "p1", "p2", "p3",
163fe6060f1SDimitry Andric     // Control registers:
164fe6060f1SDimitry Andric     "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
165fe6060f1SDimitry Andric     "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
166fe6060f1SDimitry Andric     "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
167fe6060f1SDimitry Andric     "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
168fe6060f1SDimitry Andric     "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
169fe6060f1SDimitry Andric     "c31:30",
170fe6060f1SDimitry Andric     // Control register aliases:
171fe6060f1SDimitry Andric     "sa0", "lc0", "sa1", "lc1", "p3:0", "m0",  "m1",  "usr", "pc", "ugp",
172fe6060f1SDimitry Andric     "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
173fe6060f1SDimitry Andric     "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
174fe6060f1SDimitry Andric     "upcycle", "pktcount", "utimer",
175fe6060f1SDimitry Andric     // HVX vector registers:
176fe6060f1SDimitry Andric     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
177fe6060f1SDimitry Andric     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
178fe6060f1SDimitry Andric     "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
179fe6060f1SDimitry Andric     "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
180fe6060f1SDimitry Andric     "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
181fe6060f1SDimitry Andric     "v31:30",
182fe6060f1SDimitry Andric     "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
183fe6060f1SDimitry Andric     // HVX vector predicates:
184fe6060f1SDimitry Andric     "q0", "q1", "q2", "q3",
1850b57cec5SDimitry Andric };
1860b57cec5SDimitry Andric 
getGCCRegNames() const1870b57cec5SDimitry Andric ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
188bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
1920b57cec5SDimitry Andric     {{"sp"}, "r29"},
1930b57cec5SDimitry Andric     {{"fp"}, "r30"},
1940b57cec5SDimitry Andric     {{"lr"}, "r31"},
1950b57cec5SDimitry Andric };
1960b57cec5SDimitry Andric 
getGCCRegAliases() const1970b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
198bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
201bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfo[] = {
2020b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
203bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
2040b57cec5SDimitry Andric #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
205bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
2065ffd83dbSDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
207bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
2080b57cec5SDimitry Andric #include "clang/Basic/BuiltinsHexagon.def"
2090b57cec5SDimitry Andric };
2100b57cec5SDimitry Andric 
hasFeature(StringRef Feature) const2110b57cec5SDimitry Andric bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
2120b57cec5SDimitry Andric   std::string VS = "hvxv" + HVXVersion;
2130b57cec5SDimitry Andric   if (Feature == VS)
2140b57cec5SDimitry Andric     return true;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
2170b57cec5SDimitry Andric       .Case("hexagon", true)
2180b57cec5SDimitry Andric       .Case("hvx", HasHVX)
2190b57cec5SDimitry Andric       .Case("hvx-length64b", HasHVX64B)
2200b57cec5SDimitry Andric       .Case("hvx-length128b", HasHVX128B)
2210b57cec5SDimitry Andric       .Case("long-calls", UseLongCalls)
2225ffd83dbSDimitry Andric       .Case("audio", HasAudio)
2230b57cec5SDimitry Andric       .Default(false);
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric struct CPUSuffix {
2270b57cec5SDimitry Andric   llvm::StringLiteral Name;
2280b57cec5SDimitry Andric   llvm::StringLiteral Suffix;
2290b57cec5SDimitry Andric };
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric static constexpr CPUSuffix Suffixes[] = {
2320b57cec5SDimitry Andric     {{"hexagonv5"},  {"5"}},  {{"hexagonv55"},  {"55"}},
2330b57cec5SDimitry Andric     {{"hexagonv60"}, {"60"}}, {{"hexagonv62"},  {"62"}},
2340b57cec5SDimitry Andric     {{"hexagonv65"}, {"65"}}, {{"hexagonv66"},  {"66"}},
2355ffd83dbSDimitry Andric     {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
2360eae32dcSDimitry Andric     {{"hexagonv68"}, {"68"}}, {{"hexagonv69"},  {"69"}},
237bdd1243dSDimitry Andric     {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"},  {"71t"}},
238bdd1243dSDimitry Andric     {{"hexagonv73"}, {"73"}},
2390b57cec5SDimitry Andric };
2400b57cec5SDimitry Andric 
getHexagonCPURev(StringRef Name)241*0fca6ea1SDimitry Andric std::optional<unsigned> HexagonTargetInfo::getHexagonCPURev(StringRef Name) {
242*0fca6ea1SDimitry Andric   StringRef Arch = Name;
243*0fca6ea1SDimitry Andric   Arch.consume_front("hexagonv");
244*0fca6ea1SDimitry Andric   Arch.consume_back("t");
245*0fca6ea1SDimitry Andric 
246*0fca6ea1SDimitry Andric   unsigned Val;
247*0fca6ea1SDimitry Andric   if (!Arch.getAsInteger(0, Val))
248*0fca6ea1SDimitry Andric     return Val;
249*0fca6ea1SDimitry Andric 
250*0fca6ea1SDimitry Andric   return std::nullopt;
251*0fca6ea1SDimitry Andric }
252*0fca6ea1SDimitry Andric 
getHexagonCPUSuffix(StringRef Name)2530b57cec5SDimitry Andric const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
2540b57cec5SDimitry Andric   const CPUSuffix *Item = llvm::find_if(
2550b57cec5SDimitry Andric       Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
2560b57cec5SDimitry Andric   if (Item == std::end(Suffixes))
2570b57cec5SDimitry Andric     return nullptr;
2580b57cec5SDimitry Andric   return Item->Suffix.data();
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const2610b57cec5SDimitry Andric void HexagonTargetInfo::fillValidCPUList(
2620b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
2630b57cec5SDimitry Andric   for (const CPUSuffix &Suffix : Suffixes)
2640b57cec5SDimitry Andric     Values.push_back(Suffix.Name);
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric 
getTargetBuiltins() const2670b57cec5SDimitry Andric ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
268bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
2690b57cec5SDimitry Andric                                          Builtin::FirstTSBuiltin);
2700b57cec5SDimitry Andric }
271