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