Coverage Report

Created: 2020-09-22 08:39

/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
519
bool MipsTargetInfo::processorSupportsGPR64() const {
32
519
  return llvm::StringSwitch<bool>(CPU)
33
519
      .Case("mips3", true)
34
519
      .Case("mips4", true)
35
519
      .Case("mips5", true)
36
519
      .Case("mips64", true)
37
519
      .Case("mips64r2", true)
38
519
      .Case("mips64r3", true)
39
519
      .Case("mips64r5", true)
40
519
      .Case("mips64r6", true)
41
519
      .Case("octeon", true)
42
519
      .Case("octeon+", true)
43
519
      .Default(false);
44
519
}
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
250
                                      MacroBuilder &Builder) const {
73
250
  if (BigEndian) {
74
166
    DefineStd(Builder, "MIPSEB", Opts);
75
166
    Builder.defineMacro("_MIPSEB");
76
84
  } else {
77
84
    DefineStd(Builder, "MIPSEL", Opts);
78
84
    Builder.defineMacro("_MIPSEL");
79
84
  }
80
81
250
  Builder.defineMacro("__mips__");
82
250
  Builder.defineMacro("_mips");
83
250
  if (Opts.GNUMode)
84
222
    Builder.defineMacro("mips");
85
86
250
  if (ABI == "o32") {
87
121
    Builder.defineMacro("__mips", "32");
88
121
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
89
129
  } else {
90
129
    Builder.defineMacro("__mips", "64");
91
129
    Builder.defineMacro("__mips64");
92
129
    Builder.defineMacro("__mips64__");
93
129
    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
94
129
  }
95
96
250
  const std::string ISARev = std::to_string(getISARev());
97
98
250
  if (!ISARev.empty())
99
250
    Builder.defineMacro("__mips_isa_rev", ISARev);
100
101
250
  if (ABI == "o32") {
102
121
    Builder.defineMacro("__mips_o32");
103
121
    Builder.defineMacro("_ABIO32", "1");
104
121
    Builder.defineMacro("_MIPS_SIM", "_ABIO32");
105
129
  } else if (ABI == "n32") {
106
31
    Builder.defineMacro("__mips_n32");
107
31
    Builder.defineMacro("_ABIN32", "2");
108
31
    Builder.defineMacro("_MIPS_SIM", "_ABIN32");
109
98
  } else if (ABI == "n64") {
110
98
    Builder.defineMacro("__mips_n64");
111
98
    Builder.defineMacro("_ABI64", "3");
112
98
    Builder.defineMacro("_MIPS_SIM", "_ABI64");
113
98
  } else
114
0
    llvm_unreachable("Invalid ABI.");
115
116
250
  if (!IsNoABICalls) {
117
250
    Builder.defineMacro("__mips_abicalls");
118
250
    if (CanUseBSDABICalls)
119
8
      Builder.defineMacro("__ABICALLS__");
120
250
  }
121
122
250
  Builder.defineMacro("__REGISTER_PREFIX__", "");
123
124
250
  switch (FloatABI) {
125
247
  case HardFloat:
126
247
    Builder.defineMacro("__mips_hard_float", Twine(1));
127
247
    break;
128
3
  case SoftFloat:
129
3
    Builder.defineMacro("__mips_soft_float", Twine(1));
130
3
    break;
131
250
  }
132
133
250
  if (IsSingleFloat)
134
4
    Builder.defineMacro("__mips_single_float", Twine(1));
135
136
250
  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
136
  case FP64:
144
136
    Builder.defineMacro("__mips_fpr", Twine(64));
145
136
    break;
146
250
}
147
148
250
  if (FPMode == FP64 || 
IsSingleFloat114
)
149
140
    Builder.defineMacro("_MIPS_FPSET", Twine(32));
150
110
  else
151
110
    Builder.defineMacro("_MIPS_FPSET", Twine(16));
152
153
250
  if (IsMips16)
154
1
    Builder.defineMacro("__mips16", Twine(1));
155
156
250
  if (IsMicromips)
157
1
    Builder.defineMacro("__mips_micromips", Twine(1));
158
159
250
  if (IsNan2008)
160
12
    Builder.defineMacro("__mips_nan2008", Twine(1));
161
162
250
  if (IsAbs2008)
163
9
    Builder.defineMacro("__mips_abs2008", Twine(1));
164
165
250
  switch (DspRev) {
166
246
  default:
167
246
    break;
168
1
  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
250
  }
178
179
250
  if (HasMSA)
180
3
    Builder.defineMacro("__mips_msa", Twine(1));
181
182
250
  if (DisableMadd4)
183
3
    Builder.defineMacro("__mips_no_madd4", Twine(1));
184
185
250
  Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
186
250
  Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
187
250
  Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
188
189
250
  Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
190
250
  if (CPU == "octeon+")
191
1
    Builder.defineMacro("_MIPS_ARCH_OCTEONP");
192
249
  else
193
249
    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
194
195
250
  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
250
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
201
250
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
202
250
  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
250
  if (ABI == "n32" || 
ABI == "n64"219
)
209
129
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
210
250
}
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
251
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
223
251
  return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin -
224
251
                                             Builtin::FirstTSBuiltin);
225
251
}
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
260
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
236
  // microMIPS64R6 backend was removed.
237
260
  if (getTriple().isMIPS64() && 
IsMicromips137
&&
(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
260
  if (processorSupportsGPR64() && 
ABI == "o32"136
) {
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
259
  if (!processorSupportsGPR64() && 
(124
ABI == "n32"124
||
ABI == "n64"124
)) {
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
257
  if (getTriple().isMIPS64() && 
ABI == "o32"135
) {
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
257
  if (getTriple().isMIPS32() && 
(122
ABI == "n32"122
||
ABI == "n64"122
)) {
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
257
  if (FPMode == FPXX && 
(115
ABI == "n32"115
||
ABI == "n64"115
)) {
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
255
  if (FPMode != FP64 && 
FPMode != FPXX116
&&
!IsSingleFloat3
&&
280
2
      (ABI == "n32" || ABI == "n64")) {
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
254
  if (FPMode != FP64 && 
FPMode != FPXX115
&&
(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
254
  if (FPMode == FP64 && 
(139
CPU == "mips1"139
||
CPU == "mips2"139
||
292
139
      getISARev() < 2) && 
ABI == "o32"8
) {
293
0
    Diags.Report(diag::err_mips_fp64_req) << "-mfp64";
294
0
    return false;
295
0
  }
296
297
254
  return true;
298
254
}