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 // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android). 43 if (Triple.isAndroid()) { 44 DefMips32CPU = "mips32"; 45 DefMips64CPU = "mips64r6"; 46 } 47 48 // MIPS3 is the default for mips64*-unknown-openbsd. 49 if (Triple.isOSOpenBSD()) 50 DefMips64CPU = "mips3"; 51 52 // MIPS2 is the default for mips(el)?-unknown-freebsd. 53 // MIPS3 is the default for mips64(el)?-unknown-freebsd. 54 if (Triple.isOSFreeBSD()) { 55 DefMips32CPU = "mips2"; 56 DefMips64CPU = "mips3"; 57 } 58 59 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ, 60 options::OPT_mcpu_EQ)) 61 CPUName = A->getValue(); 62 63 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { 64 ABIName = A->getValue(); 65 // Convert a GNU style Mips ABI name to the name 66 // accepted by LLVM Mips backend. 67 ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName) 68 .Case("32", "o32") 69 .Case("64", "n64") 70 .Default(ABIName); 71 } 72 73 // Setup default CPU and ABI names. 74 if (CPUName.empty() && ABIName.empty()) { 75 switch (Triple.getArch()) { 76 default: 77 llvm_unreachable("Unexpected triple arch name"); 78 case llvm::Triple::mips: 79 case llvm::Triple::mipsel: 80 CPUName = DefMips32CPU; 81 break; 82 case llvm::Triple::mips64: 83 case llvm::Triple::mips64el: 84 CPUName = DefMips64CPU; 85 break; 86 } 87 } 88 89 if (ABIName.empty() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32)) 90 ABIName = "n32"; 91 92 if (ABIName.empty() && 93 (Triple.getVendor() == llvm::Triple::MipsTechnologies || 94 Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) { 95 ABIName = llvm::StringSwitch<const char *>(CPUName) 96 .Case("mips1", "o32") 97 .Case("mips2", "o32") 98 .Case("mips3", "n64") 99 .Case("mips4", "n64") 100 .Case("mips5", "n64") 101 .Case("mips32", "o32") 102 .Case("mips32r2", "o32") 103 .Case("mips32r3", "o32") 104 .Case("mips32r5", "o32") 105 .Case("mips32r6", "o32") 106 .Case("mips64", "n64") 107 .Case("mips64r2", "n64") 108 .Case("mips64r3", "n64") 109 .Case("mips64r5", "n64") 110 .Case("mips64r6", "n64") 111 .Case("octeon", "n64") 112 .Case("p5600", "o32") 113 .Default(""); 114 } 115 116 if (ABIName.empty()) { 117 // Deduce ABI name from the target triple. 118 ABIName = Triple.isMIPS32() ? "o32" : "n64"; 119 } 120 121 if (CPUName.empty()) { 122 // Deduce CPU name from ABI name. 123 CPUName = llvm::StringSwitch<const char *>(ABIName) 124 .Case("o32", DefMips32CPU) 125 .Cases("n32", "n64", DefMips64CPU) 126 .Default(""); 127 } 128 129 // FIXME: Warn on inconsistent use of -march and -mabi. 130 } 131 132 std::string mips::getMipsABILibSuffix(const ArgList &Args, 133 const llvm::Triple &Triple) { 134 StringRef CPUName, ABIName; 135 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 136 return llvm::StringSwitch<std::string>(ABIName) 137 .Case("o32", "") 138 .Case("n32", "32") 139 .Case("n64", "64"); 140 } 141 142 // Convert ABI name to the GNU tools acceptable variant. 143 StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) { 144 return llvm::StringSwitch<llvm::StringRef>(ABI) 145 .Case("o32", "32") 146 .Case("n64", "64") 147 .Default(ABI); 148 } 149 150 // Select the MIPS float ABI as determined by -msoft-float, -mhard-float, 151 // and -mfloat-abi=. 152 mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) { 153 mips::FloatABI ABI = mips::FloatABI::Invalid; 154 if (Arg *A = 155 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 156 options::OPT_mfloat_abi_EQ)) { 157 if (A->getOption().matches(options::OPT_msoft_float)) 158 ABI = mips::FloatABI::Soft; 159 else if (A->getOption().matches(options::OPT_mhard_float)) 160 ABI = mips::FloatABI::Hard; 161 else { 162 ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue()) 163 .Case("soft", mips::FloatABI::Soft) 164 .Case("hard", mips::FloatABI::Hard) 165 .Default(mips::FloatABI::Invalid); 166 if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { 167 D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 168 ABI = mips::FloatABI::Hard; 169 } 170 } 171 } 172 173 // If unspecified, choose the default based on the platform. 174 if (ABI == mips::FloatABI::Invalid) { 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 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 225 Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 226 options::OPT_fpic, options::OPT_fno_pic, 227 options::OPT_fPIE, options::OPT_fno_PIE, 228 options::OPT_fpie, options::OPT_fno_pie); 229 if (LastPICArg) { 230 Option O = LastPICArg->getOption(); 231 NonPIC = 232 (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) || 233 O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie)); 234 IsPIC = 235 (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || 236 O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)); 237 } 238 239 bool UseAbiCalls = false; 240 241 Arg *ABICallsArg = 242 Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls); 243 UseAbiCalls = 244 !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls); 245 246 if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) { 247 D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls) 248 << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1); 249 } 250 251 if (ABICallsArg && !UseAbiCalls && IsPIC) { 252 D.Diag(diag::err_drv_unsupported_noabicalls_pic); 253 } 254 255 if (!UseAbiCalls) 256 Features.push_back("+noabicalls"); 257 else 258 Features.push_back("-noabicalls"); 259 260 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, 261 options::OPT_mno_long_calls)) { 262 if (A->getOption().matches(options::OPT_mno_long_calls)) 263 Features.push_back("-long-calls"); 264 else if (!UseAbiCalls) 265 Features.push_back("+long-calls"); 266 else 267 D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1); 268 } 269 270 if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) { 271 if (A->getOption().matches(options::OPT_mxgot)) 272 Features.push_back("+xgot"); 273 else 274 Features.push_back("-xgot"); 275 } 276 277 mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args); 278 if (FloatABI == mips::FloatABI::Soft) { 279 // FIXME: Note, this is a hack. We need to pass the selected float 280 // mode to the MipsTargetInfoBase to define appropriate macros there. 281 // Now it is the only method. 282 Features.push_back("+soft-float"); 283 } 284 285 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 286 StringRef Val = StringRef(A->getValue()); 287 if (Val == "2008") { 288 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) 289 Features.push_back("+nan2008"); 290 else { 291 Features.push_back("-nan2008"); 292 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; 293 } 294 } else if (Val == "legacy") { 295 if (mips::getIEEE754Standard(CPUName) & mips::Legacy) 296 Features.push_back("-nan2008"); 297 else { 298 Features.push_back("+nan2008"); 299 D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName; 300 } 301 } else 302 D.Diag(diag::err_drv_unsupported_option_argument) 303 << A->getOption().getName() << Val; 304 } 305 306 if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) { 307 StringRef Val = StringRef(A->getValue()); 308 if (Val == "2008") { 309 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) { 310 Features.push_back("+abs2008"); 311 } else { 312 Features.push_back("-abs2008"); 313 D.Diag(diag::warn_target_unsupported_abs2008) << CPUName; 314 } 315 } else if (Val == "legacy") { 316 if (mips::getIEEE754Standard(CPUName) & mips::Legacy) { 317 Features.push_back("-abs2008"); 318 } else { 319 Features.push_back("+abs2008"); 320 D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName; 321 } 322 } else { 323 D.Diag(diag::err_drv_unsupported_option_argument) 324 << A->getOption().getName() << Val; 325 } 326 } 327 328 AddTargetFeature(Args, Features, options::OPT_msingle_float, 329 options::OPT_mdouble_float, "single-float"); 330 AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, 331 "mips16"); 332 AddTargetFeature(Args, Features, options::OPT_mmicromips, 333 options::OPT_mno_micromips, "micromips"); 334 AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, 335 "dsp"); 336 AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, 337 "dspr2"); 338 AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, 339 "msa"); 340 341 // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32 342 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and 343 // nooddspreg. 344 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, 345 options::OPT_mfp64)) { 346 if (A->getOption().matches(options::OPT_mfp32)) 347 Features.push_back("-fp64"); 348 else if (A->getOption().matches(options::OPT_mfpxx)) { 349 Features.push_back("+fpxx"); 350 Features.push_back("+nooddspreg"); 351 } else 352 Features.push_back("+fp64"); 353 } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) { 354 Features.push_back("+fpxx"); 355 Features.push_back("+nooddspreg"); 356 } else if (mips::isFP64ADefault(Triple, CPUName)) { 357 Features.push_back("+fp64"); 358 Features.push_back("+nooddspreg"); 359 } 360 361 AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, 362 options::OPT_modd_spreg, "nooddspreg"); 363 AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4, 364 "nomadd4"); 365 AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt"); 366 AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc, 367 "crc"); 368 AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt, 369 "virt"); 370 AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv, 371 "ginv"); 372 373 if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) { 374 StringRef Val = StringRef(A->getValue()); 375 if (Val == "hazard") { 376 Arg *B = 377 Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); 378 Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); 379 380 if (B && B->getOption().matches(options::OPT_mmicromips)) 381 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 382 << "hazard" << "micromips"; 383 else if (C && C->getOption().matches(options::OPT_mips16)) 384 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 385 << "hazard" << "mips16"; 386 else if (mips::supportsIndirectJumpHazardBarrier(CPUName)) 387 Features.push_back("+use-indirect-jump-hazard"); 388 else 389 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 390 << "hazard" << CPUName; 391 } else 392 D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val; 393 } 394 } 395 396 mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) { 397 // Strictly speaking, mips32r2 and mips64r2 do not conform to the 398 // IEEE754-2008 standard. Support for this standard was first introduced 399 // in Release 3. However, other compilers have traditionally allowed it 400 // for Release 2 so we should do the same. 401 return (IEEE754Standard)llvm::StringSwitch<int>(CPU) 402 .Case("mips1", Legacy) 403 .Case("mips2", Legacy) 404 .Case("mips3", Legacy) 405 .Case("mips4", Legacy) 406 .Case("mips5", Legacy) 407 .Case("mips32", Legacy) 408 .Case("mips32r2", Legacy | Std2008) 409 .Case("mips32r3", Legacy | Std2008) 410 .Case("mips32r5", Legacy | Std2008) 411 .Case("mips32r6", Std2008) 412 .Case("mips64", Legacy) 413 .Case("mips64r2", Legacy | Std2008) 414 .Case("mips64r3", Legacy | Std2008) 415 .Case("mips64r5", Legacy | Std2008) 416 .Case("mips64r6", Std2008) 417 .Default(Std2008); 418 } 419 420 bool mips::hasCompactBranches(StringRef &CPU) { 421 // mips32r6 and mips64r6 have compact branches. 422 return llvm::StringSwitch<bool>(CPU) 423 .Case("mips32r6", true) 424 .Case("mips64r6", true) 425 .Default(false); 426 } 427 428 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) { 429 Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 430 return A && (A->getValue() == StringRef(Value)); 431 } 432 433 bool mips::isUCLibc(const ArgList &Args) { 434 Arg *A = Args.getLastArg(options::OPT_m_libc_Group); 435 return A && A->getOption().matches(options::OPT_muclibc); 436 } 437 438 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { 439 if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ)) 440 return llvm::StringSwitch<bool>(NaNArg->getValue()) 441 .Case("2008", true) 442 .Case("legacy", false) 443 .Default(false); 444 445 // NaN2008 is the default for MIPS32r6/MIPS64r6. 446 return llvm::StringSwitch<bool>(getCPUName(Args, Triple)) 447 .Cases("mips32r6", "mips64r6", true) 448 .Default(false); 449 450 return false; 451 } 452 453 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { 454 if (!Triple.isAndroid()) 455 return false; 456 457 // Android MIPS32R6 defaults to FP64A. 458 return llvm::StringSwitch<bool>(CPUName) 459 .Case("mips32r6", true) 460 .Default(false); 461 } 462 463 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, 464 StringRef ABIName, mips::FloatABI FloatABI) { 465 if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && 466 Triple.getVendor() != llvm::Triple::MipsTechnologies && 467 !Triple.isAndroid()) 468 return false; 469 470 if (ABIName != "32") 471 return false; 472 473 // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is 474 // present. 475 if (FloatABI == mips::FloatABI::Soft) 476 return false; 477 478 return llvm::StringSwitch<bool>(CPUName) 479 .Cases("mips2", "mips3", "mips4", "mips5", true) 480 .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true) 481 .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true) 482 .Default(false); 483 } 484 485 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple, 486 StringRef CPUName, StringRef ABIName, 487 mips::FloatABI FloatABI) { 488 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI); 489 490 // FPXX shouldn't be used if -msingle-float is present. 491 if (Arg *A = Args.getLastArg(options::OPT_msingle_float, 492 options::OPT_mdouble_float)) 493 if (A->getOption().matches(options::OPT_msingle_float)) 494 UseFPXX = false; 495 496 return UseFPXX; 497 } 498 499 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) { 500 // Supporting the hazard barrier method of dealing with indirect 501 // jumps requires MIPSR2 support. 502 return llvm::StringSwitch<bool>(CPU) 503 .Case("mips32r2", true) 504 .Case("mips32r3", true) 505 .Case("mips32r5", true) 506 .Case("mips32r6", true) 507 .Case("mips64r2", true) 508 .Case("mips64r3", true) 509 .Case("mips64r5", true) 510 .Case("mips64r6", true) 511 .Case("octeon", true) 512 .Case("p5600", true) 513 .Default(false); 514 } 515