Coverage Report

Created: 2020-02-15 09:57

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