14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/Option/ArgList.h"
25 StringRef &CPUName, StringRef &ABIName) {
26 const char *DefMips32CPU =
"mips32r2";
27 const char *DefMips64CPU =
"mips64r2";
31 if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
32 Triple.isGNUEnvironment()) {
33 DefMips32CPU =
"mips32r6";
34 DefMips64CPU =
"mips64r6";
37 if (Triple.getSubArch() == llvm::Triple::MipsSubArch_r6) {
38 DefMips32CPU =
"mips32r6";
39 DefMips64CPU =
"mips64r6";
43 if (Triple.isOSOpenBSD())
44 DefMips64CPU =
"mips3";
48 if (Triple.isOSFreeBSD()) {
49 DefMips32CPU =
"mips2";
50 DefMips64CPU =
"mips3";
53 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
54 options::OPT_mcpu_EQ))
55 CPUName = A->getValue();
57 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
58 ABIName = A->getValue();
61 ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
68 if (CPUName.empty() && ABIName.empty()) {
69 switch (Triple.getArch()) {
71 llvm_unreachable(
"Unexpected triple arch name");
72 case llvm::Triple::mips:
73 case llvm::Triple::mipsel:
74 CPUName = DefMips32CPU;
76 case llvm::Triple::mips64:
77 case llvm::Triple::mips64el:
78 CPUName = DefMips64CPU;
83 if (ABIName.empty() && Triple.isABIN32())
86 if (ABIName.empty() &&
87 (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
88 Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
89 ABIName = llvm::StringSwitch<const char *>(CPUName)
95 .Case(
"mips32",
"o32")
96 .Case(
"mips32r2",
"o32")
97 .Case(
"mips32r3",
"o32")
98 .Case(
"mips32r5",
"o32")
99 .Case(
"mips32r6",
"o32")
100 .Case(
"mips64",
"n64")
101 .Case(
"mips64r2",
"n64")
102 .Case(
"mips64r3",
"n64")
103 .Case(
"mips64r5",
"n64")
104 .Case(
"mips64r6",
"n64")
105 .Case(
"octeon",
"n64")
106 .Case(
"p5600",
"o32")
110 if (ABIName.empty()) {
112 ABIName = Triple.isMIPS32() ?
"o32" :
"n64";
115 if (CPUName.empty()) {
117 CPUName = llvm::StringSwitch<const char *>(ABIName)
118 .Case(
"o32", DefMips32CPU)
119 .Cases(
"n32",
"n64", DefMips64CPU)
127 const llvm::Triple &Triple) {
128 StringRef CPUName, ABIName;
130 return llvm::StringSwitch<std::string>(ABIName)
138 return llvm::StringSwitch<llvm::StringRef>(ABI)
147 const llvm::Triple &Triple) {
150 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
151 options::OPT_mfloat_abi_EQ)) {
152 if (A->getOption().matches(options::OPT_msoft_float))
153 ABI = mips::FloatABI::Soft;
154 else if (A->getOption().matches(options::OPT_mhard_float))
155 ABI = mips::FloatABI::Hard;
157 ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
158 .Case(
"soft", mips::FloatABI::Soft)
159 .Case(
"hard", mips::FloatABI::Hard)
160 .Default(mips::FloatABI::Invalid);
161 if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
162 D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
163 ABI = mips::FloatABI::Hard;
169 if (ABI == mips::FloatABI::Invalid) {
170 if (Triple.isOSFreeBSD()) {
172 ABI = mips::FloatABI::Soft;
177 ABI = mips::FloatABI::Hard;
181 assert(ABI != mips::FloatABI::Invalid &&
"must select an ABI");
187 std::vector<StringRef> &Features) {
221 bool IsN64 = ABIName ==
"64";
224 bool HasNaN2008Opt =
false;
226 Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
227 options::OPT_fpic, options::OPT_fno_pic,
228 options::OPT_fPIE, options::OPT_fno_PIE,
229 options::OPT_fpie, options::OPT_fno_pie);
231 Option O = LastPICArg->getOption();
233 (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
234 O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
236 (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
237 O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
240 bool UseAbiCalls =
false;
243 Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
245 !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
247 if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
248 D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
249 << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
252 if (ABICallsArg && !UseAbiCalls && IsPIC) {
253 D.Diag(diag::err_drv_unsupported_noabicalls_pic);
257 Features.push_back(
"+noabicalls");
259 Features.push_back(
"-noabicalls");
261 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
262 options::OPT_mno_long_calls)) {
263 if (A->getOption().matches(options::OPT_mno_long_calls))
264 Features.push_back(
"-long-calls");
265 else if (!UseAbiCalls)
266 Features.push_back(
"+long-calls");
268 D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
271 if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
272 if (A->getOption().matches(options::OPT_mxgot))
273 Features.push_back(
"+xgot");
275 Features.push_back(
"-xgot");
279 if (FloatABI == mips::FloatABI::Soft) {
283 Features.push_back(
"+soft-float");
286 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
287 StringRef Val = StringRef(A->getValue());
290 Features.push_back(
"+nan2008");
291 HasNaN2008Opt =
true;
293 Features.push_back(
"-nan2008");
294 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
296 }
else if (Val ==
"legacy") {
298 Features.push_back(
"-nan2008");
300 Features.push_back(
"+nan2008");
301 D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
304 D.Diag(diag::err_drv_unsupported_option_argument)
305 << A->getSpelling() << Val;
308 if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
309 StringRef Val = StringRef(A->getValue());
312 Features.push_back(
"+abs2008");
314 Features.push_back(
"-abs2008");
315 D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
317 }
else if (Val ==
"legacy") {
319 Features.push_back(
"-abs2008");
321 Features.push_back(
"+abs2008");
322 D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
325 D.Diag(diag::err_drv_unsupported_option_argument)
326 << A->getSpelling() << Val;
328 }
else if (HasNaN2008Opt) {
329 Features.push_back(
"+abs2008");
333 options::OPT_mdouble_float,
"single-float");
334 AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
337 options::OPT_mno_micromips,
"micromips");
340 AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
344 if (Arg *A = Args.getLastArg(
345 options::OPT_mstrict_align, options::OPT_mno_strict_align,
346 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
347 if (A->getOption().matches(options::OPT_mstrict_align) ||
348 A->getOption().matches(options::OPT_mno_unaligned_access))
349 Features.push_back(Args.MakeArgString(
"+strict-align"));
351 Features.push_back(Args.MakeArgString(
"-strict-align"));
357 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
358 options::OPT_mfp64)) {
359 if (A->getOption().matches(options::OPT_mfp32))
360 Features.push_back(
"-fp64");
361 else if (A->getOption().matches(options::OPT_mfpxx)) {
362 Features.push_back(
"+fpxx");
363 Features.push_back(
"+nooddspreg");
365 Features.push_back(
"+fp64");
367 Features.push_back(
"+fpxx");
368 Features.push_back(
"+nooddspreg");
370 Features.push_back(
"+fp64");
371 Features.push_back(
"+nooddspreg");
372 }
else if (Arg *A = Args.getLastArg(options::OPT_mmsa)) {
373 if (A->getOption().matches(options::OPT_mmsa))
374 Features.push_back(
"+fp64");
378 options::OPT_modd_spreg,
"nooddspreg");
379 AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
381 AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt,
"mt");
389 if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
390 StringRef Val = StringRef(A->getValue());
391 if (Val ==
"hazard") {
393 Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
394 Arg *
C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
396 if (B && B->getOption().matches(options::OPT_mmicromips))
397 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
398 <<
"hazard" <<
"micromips";
399 else if (
C &&
C->getOption().matches(options::OPT_mips16))
400 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
401 <<
"hazard" <<
"mips16";
403 Features.push_back(
"+use-indirect-jump-hazard");
405 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
406 <<
"hazard" << CPUName;
408 D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
438 return llvm::StringSwitch<bool>(CPU)
439 .Case(
"mips32r6",
true)
440 .Case(
"mips64r6",
true)
445 Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
446 return A && (A->getValue() == StringRef(
Value));
450 Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
451 return A && A->getOption().matches(options::OPT_muclibc);
455 const llvm::Triple &Triple) {
456 if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
457 return llvm::StringSwitch<bool>(NaNArg->getValue())
459 .Case(
"legacy",
false)
463 return llvm::StringSwitch<bool>(
getCPUName(
D, Args, Triple))
464 .Cases(
"mips32r6",
"mips64r6",
true)
469 if (!Triple.isAndroid())
473 return llvm::StringSwitch<bool>(CPUName)
474 .Case(
"mips32r6",
true)
485 if (
FloatABI == mips::FloatABI::Soft)
488 return llvm::StringSwitch<bool>(CPUName)
489 .Cases(
"mips2",
"mips3",
"mips4",
"mips5",
true)
490 .Cases(
"mips32",
"mips32r2",
"mips32r3",
"mips32r5",
true)
491 .Cases(
"mips64",
"mips64r2",
"mips64r3",
"mips64r5",
true)
496 StringRef CPUName, StringRef ABIName,
498 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
501 if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
502 options::OPT_mdouble_float))
503 if (A->getOption().matches(options::OPT_msingle_float))
506 if (Arg *A = Args.getLastArg(options::OPT_mmsa))
507 if (A->getOption().matches(options::OPT_mmsa))
508 UseFPXX = llvm::StringSwitch<bool>(CPUName)
509 .Cases(
"mips32r2",
"mips32r3",
"mips32r5",
false)
510 .Cases(
"mips64r2",
"mips64r3",
"mips64r5",
false)
519 return llvm::StringSwitch<bool>(CPU)
520 .Case(
"mips32r2",
true)
521 .Case(
"mips32r3",
true)
522 .Case(
"mips32r5",
true)
523 .Case(
"mips32r6",
true)
524 .Case(
"mips64r2",
true)
525 .Case(
"mips64r3",
true)
526 .Case(
"mips64r5",
true)
527 .Case(
"mips64r6",
true)
528 .Case(
"octeon",
true)
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
The JSON file list parser is used to communicate input to InstallAPI.