Coverage Report

Created: 2022-01-18 06:27

/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/Diagnostic.h"
15
#include "clang/Basic/MacroBuilder.h"
16
#include "clang/Basic/TargetBuiltins.h"
17
#include "llvm/ADT/StringSwitch.h"
18
#include "llvm/Support/TargetParser.h"
19
#include "llvm/Support/raw_ostream.h"
20
21
using namespace clang;
22
using namespace clang::targets;
23
24
818
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
25
818
  static const char *const GCCRegNames[] = {
26
      // Integer registers
27
818
      "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
28
818
      "x8",  "x9",  "x10", "x11", "x12", "x13", "x14", "x15",
29
818
      "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
30
818
      "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
31
32
      // Floating point registers
33
818
      "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
34
818
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
35
818
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
36
818
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
37
38
      // Vector registers
39
818
      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
40
818
      "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
41
818
      "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
42
818
      "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
43
818
  return llvm::makeArrayRef(GCCRegNames);
44
818
}
45
46
536
ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
47
536
  static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
48
536
      {{"zero"}, "x0"}, {{"ra"}, "x1"},   {{"sp"}, "x2"},    {{"gp"}, "x3"},
49
536
      {{"tp"}, "x4"},   {{"t0"}, "x5"},   {{"t1"}, "x6"},    {{"t2"}, "x7"},
50
536
      {{"s0"}, "x8"},   {{"s1"}, "x9"},   {{"a0"}, "x10"},   {{"a1"}, "x11"},
51
536
      {{"a2"}, "x12"},  {{"a3"}, "x13"},  {{"a4"}, "x14"},   {{"a5"}, "x15"},
52
536
      {{"a6"}, "x16"},  {{"a7"}, "x17"},  {{"s2"}, "x18"},   {{"s3"}, "x19"},
53
536
      {{"s4"}, "x20"},  {{"s5"}, "x21"},  {{"s6"}, "x22"},   {{"s7"}, "x23"},
54
536
      {{"s8"}, "x24"},  {{"s9"}, "x25"},  {{"s10"}, "x26"},  {{"s11"}, "x27"},
55
536
      {{"t3"}, "x28"},  {{"t4"}, "x29"},  {{"t5"}, "x30"},   {{"t6"}, "x31"},
56
536
      {{"ft0"}, "f0"},  {{"ft1"}, "f1"},  {{"ft2"}, "f2"},   {{"ft3"}, "f3"},
57
536
      {{"ft4"}, "f4"},  {{"ft5"}, "f5"},  {{"ft6"}, "f6"},   {{"ft7"}, "f7"},
58
536
      {{"fs0"}, "f8"},  {{"fs1"}, "f9"},  {{"fa0"}, "f10"},  {{"fa1"}, "f11"},
59
536
      {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"},  {{"fa5"}, "f15"},
60
536
      {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"},  {{"fs3"}, "f19"},
61
536
      {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"},  {{"fs7"}, "f23"},
62
536
      {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
63
536
      {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
64
536
  return llvm::makeArrayRef(GCCRegAliases);
65
536
}
66
67
bool RISCVTargetInfo::validateAsmConstraint(
68
48
    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
69
48
  switch (*Name) {
70
0
  default:
71
0
    return false;
72
12
  case 'I':
73
    // A 12-bit signed immediate.
74
12
    Info.setRequiresImmediate(-2048, 2047);
75
12
    return true;
76
8
  case 'J':
77
    // Integer zero.
78
8
    Info.setRequiresImmediate(0);
79
8
    return true;
80
12
  case 'K':
81
    // A 5-bit unsigned immediate for CSR access instructions.
82
12
    Info.setRequiresImmediate(0, 31);
83
12
    return true;
84
8
  case 'f':
85
    // A floating-point register.
86
8
    Info.setAllowsRegister();
87
8
    return true;
88
4
  case 'A':
89
    // An address that is held in a general-purpose register.
90
4
    Info.setAllowsMemory();
91
4
    return true;
92
4
  case 'S': // A symbolic address
93
4
    Info.setAllowsRegister();
94
4
    return true;
95
0
  case 'v':
96
    // A vector register.
97
0
    if (Name[1] == 'r' || Name[1] == 'm') {
98
0
      Info.setAllowsRegister();
99
0
      Name += 1;
100
0
      return true;
101
0
    }
102
0
    return false;
103
48
  }
104
48
}
105
106
18
std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
107
18
  std::string R;
108
18
  switch (*Constraint) {
109
0
  case 'v':
110
0
    R = std::string("^") + std::string(Constraint, 2);
111
0
    Constraint += 1;
112
0
    break;
113
18
  default:
114
18
    R = TargetInfo::convertConstraint(Constraint);
115
18
    break;
116
18
  }
117
18
  return R;
118
18
}
119
120
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
121
199
                                       MacroBuilder &Builder) const {
122
199
  Builder.defineMacro("__ELF__");
123
199
  Builder.defineMacro("__riscv");
124
199
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
125
199
  Builder.defineMacro("__riscv_xlen", Is64Bit ? 
"64"109
:
"32"90
);
126
199
  StringRef CodeModel = getTargetOpts().CodeModel;
127
199
  unsigned FLen = ISAInfo->getFLen();
128
199
  unsigned MinVLen = ISAInfo->getMinVLen();
129
199
  if (CodeModel == "default")
130
190
    CodeModel = "small";
131
132
199
  if (CodeModel == "small")
133
194
    Builder.defineMacro("__riscv_cmodel_medlow");
134
5
  else if (CodeModel == "medium")
135
4
    Builder.defineMacro("__riscv_cmodel_medany");
136
137
199
  StringRef ABIName = getABI();
138
199
  if (ABIName == "ilp32f" || 
ABIName == "lp64f"193
)
139
11
    Builder.defineMacro("__riscv_float_abi_single");
140
188
  else if (ABIName == "ilp32d" || 
ABIName == "lp64d"176
)
141
28
    Builder.defineMacro("__riscv_float_abi_double");
142
160
  else
143
160
    Builder.defineMacro("__riscv_float_abi_soft");
144
145
199
  if (ABIName == "ilp32e")
146
0
    Builder.defineMacro("__riscv_abi_rve");
147
148
199
  Builder.defineMacro("__riscv_arch_test");
149
150
543
  for (auto &Extension : ISAInfo->getExtensions()) {
151
543
    auto ExtName = Extension.first;
152
543
    auto ExtInfo = Extension.second;
153
543
    unsigned Version =
154
543
        (ExtInfo.MajorVersion * 1000000) + (ExtInfo.MinorVersion * 1000);
155
156
543
    Builder.defineMacro(Twine("__riscv_", ExtName), Twine(Version));
157
543
  }
158
159
199
  if (ISAInfo->hasExtension("m")) {
160
30
    Builder.defineMacro("__riscv_mul");
161
30
    Builder.defineMacro("__riscv_div");
162
30
    Builder.defineMacro("__riscv_muldiv");
163
30
  }
164
165
199
  if (ISAInfo->hasExtension("a")) {
166
32
    Builder.defineMacro("__riscv_atomic");
167
32
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
168
32
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
169
32
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
170
32
    if (Is64Bit)
171
20
      Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
172
32
  }
173
174
199
  if (FLen) {
175
43
    Builder.defineMacro("__riscv_flen", Twine(FLen));
176
43
    Builder.defineMacro("__riscv_fdiv");
177
43
    Builder.defineMacro("__riscv_fsqrt");
178
43
  }
179
180
199
  if (MinVLen)
181
17
    Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
182
183
199
  if (ISAInfo->hasExtension("c"))
184
30
    Builder.defineMacro("__riscv_compressed");
185
186
199
  if (ISAInfo->hasExtension("v"))
187
17
    Builder.defineMacro("__riscv_vector");
188
199
}
189
190
const Builtin::Info RISCVTargetInfo::BuiltinInfo[] = {
191
#define BUILTIN(ID, TYPE, ATTRS)                                               \
192
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
193
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
194
    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
195
#include "clang/Basic/BuiltinsRISCVVector.def"
196
#define BUILTIN(ID, TYPE, ATTRS)                                               \
197
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
198
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
199
    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
200
#include "clang/Basic/BuiltinsRISCV.def"
201
};
202
203
199
ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
204
199
  return llvm::makeArrayRef(BuiltinInfo, clang::RISCV::LastTSBuiltin -
205
199
                                             Builtin::FirstTSBuiltin);
206
199
}
207
208
bool RISCVTargetInfo::initFeatureMap(
209
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
210
200
    const std::vector<std::string> &FeaturesVec) const {
211
212
200
  if (getTriple().getArch() == llvm::Triple::riscv64)
213
110
    Features["64bit"] = true;
214
215
200
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
216
200
}
217
218
/// Return true if has this feature, need to sync with handleTargetFeatures.
219
179
bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
220
179
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
221
179
  auto Result = llvm::StringSwitch<Optional<bool>>(Feature)
222
179
                    .Case("riscv", true)
223
179
                    .Case("riscv32", !Is64Bit)
224
179
                    .Case("riscv64", Is64Bit)
225
179
                    .Case("64bit", Is64Bit)
226
179
                    .Default(None);
227
179
  if (Result.hasValue())
228
16
    return Result.getValue();
229
230
163
  if (ISAInfo->isSupportedExtensionFeature(Feature))
231
70
    return ISAInfo->hasExtension(Feature);
232
233
93
  return false;
234
163
}
235
236
/// Perform initialization based on the user configured set of features.
237
bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
238
200
                                           DiagnosticsEngine &Diags) {
239
200
  unsigned XLen = getTriple().isArch64Bit() ? 
64110
:
3290
;
240
200
  auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
241
200
  if (!ParseResult) {
242
1
    std::string Buffer;
243
1
    llvm::raw_string_ostream OutputErrMsg(Buffer);
244
1
    handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
245
1
      OutputErrMsg << ErrMsg.getMessage();
246
1
    });
247
1
    Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
248
1
    return false;
249
199
  } else {
250
199
    ISAInfo = std::move(*ParseResult);
251
199
  }
252
253
199
  if (ABI.empty())
254
77
    ABI = llvm::RISCV::computeDefaultABIFromArch(*ISAInfo).str();
255
256
199
  return true;
257
200
}
258
259
2
bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
260
2
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
261
2
                                   /*Is64Bit=*/false);
262
2
}
263
264
void RISCV32TargetInfo::fillValidCPUList(
265
1
    SmallVectorImpl<StringRef> &Values) const {
266
1
  llvm::RISCV::fillValidCPUArchList(Values, false);
267
1
}
268
269
1
bool RISCV32TargetInfo::isValidTuneCPUName(StringRef Name) const {
270
1
  return llvm::RISCV::checkTuneCPUKind(
271
1
      llvm::RISCV::parseTuneCPUKind(Name, false),
272
1
      /*Is64Bit=*/false);
273
1
}
274
275
void RISCV32TargetInfo::fillValidTuneCPUList(
276
1
    SmallVectorImpl<StringRef> &Values) const {
277
1
  llvm::RISCV::fillValidTuneCPUArchList(Values, false);
278
1
}
279
280
2
bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
281
2
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
282
2
                                   /*Is64Bit=*/true);
283
2
}
284
285
void RISCV64TargetInfo::fillValidCPUList(
286
1
    SmallVectorImpl<StringRef> &Values) const {
287
1
  llvm::RISCV::fillValidCPUArchList(Values, true);
288
1
}
289
290
1
bool RISCV64TargetInfo::isValidTuneCPUName(StringRef Name) const {
291
1
  return llvm::RISCV::checkTuneCPUKind(
292
1
      llvm::RISCV::parseTuneCPUKind(Name, true),
293
1
      /*Is64Bit=*/true);
294
1
}
295
296
void RISCV64TargetInfo::fillValidTuneCPUList(
297
1
    SmallVectorImpl<StringRef> &Values) const {
298
1
  llvm::RISCV::fillValidTuneCPUArchList(Values, true);
299
1
}