Coverage Report

Created: 2022-07-16 07:03

/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
492
bool MipsTargetInfo::processorSupportsGPR64() const {
32
492
  return llvm::StringSwitch<bool>(CPU)
33
492
      .Case("mips3", true)
34
492
      .Case("mips4", true)
35
492
      .Case("mips5", true)
36
492
      .Case("mips64", true)
37
492
      .Case("mips64r2", true)
38
492
      .Case("mips64r3", true)
39
492
      .Case("mips64r5", true)
40
492
      .Case("mips64r6", true)
41
492
      .Case("octeon", true)
42
492
      .Case("octeon+", true)
43
492
      .Default(false);
44
492
}
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
49
bool MipsTargetInfo::isValidCPUName(StringRef Name) const {
53
49
  return llvm::is_contained(ValidCPUNames, Name);
54
49
}
55
56
void MipsTargetInfo::fillValidCPUList(
57
1
    SmallVectorImpl<StringRef> &Values) const {
58
1
  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
59
1
}
60
61
372
unsigned MipsTargetInfo::getISARev() const {
62
372
  return llvm::StringSwitch<unsigned>(getCPU())
63
372
             .Cases("mips32", "mips64", 1)
64
372
             .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2)
65
372
             .Cases("mips32r3", "mips64r3", 3)
66
372
             .Cases("mips32r5", "mips64r5", 5)
67
372
             .Cases("mips32r6", "mips64r6", 6)
68
372
             .Default(0);
69
372
}
70
71
void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
72
243
                                      MacroBuilder &Builder) const {
73
243
  if (BigEndian) {
74
158
    DefineStd(Builder, "MIPSEB", Opts);
75
158
    Builder.defineMacro("_MIPSEB");
76
158
  } else {
77
85
    DefineStd(Builder, "MIPSEL", Opts);
78
85
    Builder.defineMacro("_MIPSEL");
79
85
  }
80
81
243
  Builder.defineMacro("__mips__");
82
243
  Builder.defineMacro("_mips");
83
243
  if (Opts.GNUMode)
84
210
    Builder.defineMacro("mips");
85
86
243
  if (ABI == "o32") {
87
118
    Builder.defineMacro("__mips", "32");
88
118
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
89
125
  } else {
90
125
    Builder.defineMacro("__mips", "64");
91
125
    Builder.defineMacro("__mips64");
92
125
    Builder.defineMacro("__mips64__");
93
125
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
94
125
  }
95
96
243
  const std::string ISARev = std::to_string(getISARev());
97
98
243
  if (!ISARev.empty())
99
243
    Builder.defineMacro("__mips_isa_rev", ISARev);
100
101
243
  if (ABI == "o32") {
102
118
    Builder.defineMacro("__mips_o32");
103
118
    Builder.defineMacro("_ABIO32", "1");
104
118
    Builder.defineMacro("_MIPS_SIM", "_ABIO32");
105
125
  } else if (ABI == "n32") {
106
31
    Builder.defineMacro("__mips_n32");
107
31
    Builder.defineMacro("_ABIN32", "2");
108
31
    Builder.defineMacro("_MIPS_SIM", "_ABIN32");
109
94
  } else if (ABI == "n64") {
110
94
    Builder.defineMacro("__mips_n64");
111
94
    Builder.defineMacro("_ABI64", "3");
112
94
    Builder.defineMacro("_MIPS_SIM", "_ABI64");
113
94
  } else
114
0
    llvm_unreachable("Invalid ABI.");
115
116
243
  if (!IsNoABICalls) {
117
243
    Builder.defineMacro("__mips_abicalls");
118
243
    if (CanUseBSDABICalls)
119
8
      Builder.defineMacro("__ABICALLS__");
120
243
  }
121
122
243
  Builder.defineMacro("__REGISTER_PREFIX__", "");
123
124
243
  switch (FloatABI) {
125
240
  case HardFloat:
126
240
    Builder.defineMacro("__mips_hard_float", Twine(1));
127
240
    break;
128
3
  case SoftFloat:
129
3
    Builder.defineMacro("__mips_soft_float", Twine(1));
130
3
    break;
131
243
  }
132
133
243
  if (IsSingleFloat)
134
4
    Builder.defineMacro("__mips_single_float", Twine(1));
135
136
243
  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
129
  case FP64:
144
129
    Builder.defineMacro("__mips_fpr", Twine(64));
145
129
    break;
146
243
}
147
148
243
  if (FPMode == FP64 || 
IsSingleFloat114
)
149
133
    Builder.defineMacro("_MIPS_FPSET", Twine(32));
150
110
  else
151
110
    Builder.defineMacro("_MIPS_FPSET", Twine(16));
152
153
243
  if (IsMips16)
154
1
    Builder.defineMacro("__mips16", Twine(1));
155
156
243
  if (IsMicromips)
157
1
    Builder.defineMacro("__mips_micromips", Twine(1));
158
159
243
  if (IsNan2008)
160
11
    Builder.defineMacro("__mips_nan2008", Twine(1));
161
162
243
  if (IsAbs2008)
163
8
    Builder.defineMacro("__mips_abs2008", Twine(1));
164
165
243
  switch (DspRev) {
166
241
  default:
167
241
    break;
168
241
  case DSP1:
169
1
    Builder.defineMacro("__mips_dsp_rev", Twine(1));
170
1
    Builder.defineMacro("__mips_dsp", Twine(1));
171
1
    break;
172
1
  case DSP2:
173
1
    Builder.defineMacro("__mips_dsp_rev", Twine(2));
174
1
    Builder.defineMacro("__mips_dspr2", Twine(1));
175
1
    Builder.defineMacro("__mips_dsp", Twine(1));
176
1
    break;
177
243
  }
178
179
243
  if (HasMSA)
180
1
    Builder.defineMacro("__mips_msa", Twine(1));
181
182
243
  if (DisableMadd4)
183
1
    Builder.defineMacro("__mips_no_madd4", Twine(1));
184
185
243
  Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
186
243
  Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
187
243
  Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
188
189
243
  Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
190
243
  if (CPU == "octeon+")
191
1
    Builder.defineMacro("_MIPS_ARCH_OCTEONP");
192
242
  else
193
242
    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
194
195
243
  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
243
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201
243
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202
243
  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
243
  if (ABI == "n32" || 
ABI == "n64"212
)
209
125
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
210
243
}
211
212
150
bool MipsTargetInfo::hasFeature(StringRef Feature) const {
213
150
  return llvm::StringSwitch<bool>(Feature)
214
150
      .Case("mips", true)
215
150
      .Case("dsp", DspRev >= DSP1)
216
150
      .Case("dspr2", DspRev >= DSP2)
217
150
      .Case("fp64", FPMode == FP64)
218
150
      .Case("msa", HasMSA)
219
150
      .Default(false);
220
150
}
221
222
243
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
223
243
  return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin -
224
243
                                             Builtin::FirstTSBuiltin);
225
243
}
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
246
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
236
  // microMIPS64R6 backend was removed.
237
246
  if (getTriple().isMIPS64() && 
IsMicromips128
&&
(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
246
  if (processorSupportsGPR64() && 
ABI == "o32"128
) {
244
0
    Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
245
0
    return false;
246
0
  }
247
248
  // 64-bit ABI's require 64-bit CPU's.
249
246
  if (!processorSupportsGPR64() && 
(118
ABI == "n32"118
||
ABI == "n64"118
)) {
250
0
    Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
251
0
    return false;
252
0
  }
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
246
  if (getTriple().isMIPS64() && 
ABI == "o32"128
) {
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
246
  if (getTriple().isMIPS32() && 
(118
ABI == "n32"118
||
ABI == "n64"118
)) {
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
246
  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
244
  if (FPMode != FP64 && 
FPMode != FPXX115
&&
!IsSingleFloat3
&&
280
244
      
(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
243
  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
243
  if (FPMode == FP64 && 
(129
CPU == "mips1"129
||
CPU == "mips2"129
||
292
129
      getISARev() < 2) && 
ABI == "o32"8
) {
293
0
    Diags.Report(diag::err_mips_fp64_req) << "-mfp64";
294
0
    return false;
295
0
  }
296
297
243
  return true;
298
243
}