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 const llvm::Triple &Triple) { 154 mips::FloatABI ABI = mips::FloatABI::Invalid; 155 if (Arg *A = 156 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 157 options::OPT_mfloat_abi_EQ)) { 158 if (A->getOption().matches(options::OPT_msoft_float)) 159 ABI = mips::FloatABI::Soft; 160 else if (A->getOption().matches(options::OPT_mhard_float)) 161 ABI = mips::FloatABI::Hard; 162 else { 163 ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue()) 164 .Case("soft", mips::FloatABI::Soft) 165 .Case("hard", mips::FloatABI::Hard) 166 .Default(mips::FloatABI::Invalid); 167 if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { 168 D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 169 ABI = mips::FloatABI::Hard; 170 } 171 } 172 } 173 174 // If unspecified, choose the default based on the platform. 175 if (ABI == mips::FloatABI::Invalid) { 176 if (Triple.isOSFreeBSD()) { 177 // For FreeBSD, assume "soft" on all flavors of MIPS. 178 ABI = mips::FloatABI::Soft; 179 } else { 180 // Assume "hard", because it's a default value used by gcc. 181 // When we start to recognize specific target MIPS processors, 182 // we will be able to select the default more correctly. 183 ABI = mips::FloatABI::Hard; 184 } 185 } 186 187 assert(ABI != mips::FloatABI::Invalid && "must select an ABI"); 188 return ABI; 189 } 190 191 void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, 192 const ArgList &Args, 193 std::vector<StringRef> &Features) { 194 StringRef CPUName; 195 StringRef ABIName; 196 getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 197 ABIName = getGnuCompatibleMipsABIName(ABIName); 198 199 // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a 200 // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI 201 // extension was developed by Richard Sandiford & Code Sourcery to support 202 // static code calling PIC code (CPIC). For O32 and N32 this means we have 203 // several combinations of PIC/static and abicalls. Pure static, static 204 // with the CPIC extension, and pure PIC code. 205 206 // At final link time, O32 and N32 with CPIC will have another section 207 // added to the binary which contains the stub functions to perform 208 // any fixups required for PIC code. 209 210 // For N64, the situation is more regular: code can either be static 211 // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code 212 // code for N64. Since Clang has already built the relocation model portion 213 // of the commandline, we pick add +noabicalls feature in the N64 static 214 // case. 215 216 // The is another case to be accounted for: -msym32, which enforces that all 217 // symbols have 32 bits in size. In this case, N64 can in theory use CPIC 218 // but it is unsupported. 219 220 // The combinations for N64 are: 221 // a) Static without abicalls and 64bit symbols. 222 // b) Static with abicalls and 32bit symbols. 223 // c) PIC with abicalls and 64bit symbols. 224 225 // For case (a) we need to add +noabicalls for N64. 226 227 bool IsN64 = ABIName == "64"; 228 bool IsPIC = false; 229 bool NonPIC = false; 230 231 Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 232 options::OPT_fpic, options::OPT_fno_pic, 233 options::OPT_fPIE, options::OPT_fno_PIE, 234 options::OPT_fpie, options::OPT_fno_pie); 235 if (LastPICArg) { 236 Option O = LastPICArg->getOption(); 237 NonPIC = 238 (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) || 239 O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie)); 240 IsPIC = 241 (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || 242 O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)); 243 } 244 245 bool UseAbiCalls = false; 246 247 Arg *ABICallsArg = 248 Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls); 249 UseAbiCalls = 250 !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls); 251 252 if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) { 253 D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls) 254 << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1); 255 } 256 257 if (ABICallsArg && !UseAbiCalls && IsPIC) { 258 D.Diag(diag::err_drv_unsupported_noabicalls_pic); 259 } 260 261 if (!UseAbiCalls) 262 Features.push_back("+noabicalls"); 263 else 264 Features.push_back("-noabicalls"); 265 266 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, 267 options::OPT_mno_long_calls)) { 268 if (A->getOption().matches(options::OPT_mno_long_calls)) 269 Features.push_back("-long-calls"); 270 else if (!UseAbiCalls) 271 Features.push_back("+long-calls"); 272 else 273 D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1); 274 } 275 276 mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple); 277 if (FloatABI == mips::FloatABI::Soft) { 278 // FIXME: Note, this is a hack. We need to pass the selected float 279 // mode to the MipsTargetInfoBase to define appropriate macros there. 280 // Now it is the only method. 281 Features.push_back("+soft-float"); 282 } 283 284 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 285 StringRef Val = StringRef(A->getValue()); 286 if (Val == "2008") { 287 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) 288 Features.push_back("+nan2008"); 289 else { 290 Features.push_back("-nan2008"); 291 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; 292 } 293 } else if (Val == "legacy") { 294 if (mips::getIEEE754Standard(CPUName) & mips::Legacy) 295 Features.push_back("-nan2008"); 296 else { 297 Features.push_back("+nan2008"); 298 D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName; 299 } 300 } else 301 D.Diag(diag::err_drv_unsupported_option_argument) 302 << A->getOption().getName() << Val; 303 } 304 305 if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) { 306 StringRef Val = StringRef(A->getValue()); 307 if (Val == "2008") { 308 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) { 309 Features.push_back("+abs2008"); 310 } else { 311 Features.push_back("-abs2008"); 312 D.Diag(diag::warn_target_unsupported_abs2008) << CPUName; 313 } 314 } else if (Val == "legacy") { 315 if (mips::getIEEE754Standard(CPUName) & mips::Legacy) { 316 Features.push_back("-abs2008"); 317 } else { 318 Features.push_back("+abs2008"); 319 D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName; 320 } 321 } else { 322 D.Diag(diag::err_drv_unsupported_option_argument) 323 << A->getOption().getName() << Val; 324 } 325 } 326 327 AddTargetFeature(Args, Features, options::OPT_msingle_float, 328 options::OPT_mdouble_float, "single-float"); 329 AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, 330 "mips16"); 331 AddTargetFeature(Args, Features, options::OPT_mmicromips, 332 options::OPT_mno_micromips, "micromips"); 333 AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, 334 "dsp"); 335 AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, 336 "dspr2"); 337 AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, 338 "msa"); 339 340 // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32 341 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and 342 // nooddspreg. 343 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, 344 options::OPT_mfp64)) { 345 if (A->getOption().matches(options::OPT_mfp32)) 346 Features.push_back("-fp64"); 347 else if (A->getOption().matches(options::OPT_mfpxx)) { 348 Features.push_back("+fpxx"); 349 Features.push_back("+nooddspreg"); 350 } else 351 Features.push_back("+fp64"); 352 } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) { 353 Features.push_back("+fpxx"); 354 Features.push_back("+nooddspreg"); 355 } else if (mips::isFP64ADefault(Triple, CPUName)) { 356 Features.push_back("+fp64"); 357 Features.push_back("+nooddspreg"); 358 } 359 360 AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, 361 options::OPT_modd_spreg, "nooddspreg"); 362 AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4, 363 "nomadd4"); 364 AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt"); 365 AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc, 366 "crc"); 367 AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt, 368 "virt"); 369 AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv, 370 "ginv"); 371 372 if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) { 373 StringRef Val = StringRef(A->getValue()); 374 if (Val == "hazard") { 375 Arg *B = 376 Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); 377 Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); 378 379 if (B && B->getOption().matches(options::OPT_mmicromips)) 380 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 381 << "hazard" << "micromips"; 382 else if (C && C->getOption().matches(options::OPT_mips16)) 383 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 384 << "hazard" << "mips16"; 385 else if (mips::supportsIndirectJumpHazardBarrier(CPUName)) 386 Features.push_back("+use-indirect-jump-hazard"); 387 else 388 D.Diag(diag::err_drv_unsupported_indirect_jump_opt) 389 << "hazard" << CPUName; 390 } else 391 D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val; 392 } 393 } 394 395 mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) { 396 // Strictly speaking, mips32r2 and mips64r2 do not conform to the 397 // IEEE754-2008 standard. Support for this standard was first introduced 398 // in Release 3. However, other compilers have traditionally allowed it 399 // for Release 2 so we should do the same. 400 return (IEEE754Standard)llvm::StringSwitch<int>(CPU) 401 .Case("mips1", Legacy) 402 .Case("mips2", Legacy) 403 .Case("mips3", Legacy) 404 .Case("mips4", Legacy) 405 .Case("mips5", Legacy) 406 .Case("mips32", Legacy) 407 .Case("mips32r2", Legacy | Std2008) 408 .Case("mips32r3", Legacy | Std2008) 409 .Case("mips32r5", Legacy | Std2008) 410 .Case("mips32r6", Std2008) 411 .Case("mips64", Legacy) 412 .Case("mips64r2", Legacy | Std2008) 413 .Case("mips64r3", Legacy | Std2008) 414 .Case("mips64r5", Legacy | Std2008) 415 .Case("mips64r6", Std2008) 416 .Default(Std2008); 417 } 418 419 bool mips::hasCompactBranches(StringRef &CPU) { 420 // mips32r6 and mips64r6 have compact branches. 421 return llvm::StringSwitch<bool>(CPU) 422 .Case("mips32r6", true) 423 .Case("mips64r6", true) 424 .Default(false); 425 } 426 427 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) { 428 Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 429 return A && (A->getValue() == StringRef(Value)); 430 } 431 432 bool mips::isUCLibc(const ArgList &Args) { 433 Arg *A = Args.getLastArg(options::OPT_m_libc_Group); 434 return A && A->getOption().matches(options::OPT_muclibc); 435 } 436 437 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { 438 if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ)) 439 return llvm::StringSwitch<bool>(NaNArg->getValue()) 440 .Case("2008", true) 441 .Case("legacy", false) 442 .Default(false); 443 444 // NaN2008 is the default for MIPS32r6/MIPS64r6. 445 return llvm::StringSwitch<bool>(getCPUName(Args, Triple)) 446 .Cases("mips32r6", "mips64r6", true) 447 .Default(false); 448 449 return false; 450 } 451 452 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { 453 if (!Triple.isAndroid()) 454 return false; 455 456 // Android MIPS32R6 defaults to FP64A. 457 return llvm::StringSwitch<bool>(CPUName) 458 .Case("mips32r6", true) 459 .Default(false); 460 } 461 462 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, 463 StringRef ABIName, mips::FloatABI FloatABI) { 464 if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && 465 Triple.getVendor() != llvm::Triple::MipsTechnologies && 466 !Triple.isAndroid()) 467 return false; 468 469 if (ABIName != "32") 470 return false; 471 472 // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is 473 // present. 474 if (FloatABI == mips::FloatABI::Soft) 475 return false; 476 477 return llvm::StringSwitch<bool>(CPUName) 478 .Cases("mips2", "mips3", "mips4", "mips5", true) 479 .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true) 480 .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true) 481 .Default(false); 482 } 483 484 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple, 485 StringRef CPUName, StringRef ABIName, 486 mips::FloatABI FloatABI) { 487 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI); 488 489 // FPXX shouldn't be used if -msingle-float is present. 490 if (Arg *A = Args.getLastArg(options::OPT_msingle_float, 491 options::OPT_mdouble_float)) 492 if (A->getOption().matches(options::OPT_msingle_float)) 493 UseFPXX = false; 494 495 return UseFPXX; 496 } 497 498 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) { 499 // Supporting the hazard barrier method of dealing with indirect 500 // jumps requires MIPSR2 support. 501 return llvm::StringSwitch<bool>(CPU) 502 .Case("mips32r2", true) 503 .Case("mips32r3", true) 504 .Case("mips32r5", true) 505 .Case("mips32r6", true) 506 .Case("mips64r2", true) 507 .Case("mips64r3", true) 508 .Case("mips64r5", true) 509 .Case("mips64r6", true) 510 .Case("octeon", true) 511 .Case("p5600", true) 512 .Default(false); 513 } 514