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