Coverage Report

Created: 2021-09-21 08:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- RISCV.cpp - Implement RISCV 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 RISCV TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "RISCV.h"
14
#include "clang/Basic/MacroBuilder.h"
15
#include "clang/Basic/TargetBuiltins.h"
16
#include "llvm/ADT/StringSwitch.h"
17
#include "llvm/Support/TargetParser.h"
18
19
using namespace clang;
20
using namespace clang::targets;
21
22
838
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
23
838
  static const char *const GCCRegNames[] = {
24
      // Integer registers
25
838
      "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
26
838
      "x8",  "x9",  "x10", "x11", "x12", "x13", "x14", "x15",
27
838
      "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
28
838
      "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
29
30
      // Floating point registers
31
838
      "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
32
838
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
33
838
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
34
838
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
35
36
      // Vector registers
37
838
      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
38
838
      "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
39
838
      "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
40
838
      "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
41
838
  return llvm::makeArrayRef(GCCRegNames);
42
838
}
43
44
544
ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
45
544
  static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
46
544
      {{"zero"}, "x0"}, {{"ra"}, "x1"},   {{"sp"}, "x2"},    {{"gp"}, "x3"},
47
544
      {{"tp"}, "x4"},   {{"t0"}, "x5"},   {{"t1"}, "x6"},    {{"t2"}, "x7"},
48
544
      {{"s0"}, "x8"},   {{"s1"}, "x9"},   {{"a0"}, "x10"},   {{"a1"}, "x11"},
49
544
      {{"a2"}, "x12"},  {{"a3"}, "x13"},  {{"a4"}, "x14"},   {{"a5"}, "x15"},
50
544
      {{"a6"}, "x16"},  {{"a7"}, "x17"},  {{"s2"}, "x18"},   {{"s3"}, "x19"},
51
544
      {{"s4"}, "x20"},  {{"s5"}, "x21"},  {{"s6"}, "x22"},   {{"s7"}, "x23"},
52
544
      {{"s8"}, "x24"},  {{"s9"}, "x25"},  {{"s10"}, "x26"},  {{"s11"}, "x27"},
53
544
      {{"t3"}, "x28"},  {{"t4"}, "x29"},  {{"t5"}, "x30"},   {{"t6"}, "x31"},
54
544
      {{"ft0"}, "f0"},  {{"ft1"}, "f1"},  {{"ft2"}, "f2"},   {{"ft3"}, "f3"},
55
544
      {{"ft4"}, "f4"},  {{"ft5"}, "f5"},  {{"ft6"}, "f6"},   {{"ft7"}, "f7"},
56
544
      {{"fs0"}, "f8"},  {{"fs1"}, "f9"},  {{"fa0"}, "f10"},  {{"fa1"}, "f11"},
57
544
      {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"},  {{"fa5"}, "f15"},
58
544
      {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"},  {{"fs3"}, "f19"},
59
544
      {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"},  {{"fs7"}, "f23"},
60
544
      {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
61
544
      {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
62
544
  return llvm::makeArrayRef(GCCRegAliases);
63
544
}
64
65
bool RISCVTargetInfo::validateAsmConstraint(
66
72
    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
67
72
  switch (*Name) {
68
0
  default:
69
0
    return false;
70
12
  case 'I':
71
    // A 12-bit signed immediate.
72
12
    Info.setRequiresImmediate(-2048, 2047);
73
12
    return true;
74
8
  case 'J':
75
    // Integer zero.
76
8
    Info.setRequiresImmediate(0);
77
8
    return true;
78
12
  case 'K':
79
    // A 5-bit unsigned immediate for CSR access instructions.
80
12
    Info.setRequiresImmediate(0, 31);
81
12
    return true;
82
8
  case 'f':
83
    // A floating-point register.
84
8
    Info.setAllowsRegister();
85
8
    return true;
86
4
  case 'A':
87
    // An address that is held in a general-purpose register.
88
4
    Info.setAllowsMemory();
89
4
    return true;
90
4
  case 'S': // A symbolic address
91
4
    Info.setAllowsRegister();
92
4
    return true;
93
24
  case 'v':
94
    // A vector register.
95
24
    if (Name[1] == 'r' || 
Name[1] == 'm'12
) {
96
24
      Info.setAllowsRegister();
97
24
      Name += 1;
98
24
      return true;
99
24
    }
100
0
    return false;
101
72
  }
102
72
}
103
104
30
std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
105
30
  std::string R;
106
30
  switch (*Constraint) {
107
12
  case 'v':
108
12
    R = std::string("^") + std::string(Constraint, 2);
109
12
    Constraint += 1;
110
12
    break;
111
18
  default:
112
18
    R = TargetInfo::convertConstraint(Constraint);
113
18
    break;
114
30
  }
115
30
  return R;
116
30
}
117
118
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
119
497
                                       MacroBuilder &Builder) const {
120
497
  Builder.defineMacro("__ELF__");
121
497
  Builder.defineMacro("__riscv");
122
497
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
123
497
  Builder.defineMacro("__riscv_xlen", Is64Bit ? 
"64"403
:
"32"94
);
124
497
  StringRef CodeModel = getTargetOpts().CodeModel;
125
497
  if (CodeModel == "default")
126
487
    CodeModel = "small";
127
128
497
  if (CodeModel == "small")
129
491
    Builder.defineMacro("__riscv_cmodel_medlow");
130
6
  else if (CodeModel == "medium")
131
4
    Builder.defineMacro("__riscv_cmodel_medany");
132
133
497
  StringRef ABIName = getABI();
134
497
  if (ABIName == "ilp32f" || 
ABIName == "lp64f"491
)
135
11
    Builder.defineMacro("__riscv_float_abi_single");
136
486
  else if (ABIName == "ilp32d" || 
ABIName == "lp64d"474
)
137
18
    Builder.defineMacro("__riscv_float_abi_double");
138
468
  else
139
468
    Builder.defineMacro("__riscv_float_abi_soft");
140
141
497
  if (ABIName == "ilp32e")
142
0
    Builder.defineMacro("__riscv_abi_rve");
143
144
497
  Builder.defineMacro("__riscv_arch_test");
145
497
  Builder.defineMacro("__riscv_i", "2000000");
146
147
497
  if (HasM) {
148
38
    Builder.defineMacro("__riscv_m", "2000000");
149
38
    Builder.defineMacro("__riscv_mul");
150
38
    Builder.defineMacro("__riscv_div");
151
38
    Builder.defineMacro("__riscv_muldiv");
152
38
  }
153
154
497
  if (HasA) {
155
26
    Builder.defineMacro("__riscv_a", "2000000");
156
26
    Builder.defineMacro("__riscv_atomic");
157
26
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
158
26
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
159
26
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
160
26
    if (Is64Bit)
161
13
      Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
162
26
  }
163
164
497
  if (HasF || 
HasD313
) {
165
193
    Builder.defineMacro("__riscv_f", "2000000");
166
193
    Builder.defineMacro("__riscv_flen", HasD ? 
"64"182
:
"32"11
);
167
193
    Builder.defineMacro("__riscv_fdiv");
168
193
    Builder.defineMacro("__riscv_fsqrt");
169
193
  }
170
171
497
  if (HasD)
172
182
    Builder.defineMacro("__riscv_d", "2000000");
173
174
497
  if (HasC) {
175
23
    Builder.defineMacro("__riscv_c", "2000000");
176
23
    Builder.defineMacro("__riscv_compressed");
177
23
  }
178
179
497
  if (HasB) {
180
2
    Builder.defineMacro("__riscv_b", "93000");
181
2
    Builder.defineMacro("__riscv_bitmanip");
182
2
  }
183
184
497
  if (HasV) {
185
332
    Builder.defineMacro("__riscv_v", "10000");
186
332
    Builder.defineMacro("__riscv_vector");
187
332
  }
188
189
497
  if (HasZba)
190
4
    Builder.defineMacro("__riscv_zba", "93000");
191
192
497
  if (HasZbb)
193
7
    Builder.defineMacro("__riscv_zbb", "93000");
194
195
497
  if (HasZbc)
196
6
    Builder.defineMacro("__riscv_zbc", "93000");
197
198
497
  if (HasZbe)
199
6
    Builder.defineMacro("__riscv_zbe", "93000");
200
201
497
  if (HasZbf)
202
4
    Builder.defineMacro("__riscv_zbf", "93000");
203
204
497
  if (HasZbm)
205
4
    Builder.defineMacro("__riscv_zbm", "93000");
206
207
497
  if (HasZbp)
208
6
    Builder.defineMacro("__riscv_zbp", "93000");
209
210
497
  if (HasZbproposedc)
211
2
    Builder.defineMacro("__riscv_zbproposedc", "93000");
212
213
497
  if (HasZbr)
214
6
    Builder.defineMacro("__riscv_zbr", "93000");
215
216
497
  if (HasZbs)
217
4
    Builder.defineMacro("__riscv_zbs", "93000");
218
219
497
  if (HasZbt)
220
4
    Builder.defineMacro("__riscv_zbt", "93000");
221
222
497
  if (HasZfh)
223
22
    Builder.defineMacro("__riscv_zfh", "1000");
224
225
497
  if (HasZvamo)
226
16
    Builder.defineMacro("__riscv_zvamo", "10000");
227
228
497
  if (HasZvlsseg)
229
28
    Builder.defineMacro("__riscv_zvlsseg", "10000");
230
497
}
231
232
const Builtin::Info RISCVTargetInfo::BuiltinInfo[] = {
233
#define BUILTIN(ID, TYPE, ATTRS)                                               \
234
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
235
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
236
    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
237
#include "clang/Basic/BuiltinsRISCV.def"
238
};
239
240
497
ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
241
497
  return llvm::makeArrayRef(BuiltinInfo, clang::RISCV::LastTSBuiltin -
242
497
                                             Builtin::FirstTSBuiltin);
243
497
}
244
245
bool RISCVTargetInfo::initFeatureMap(
246
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
247
497
    const std::vector<std::string> &FeaturesVec) const {
248
249
497
  if (getTriple().getArch() == llvm::Triple::riscv64)
250
403
    Features["64bit"] = true;
251
252
497
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
253
497
}
254
255
/// Return true if has this feature, need to sync with handleTargetFeatures.
256
45.9k
bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
257
45.9k
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
258
45.9k
  return llvm::StringSwitch<bool>(Feature)
259
45.9k
      .Case("riscv", true)
260
45.9k
      .Case("riscv32", !Is64Bit)
261
45.9k
      .Case("riscv64", Is64Bit)
262
45.9k
      .Case("64bit", Is64Bit)
263
45.9k
      .Case("m", HasM)
264
45.9k
      .Case("a", HasA)
265
45.9k
      .Case("f", HasF)
266
45.9k
      .Case("d", HasD)
267
45.9k
      .Case("c", HasC)
268
45.9k
      .Case("experimental-b", HasB)
269
45.9k
      .Case("experimental-v", HasV)
270
45.9k
      .Case("experimental-zba", HasZba)
271
45.9k
      .Case("experimental-zbb", HasZbb)
272
45.9k
      .Case("experimental-zbc", HasZbc)
273
45.9k
      .Case("experimental-zbe", HasZbe)
274
45.9k
      .Case("experimental-zbf", HasZbf)
275
45.9k
      .Case("experimental-zbm", HasZbm)
276
45.9k
      .Case("experimental-zbp", HasZbp)
277
45.9k
      .Case("experimental-zbproposedc", HasZbproposedc)
278
45.9k
      .Case("experimental-zbr", HasZbr)
279
45.9k
      .Case("experimental-zbs", HasZbs)
280
45.9k
      .Case("experimental-zbt", HasZbt)
281
45.9k
      .Case("experimental-zfh", HasZfh)
282
45.9k
      .Case("experimental-zvamo", HasZvamo)
283
45.9k
      .Case("experimental-zvlsseg", HasZvlsseg)
284
45.9k
      .Default(false);
285
45.9k
}
286
287
/// Perform initialization based on the user configured set of features.
288
bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
289
497
                                           DiagnosticsEngine &Diags) {
290
1.47k
  for (const auto &Feature : Features) {
291
1.47k
    if (Feature == "+m")
292
38
      HasM = true;
293
1.43k
    else if (Feature == "+a")
294
26
      HasA = true;
295
1.40k
    else if (Feature == "+f")
296
184
      HasF = true;
297
1.22k
    else if (Feature == "+d")
298
182
      HasD = true;
299
1.04k
    else if (Feature == "+c")
300
23
      HasC = true;
301
1.01k
    else if (Feature == "+experimental-b")
302
2
      HasB = true;
303
1.01k
    else if (Feature == "+experimental-v")
304
332
      HasV = true;
305
685
    else if (Feature == "+experimental-zba")
306
4
      HasZba = true;
307
681
    else if (Feature == "+experimental-zbb")
308
7
      HasZbb = true;
309
674
    else if (Feature == "+experimental-zbc")
310
6
      HasZbc = true;
311
668
    else if (Feature == "+experimental-zbe")
312
6
      HasZbe = true;
313
662
    else if (Feature == "+experimental-zbf")
314
4
      HasZbf = true;
315
658
    else if (Feature == "+experimental-zbm")
316
4
      HasZbm = true;
317
654
    else if (Feature == "+experimental-zbp")
318
6
      HasZbp = true;
319
648
    else if (Feature == "+experimental-zbproposedc")
320
2
      HasZbproposedc = true;
321
646
    else if (Feature == "+experimental-zbr")
322
6
      HasZbr = true;
323
640
    else if (Feature == "+experimental-zbs")
324
4
      HasZbs = true;
325
636
    else if (Feature == "+experimental-zbt")
326
4
      HasZbt = true;
327
632
    else if (Feature == "+experimental-zfh")
328
22
      HasZfh = true;
329
610
    else if (Feature == "+experimental-zvamo")
330
16
      HasZvamo = true;
331
594
    else if (Feature == "+experimental-zvlsseg")
332
28
      HasZvlsseg = true;
333
1.47k
  }
334
335
497
  return true;
336
497
}
337
338
1
bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
339
1
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
340
1
                                   /*Is64Bit=*/false);
341
1
}
342
343
void RISCV32TargetInfo::fillValidCPUList(
344
1
    SmallVectorImpl<StringRef> &Values) const {
345
1
  llvm::RISCV::fillValidCPUArchList(Values, false);
346
1
}
347
348
1
bool RISCV32TargetInfo::isValidTuneCPUName(StringRef Name) const {
349
1
  return llvm::RISCV::checkTuneCPUKind(
350
1
      llvm::RISCV::parseTuneCPUKind(Name, false),
351
1
      /*Is64Bit=*/false);
352
1
}
353
354
void RISCV32TargetInfo::fillValidTuneCPUList(
355
1
    SmallVectorImpl<StringRef> &Values) const {
356
1
  llvm::RISCV::fillValidTuneCPUArchList(Values, false);
357
1
}
358
359
1
bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
360
1
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
361
1
                                   /*Is64Bit=*/true);
362
1
}
363
364
void RISCV64TargetInfo::fillValidCPUList(
365
1
    SmallVectorImpl<StringRef> &Values) const {
366
1
  llvm::RISCV::fillValidCPUArchList(Values, true);
367
1
}
368
369
1
bool RISCV64TargetInfo::isValidTuneCPUName(StringRef Name) const {
370
1
  return llvm::RISCV::checkTuneCPUKind(
371
1
      llvm::RISCV::parseTuneCPUKind(Name, true),
372
1
      /*Is64Bit=*/true);
373
1
}
374
375
void RISCV64TargetInfo::fillValidTuneCPUList(
376
1
    SmallVectorImpl<StringRef> &Values) const {
377
1
  llvm::RISCV::fillValidTuneCPUArchList(Values, true);
378
1
}