1//===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
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#include "Mips.h"
10#include "clang/Driver/CommonArgs.h"
11#include "clang/Driver/Driver.h"
12#include "clang/Driver/Options.h"
13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/Option/ArgList.h"
15
16using namespace clang::driver;
17using namespace clang::driver::tools;
18using namespace clang;
19using namespace llvm::opt;
20
21// Get CPU and ABI names. They are not independent
22// so we have to calculate them together.
23void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
24 StringRef &CPUName, StringRef &ABIName) {
25 const char *DefMips32CPU = "mips32r2";
26 const char *DefMips64CPU = "mips64r2";
27
28 // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
29 // default for mips64(el)?-img-linux-gnu.
30 if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
31 Triple.isGNUEnvironment()) {
32 DefMips32CPU = "mips32r6";
33 DefMips64CPU = "mips64r6";
34 }
35
36 if (Triple.getSubArch() == llvm::Triple::MipsSubArch_r6) {
37 DefMips32CPU = "mips32r6";
38 DefMips64CPU = "mips64r6";
39 }
40
41 // MIPS3 is the default for mips64*-unknown-openbsd.
42 if (Triple.isOSOpenBSD())
43 DefMips64CPU = "mips3";
44
45 // MIPS2 is the default for mips(el)?-unknown-freebsd.
46 // MIPS3 is the default for mips64(el)?-unknown-freebsd.
47 if (Triple.isOSFreeBSD()) {
48 DefMips32CPU = "mips2";
49 DefMips64CPU = "mips3";
50 }
51
52 if (Arg *A = Args.getLastArg(Ids: clang::driver::options::OPT_march_EQ,
53 Ids: options::OPT_mcpu_EQ))
54 CPUName = A->getValue();
55
56 if (Arg *A = Args.getLastArg(Ids: options::OPT_mabi_EQ)) {
57 ABIName = A->getValue();
58 // Convert a GNU style Mips ABI name to the name
59 // accepted by LLVM Mips backend.
60 ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
61 .Case(S: "32", Value: "o32")
62 .Case(S: "64", Value: "n64")
63 .Default(Value: ABIName);
64 }
65
66 // Setup default CPU and ABI names.
67 if (CPUName.empty() && ABIName.empty()) {
68 switch (Triple.getArch()) {
69 default:
70 llvm_unreachable("Unexpected triple arch name");
71 case llvm::Triple::mips:
72 case llvm::Triple::mipsel:
73 CPUName = DefMips32CPU;
74 break;
75 case llvm::Triple::mips64:
76 case llvm::Triple::mips64el:
77 CPUName = DefMips64CPU;
78 break;
79 }
80 }
81
82 if (ABIName.empty() && Triple.isABIN32())
83 ABIName = "n32";
84
85 if (ABIName.empty() &&
86 (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
87 Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
88 ABIName = llvm::StringSwitch<const char *>(CPUName)
89 .Case(S: "mips1", Value: "o32")
90 .Case(S: "mips2", Value: "o32")
91 .Case(S: "mips3", Value: "n64")
92 .Case(S: "mips4", Value: "n64")
93 .Case(S: "mips5", Value: "n64")
94 .Case(S: "mips32", Value: "o32")
95 .Case(S: "mips32r2", Value: "o32")
96 .Case(S: "mips32r3", Value: "o32")
97 .Case(S: "mips32r5", Value: "o32")
98 .Case(S: "mips32r6", Value: "o32")
99 .Case(S: "mips64", Value: "n64")
100 .Case(S: "mips64r2", Value: "n64")
101 .Case(S: "mips64r3", Value: "n64")
102 .Case(S: "mips64r5", Value: "n64")
103 .Case(S: "mips64r6", Value: "n64")
104 .Case(S: "octeon", Value: "n64")
105 .Case(S: "p5600", Value: "o32")
106 .Case(S: "i6400", Value: "n64")
107 .Case(S: "i6500", Value: "n64")
108 .Default(Value: "");
109 }
110
111 if (ABIName.empty()) {
112 // Deduce ABI name from the target triple.
113 ABIName = Triple.isMIPS32() ? "o32" : "n64";
114 }
115
116 if (CPUName.empty()) {
117 // Deduce CPU name from ABI name.
118 CPUName = llvm::StringSwitch<const char *>(ABIName)
119 .Case(S: "o32", Value: DefMips32CPU)
120 .Cases(S0: "n32", S1: "n64", Value: DefMips64CPU)
121 .Default(Value: "");
122 }
123
124 // FIXME: Warn on inconsistent use of -march and -mabi.
125}
126
127std::string mips::getMipsABILibSuffix(const ArgList &Args,
128 const llvm::Triple &Triple) {
129 StringRef CPUName, ABIName;
130 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
131 return llvm::StringSwitch<std::string>(ABIName)
132 .Case(S: "o32", Value: "")
133 .Case(S: "n32", Value: "32")
134 .Case(S: "n64", Value: "64");
135}
136
137// Convert ABI name to the GNU tools acceptable variant.
138StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
139 return llvm::StringSwitch<llvm::StringRef>(ABI)
140 .Case(S: "o32", Value: "32")
141 .Case(S: "n64", Value: "64")
142 .Default(Value: ABI);
143}
144
145// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
146// and -mfloat-abi=.
147mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args,
148 const llvm::Triple &Triple) {
149 mips::FloatABI ABI = mips::FloatABI::Invalid;
150 if (Arg *A =
151 Args.getLastArg(Ids: options::OPT_msoft_float, Ids: options::OPT_mhard_float,
152 Ids: options::OPT_mfloat_abi_EQ)) {
153 if (A->getOption().matches(ID: options::OPT_msoft_float))
154 ABI = mips::FloatABI::Soft;
155 else if (A->getOption().matches(ID: options::OPT_mhard_float))
156 ABI = mips::FloatABI::Hard;
157 else {
158 ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
159 .Case(S: "soft", Value: mips::FloatABI::Soft)
160 .Case(S: "hard", Value: mips::FloatABI::Hard)
161 .Default(Value: mips::FloatABI::Invalid);
162 if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
163 D.Diag(DiagID: clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
164 ABI = mips::FloatABI::Hard;
165 }
166 }
167 }
168
169 // If unspecified, choose the default based on the platform.
170 if (ABI == mips::FloatABI::Invalid) {
171 if (Triple.isOSFreeBSD()) {
172 // For FreeBSD, assume "soft" on all flavors of MIPS.
173 ABI = mips::FloatABI::Soft;
174 } else {
175 // Assume "hard", because it's a default value used by gcc.
176 // When we start to recognize specific target MIPS processors,
177 // we will be able to select the default more correctly.
178 ABI = mips::FloatABI::Hard;
179 }
180 }
181
182 assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
183 return ABI;
184}
185
186void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
187 const ArgList &Args,
188 std::vector<StringRef> &Features) {
189 StringRef CPUName;
190 StringRef ABIName;
191 getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
192 ABIName = getGnuCompatibleMipsABIName(ABI: ABIName);
193
194 // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
195 // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
196 // extension was developed by Richard Sandiford & Code Sourcery to support
197 // static code calling PIC code (CPIC). For O32 and N32 this means we have
198 // several combinations of PIC/static and abicalls. Pure static, static
199 // with the CPIC extension, and pure PIC code.
200
201 // At final link time, O32 and N32 with CPIC will have another section
202 // added to the binary which contains the stub functions to perform
203 // any fixups required for PIC code.
204
205 // For N64, the situation is more regular: code can either be static
206 // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
207 // code for N64. Since Clang has already built the relocation model portion
208 // of the commandline, we pick add +noabicalls feature in the N64 static
209 // case.
210
211 // The is another case to be accounted for: -msym32, which enforces that all
212 // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
213 // but it is unsupported.
214
215 // The combinations for N64 are:
216 // a) Static without abicalls and 64bit symbols.
217 // b) Static with abicalls and 32bit symbols.
218 // c) PIC with abicalls and 64bit symbols.
219
220 // For case (a) we need to add +noabicalls for N64.
221
222 bool IsN64 = ABIName == "64";
223 bool IsPIC = false;
224 bool NonPIC = false;
225 bool HasNaN2008Opt = false;
226
227 Arg *LastPICArg = Args.getLastArg(Ids: options::OPT_fPIC, Ids: options::OPT_fno_PIC,
228 Ids: options::OPT_fpic, Ids: options::OPT_fno_pic,
229 Ids: options::OPT_fPIE, Ids: options::OPT_fno_PIE,
230 Ids: options::OPT_fpie, Ids: options::OPT_fno_pie);
231 if (LastPICArg) {
232 Option O = LastPICArg->getOption();
233 NonPIC =
234 (O.matches(ID: options::OPT_fno_PIC) || O.matches(ID: options::OPT_fno_pic) ||
235 O.matches(ID: options::OPT_fno_PIE) || O.matches(ID: options::OPT_fno_pie));
236 IsPIC =
237 (O.matches(ID: options::OPT_fPIC) || O.matches(ID: options::OPT_fpic) ||
238 O.matches(ID: options::OPT_fPIE) || O.matches(ID: options::OPT_fpie));
239 }
240
241 bool UseAbiCalls = false;
242
243 Arg *ABICallsArg =
244 Args.getLastArg(Ids: options::OPT_mabicalls, Ids: options::OPT_mno_abicalls);
245 UseAbiCalls =
246 !ABICallsArg || ABICallsArg->getOption().matches(ID: options::OPT_mabicalls);
247
248 if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
249 D.Diag(DiagID: diag::warn_drv_unsupported_pic_with_mabicalls)
250 << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
251 }
252
253 if (ABICallsArg && !UseAbiCalls && IsPIC) {
254 D.Diag(DiagID: diag::err_drv_unsupported_noabicalls_pic);
255 }
256
257 if (CPUName == "i6500" || CPUName == "i6400") {
258 // MIPS cpu i6400 and i6500 support MSA (Mips SIMD Architecture)
259 // by default.
260 Features.push_back(x: "+msa");
261 }
262
263 if (!UseAbiCalls)
264 Features.push_back(x: "+noabicalls");
265 else
266 Features.push_back(x: "-noabicalls");
267
268 if (Arg *A = Args.getLastArg(Ids: options::OPT_mlong_calls,
269 Ids: options::OPT_mno_long_calls)) {
270 if (A->getOption().matches(ID: options::OPT_mno_long_calls))
271 Features.push_back(x: "-long-calls");
272 else if (!UseAbiCalls)
273 Features.push_back(x: "+long-calls");
274 else
275 D.Diag(DiagID: diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
276 }
277
278 if (Arg *A = Args.getLastArg(Ids: options::OPT_mxgot, Ids: options::OPT_mno_xgot)) {
279 if (A->getOption().matches(ID: options::OPT_mxgot))
280 Features.push_back(x: "+xgot");
281 else
282 Features.push_back(x: "-xgot");
283 }
284
285 mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
286 if (FloatABI == mips::FloatABI::Soft) {
287 // FIXME: Note, this is a hack. We need to pass the selected float
288 // mode to the MipsTargetInfoBase to define appropriate macros there.
289 // Now it is the only method.
290 Features.push_back(x: "+soft-float");
291 }
292
293 if (Arg *A = Args.getLastArg(Ids: options::OPT_mnan_EQ)) {
294 StringRef Val = StringRef(A->getValue());
295 if (Val == "2008") {
296 if (mips::getIEEE754Standard(CPU&: CPUName) & mips::Std2008) {
297 Features.push_back(x: "+nan2008");
298 HasNaN2008Opt = true;
299 } else {
300 Features.push_back(x: "-nan2008");
301 D.Diag(DiagID: diag::warn_target_unsupported_nan2008) << CPUName;
302 }
303 } else if (Val == "legacy") {
304 if (mips::getIEEE754Standard(CPU&: CPUName) & mips::Legacy)
305 Features.push_back(x: "-nan2008");
306 else {
307 Features.push_back(x: "+nan2008");
308 D.Diag(DiagID: diag::warn_target_unsupported_nanlegacy) << CPUName;
309 }
310 } else
311 D.Diag(DiagID: diag::err_drv_unsupported_option_argument)
312 << A->getSpelling() << Val;
313 }
314
315 if (Arg *A = Args.getLastArg(Ids: options::OPT_mabs_EQ)) {
316 StringRef Val = StringRef(A->getValue());
317 if (Val == "2008") {
318 if (mips::getIEEE754Standard(CPU&: CPUName) & mips::Std2008) {
319 Features.push_back(x: "+abs2008");
320 } else {
321 Features.push_back(x: "-abs2008");
322 D.Diag(DiagID: diag::warn_target_unsupported_abs2008) << CPUName;
323 }
324 } else if (Val == "legacy") {
325 if (mips::getIEEE754Standard(CPU&: CPUName) & mips::Legacy) {
326 Features.push_back(x: "-abs2008");
327 } else {
328 Features.push_back(x: "+abs2008");
329 D.Diag(DiagID: diag::warn_target_unsupported_abslegacy) << CPUName;
330 }
331 } else {
332 D.Diag(DiagID: diag::err_drv_unsupported_option_argument)
333 << A->getSpelling() << Val;
334 }
335 } else if (HasNaN2008Opt) {
336 Features.push_back(x: "+abs2008");
337 }
338
339 AddTargetFeature(Args, Features, OnOpt: options::OPT_msingle_float,
340 OffOpt: options::OPT_mdouble_float, FeatureName: "single-float");
341 AddTargetFeature(Args, Features, OnOpt: options::OPT_mips16, OffOpt: options::OPT_mno_mips16,
342 FeatureName: "mips16");
343 AddTargetFeature(Args, Features, OnOpt: options::OPT_mmicromips,
344 OffOpt: options::OPT_mno_micromips, FeatureName: "micromips");
345 AddTargetFeature(Args, Features, OnOpt: options::OPT_mdsp, OffOpt: options::OPT_mno_dsp,
346 FeatureName: "dsp");
347 AddTargetFeature(Args, Features, OnOpt: options::OPT_mdspr2, OffOpt: options::OPT_mno_dspr2,
348 FeatureName: "dspr2");
349 AddTargetFeature(Args, Features, OnOpt: options::OPT_mmsa, OffOpt: options::OPT_mno_msa,
350 FeatureName: "msa");
351 if (Arg *A = Args.getLastArg(
352 Ids: options::OPT_mstrict_align, Ids: options::OPT_mno_strict_align,
353 Ids: options::OPT_mno_unaligned_access, Ids: options::OPT_munaligned_access)) {
354 if (A->getOption().matches(ID: options::OPT_mstrict_align) ||
355 A->getOption().matches(ID: options::OPT_mno_unaligned_access))
356 Features.push_back(x: Args.MakeArgString(Str: "+strict-align"));
357 else
358 Features.push_back(x: Args.MakeArgString(Str: "-strict-align"));
359 }
360
361 // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
362 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
363 // nooddspreg.
364 if (Arg *A = Args.getLastArg(Ids: options::OPT_mfp32, Ids: options::OPT_mfpxx,
365 Ids: options::OPT_mfp64)) {
366 if (A->getOption().matches(ID: options::OPT_mfp32))
367 Features.push_back(x: "-fp64");
368 else if (A->getOption().matches(ID: options::OPT_mfpxx)) {
369 Features.push_back(x: "+fpxx");
370 Features.push_back(x: "+nooddspreg");
371 } else
372 Features.push_back(x: "+fp64");
373 } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
374 Features.push_back(x: "+fpxx");
375 Features.push_back(x: "+nooddspreg");
376 } else if (Arg *A = Args.getLastArg(Ids: options::OPT_mmsa)) {
377 if (A->getOption().matches(ID: options::OPT_mmsa))
378 Features.push_back(x: "+fp64");
379 }
380
381 AddTargetFeature(Args, Features, OnOpt: options::OPT_mno_odd_spreg,
382 OffOpt: options::OPT_modd_spreg, FeatureName: "nooddspreg");
383 AddTargetFeature(Args, Features, OnOpt: options::OPT_mno_madd4, OffOpt: options::OPT_mmadd4,
384 FeatureName: "nomadd4");
385 AddTargetFeature(Args, Features, OnOpt: options::OPT_mmt, OffOpt: options::OPT_mno_mt, FeatureName: "mt");
386 AddTargetFeature(Args, Features, OnOpt: options::OPT_mcrc, OffOpt: options::OPT_mno_crc,
387 FeatureName: "crc");
388 AddTargetFeature(Args, Features, OnOpt: options::OPT_mvirt, OffOpt: options::OPT_mno_virt,
389 FeatureName: "virt");
390 AddTargetFeature(Args, Features, OnOpt: options::OPT_mginv, OffOpt: options::OPT_mno_ginv,
391 FeatureName: "ginv");
392
393 if (Arg *A = Args.getLastArg(Ids: options::OPT_mindirect_jump_EQ)) {
394 StringRef Val = StringRef(A->getValue());
395 if (Val == "hazard") {
396 Arg *B =
397 Args.getLastArg(Ids: options::OPT_mmicromips, Ids: options::OPT_mno_micromips);
398 Arg *C = Args.getLastArg(Ids: options::OPT_mips16, Ids: options::OPT_mno_mips16);
399
400 if (B && B->getOption().matches(ID: options::OPT_mmicromips))
401 D.Diag(DiagID: diag::err_drv_unsupported_indirect_jump_opt)
402 << "hazard" << "micromips";
403 else if (C && C->getOption().matches(ID: options::OPT_mips16))
404 D.Diag(DiagID: diag::err_drv_unsupported_indirect_jump_opt)
405 << "hazard" << "mips16";
406 else if (mips::supportsIndirectJumpHazardBarrier(CPU&: CPUName))
407 Features.push_back(x: "+use-indirect-jump-hazard");
408 else
409 D.Diag(DiagID: diag::err_drv_unsupported_indirect_jump_opt)
410 << "hazard" << CPUName;
411 } else
412 D.Diag(DiagID: diag::err_drv_unknown_indirect_jump_opt) << Val;
413 }
414}
415
416mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
417 // Strictly speaking, mips32r2 and mips64r2 do not conform to the
418 // IEEE754-2008 standard. Support for this standard was first introduced
419 // in Release 3. However, other compilers have traditionally allowed it
420 // for Release 2 so we should do the same.
421 return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
422 .Case(S: "mips1", Value: Legacy)
423 .Case(S: "mips2", Value: Legacy)
424 .Case(S: "mips3", Value: Legacy)
425 .Case(S: "mips4", Value: Legacy)
426 .Case(S: "mips5", Value: Legacy)
427 .Case(S: "mips32", Value: Legacy)
428 .Case(S: "mips32r2", Value: Legacy | Std2008)
429 .Case(S: "mips32r3", Value: Legacy | Std2008)
430 .Case(S: "mips32r5", Value: Legacy | Std2008)
431 .Case(S: "mips32r6", Value: Std2008)
432 .Case(S: "mips64", Value: Legacy)
433 .Case(S: "mips64r2", Value: Legacy | Std2008)
434 .Case(S: "mips64r3", Value: Legacy | Std2008)
435 .Case(S: "mips64r5", Value: Legacy | Std2008)
436 .Case(S: "mips64r6", Value: Std2008)
437 .Default(Value: Std2008);
438}
439
440bool mips::hasCompactBranches(StringRef &CPU) {
441 // mips32r6 and mips64r6 have compact branches.
442 return llvm::StringSwitch<bool>(CPU)
443 .Case(S: "mips32r6", Value: true)
444 .Case(S: "mips64r6", Value: true)
445 .Default(Value: false);
446}
447
448bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
449 Arg *A = Args.getLastArg(Ids: options::OPT_mabi_EQ);
450 return A && (A->getValue() == StringRef(Value));
451}
452
453bool mips::isUCLibc(const ArgList &Args) {
454 Arg *A = Args.getLastArg(Ids: options::OPT_m_libc_Group);
455 return A && A->getOption().matches(ID: options::OPT_muclibc);
456}
457
458bool mips::isNaN2008(const Driver &D, const ArgList &Args,
459 const llvm::Triple &Triple) {
460 if (Arg *NaNArg = Args.getLastArg(Ids: options::OPT_mnan_EQ))
461 return llvm::StringSwitch<bool>(NaNArg->getValue())
462 .Case(S: "2008", Value: true)
463 .Case(S: "legacy", Value: false)
464 .Default(Value: false);
465
466 // NaN2008 is the default for MIPS32r6/MIPS64r6.
467 return llvm::StringSwitch<bool>(getCPUName(D, Args, T: Triple))
468 .Cases(S0: "mips32r6", S1: "mips64r6", Value: true)
469 .Default(Value: false);
470}
471
472bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
473 StringRef ABIName, mips::FloatABI FloatABI) {
474 if (ABIName != "32")
475 return false;
476
477 // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
478 // present.
479 if (FloatABI == mips::FloatABI::Soft)
480 return false;
481
482 return llvm::StringSwitch<bool>(CPUName)
483 .Cases(S0: "mips2", S1: "mips3", S2: "mips4", S3: "mips5", Value: true)
484 .Cases(S0: "mips32", S1: "mips32r2", S2: "mips32r3", S3: "mips32r5", Value: true)
485 .Cases(S0: "mips64", S1: "mips64r2", S2: "mips64r3", S3: "mips64r5", Value: true)
486 .Default(Value: false);
487}
488
489bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
490 StringRef CPUName, StringRef ABIName,
491 mips::FloatABI FloatABI) {
492 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
493
494 // FPXX shouldn't be used if -msingle-float is present.
495 if (Arg *A = Args.getLastArg(Ids: options::OPT_msingle_float,
496 Ids: options::OPT_mdouble_float))
497 if (A->getOption().matches(ID: options::OPT_msingle_float))
498 UseFPXX = false;
499 // FP64 should be used for MSA.
500 if (Arg *A = Args.getLastArg(Ids: options::OPT_mmsa))
501 if (A->getOption().matches(ID: options::OPT_mmsa))
502 UseFPXX = llvm::StringSwitch<bool>(CPUName)
503 .Cases(S0: "mips32r2", S1: "mips32r3", S2: "mips32r5", Value: false)
504 .Cases(S0: "mips64r2", S1: "mips64r3", S2: "mips64r5", Value: false)
505 .Default(Value: UseFPXX);
506
507 return UseFPXX;
508}
509
510bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
511 // Supporting the hazard barrier method of dealing with indirect
512 // jumps requires MIPSR2 support.
513 return llvm::StringSwitch<bool>(CPU)
514 .Case(S: "mips32r2", Value: true)
515 .Case(S: "mips32r3", Value: true)
516 .Case(S: "mips32r5", Value: true)
517 .Case(S: "mips32r6", Value: true)
518 .Case(S: "mips64r2", Value: true)
519 .Case(S: "mips64r3", Value: true)
520 .Case(S: "mips64r5", Value: true)
521 .Case(S: "mips64r6", Value: true)
522 .Case(S: "octeon", Value: true)
523 .Case(S: "p5600", Value: true)
524 .Case(S: "i6400", Value: true)
525 .Case(S: "i6500", Value: true)
526 .Default(Value: false);
527}
528