1 //===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Mips.h" 11 #include "ToolChains/CommonArgs.h" 12 #include "clang/Driver/Driver.h" 13 #include "clang/Driver/DriverDiagnostic.h" 14 #include "clang/Driver/Options.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/Option/ArgList.h" 17 18 using namespace clang::driver; 19 using namespace clang::driver::tools; 20 using namespace clang; 21 using namespace llvm::opt; 22 23 bool tools::isMipsArch(llvm::Triple::ArchType Arch) { 24 return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel || 25 Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el; 26 } 27 28 // Get CPU and ABI names. They are not independent 29 // so we have to calculate them together. 30 void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple, 31 StringRef &CPUName, StringRef &ABIName) { 32 const char *DefMips32CPU = "mips32r2"; 33 const char *DefMips64CPU = "mips64r2"; 34 35 // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the 36 // default for mips64(el)?-img-linux-gnu. 37 if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies && 38 Triple.getEnvironment() == llvm::Triple::GNU) { 39 DefMips32CPU = "mips32r6"; 40 DefMips64CPU = "mips64r6"; 41 } 42 43 // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android). 44 if (Triple.isAndroid()) { 45 DefMips32CPU = "mips32"; 46 DefMips64CPU = "mips64r6"; 47 } 48 49 // MIPS3 is the default for mips64*-unknown-openbsd. 50 if (Triple.getOS() == llvm::Triple::OpenBSD) 51 DefMips64CPU = "mips3"; 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() && 84 (Triple.getVendor() == llvm::Triple::MipsTechnologies || 85 Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) { 86 ABIName = llvm::StringSwitch<const char *>(CPUName) 87 .Case("mips1", "o32") 88 .Case("mips2", "o32") 89 .Case("mips3", "n64") 90 .Case("mips4", "n64") 91 .Case("mips5", "n64") 92 .Case("mips32", "o32") 93 .Case("mips32r2", "o32") 94 .Case("mips32r3", "o32") 95 .Case("mips32r5", "o32") 96 .Case("mips32r6", "o32") 97 .Case("mips64", "n64") 98 .Case("mips64r2", "n64") 99 .Case("mips64r3", "n64") 100 .Case("mips64r5", "n64") 101 .Case("mips64r6", "n64") 102 .Case("octeon", "n64") 103 .Case("p5600", "o32") 104 .Default(""); 105 } 106 107 if (ABIName.empty()) { 108 // Deduce ABI name from the target triple. 109 if (Triple.getArch() == llvm::Triple::mips || 110 Triple.getArch() == llvm::Triple::mipsel) 111 ABIName = "o32"; 112 else 113 ABIName = "n64"; 114 } 115 116 if (CPUName.empty()) { 117 // Deduce CPU name from ABI name. 118 CPUName = llvm::StringSwitch<const char *>(ABIName) 119 .Case("o32", DefMips32CPU) 120 .Cases("n32", "n64", DefMips64CPU) 121 .Default(""); 122 } 123 124 // FIXME: Warn on inconsistent use of -march and -mabi. 125 } 126 127 std::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("o32", "") 133 .Case("n32", "32") 134 .Case("n64", "64"); 135 } 136 137 // Convert ABI name to the GNU tools acceptable variant. 138 StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) { 139 return llvm::StringSwitch<llvm::StringRef>(ABI) 140 .Case("o32", "32") 141 .Case("n64", "64") 142 .Default(ABI); 143 } 144 145 // Select the MIPS float ABI as determined by -msoft-float, -mhard-float, 146 // and -mfloat-abi=. 147 mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) { 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 // Assume "hard", because it's a default value used by gcc. 171 // When we start to recognize specific target MIPS processors, 172 // we will be able to select the default more correctly. 173 ABI = mips::FloatABI::Hard; 174 } 175 176 assert(ABI != mips::FloatABI::Invalid && "must select an ABI"); 177 return ABI; 178 } 179 180 void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, 181 const ArgList &Args, 182 std::vector<StringRef> &Features) { 183 StringRef CPUName; 184 StringRef ABIName; 185 getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 186 ABIName = getGnuCompatibleMipsABIName(ABIName); 187 188 // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a 189 // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI 190 // extension was developed by Richard Sandiford & Code Sourcery to support 191 // static code calling PIC code (CPIC). For O32 and N32 this means we have 192 // several combinations of PIC/static and abicalls. Pure static, static 193 // with the CPIC extension, and pure PIC code. 194 195 // At final link time, O32 and N32 with CPIC will have another section 196 // added to the binary which contains the stub functions to perform 197 // any fixups required for PIC code. 198 199 // For N64, the situation is more regular: code can either be static 200 // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code 201 // code for N64. Since Clang has already built the relocation model portion 202 // of the commandline, we pick add +noabicalls feature in the N64 static 203 // case. 204 205 // The is another case to be accounted for: -msym32, which enforces that all 206 // symbols have 32 bits in size. In this case, N64 can in theory use CPIC 207 // but it is unsupported. 208 209 // The combinations for N64 are: 210 // a) Static without abicalls and 64bit symbols. 211 // b) Static with abicalls and 32bit symbols. 212 // c) PIC with abicalls and 64bit symbols. 213 214 // For case (a) we need to add +noabicalls for N64. 215 216 bool IsN64 = ABIName == "64"; 217 bool NonPIC = false; 218 219 Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, 220 options::OPT_fpic, options::OPT_fno_pic, 221 options::OPT_fPIE, options::OPT_fno_PIE, 222 options::OPT_fpie, options::OPT_fno_pie); 223 if (LastPICArg) { 224 Option O = LastPICArg->getOption(); 225 NonPIC = 226 (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) || 227 O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie)); 228 } 229 230 if (IsN64 && NonPIC) { 231 Features.push_back("+noabicalls"); 232 } else { 233 AddTargetFeature(Args, Features, options::OPT_mno_abicalls, 234 options::OPT_mabicalls, "noabicalls"); 235 } 236 237 mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args); 238 if (FloatABI == mips::FloatABI::Soft) { 239 // FIXME: Note, this is a hack. We need to pass the selected float 240 // mode to the MipsTargetInfoBase to define appropriate macros there. 241 // Now it is the only method. 242 Features.push_back("+soft-float"); 243 } 244 245 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 246 StringRef Val = StringRef(A->getValue()); 247 if (Val == "2008") { 248 if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008) 249 Features.push_back("+nan2008"); 250 else { 251 Features.push_back("-nan2008"); 252 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; 253 } 254 } else if (Val == "legacy") { 255 if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy) 256 Features.push_back("-nan2008"); 257 else { 258 Features.push_back("+nan2008"); 259 D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName; 260 } 261 } else 262 D.Diag(diag::err_drv_unsupported_option_argument) 263 << A->getOption().getName() << Val; 264 } 265 266 AddTargetFeature(Args, Features, options::OPT_msingle_float, 267 options::OPT_mdouble_float, "single-float"); 268 AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, 269 "mips16"); 270 AddTargetFeature(Args, Features, options::OPT_mmicromips, 271 options::OPT_mno_micromips, "micromips"); 272 AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, 273 "dsp"); 274 AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, 275 "dspr2"); 276 AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, 277 "msa"); 278 279 // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32 280 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and 281 // nooddspreg. 282 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, 283 options::OPT_mfp64)) { 284 if (A->getOption().matches(options::OPT_mfp32)) 285 Features.push_back(Args.MakeArgString("-fp64")); 286 else if (A->getOption().matches(options::OPT_mfpxx)) { 287 Features.push_back(Args.MakeArgString("+fpxx")); 288 Features.push_back(Args.MakeArgString("+nooddspreg")); 289 } else 290 Features.push_back(Args.MakeArgString("+fp64")); 291 } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) { 292 Features.push_back(Args.MakeArgString("+fpxx")); 293 Features.push_back(Args.MakeArgString("+nooddspreg")); 294 } else if (mips::isFP64ADefault(Triple, CPUName)) { 295 Features.push_back(Args.MakeArgString("+fp64")); 296 Features.push_back(Args.MakeArgString("+nooddspreg")); 297 } 298 299 AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, 300 options::OPT_modd_spreg, "nooddspreg"); 301 } 302 303 mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) { 304 // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008 305 // was first introduced in Release 3. However, other compilers have 306 // traditionally allowed it for Release 2 so we should do the same. 307 return (NanEncoding)llvm::StringSwitch<int>(CPU) 308 .Case("mips1", NanLegacy) 309 .Case("mips2", NanLegacy) 310 .Case("mips3", NanLegacy) 311 .Case("mips4", NanLegacy) 312 .Case("mips5", NanLegacy) 313 .Case("mips32", NanLegacy) 314 .Case("mips32r2", NanLegacy | Nan2008) 315 .Case("mips32r3", NanLegacy | Nan2008) 316 .Case("mips32r5", NanLegacy | Nan2008) 317 .Case("mips32r6", Nan2008) 318 .Case("mips64", NanLegacy) 319 .Case("mips64r2", NanLegacy | Nan2008) 320 .Case("mips64r3", NanLegacy | Nan2008) 321 .Case("mips64r5", NanLegacy | Nan2008) 322 .Case("mips64r6", Nan2008) 323 .Default(NanLegacy); 324 } 325 326 bool mips::hasCompactBranches(StringRef &CPU) { 327 // mips32r6 and mips64r6 have compact branches. 328 return llvm::StringSwitch<bool>(CPU) 329 .Case("mips32r6", true) 330 .Case("mips64r6", true) 331 .Default(false); 332 } 333 334 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) { 335 Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 336 return A && (A->getValue() == StringRef(Value)); 337 } 338 339 bool mips::isUCLibc(const ArgList &Args) { 340 Arg *A = Args.getLastArg(options::OPT_m_libc_Group); 341 return A && A->getOption().matches(options::OPT_muclibc); 342 } 343 344 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { 345 if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ)) 346 return llvm::StringSwitch<bool>(NaNArg->getValue()) 347 .Case("2008", true) 348 .Case("legacy", false) 349 .Default(false); 350 351 // NaN2008 is the default for MIPS32r6/MIPS64r6. 352 return llvm::StringSwitch<bool>(getCPUName(Args, Triple)) 353 .Cases("mips32r6", "mips64r6", true) 354 .Default(false); 355 356 return false; 357 } 358 359 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { 360 if (!Triple.isAndroid()) 361 return false; 362 363 // Android MIPS32R6 defaults to FP64A. 364 return llvm::StringSwitch<bool>(CPUName) 365 .Case("mips32r6", true) 366 .Default(false); 367 } 368 369 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, 370 StringRef ABIName, mips::FloatABI FloatABI) { 371 if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies && 372 Triple.getVendor() != llvm::Triple::MipsTechnologies && 373 !Triple.isAndroid()) 374 return false; 375 376 if (ABIName != "32") 377 return false; 378 379 // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is 380 // present. 381 if (FloatABI == mips::FloatABI::Soft) 382 return false; 383 384 return llvm::StringSwitch<bool>(CPUName) 385 .Cases("mips2", "mips3", "mips4", "mips5", true) 386 .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true) 387 .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true) 388 .Default(false); 389 } 390 391 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple, 392 StringRef CPUName, StringRef ABIName, 393 mips::FloatABI FloatABI) { 394 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI); 395 396 // FPXX shouldn't be used if -msingle-float is present. 397 if (Arg *A = Args.getLastArg(options::OPT_msingle_float, 398 options::OPT_mdouble_float)) 399 if (A->getOption().matches(options::OPT_msingle_float)) 400 UseFPXX = false; 401 402 return UseFPXX; 403 } 404