Coverage Report

Created: 2021-09-21 08:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/Mips.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- Mips.cpp - Implement Mips 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 Mips TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Mips.h"
14
#include "Targets.h"
15
#include "clang/Basic/Diagnostic.h"
16
#include "clang/Basic/MacroBuilder.h"
17
#include "clang/Basic/TargetBuiltins.h"
18
#include "llvm/ADT/StringSwitch.h"
19
20
using namespace clang;
21
using namespace clang::targets;
22
23
const Builtin::Info MipsTargetInfo::BuiltinInfo[] = {
24
#define BUILTIN(ID, TYPE, ATTRS)                                               \
25
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
26
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
27
  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
28
#include "clang/Basic/BuiltinsMips.def"
29
};
30
31
515
bool MipsTargetInfo::processorSupportsGPR64() const {
32
515
  return llvm::StringSwitch<bool>(CPU)
33
515
      .Case("mips3", true)
34
515
      .Case("mips4", true)
35
515
      .Case("mips5", true)
36
515
      .Case("mips64", true)
37
515
      .Case("mips64r2", true)
38
515
      .Case("mips64r3", true)
39
515
      .Case("mips64r5", true)
40
515
      .Case("mips64r6", true)
41
515
      .Case("octeon", true)
42
515
      .Case("octeon+", true)
43
515
      .Default(false);
44
515
}
45
46
static constexpr llvm::StringLiteral ValidCPUNames[] = {
47
    {"mips1"},  {"mips2"},    {"mips3"},    {"mips4"},    {"mips5"},
48
    {"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"},
49
    {"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"},
50
    {"octeon"}, {"octeon+"}, {"p5600"}};
51
52
64
bool MipsTargetInfo::isValidCPUName(StringRef Name) const {
53
64
  return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
54
64
}
55
56
void MipsTargetInfo::fillValidCPUList(
57
2
    SmallVectorImpl<StringRef> &Values) const {
58
2
  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
59
2
}
60
61
389
unsigned MipsTargetInfo::getISARev() const {
62
389
  return llvm::StringSwitch<unsigned>(getCPU())
63
389
             .Cases("mips32", "mips64", 1)
64
389
             .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2)
65
389
             .Cases("mips32r3", "mips64r3", 3)
66
389
             .Cases("mips32r5", "mips64r5", 5)
67
389
             .Cases("mips32r6", "mips64r6", 6)
68
389
             .Default(0);
69
389
}
70
71
void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
72
251
                                      MacroBuilder &Builder) const {
73
251
  if (BigEndian) {
74
167
    DefineStd(Builder, "MIPSEB", Opts);
75
167
    Builder.defineMacro("_MIPSEB");
76
167
  } else {
77
84
    DefineStd(Builder, "MIPSEL", Opts);
78
84
    Builder.defineMacro("_MIPSEL");
79
84
  }
80
81
251
  Builder.defineMacro("__mips__");
82
251
  Builder.defineMacro("_mips");
83
251
  if (Opts.GNUMode)
84
223
    Builder.defineMacro("mips");
85
86
251
  if (ABI == "o32") {
87
121
    Builder.defineMacro("__mips", "32");
88
121
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
89
130
  } else {
90
130
    Builder.defineMacro("__mips", "64");
91
130
    Builder.defineMacro("__mips64");
92
130
    Builder.defineMacro("__mips64__");
93
130
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
94
130
  }
95
96
251
  const std::string ISARev = std::to_string(getISARev());
97
98
251
  if (!ISARev.empty())
99
251
    Builder.defineMacro("__mips_isa_rev", ISARev);
100
101
251
  if (ABI == "o32") {
102
121
    Builder.defineMacro("__mips_o32");
103
121
    Builder.defineMacro("_ABIO32", "1");
104
121
    Builder.defineMacro("_MIPS_SIM", "_ABIO32");
105
130
  } else if (ABI == "n32") {
106
31
    Builder.defineMacro("__mips_n32");
107
31
    Builder.defineMacro("_ABIN32", "2");
108
31
    Builder.defineMacro("_MIPS_SIM", "_ABIN32");
109
99
  } else if (ABI == "n64") {
110
99
    Builder.defineMacro("__mips_n64");
111
99
    Builder.defineMacro("_ABI64", "3");
112
99
    Builder.defineMacro("_MIPS_SIM", "_ABI64");
113
99
  } else
114
0
    llvm_unreachable("Invalid ABI.");
115
116
251
  if (!IsNoABICalls) {
117
251
    Builder.defineMacro("__mips_abicalls");
118
251
    if (CanUseBSDABICalls)
119
8
      Builder.defineMacro("__ABICALLS__");
120
251
  }
121
122
251
  Builder.defineMacro("__REGISTER_PREFIX__", "");
123
124
251
  switch (FloatABI) {
125
248
  case HardFloat:
126
248
    Builder.defineMacro("__mips_hard_float", Twine(1));
127
248
    break;
128
3
  case SoftFloat:
129
3
    Builder.defineMacro("__mips_soft_float", Twine(1));
130
3
    break;
131
251
  }
132
133
251
  if (IsSingleFloat)
134
4
    Builder.defineMacro("__mips_single_float", Twine(1));
135
136
251
  switch (FPMode) {
137
112
  case FPXX:
138
112
    Builder.defineMacro("__mips_fpr", Twine(0));
139
112
    break;
140
2
  case FP32:
141
2
    Builder.defineMacro("__mips_fpr", Twine(32));
142
2
    break;
143
137
  case FP64:
144
137
    Builder.defineMacro("__mips_fpr", Twine(64));
145
137
    break;
146
251
}
147
148
251
  if (FPMode == FP64 || 
IsSingleFloat114
)
149
141
    Builder.defineMacro("_MIPS_FPSET", Twine(32));
150
110
  else
151
110
    Builder.defineMacro("_MIPS_FPSET", Twine(16));
152
153
251
  if (IsMips16)
154
1
    Builder.defineMacro("__mips16", Twine(1));
155
156
251
  if (IsMicromips)
157
1
    Builder.defineMacro("__mips_micromips", Twine(1));
158
159
251
  if (IsNan2008)
160
12
    Builder.defineMacro("__mips_nan2008", Twine(1));
161
162
251
  if (IsAbs2008)
163
9
    Builder.defineMacro("__mips_abs2008", Twine(1));
164
165
251
  switch (DspRev) {
166
247
  default:
167
247
    break;
168
247
  case DSP1:
169
1
    Builder.defineMacro("__mips_dsp_rev", Twine(1));
170
1
    Builder.defineMacro("__mips_dsp", Twine(1));
171
1
    break;
172
3
  case DSP2:
173
3
    Builder.defineMacro("__mips_dsp_rev", Twine(2));
174
3
    Builder.defineMacro("__mips_dspr2", Twine(1));
175
3
    Builder.defineMacro("__mips_dsp", Twine(1));
176
3
    break;
177
251
  }
178
179
251
  if (HasMSA)
180
3
    Builder.defineMacro("__mips_msa", Twine(1));
181
182
251
  if (DisableMadd4)
183
3
    Builder.defineMacro("__mips_no_madd4", Twine(1));
184
185
251
  Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
186
251
  Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
187
251
  Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
188
189
251
  Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
190
251
  if (CPU == "octeon+")
191
1
    Builder.defineMacro("_MIPS_ARCH_OCTEONP");
192
250
  else
193
250
    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
194
195
251
  if (StringRef(CPU).startswith("octeon"))
196
2
    Builder.defineMacro("__OCTEON__");
197
198
  // These shouldn't be defined for MIPS-I but there's no need to check
199
  // for that since MIPS-I isn't supported.
200
251
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201
251
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202
251
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
203
204
  // 32-bit MIPS processors don't have the necessary lld/scd instructions
205
  // found in 64-bit processors. In the case of O32 on a 64-bit processor,
206
  // the instructions exist but using them violates the ABI since they
207
  // require 64-bit GPRs and O32 only supports 32-bit GPRs.
208
251
  if (ABI == "n32" || 
ABI == "n64"220
)
209
130
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
210
251
}
211
212
1.05k
bool MipsTargetInfo::hasFeature(StringRef Feature) const {
213
1.05k
  return llvm::StringSwitch<bool>(Feature)
214
1.05k
      .Case("mips", true)
215
1.05k
      .Case("dsp", DspRev >= DSP1)
216
1.05k
      .Case("dspr2", DspRev >= DSP2)
217
1.05k
      .Case("fp64", FPMode == FP64)
218
1.05k
      .Case("msa", HasMSA)
219
1.05k
      .Default(false);
220
1.05k
}
221
222
252
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
223
252
  return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin -
224
252
                                             Builtin::FirstTSBuiltin);
225
252
}
226
227
10
unsigned MipsTargetInfo::getUnwindWordWidth() const {
228
10
  return llvm::StringSwitch<unsigned>(ABI)
229
10
      .Case("o32", 32)
230
10
      .Case("n32", 64)
231
10
      .Case("n64", 64)
232
10
      .Default(getPointerWidth(0));
233
10
}
234
235
258
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
236
  // microMIPS64R6 backend was removed.
237
258
  if (getTriple().isMIPS64() && 
IsMicromips136
&&
(0
ABI == "n32"0
||
ABI == "n64"0
)) {
238
0
    Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU;
239
0
    return false;
240
0
  }
241
  // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle
242
  //        this yet. It's better to fail here than on the backend assertion.
243
258
  if (processorSupportsGPR64() && 
ABI == "o32"135
) {
244
1
    Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
245
1
    return false;
246
1
  }
247
248
  // 64-bit ABI's require 64-bit CPU's.
249
257
  if (!processorSupportsGPR64() && 
(123
ABI == "n32"123
||
ABI == "n64"123
)) {
250
2
    Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
251
2
    return false;
252
2
  }
253
254
  // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend
255
  //        can't handle this yet. It's better to fail here than on the
256
  //        backend assertion.
257
255
  if (getTriple().isMIPS64() && 
ABI == "o32"134
) {
258
0
    Diags.Report(diag::err_target_unsupported_abi_for_triple)
259
0
        << ABI << getTriple().str();
260
0
    return false;
261
0
  }
262
263
  // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend
264
  //        can't handle this yet. It's better to fail here than on the
265
  //        backend assertion.
266
255
  if (getTriple().isMIPS32() && 
(121
ABI == "n32"121
||
ABI == "n64"121
)) {
267
0
    Diags.Report(diag::err_target_unsupported_abi_for_triple)
268
0
        << ABI << getTriple().str();
269
0
    return false;
270
0
  }
271
272
  // -fpxx is valid only for the o32 ABI
273
255
  if (FPMode == FPXX && 
(114
ABI == "n32"114
||
ABI == "n64"114
)) {
274
2
    Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32";
275
2
    return false;
276
2
  }
277
278
  // -mfp32 and n32/n64 ABIs are incompatible
279
253
  if (FPMode != FP64 && 
FPMode != FPXX115
&&
!IsSingleFloat3
&&
280
253
      
(2
ABI == "n32"2
||
ABI == "n64"2
)) {
281
1
    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU;
282
1
    return false;
283
1
  }
284
  // Mips revision 6 and -mfp32 are incompatible
285
252
  if (FPMode != FP64 && 
FPMode != FPXX114
&&
(2
CPU == "mips32r6"2
||
286
2
      CPU == "mips64r6")) {
287
0
    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32" << CPU;
288
0
    return false;
289
0
  }
290
  // Option -mfp64 permitted on Mips32 iff revision 2 or higher is present
291
252
  if (FPMode == FP64 && 
(138
CPU == "mips1"138
||
CPU == "mips2"138
||
292
138
      getISARev() < 2) && 
ABI == "o32"8
) {
293
0
    Diags.Report(diag::err_mips_fp64_req) << "-mfp64";
294
0
    return false;
295
0
  }
296
297
252
  return true;
298
252
}