clang  14.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  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 
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 
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  // Scalar registers:
136  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
137  "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
138  "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
139  "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
140  "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
141  "r31:30",
142  // Predicate registers:
143  "p0", "p1", "p2", "p3",
144  // Control registers:
145  "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
146  "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
147  "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
148  "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
149  "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
150  "c31:30",
151  // Control register aliases:
152  "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",
153  "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
154  "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
155  "upcycle", "pktcount", "utimer",
156  // HVX vector registers:
157  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
158  "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
159  "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
160  "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
161  "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
162  "v31:30",
163  "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
164  // HVX vector predicates:
165  "q0", "q1", "q2", "q3",
166 };
167 
169  return llvm::makeArrayRef(GCCRegNames);
170 }
171 
172 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
173  {{"sp"}, "r29"},
174  {{"fp"}, "r30"},
175  {{"lr"}, "r31"},
176 };
177 
179  return llvm::makeArrayRef(GCCRegAliases);
180 }
181 
182 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
183 #define BUILTIN(ID, TYPE, ATTRS) \
184  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
185 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
186  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
187 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
188  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
189 #include "clang/Basic/BuiltinsHexagon.def"
190 };
191 
192 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
193  std::string VS = "hvxv" + HVXVersion;
194  if (Feature == VS)
195  return true;
196 
197  return llvm::StringSwitch<bool>(Feature)
198  .Case("hexagon", true)
199  .Case("hvx", HasHVX)
200  .Case("hvx-length64b", HasHVX64B)
201  .Case("hvx-length128b", HasHVX128B)
202  .Case("long-calls", UseLongCalls)
203  .Case("audio", HasAudio)
204  .Default(false);
205 }
206 
207 struct CPUSuffix {
208  llvm::StringLiteral Name;
209  llvm::StringLiteral Suffix;
210 };
211 
212 static constexpr CPUSuffix Suffixes[] = {
213  {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
214  {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
215  {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
216  {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
217  {{"hexagonv68"}, {"68"}},
218 };
219 
220 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
221  const CPUSuffix *Item = llvm::find_if(
222  Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
223  if (Item == std::end(Suffixes))
224  return nullptr;
225  return Item->Suffix.data();
226 }
227 
229  SmallVectorImpl<StringRef> &Values) const {
230  for (const CPUSuffix &Suffix : Suffixes)
231  Values.push_back(Suffix.Name);
232 }
233 
235  return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
237 }
clang::targets::HexagonTargetInfo::hasFeature
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: Hexagon.cpp:192
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
CPUSuffix
Definition: Hexagon.cpp:207
clang::DiagnosticsEngine
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:191
clang::targets::HexagonTargetInfo::isTinyCore
bool isTinyCore() const
Definition: Hexagon.h:137
clang::targets::HexagonTargetInfo::getGCCRegAliases
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: Hexagon.cpp:178
clang::Hexagon::LastTSBuiltin
@ LastTSBuiltin
Definition: TargetBuiltins.h:279
clang::targets::HexagonTargetInfo::getGCCRegNames
ArrayRef< const char * > getGCCRegNames() const override
Definition: Hexagon.cpp:168
Hexagon.h
Suffixes
static constexpr CPUSuffix Suffixes[]
Definition: Hexagon.cpp:212
clang::targets::HexagonTargetInfo::fillValidCPUList
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: Hexagon.cpp:228
clang::targets::HexagonTargetInfo::getTargetDefines
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: Hexagon.cpp:22
CPUSuffix::Suffix
llvm::StringLiteral Suffix
Definition: Hexagon.cpp:209
Targets.h
clang::TargetInfo::initFeatureMap
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:461
MacroBuilder.h
clang::TargetInfo::GCCRegAlias
Definition: TargetInfo.h:1142
length
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
llvm::ArrayRef< const char * >
clang::targets::HexagonTargetInfo::initFeatureMap
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:95
TargetBuiltins.h
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:58
clang::targets::HexagonTargetInfo::getTargetBuiltins
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: Hexagon.cpp:234
clang
Definition: CalledOnceCheck.h:17
clang::targets
Definition: AArch64.h:21
clang::targets::HexagonTargetInfo::handleTargetFeatures
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:112
clang::Builtin::Info
Definition: Builtins.h:55
clang::targets::HexagonTargetInfo::getHexagonCPUSuffix
static const char * getHexagonCPUSuffix(StringRef Name)
Definition: Hexagon.cpp:220
clang::Builtin::FirstTSBuiltin
@ FirstTSBuiltin
Definition: Builtins.h:52
CPUSuffix::Name
llvm::StringLiteral Name
Definition: Hexagon.cpp:208
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::MacroBuilder
Definition: MacroBuilder.h:23