xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Basic/Targets/Hexagon.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
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 "Targets.h"
15 #include "clang/Basic/MacroBuilder.h"
16 #include "clang/Basic/TargetBuiltins.h"
17 #include "llvm/ADT/StringSwitch.h"
18 
19 using namespace clang;
20 using namespace clang::targets;
21 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const22 void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
23                                          MacroBuilder &Builder) const {
24   Builder.defineMacro("__qdsp6__", "1");
25   Builder.defineMacro("__hexagon__", "1");
26 
27   Builder.defineMacro("__ELF__");
28 
29   // The macro __HVXDBL__ is deprecated.
30   bool DefineHvxDbl = false;
31 
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");
38     }
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   }
72 
73   if (hasFeature("hvx-length64b")) {
74     Builder.defineMacro("__HVX__");
75     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
76     Builder.defineMacro("__HVX_LENGTH__", "64");
77   }
78 
79   if (hasFeature("hvx-length128b")) {
80     Builder.defineMacro("__HVX__");
81     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
82     Builder.defineMacro("__HVX_LENGTH__", "128");
83     if (DefineHvxDbl)
84       Builder.defineMacro("__HVXDBL__");
85   }
86 
87   if (hasFeature("audio")) {
88     Builder.defineMacro("__HEXAGON_AUDIO__");
89   }
90 
91   std::string NumPhySlots = isTinyCore() ? "3" : "4";
92   Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
93 }
94 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const95 bool HexagonTargetInfo::initFeatureMap(
96     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
97     const std::vector<std::string> &FeaturesVec) const {
98   if (isTinyCore())
99     Features["audio"] = true;
100 
101   StringRef CPUFeature = CPU;
102   CPUFeature.consume_front("hexagon");
103   CPUFeature.consume_back("t");
104   if (!CPUFeature.empty())
105     Features[CPUFeature] = true;
106 
107   Features["long-calls"] = false;
108 
109   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
110 }
111 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)112 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
113                                              DiagnosticsEngine &Diags) {
114   for (auto &F : Features) {
115     if (F == "+hvx-length64b")
116       HasHVX = HasHVX64B = true;
117     else if (F == "+hvx-length128b")
118       HasHVX = HasHVX128B = true;
119     else if (F.find("+hvxv") != std::string::npos) {
120       HasHVX = true;
121       HVXVersion = F.substr(std::string("+hvxv").length());
122     } else if (F == "-hvx")
123       HasHVX = HasHVX64B = HasHVX128B = false;
124     else if (F == "+long-calls")
125       UseLongCalls = true;
126     else if (F == "-long-calls")
127       UseLongCalls = false;
128     else if (F == "+audio")
129       HasAudio = true;
130   }
131   return true;
132 }
133 
134 const char *const HexagonTargetInfo::GCCRegNames[] = {
135     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",
136     "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
137     "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
138     "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3",
139     "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp", "cs0", "cs1",
140     "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
141     "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
142     "r31:30"
143 };
144 
getGCCRegNames() const145 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
146   return llvm::makeArrayRef(GCCRegNames);
147 }
148 
149 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
150     {{"sp"}, "r29"},
151     {{"fp"}, "r30"},
152     {{"lr"}, "r31"},
153 };
154 
getGCCRegAliases() const155 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
156   return llvm::makeArrayRef(GCCRegAliases);
157 }
158 
159 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
160 #define BUILTIN(ID, TYPE, ATTRS)                                               \
161   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
162 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
163   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
164 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
165   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
166 #include "clang/Basic/BuiltinsHexagon.def"
167 };
168 
hasFeature(StringRef Feature) const169 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
170   std::string VS = "hvxv" + HVXVersion;
171   if (Feature == VS)
172     return true;
173 
174   return llvm::StringSwitch<bool>(Feature)
175       .Case("hexagon", true)
176       .Case("hvx", HasHVX)
177       .Case("hvx-length64b", HasHVX64B)
178       .Case("hvx-length128b", HasHVX128B)
179       .Case("long-calls", UseLongCalls)
180       .Case("audio", HasAudio)
181       .Default(false);
182 }
183 
184 struct CPUSuffix {
185   llvm::StringLiteral Name;
186   llvm::StringLiteral Suffix;
187 };
188 
189 static constexpr CPUSuffix Suffixes[] = {
190     {{"hexagonv5"},  {"5"}},  {{"hexagonv55"},  {"55"}},
191     {{"hexagonv60"}, {"60"}}, {{"hexagonv62"},  {"62"}},
192     {{"hexagonv65"}, {"65"}}, {{"hexagonv66"},  {"66"}},
193     {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
194     {{"hexagonv68"}, {"68"}},
195 };
196 
getHexagonCPUSuffix(StringRef Name)197 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
198   const CPUSuffix *Item = llvm::find_if(
199       Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
200   if (Item == std::end(Suffixes))
201     return nullptr;
202   return Item->Suffix.data();
203 }
204 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const205 void HexagonTargetInfo::fillValidCPUList(
206     SmallVectorImpl<StringRef> &Values) const {
207   for (const CPUSuffix &Suffix : Suffixes)
208     Values.push_back(Suffix.Name);
209 }
210 
getTargetBuiltins() const211 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
212   return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
213                                              Builtin::FirstTSBuiltin);
214 }
215