Coverage Report

Created: 2022-01-25 06:29

/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
486
bool MipsTargetInfo::processorSupportsGPR64() const {
32
486
  return llvm::StringSwitch<bool>(CPU)
33
486
      .Case("mips3", true)
34
486
      .Case("mips4", true)
35
486
      .Case("mips5", true)
36
486
      .Case("mips64", true)
37
486
      .Case("mips64r2", true)
38
486
      .Case("mips64r3", true)
39
486
      .Case("mips64r5", true)
40
486
      .Case("mips64r6", true)
41
486
      .Case("octeon", true)
42
486
      .Case("octeon+", true)
43
486
      .Default(false);
44
486
}
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
54
bool MipsTargetInfo::isValidCPUName(StringRef Name) const {
53
54
  return llvm::is_contained(ValidCPUNames, Name);
54
54
}
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
369
unsigned MipsTargetInfo::getISARev() const {
62
369
  return llvm::StringSwitch<unsigned>(getCPU())
63
369
             .Cases("mips32", "mips64", 1)
64
369
             .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2)
65
369
             .Cases("mips32r3", "mips64r3", 3)
66
369
             .Cases("mips32r5", "mips64r5", 5)
67
369
             .Cases("mips32r6", "mips64r6", 6)
68
369
             .Default(0);
69
369
}
70
71
void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
72
240
                                      MacroBuilder &Builder) const {
73
240
  if (BigEndian) {
74
155
    DefineStd(Builder, "MIPSEB", Opts);
75
155
    Builder.defineMacro("_MIPSEB");
76
155
  } else {
77
85
    DefineStd(Builder, "MIPSEL", Opts);
78
85
    Builder.defineMacro("_MIPSEL");
79
85
  }
80
81
240
  Builder.defineMacro("__mips__");
82
240
  Builder.defineMacro("_mips");
83
240
  if (Opts.GNUMode)
84
210
    Builder.defineMacro("mips");
85
86
240
  if (ABI == "o32") {
87
115
    Builder.defineMacro("__mips", "32");
88
115
    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
240
  const std::string ISARev = std::to_string(getISARev());
97
98
240
  if (!ISARev.empty())
99
240
    Builder.defineMacro("__mips_isa_rev", ISARev);
100
101
240
  if (ABI == "o32") {
102
115
    Builder.defineMacro("__mips_o32");
103
115
    Builder.defineMacro("_ABIO32", "1");
104
115
    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
240
  if (!IsNoABICalls) {
117
240
    Builder.defineMacro("__mips_abicalls");
118
240
    if (CanUseBSDABICalls)
119
8
      Builder.defineMacro("__ABICALLS__");
120
240
  }
121
122
240
  Builder.defineMacro("__REGISTER_PREFIX__", "");
123
124
240
  switch (FloatABI) {
125
237
  case HardFloat:
126
237
    Builder.defineMacro("__mips_hard_float", Twine(1));
127
237
    break;
128
3
  case SoftFloat:
129
3
    Builder.defineMacro("__mips_soft_float", Twine(1));
130
3
    break;
131
240
  }
132
133
240
  if (IsSingleFloat)
134
4
    Builder.defineMacro("__mips_single_float", Twine(1));
135
136
240
  switch (FPMode) {
137
109
  case FPXX:
138
109
    Builder.defineMacro("__mips_fpr", Twine(0));
139
109
    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
240
}
147
148
240
  if (FPMode == FP64 || 
IsSingleFloat111
)
149
133
    Builder.defineMacro("_MIPS_FPSET", Twine(32));
150
107
  else
151
107
    Builder.defineMacro("_MIPS_FPSET", Twine(16));
152
153
240
  if (IsMips16)
154
1
    Builder.defineMacro("__mips16", Twine(1));
155
156
240
  if (IsMicromips)
157
1
    Builder.defineMacro("__mips_micromips", Twine(1));
158
159
240
  if (IsNan2008)
160
11
    Builder.defineMacro("__mips_nan2008", Twine(1));
161
162
240
  if (IsAbs2008)
163
8
    Builder.defineMacro("__mips_abs2008", Twine(1));
164
165
240
  switch (DspRev) {
166
238
  default:
167
238
    break;
168
238
  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
240
  }
178
179
240
  if (HasMSA)
180
1
    Builder.defineMacro("__mips_msa", Twine(1));
181
182
240
  if (DisableMadd4)
183
1
    Builder.defineMacro("__mips_no_madd4", Twine(1));
184
185
240
  Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
186
240
  Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
187
240
  Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
188
189
240
  Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
190
240
  if (CPU == "octeon+")
191
1
    Builder.defineMacro("_MIPS_ARCH_OCTEONP");
192
239
  else
193
239
    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
194
195
240
  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
240
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201
240
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202
240
  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
240
  if (ABI == "n32" || 
ABI == "n64"209
)
209
125
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
210
240
}
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
240
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
223
240
  return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin -
224
240
                                             Builtin::FirstTSBuiltin);
225
240
}
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
243
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
236
  // microMIPS64R6 backend was removed.
237
243
  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
243
  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
243
  if (!processorSupportsGPR64() && 
(115
ABI == "n32"115
||
ABI == "n64"115
)) {
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
243
  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
243
  if (getTriple().isMIPS32() && 
(115
ABI == "n32"115
||
ABI == "n64"115
)) {
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
243
  if (FPMode == FPXX && 
(111
ABI == "n32"111
||
ABI == "n64"111
)) {
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
241
  if (FPMode != FP64 && 
FPMode != FPXX112
&&
!IsSingleFloat3
&&
280
241
      
(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
240
  if (FPMode != FP64 && 
FPMode != FPXX111
&&
(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
240
  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
240
  return true;
298
240
}