Coverage Report

Created: 2020-09-19 12:23

/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 "llvm/ADT/StringSwitch.h"
16
#include "llvm/Support/TargetParser.h"
17
18
using namespace clang;
19
using namespace clang::targets;
20
21
768
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
22
768
  static const char *const GCCRegNames[] = {
23
      // Integer registers
24
768
      "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
25
768
      "x8",  "x9",  "x10", "x11", "x12", "x13", "x14", "x15",
26
768
      "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
27
768
      "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
28
768
29
      // Floating point registers
30
768
      "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
31
768
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
32
768
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
33
768
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
34
768
  return llvm::makeArrayRef(GCCRegNames);
35
768
}
36
37
512
ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
38
512
  static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
39
512
      {{"zero"}, "x0"}, {{"ra"}, "x1"},   {{"sp"}, "x2"},    {{"gp"}, "x3"},
40
512
      {{"tp"}, "x4"},   {{"t0"}, "x5"},   {{"t1"}, "x6"},    {{"t2"}, "x7"},
41
512
      {{"s0"}, "x8"},   {{"s1"}, "x9"},   {{"a0"}, "x10"},   {{"a1"}, "x11"},
42
512
      {{"a2"}, "x12"},  {{"a3"}, "x13"},  {{"a4"}, "x14"},   {{"a5"}, "x15"},
43
512
      {{"a6"}, "x16"},  {{"a7"}, "x17"},  {{"s2"}, "x18"},   {{"s3"}, "x19"},
44
512
      {{"s4"}, "x20"},  {{"s5"}, "x21"},  {{"s6"}, "x22"},   {{"s7"}, "x23"},
45
512
      {{"s8"}, "x24"},  {{"s9"}, "x25"},  {{"s10"}, "x26"},  {{"s11"}, "x27"},
46
512
      {{"t3"}, "x28"},  {{"t4"}, "x29"},  {{"t5"}, "x30"},   {{"t6"}, "x31"},
47
512
      {{"ft0"}, "f0"},  {{"ft1"}, "f1"},  {{"ft2"}, "f2"},   {{"ft3"}, "f3"},
48
512
      {{"ft4"}, "f4"},  {{"ft5"}, "f5"},  {{"ft6"}, "f6"},   {{"ft7"}, "f7"},
49
512
      {{"fs0"}, "f8"},  {{"fs1"}, "f9"},  {{"fa0"}, "f10"},  {{"fa1"}, "f11"},
50
512
      {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"},  {{"fa5"}, "f15"},
51
512
      {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"},  {{"fs3"}, "f19"},
52
512
      {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"},  {{"fs7"}, "f23"},
53
512
      {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
54
512
      {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
55
512
  return llvm::makeArrayRef(GCCRegAliases);
56
512
}
57
58
bool RISCVTargetInfo::validateAsmConstraint(
59
44
    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
60
44
  switch (*Name) {
61
0
  default:
62
0
    return false;
63
12
  case 'I':
64
    // A 12-bit signed immediate.
65
12
    Info.setRequiresImmediate(-2048, 2047);
66
12
    return true;
67
8
  case 'J':
68
    // Integer zero.
69
8
    Info.setRequiresImmediate(0);
70
8
    return true;
71
12
  case 'K':
72
    // A 5-bit unsigned immediate for CSR access instructions.
73
12
    Info.setRequiresImmediate(0, 31);
74
12
    return true;
75
8
  case 'f':
76
    // A floating-point register.
77
8
    Info.setAllowsRegister();
78
8
    return true;
79
4
  case 'A':
80
    // An address that is held in a general-purpose register.
81
4
    Info.setAllowsMemory();
82
4
    return true;
83
44
  }
84
44
}
85
86
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
87
118
                                       MacroBuilder &Builder) const {
88
118
  Builder.defineMacro("__ELF__");
89
118
  Builder.defineMacro("__riscv");
90
118
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
91
61
  Builder.defineMacro("__riscv_xlen", Is64Bit ? 
"64"57
: "32");
92
118
  StringRef CodeModel = getTargetOpts().CodeModel;
93
118
  if (CodeModel == "default")
94
108
    CodeModel = "small";
95
118
96
118
  if (CodeModel == "small")
97
112
    Builder.defineMacro("__riscv_cmodel_medlow");
98
6
  else if (CodeModel == "medium")
99
4
    Builder.defineMacro("__riscv_cmodel_medany");
100
118
101
118
  StringRef ABIName = getABI();
102
118
  if (ABIName == "ilp32f" || 
ABIName == "lp64f"112
)
103
11
    Builder.defineMacro("__riscv_float_abi_single");
104
107
  else if (ABIName == "ilp32d" || 
ABIName == "lp64d"98
)
105
15
    Builder.defineMacro("__riscv_float_abi_double");
106
92
  else
107
92
    Builder.defineMacro("__riscv_float_abi_soft");
108
118
109
118
  if (ABIName == "ilp32e")
110
0
    Builder.defineMacro("__riscv_abi_rve");
111
118
112
118
  if (HasM) {
113
22
    Builder.defineMacro("__riscv_mul");
114
22
    Builder.defineMacro("__riscv_div");
115
22
    Builder.defineMacro("__riscv_muldiv");
116
22
  }
117
118
118
118
  if (HasA)
119
24
    Builder.defineMacro("__riscv_atomic");
120
118
121
118
  if (HasF || 
HasD96
) {
122
19
    Builder.defineMacro("__riscv_flen", HasD ? "64" : 
"32"11
);
123
30
    Builder.defineMacro("__riscv_fdiv");
124
30
    Builder.defineMacro("__riscv_fsqrt");
125
30
  }
126
118
127
118
  if (HasC)
128
22
    Builder.defineMacro("__riscv_compressed");
129
118
130
118
  if (HasB)
131
2
    Builder.defineMacro("__riscv_bitmanip");
132
118
}
133
134
/// Return true if has this feature, need to sync with handleTargetFeatures.
135
80
bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
136
80
  bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
137
80
  return llvm::StringSwitch<bool>(Feature)
138
80
      .Case("riscv", true)
139
80
      .Case("riscv32", !Is64Bit)
140
80
      .Case("riscv64", Is64Bit)
141
80
      .Case("m", HasM)
142
80
      .Case("a", HasA)
143
80
      .Case("f", HasF)
144
80
      .Case("d", HasD)
145
80
      .Case("c", HasC)
146
80
      .Case("experimental-b", HasB)
147
80
      .Default(false);
148
80
}
149
150
/// Perform initialization based on the user configured set of features.
151
bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
152
118
                                           DiagnosticsEngine &Diags) {
153
212
  for (const auto &Feature : Features) {
154
212
    if (Feature == "+m")
155
22
      HasM = true;
156
190
    else if (Feature == "+a")
157
24
      HasA = true;
158
166
    else if (Feature == "+f")
159
22
      HasF = true;
160
144
    else if (Feature == "+d")
161
19
      HasD = true;
162
125
    else if (Feature == "+c")
163
22
      HasC = true;
164
103
    else if (Feature == "+experimental-b")
165
2
      HasB = true;
166
212
  }
167
118
168
118
  return true;
169
118
}
170
171
1
bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
172
1
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
173
1
                                   /*Is64Bit=*/false);
174
1
}
175
176
void RISCV32TargetInfo::fillValidCPUList(
177
1
    SmallVectorImpl<StringRef> &Values) const {
178
1
  llvm::RISCV::fillValidCPUArchList(Values, false);
179
1
}
180
181
1
bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
182
1
  return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
183
1
                                   /*Is64Bit=*/true);
184
1
}
185
186
void RISCV64TargetInfo::fillValidCPUList(
187
1
    SmallVectorImpl<StringRef> &Values) const {
188
1
  llvm::RISCV::fillValidCPUArchList(Values, true);
189
1
}