clang  19.0.0git
Hexagon.cpp
Go to the documentation of this file.
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"
17 #include "llvm/ADT/StringSwitch.h"
18 
19 using namespace clang;
20 using namespace clang::targets;
21 
23  MacroBuilder &Builder) const {
24  Builder.defineMacro("__qdsp6__", "1");
25  Builder.defineMacro("__hexagon__", "1");
26 
27  // The macro __HVXDBL__ is deprecated.
28  bool DefineHvxDbl = false;
29 
30  if (CPU == "hexagonv5") {
31  Builder.defineMacro("__HEXAGON_V5__");
32  Builder.defineMacro("__HEXAGON_ARCH__", "5");
33  if (Opts.HexagonQdsp6Compat) {
34  Builder.defineMacro("__QDSP6_V5__");
35  Builder.defineMacro("__QDSP6_ARCH__", "5");
36  }
37  } else if (CPU == "hexagonv55") {
38  Builder.defineMacro("__HEXAGON_V55__");
39  Builder.defineMacro("__HEXAGON_ARCH__", "55");
40  Builder.defineMacro("__QDSP6_V55__");
41  Builder.defineMacro("__QDSP6_ARCH__", "55");
42  } else if (CPU == "hexagonv60") {
43  DefineHvxDbl = true;
44  Builder.defineMacro("__HEXAGON_V60__");
45  Builder.defineMacro("__HEXAGON_ARCH__", "60");
46  Builder.defineMacro("__QDSP6_V60__");
47  Builder.defineMacro("__QDSP6_ARCH__", "60");
48  } else if (CPU == "hexagonv62") {
49  DefineHvxDbl = true;
50  Builder.defineMacro("__HEXAGON_V62__");
51  Builder.defineMacro("__HEXAGON_ARCH__", "62");
52  } else if (CPU == "hexagonv65") {
53  DefineHvxDbl = true;
54  Builder.defineMacro("__HEXAGON_V65__");
55  Builder.defineMacro("__HEXAGON_ARCH__", "65");
56  } else if (CPU == "hexagonv66") {
57  DefineHvxDbl = true;
58  Builder.defineMacro("__HEXAGON_V66__");
59  Builder.defineMacro("__HEXAGON_ARCH__", "66");
60  } else if (CPU == "hexagonv67") {
61  Builder.defineMacro("__HEXAGON_V67__");
62  Builder.defineMacro("__HEXAGON_ARCH__", "67");
63  } else if (CPU == "hexagonv67t") {
64  Builder.defineMacro("__HEXAGON_V67T__");
65  Builder.defineMacro("__HEXAGON_ARCH__", "67");
66  } else if (CPU == "hexagonv68") {
67  Builder.defineMacro("__HEXAGON_V68__");
68  Builder.defineMacro("__HEXAGON_ARCH__", "68");
69  } else if (CPU == "hexagonv69") {
70  Builder.defineMacro("__HEXAGON_V69__");
71  Builder.defineMacro("__HEXAGON_ARCH__", "69");
72  } else if (CPU == "hexagonv71") {
73  Builder.defineMacro("__HEXAGON_V71__");
74  Builder.defineMacro("__HEXAGON_ARCH__", "71");
75  } else if (CPU == "hexagonv71t") {
76  Builder.defineMacro("__HEXAGON_V71T__");
77  Builder.defineMacro("__HEXAGON_ARCH__", "71");
78  } else if (CPU == "hexagonv73") {
79  Builder.defineMacro("__HEXAGON_V73__");
80  Builder.defineMacro("__HEXAGON_ARCH__", "73");
81  }
82 
83  if (hasFeature("hvx-length64b")) {
84  Builder.defineMacro("__HVX__");
85  Builder.defineMacro("__HVX_ARCH__", HVXVersion);
86  Builder.defineMacro("__HVX_LENGTH__", "64");
87  }
88 
89  if (hasFeature("hvx-length128b")) {
90  Builder.defineMacro("__HVX__");
91  Builder.defineMacro("__HVX_ARCH__", HVXVersion);
92  Builder.defineMacro("__HVX_LENGTH__", "128");
93  if (DefineHvxDbl)
94  Builder.defineMacro("__HVXDBL__");
95  }
96 
97  if (hasFeature("audio")) {
98  Builder.defineMacro("__HEXAGON_AUDIO__");
99  }
100 
101  std::string NumPhySlots = isTinyCore() ? "3" : "4";
102  Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
103 
104  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
105  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
106  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
107  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
108 }
109 
111  llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
112  const std::vector<std::string> &FeaturesVec) const {
113  if (isTinyCore())
114  Features["audio"] = true;
115 
116  StringRef CPUFeature = CPU;
117  CPUFeature.consume_front("hexagon");
118  CPUFeature.consume_back("t");
119  if (!CPUFeature.empty())
120  Features[CPUFeature] = true;
121 
122  Features["long-calls"] = false;
123 
124  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
125 }
126 
127 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
128  DiagnosticsEngine &Diags) {
129  for (auto &F : Features) {
130  if (F == "+hvx-length64b")
131  HasHVX = HasHVX64B = true;
132  else if (F == "+hvx-length128b")
133  HasHVX = HasHVX128B = true;
134  else if (F.find("+hvxv") != std::string::npos) {
135  HasHVX = true;
136  HVXVersion = F.substr(std::string("+hvxv").length());
137  } else if (F == "-hvx")
138  HasHVX = HasHVX64B = HasHVX128B = false;
139  else if (F == "+long-calls")
140  UseLongCalls = true;
141  else if (F == "-long-calls")
142  UseLongCalls = false;
143  else if (F == "+audio")
144  HasAudio = true;
145  }
146  if (CPU.compare("hexagonv68") >= 0) {
147  HasLegalHalfType = true;
148  HasFloat16 = true;
149  }
150  return true;
151 }
152 
153 const char *const HexagonTargetInfo::GCCRegNames[] = {
154  // Scalar registers:
155  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
156  "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
157  "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
158  "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
159  "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
160  "r31:30",
161  // Predicate registers:
162  "p0", "p1", "p2", "p3",
163  // Control registers:
164  "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
165  "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
166  "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
167  "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
168  "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
169  "c31:30",
170  // Control register aliases:
171  "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",
172  "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
173  "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
174  "upcycle", "pktcount", "utimer",
175  // HVX vector registers:
176  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
177  "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
178  "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
179  "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
180  "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
181  "v31:30",
182  "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
183  // HVX vector predicates:
184  "q0", "q1", "q2", "q3",
185 };
186 
188  return llvm::ArrayRef(GCCRegNames);
189 }
190 
191 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
192  {{"sp"}, "r29"},
193  {{"fp"}, "r30"},
194  {{"lr"}, "r31"},
195 };
196 
198  return llvm::ArrayRef(GCCRegAliases);
199 }
200 
201 static constexpr Builtin::Info BuiltinInfo[] = {
202 #define BUILTIN(ID, TYPE, ATTRS) \
203  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
204 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
205  {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
206 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
207  {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
208 #include "clang/Basic/BuiltinsHexagon.def"
209 };
210 
211 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
212  std::string VS = "hvxv" + HVXVersion;
213  if (Feature == VS)
214  return true;
215 
216  return llvm::StringSwitch<bool>(Feature)
217  .Case("hexagon", true)
218  .Case("hvx", HasHVX)
219  .Case("hvx-length64b", HasHVX64B)
220  .Case("hvx-length128b", HasHVX128B)
221  .Case("long-calls", UseLongCalls)
222  .Case("audio", HasAudio)
223  .Default(false);
224 }
225 
226 struct CPUSuffix {
227  llvm::StringLiteral Name;
228  llvm::StringLiteral Suffix;
229 };
230 
231 static constexpr CPUSuffix Suffixes[] = {
232  {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
233  {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
234  {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
235  {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
236  {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},
237  {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},
238  {{"hexagonv73"}, {"73"}},
239 };
240 
241 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
242  const CPUSuffix *Item = llvm::find_if(
243  Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
244  if (Item == std::end(Suffixes))
245  return nullptr;
246  return Item->Suffix.data();
247 }
248 
250  SmallVectorImpl<StringRef> &Values) const {
251  for (const CPUSuffix &Suffix : Suffixes)
252  Values.push_back(Suffix.Name);
253 }
254 
258 }
static constexpr CPUSuffix Suffixes[]
Definition: Hexagon.cpp:231
static constexpr Builtin::Info BuiltinInfo[]
Definition: Hexagon.cpp:201
Defines the clang::MacroBuilder utility class.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: TargetInfo.cpp:566
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
Definition: Hexagon.cpp:127
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: Hexagon.cpp:110
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: Hexagon.cpp:197
static const char * getHexagonCPUSuffix(StringRef Name)
Definition: Hexagon.cpp:241
ArrayRef< const char * > getGCCRegNames() const override
Definition: Hexagon.cpp:187
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Hexagon.cpp:249
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: Hexagon.cpp:22
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: Hexagon.cpp:255
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: Hexagon.cpp:211
The JSON file list parser is used to communicate input to InstallAPI.
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
llvm::StringLiteral Suffix
Definition: Hexagon.cpp:228
llvm::StringLiteral Name
Definition: Hexagon.cpp:227