Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
Line
Count
Source (jump to first uncovered line)
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
0
                                         MacroBuilder &Builder) const {
24
0
  Builder.defineMacro("__qdsp6__", "1");
25
0
  Builder.defineMacro("__hexagon__", "1");
26
27
  // The macro __HVXDBL__ is deprecated.
28
0
  bool DefineHvxDbl = false;
29
30
0
  if (CPU == "hexagonv5") {
31
0
    Builder.defineMacro("__HEXAGON_V5__");
32
0
    Builder.defineMacro("__HEXAGON_ARCH__", "5");
33
0
    if (Opts.HexagonQdsp6Compat) {
34
0
      Builder.defineMacro("__QDSP6_V5__");
35
0
      Builder.defineMacro("__QDSP6_ARCH__", "5");
36
0
    }
37
0
  } else if (CPU == "hexagonv55") {
38
0
    Builder.defineMacro("__HEXAGON_V55__");
39
0
    Builder.defineMacro("__HEXAGON_ARCH__", "55");
40
0
    Builder.defineMacro("__QDSP6_V55__");
41
0
    Builder.defineMacro("__QDSP6_ARCH__", "55");
42
0
  } else if (CPU == "hexagonv60") {
43
0
    DefineHvxDbl = true;
44
0
    Builder.defineMacro("__HEXAGON_V60__");
45
0
    Builder.defineMacro("__HEXAGON_ARCH__", "60");
46
0
    Builder.defineMacro("__QDSP6_V60__");
47
0
    Builder.defineMacro("__QDSP6_ARCH__", "60");
48
0
  } else if (CPU == "hexagonv62") {
49
0
    DefineHvxDbl = true;
50
0
    Builder.defineMacro("__HEXAGON_V62__");
51
0
    Builder.defineMacro("__HEXAGON_ARCH__", "62");
52
0
  } else if (CPU == "hexagonv65") {
53
0
    DefineHvxDbl = true;
54
0
    Builder.defineMacro("__HEXAGON_V65__");
55
0
    Builder.defineMacro("__HEXAGON_ARCH__", "65");
56
0
  } else if (CPU == "hexagonv66") {
57
0
    DefineHvxDbl = true;
58
0
    Builder.defineMacro("__HEXAGON_V66__");
59
0
    Builder.defineMacro("__HEXAGON_ARCH__", "66");
60
0
  } else if (CPU == "hexagonv67") {
61
0
    Builder.defineMacro("__HEXAGON_V67__");
62
0
    Builder.defineMacro("__HEXAGON_ARCH__", "67");
63
0
  } else if (CPU == "hexagonv67t") {
64
0
    Builder.defineMacro("__HEXAGON_V67T__");
65
0
    Builder.defineMacro("__HEXAGON_ARCH__", "67");
66
0
  } else if (CPU == "hexagonv68") {
67
0
    Builder.defineMacro("__HEXAGON_V68__");
68
0
    Builder.defineMacro("__HEXAGON_ARCH__", "68");
69
0
  } else if (CPU == "hexagonv69") {
70
0
    Builder.defineMacro("__HEXAGON_V69__");
71
0
    Builder.defineMacro("__HEXAGON_ARCH__", "69");
72
0
  } else if (CPU == "hexagonv71") {
73
0
    Builder.defineMacro("__HEXAGON_V71__");
74
0
    Builder.defineMacro("__HEXAGON_ARCH__", "71");
75
0
  } else if (CPU == "hexagonv71t") {
76
0
    Builder.defineMacro("__HEXAGON_V71T__");
77
0
    Builder.defineMacro("__HEXAGON_ARCH__", "71");
78
0
  } else if (CPU == "hexagonv73") {
79
0
    Builder.defineMacro("__HEXAGON_V73__");
80
0
    Builder.defineMacro("__HEXAGON_ARCH__", "73");
81
0
  }
82
83
0
  if (hasFeature("hvx-length64b")) {
84
0
    Builder.defineMacro("__HVX__");
85
0
    Builder.defineMacro("__HVX_ARCH__", HVXVersion);
86
0
    Builder.defineMacro("__HVX_LENGTH__", "64");
87
0
  }
88
89
0
  if (hasFeature("hvx-length128b")) {
90
0
    Builder.defineMacro("__HVX__");
91
0
    Builder.defineMacro("__HVX_ARCH__", HVXVersion);
92
0
    Builder.defineMacro("__HVX_LENGTH__", "128");
93
0
    if (DefineHvxDbl)
94
0
      Builder.defineMacro("__HVXDBL__");
95
0
  }
96
97
0
  if (hasFeature("audio")) {
98
0
    Builder.defineMacro("__HEXAGON_AUDIO__");
99
0
  }
100
101
0
  std::string NumPhySlots = isTinyCore() ? "3" : "4";
102
0
  Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
103
104
0
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
105
0
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
106
0
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
107
0
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
108
0
}
109
110
bool HexagonTargetInfo::initFeatureMap(
111
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
112
0
    const std::vector<std::string> &FeaturesVec) const {
113
0
  if (isTinyCore())
114
0
    Features["audio"] = true;
115
116
0
  StringRef CPUFeature = CPU;
117
0
  CPUFeature.consume_front("hexagon");
118
0
  CPUFeature.consume_back("t");
119
0
  if (!CPUFeature.empty())
120
0
    Features[CPUFeature] = true;
121
122
0
  Features["long-calls"] = false;
123
124
0
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
125
0
}
126
127
bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
128
0
                                             DiagnosticsEngine &Diags) {
129
0
  for (auto &F : Features) {
130
0
    if (F == "+hvx-length64b")
131
0
      HasHVX = HasHVX64B = true;
132
0
    else if (F == "+hvx-length128b")
133
0
      HasHVX = HasHVX128B = true;
134
0
    else if (F.find("+hvxv") != std::string::npos) {
135
0
      HasHVX = true;
136
0
      HVXVersion = F.substr(std::string("+hvxv").length());
137
0
    } else if (F == "-hvx")
138
0
      HasHVX = HasHVX64B = HasHVX128B = false;
139
0
    else if (F == "+long-calls")
140
0
      UseLongCalls = true;
141
0
    else if (F == "-long-calls")
142
0
      UseLongCalls = false;
143
0
    else if (F == "+audio")
144
0
      HasAudio = true;
145
0
  }
146
0
  if (CPU.compare("hexagonv68") >= 0) {
147
0
    HasLegalHalfType = true;
148
0
    HasFloat16 = true;
149
0
  }
150
0
  return true;
151
0
}
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
187
0
ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
188
0
  return llvm::ArrayRef(GCCRegNames);
189
0
}
190
191
const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
192
    {{"sp"}, "r29"},
193
    {{"fp"}, "r30"},
194
    {{"lr"}, "r31"},
195
};
196
197
0
ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
198
0
  return llvm::ArrayRef(GCCRegAliases);
199
0
}
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
0
bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
212
0
  std::string VS = "hvxv" + HVXVersion;
213
0
  if (Feature == VS)
214
0
    return true;
215
216
0
  return llvm::StringSwitch<bool>(Feature)
217
0
      .Case("hexagon", true)
218
0
      .Case("hvx", HasHVX)
219
0
      .Case("hvx-length64b", HasHVX64B)
220
0
      .Case("hvx-length128b", HasHVX128B)
221
0
      .Case("long-calls", UseLongCalls)
222
0
      .Case("audio", HasAudio)
223
0
      .Default(false);
224
0
}
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
0
const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
242
0
  const CPUSuffix *Item = llvm::find_if(
243
0
      Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
244
0
  if (Item == std::end(Suffixes))
245
0
    return nullptr;
246
0
  return Item->Suffix.data();
247
0
}
248
249
void HexagonTargetInfo::fillValidCPUList(
250
0
    SmallVectorImpl<StringRef> &Values) const {
251
0
  for (const CPUSuffix &Suffix : Suffixes)
252
0
    Values.push_back(Suffix.Name);
253
0
}
254
255
0
ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
256
0
  return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
257
0
                                         Builtin::FirstTSBuiltin);
258
0
}