1 //===--- ARM.cpp - ARM (not AArch64) Helpers for Tools ----------*- 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 "ARM.h" 10 #include "clang/Driver/Driver.h" 11 #include "clang/Driver/DriverDiagnostic.h" 12 #include "clang/Driver/Options.h" 13 #include "llvm/ADT/StringSwitch.h" 14 #include "llvm/Option/ArgList.h" 15 #include "llvm/TargetParser/ARMTargetParser.h" 16 #include "llvm/TargetParser/Host.h" 17 18 using namespace clang::driver; 19 using namespace clang::driver::tools; 20 using namespace clang; 21 using namespace llvm::opt; 22 23 // Get SubArch (vN). 24 int arm::getARMSubArchVersionNumber(const llvm::Triple &Triple) { 25 llvm::StringRef Arch = Triple.getArchName(); 26 return llvm::ARM::parseArchVersion(Arch); 27 } 28 29 // True if M-profile. 30 bool arm::isARMMProfile(const llvm::Triple &Triple) { 31 llvm::StringRef Arch = Triple.getArchName(); 32 return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M; 33 } 34 35 // On Arm the endianness of the output file is determined by the target and 36 // can be overridden by the pseudo-target flags '-mlittle-endian'/'-EL' and 37 // '-mbig-endian'/'-EB'. Unlike other targets the flag does not result in a 38 // normalized triple so we must handle the flag here. 39 bool arm::isARMBigEndian(const llvm::Triple &Triple, const ArgList &Args) { 40 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, 41 options::OPT_mbig_endian)) { 42 return !A->getOption().matches(options::OPT_mlittle_endian); 43 } 44 45 return Triple.getArch() == llvm::Triple::armeb || 46 Triple.getArch() == llvm::Triple::thumbeb; 47 } 48 49 // True if A-profile. 50 bool arm::isARMAProfile(const llvm::Triple &Triple) { 51 llvm::StringRef Arch = Triple.getArchName(); 52 return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A; 53 } 54 55 // Get Arch/CPU from args. 56 void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch, 57 llvm::StringRef &CPU, bool FromAs) { 58 if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) 59 CPU = A->getValue(); 60 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 61 Arch = A->getValue(); 62 if (!FromAs) 63 return; 64 65 for (const Arg *A : 66 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { 67 // Use getValues because -Wa can have multiple arguments 68 // e.g. -Wa,-mcpu=foo,-mcpu=bar 69 for (StringRef Value : A->getValues()) { 70 if (Value.starts_with("-mcpu=")) 71 CPU = Value.substr(6); 72 if (Value.starts_with("-march=")) 73 Arch = Value.substr(7); 74 } 75 } 76 } 77 78 // Handle -mhwdiv=. 79 // FIXME: Use ARMTargetParser. 80 static void getARMHWDivFeatures(const Driver &D, const Arg *A, 81 const ArgList &Args, StringRef HWDiv, 82 std::vector<StringRef> &Features) { 83 uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv); 84 if (!llvm::ARM::getHWDivFeatures(HWDivID, Features)) 85 D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 86 } 87 88 // Handle -mfpu=. 89 static llvm::ARM::FPUKind getARMFPUFeatures(const Driver &D, const Arg *A, 90 const ArgList &Args, StringRef FPU, 91 std::vector<StringRef> &Features) { 92 llvm::ARM::FPUKind FPUKind = llvm::ARM::parseFPU(FPU); 93 if (!llvm::ARM::getFPUFeatures(FPUKind, Features)) 94 D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); 95 return FPUKind; 96 } 97 98 // Decode ARM features from string like +[no]featureA+[no]featureB+... 99 static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU, 100 llvm::ARM::ArchKind ArchKind, 101 std::vector<StringRef> &Features, 102 llvm::ARM::FPUKind &ArgFPUKind) { 103 SmallVector<StringRef, 8> Split; 104 text.split(Split, StringRef("+"), -1, false); 105 106 for (StringRef Feature : Split) { 107 if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUKind)) 108 return false; 109 } 110 return true; 111 } 112 113 static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, 114 std::vector<StringRef> &Features) { 115 CPU = CPU.split("+").first; 116 if (CPU != "generic") { 117 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU); 118 uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind); 119 llvm::ARM::getExtensionFeatures(Extension, Features); 120 } 121 } 122 123 // Check if -march is valid by checking if it can be canonicalised and parsed. 124 // getARMArch is used here instead of just checking the -march value in order 125 // to handle -march=native correctly. 126 static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, 127 llvm::StringRef ArchName, llvm::StringRef CPUName, 128 std::vector<StringRef> &Features, 129 const llvm::Triple &Triple, 130 llvm::ARM::FPUKind &ArgFPUKind) { 131 std::pair<StringRef, StringRef> Split = ArchName.split("+"); 132 133 std::string MArch = arm::getARMArch(ArchName, Triple); 134 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch); 135 if (ArchKind == llvm::ARM::ArchKind::INVALID || 136 (Split.second.size() && 137 !DecodeARMFeatures(D, Split.second, CPUName, ArchKind, Features, 138 ArgFPUKind))) 139 D.Diag(clang::diag::err_drv_unsupported_option_argument) 140 << A->getSpelling() << A->getValue(); 141 } 142 143 // Check -mcpu=. Needs ArchName to handle -mcpu=generic. 144 static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, 145 llvm::StringRef CPUName, llvm::StringRef ArchName, 146 std::vector<StringRef> &Features, 147 const llvm::Triple &Triple, 148 llvm::ARM::FPUKind &ArgFPUKind) { 149 std::pair<StringRef, StringRef> Split = CPUName.split("+"); 150 151 std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); 152 llvm::ARM::ArchKind ArchKind = 153 arm::getLLVMArchKindForARM(CPU, ArchName, Triple); 154 if (ArchKind == llvm::ARM::ArchKind::INVALID || 155 (Split.second.size() && !DecodeARMFeatures(D, Split.second, CPU, ArchKind, 156 Features, ArgFPUKind))) 157 D.Diag(clang::diag::err_drv_unsupported_option_argument) 158 << A->getSpelling() << A->getValue(); 159 } 160 161 // If -mfloat-abi=hard or -mhard-float are specified explicitly then check that 162 // floating point registers are available on the target CPU. 163 static void checkARMFloatABI(const Driver &D, const ArgList &Args, 164 bool HasFPRegs) { 165 if (HasFPRegs) 166 return; 167 const Arg *A = 168 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 169 options::OPT_mfloat_abi_EQ); 170 if (A && (A->getOption().matches(options::OPT_mhard_float) || 171 (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 172 A->getValue() == StringRef("hard")))) 173 D.Diag(clang::diag::warn_drv_no_floating_point_registers) 174 << A->getAsString(Args); 175 } 176 177 bool arm::useAAPCSForMachO(const llvm::Triple &T) { 178 // The backend is hardwired to assume AAPCS for M-class processors, ensure 179 // the frontend matches that. 180 return T.getEnvironment() == llvm::Triple::EABI || 181 T.getEnvironment() == llvm::Triple::EABIHF || 182 T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); 183 } 184 185 // We follow GCC and support when the backend has support for the MRC/MCR 186 // instructions that are used to set the hard thread pointer ("CP15 C13 187 // Thread id"). 188 bool arm::isHardTPSupported(const llvm::Triple &Triple) { 189 int Ver = getARMSubArchVersionNumber(Triple); 190 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName()); 191 return Triple.isARM() || AK == llvm::ARM::ArchKind::ARMV6T2 || 192 (Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline); 193 } 194 195 // Select mode for reading thread pointer (-mtp=soft/cp15). 196 arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args, 197 const llvm::Triple &Triple, bool ForAS) { 198 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { 199 arm::ReadTPMode ThreadPointer = 200 llvm::StringSwitch<arm::ReadTPMode>(A->getValue()) 201 .Case("cp15", ReadTPMode::TPIDRURO) 202 .Case("tpidrurw", ReadTPMode::TPIDRURW) 203 .Case("tpidruro", ReadTPMode::TPIDRURO) 204 .Case("tpidrprw", ReadTPMode::TPIDRPRW) 205 .Case("soft", ReadTPMode::Soft) 206 .Default(ReadTPMode::Invalid); 207 if ((ThreadPointer == ReadTPMode::TPIDRURW || 208 ThreadPointer == ReadTPMode::TPIDRURO || 209 ThreadPointer == ReadTPMode::TPIDRPRW) && 210 !isHardTPSupported(Triple) && !ForAS) { 211 D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName(); 212 return ReadTPMode::Invalid; 213 } 214 if (ThreadPointer != ReadTPMode::Invalid) 215 return ThreadPointer; 216 if (StringRef(A->getValue()).empty()) 217 D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); 218 else 219 D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); 220 return ReadTPMode::Invalid; 221 } 222 return ReadTPMode::Soft; 223 } 224 225 void arm::setArchNameInTriple(const Driver &D, const ArgList &Args, 226 types::ID InputType, llvm::Triple &Triple) { 227 StringRef MCPU, MArch; 228 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 229 MCPU = A->getValue(); 230 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 231 MArch = A->getValue(); 232 233 std::string CPU = Triple.isOSBinFormatMachO() 234 ? tools::arm::getARMCPUForMArch(MArch, Triple).str() 235 : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); 236 StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); 237 238 bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb || 239 Triple.getArch() == llvm::Triple::thumbeb; 240 // Handle pseudo-target flags '-mlittle-endian'/'-EL' and 241 // '-mbig-endian'/'-EB'. 242 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, 243 options::OPT_mbig_endian)) { 244 IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); 245 } 246 std::string ArchName = IsBigEndian ? "armeb" : "arm"; 247 248 // FIXME: Thumb should just be another -target-feaure, not in the triple. 249 bool IsMProfile = 250 llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M; 251 bool ThumbDefault = IsMProfile || 252 // Thumb2 is the default for V7 on Darwin. 253 (llvm::ARM::parseArchVersion(Suffix) == 7 && 254 Triple.isOSBinFormatMachO()) || 255 // FIXME: this is invalid for WindowsCE 256 Triple.isOSWindows(); 257 258 // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for 259 // M-Class CPUs/architecture variants, which is not supported. 260 bool ARMModeRequested = 261 !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); 262 if (IsMProfile && ARMModeRequested) { 263 if (MCPU.size()) 264 D.Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM"; 265 else 266 D.Diag(diag::err_arch_unsupported_isa) 267 << tools::arm::getARMArch(MArch, Triple) << "ARM"; 268 } 269 270 // Check to see if an explicit choice to use thumb has been made via 271 // -mthumb. For assembler files we must check for -mthumb in the options 272 // passed to the assembler via -Wa or -Xassembler. 273 bool IsThumb = false; 274 if (InputType != types::TY_PP_Asm) 275 IsThumb = 276 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); 277 else { 278 // Ideally we would check for these flags in 279 // CollectArgsForIntegratedAssembler but we can't change the ArchName at 280 // that point. 281 llvm::StringRef WaMArch, WaMCPU; 282 for (const auto *A : 283 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { 284 for (StringRef Value : A->getValues()) { 285 // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm. 286 if (Value == "-mthumb") 287 IsThumb = true; 288 else if (Value.starts_with("-march=")) 289 WaMArch = Value.substr(7); 290 else if (Value.starts_with("-mcpu=")) 291 WaMCPU = Value.substr(6); 292 } 293 } 294 295 if (WaMCPU.size() || WaMArch.size()) { 296 // The way this works means that we prefer -Wa,-mcpu's architecture 297 // over -Wa,-march. Which matches the compiler behaviour. 298 Suffix = tools::arm::getLLVMArchSuffixForARM(WaMCPU, WaMArch, Triple); 299 } 300 } 301 302 // Assembly files should start in ARM mode, unless arch is M-profile, or 303 // -mthumb has been passed explicitly to the assembler. Windows is always 304 // thumb. 305 if (IsThumb || IsMProfile || Triple.isOSWindows()) { 306 if (IsBigEndian) 307 ArchName = "thumbeb"; 308 else 309 ArchName = "thumb"; 310 } 311 Triple.setArchName(ArchName + Suffix.str()); 312 } 313 314 void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args, 315 llvm::Triple &Triple) { 316 if (Triple.isOSLiteOS()) { 317 Triple.setEnvironment(llvm::Triple::OpenHOS); 318 return; 319 } 320 321 bool isHardFloat = 322 (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard); 323 324 switch (Triple.getEnvironment()) { 325 case llvm::Triple::GNUEABI: 326 case llvm::Triple::GNUEABIHF: 327 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF 328 : llvm::Triple::GNUEABI); 329 break; 330 case llvm::Triple::GNUEABIT64: 331 case llvm::Triple::GNUEABIHFT64: 332 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHFT64 333 : llvm::Triple::GNUEABIT64); 334 break; 335 case llvm::Triple::EABI: 336 case llvm::Triple::EABIHF: 337 Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF 338 : llvm::Triple::EABI); 339 break; 340 case llvm::Triple::MuslEABI: 341 case llvm::Triple::MuslEABIHF: 342 Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF 343 : llvm::Triple::MuslEABI); 344 break; 345 case llvm::Triple::OpenHOS: 346 break; 347 default: { 348 arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); 349 if (DefaultABI != arm::FloatABI::Invalid && 350 isHardFloat != (DefaultABI == arm::FloatABI::Hard)) { 351 Arg *ABIArg = 352 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 353 options::OPT_mfloat_abi_EQ); 354 assert(ABIArg && "Non-default float abi expected to be from arg"); 355 D.Diag(diag::err_drv_unsupported_opt_for_target) 356 << ABIArg->getAsString(Args) << Triple.getTriple(); 357 } 358 break; 359 } 360 } 361 } 362 363 arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { 364 return arm::getARMFloatABI(TC.getDriver(), TC.getEffectiveTriple(), Args); 365 } 366 367 arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) { 368 auto SubArch = getARMSubArchVersionNumber(Triple); 369 switch (Triple.getOS()) { 370 case llvm::Triple::Darwin: 371 case llvm::Triple::MacOSX: 372 case llvm::Triple::IOS: 373 case llvm::Triple::TvOS: 374 case llvm::Triple::DriverKit: 375 case llvm::Triple::XROS: 376 // Darwin defaults to "softfp" for v6 and v7. 377 if (Triple.isWatchABI()) 378 return FloatABI::Hard; 379 else 380 return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft; 381 382 case llvm::Triple::WatchOS: 383 return FloatABI::Hard; 384 385 // FIXME: this is invalid for WindowsCE 386 case llvm::Triple::Win32: 387 // It is incorrect to select hard float ABI on MachO platforms if the ABI is 388 // "apcs-gnu". 389 if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple)) 390 return FloatABI::Soft; 391 return FloatABI::Hard; 392 393 case llvm::Triple::NetBSD: 394 switch (Triple.getEnvironment()) { 395 case llvm::Triple::EABIHF: 396 case llvm::Triple::GNUEABIHF: 397 return FloatABI::Hard; 398 default: 399 return FloatABI::Soft; 400 } 401 break; 402 403 case llvm::Triple::FreeBSD: 404 switch (Triple.getEnvironment()) { 405 case llvm::Triple::GNUEABIHF: 406 return FloatABI::Hard; 407 default: 408 // FreeBSD defaults to soft float 409 return FloatABI::Soft; 410 } 411 break; 412 413 case llvm::Triple::Haiku: 414 case llvm::Triple::OpenBSD: 415 return FloatABI::SoftFP; 416 417 default: 418 if (Triple.isOHOSFamily()) 419 return FloatABI::Soft; 420 switch (Triple.getEnvironment()) { 421 case llvm::Triple::GNUEABIHF: 422 case llvm::Triple::GNUEABIHFT64: 423 case llvm::Triple::MuslEABIHF: 424 case llvm::Triple::EABIHF: 425 return FloatABI::Hard; 426 case llvm::Triple::GNUEABI: 427 case llvm::Triple::GNUEABIT64: 428 case llvm::Triple::MuslEABI: 429 case llvm::Triple::EABI: 430 // EABI is always AAPCS, and if it was not marked 'hard', it's softfp 431 return FloatABI::SoftFP; 432 case llvm::Triple::Android: 433 return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft; 434 default: 435 return FloatABI::Invalid; 436 } 437 } 438 return FloatABI::Invalid; 439 } 440 441 // Select the float ABI as determined by -msoft-float, -mhard-float, and 442 // -mfloat-abi=. 443 arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple, 444 const ArgList &Args) { 445 arm::FloatABI ABI = FloatABI::Invalid; 446 if (Arg *A = 447 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 448 options::OPT_mfloat_abi_EQ)) { 449 if (A->getOption().matches(options::OPT_msoft_float)) { 450 ABI = FloatABI::Soft; 451 } else if (A->getOption().matches(options::OPT_mhard_float)) { 452 ABI = FloatABI::Hard; 453 } else { 454 ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue()) 455 .Case("soft", FloatABI::Soft) 456 .Case("softfp", FloatABI::SoftFP) 457 .Case("hard", FloatABI::Hard) 458 .Default(FloatABI::Invalid); 459 if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) { 460 D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 461 ABI = FloatABI::Soft; 462 } 463 } 464 } 465 466 // If unspecified, choose the default based on the platform. 467 if (ABI == FloatABI::Invalid) 468 ABI = arm::getDefaultFloatABI(Triple); 469 470 if (ABI == FloatABI::Invalid) { 471 // Assume "soft", but warn the user we are guessing. 472 if (Triple.isOSBinFormatMachO() && 473 Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em) 474 ABI = FloatABI::Hard; 475 else 476 ABI = FloatABI::Soft; 477 478 if (Triple.getOS() != llvm::Triple::UnknownOS || 479 !Triple.isOSBinFormatMachO()) 480 D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; 481 } 482 483 assert(ABI != FloatABI::Invalid && "must select an ABI"); 484 return ABI; 485 } 486 487 static bool hasIntegerMVE(const std::vector<StringRef> &F) { 488 auto MVE = llvm::find(llvm::reverse(F), "+mve"); 489 auto NoMVE = llvm::find(llvm::reverse(F), "-mve"); 490 return MVE != F.rend() && 491 (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0); 492 } 493 494 llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, 495 const llvm::Triple &Triple, 496 const ArgList &Args, 497 std::vector<StringRef> &Features, 498 bool ForAS, bool ForMultilib) { 499 bool KernelOrKext = 500 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); 501 arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args); 502 std::optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch; 503 504 // This vector will accumulate features from the architecture 505 // extension suffixes on -mcpu and -march (e.g. the 'bar' in 506 // -mcpu=foo+bar). We want to apply those after the features derived 507 // from the FPU, in case -mfpu generates a negative feature which 508 // the +bar is supposed to override. 509 std::vector<StringRef> ExtensionFeatures; 510 511 if (!ForAS) { 512 // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these 513 // yet (it uses the -mfloat-abi and -msoft-float options), and it is 514 // stripped out by the ARM target. We should probably pass this a new 515 // -target-option, which is handled by the -cc1/-cc1as invocation. 516 // 517 // FIXME2: For consistency, it would be ideal if we set up the target 518 // machine state the same when using the frontend or the assembler. We don't 519 // currently do that for the assembler, we pass the options directly to the 520 // backend and never even instantiate the frontend TargetInfo. If we did, 521 // and used its handleTargetFeatures hook, then we could ensure the 522 // assembler and the frontend behave the same. 523 524 // Use software floating point operations? 525 if (ABI == arm::FloatABI::Soft) 526 Features.push_back("+soft-float"); 527 528 // Use software floating point argument passing? 529 if (ABI != arm::FloatABI::Hard) 530 Features.push_back("+soft-float-abi"); 531 } else { 532 // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down 533 // to the assembler correctly. 534 for (const Arg *A : 535 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { 536 // We use getValues here because you can have many options per -Wa 537 // We will keep the last one we find for each of these 538 for (StringRef Value : A->getValues()) { 539 if (Value.starts_with("-mfpu=")) { 540 WaFPU = std::make_pair(A, Value.substr(6)); 541 } else if (Value.starts_with("-mcpu=")) { 542 WaCPU = std::make_pair(A, Value.substr(6)); 543 } else if (Value.starts_with("-mhwdiv=")) { 544 WaHDiv = std::make_pair(A, Value.substr(8)); 545 } else if (Value.starts_with("-march=")) { 546 WaArch = std::make_pair(A, Value.substr(7)); 547 } 548 } 549 } 550 551 // The integrated assembler doesn't implement e_flags setting behavior for 552 // -meabi=gnu (gcc -mabi={apcs-gnu,atpcs} passes -meabi=gnu to gas). For 553 // compatibility we accept but warn. 554 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ)) 555 A->ignoreTargetSpecific(); 556 } 557 558 if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURW) 559 Features.push_back("+read-tp-tpidrurw"); 560 if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURO) 561 Features.push_back("+read-tp-tpidruro"); 562 if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRPRW) 563 Features.push_back("+read-tp-tpidrprw"); 564 565 const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); 566 const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); 567 StringRef ArchName; 568 StringRef CPUName; 569 llvm::ARM::FPUKind ArchArgFPUKind = llvm::ARM::FK_INVALID; 570 llvm::ARM::FPUKind CPUArgFPUKind = llvm::ARM::FK_INVALID; 571 572 // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. 573 if (WaCPU) { 574 if (CPUArg) 575 D.Diag(clang::diag::warn_drv_unused_argument) 576 << CPUArg->getAsString(Args); 577 CPUName = WaCPU->second; 578 CPUArg = WaCPU->first; 579 } else if (CPUArg) 580 CPUName = CPUArg->getValue(); 581 582 // Check -march. ClangAs gives preference to -Wa,-march=. 583 if (WaArch) { 584 if (ArchArg) 585 D.Diag(clang::diag::warn_drv_unused_argument) 586 << ArchArg->getAsString(Args); 587 ArchName = WaArch->second; 588 // This will set any features after the base architecture. 589 checkARMArchName(D, WaArch->first, Args, ArchName, CPUName, 590 ExtensionFeatures, Triple, ArchArgFPUKind); 591 // The base architecture was handled in ToolChain::ComputeLLVMTriple because 592 // triple is read only by this point. 593 } else if (ArchArg) { 594 ArchName = ArchArg->getValue(); 595 checkARMArchName(D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures, 596 Triple, ArchArgFPUKind); 597 } 598 599 // Add CPU features for generic CPUs 600 if (CPUName == "native") { 601 for (auto &F : llvm::sys::getHostCPUFeatures()) 602 Features.push_back( 603 Args.MakeArgString((F.second ? "+" : "-") + F.first())); 604 } else if (!CPUName.empty()) { 605 // This sets the default features for the specified CPU. We certainly don't 606 // want to override the features that have been explicitly specified on the 607 // command line. Therefore, process them directly instead of appending them 608 // at the end later. 609 DecodeARMFeaturesFromCPU(D, CPUName, Features); 610 } 611 612 if (CPUArg) 613 checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures, 614 Triple, CPUArgFPUKind); 615 616 // TODO Handle -mtune=. Suppress -Wunused-command-line-argument as a 617 // longstanding behavior. 618 (void)Args.getLastArg(options::OPT_mtune_EQ); 619 620 // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=. 621 llvm::ARM::FPUKind FPUKind = llvm::ARM::FK_INVALID; 622 const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ); 623 if (WaFPU) { 624 if (FPUArg) 625 D.Diag(clang::diag::warn_drv_unused_argument) 626 << FPUArg->getAsString(Args); 627 (void)getARMFPUFeatures(D, WaFPU->first, Args, WaFPU->second, Features); 628 } else if (FPUArg) { 629 FPUKind = getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features); 630 } else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) { 631 const char *AndroidFPU = "neon"; 632 FPUKind = llvm::ARM::parseFPU(AndroidFPU); 633 if (!llvm::ARM::getFPUFeatures(FPUKind, Features)) 634 D.Diag(clang::diag::err_drv_clang_unsupported) 635 << std::string("-mfpu=") + AndroidFPU; 636 } else if (ArchArgFPUKind != llvm::ARM::FK_INVALID || 637 CPUArgFPUKind != llvm::ARM::FK_INVALID) { 638 FPUKind = 639 CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind; 640 (void)llvm::ARM::getFPUFeatures(FPUKind, Features); 641 } else { 642 if (!ForAS) { 643 std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); 644 llvm::ARM::ArchKind ArchKind = 645 arm::getLLVMArchKindForARM(CPU, ArchName, Triple); 646 FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind); 647 (void)llvm::ARM::getFPUFeatures(FPUKind, Features); 648 } 649 } 650 651 // Now we've finished accumulating features from arch, cpu and fpu, 652 // we can append the ones for architecture extensions that we 653 // collected separately. 654 Features.insert(std::end(Features), 655 std::begin(ExtensionFeatures), std::end(ExtensionFeatures)); 656 657 // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=. 658 const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ); 659 if (WaHDiv) { 660 if (HDivArg) 661 D.Diag(clang::diag::warn_drv_unused_argument) 662 << HDivArg->getAsString(Args); 663 getARMHWDivFeatures(D, WaHDiv->first, Args, WaHDiv->second, Features); 664 } else if (HDivArg) 665 getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features); 666 667 // Handle (arch-dependent) fp16fml/fullfp16 relationship. 668 // Must happen before any features are disabled due to soft-float. 669 // FIXME: this fp16fml option handling will be reimplemented after the 670 // TargetParser rewrite. 671 const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16"); 672 const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml"); 673 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) { 674 const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16"); 675 if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) { 676 // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml. 677 // Only append the +fp16fml if there is no -fp16fml after the +fullfp16. 678 if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16) 679 Features.push_back("+fp16fml"); 680 } 681 else 682 goto fp16_fml_fallthrough; 683 } 684 else { 685 fp16_fml_fallthrough: 686 // In both of these cases, putting the 'other' feature on the end of the vector will 687 // result in the same effect as placing it immediately after the current feature. 688 if (ItRNoFullFP16 < ItRFP16FML) 689 Features.push_back("-fp16fml"); 690 else if (ItRNoFullFP16 > ItRFP16FML) 691 Features.push_back("+fullfp16"); 692 } 693 694 // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to 695 // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in 696 // this case). Note that the ABI can also be set implicitly by the target 697 // selected. 698 bool HasFPRegs = true; 699 if (ABI == arm::FloatABI::Soft) { 700 llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features); 701 702 // Disable all features relating to hardware FP, not already disabled by the 703 // above call. 704 Features.insert(Features.end(), 705 {"-dotprod", "-fp16fml", "-bf16", "-mve", "-mve.fp"}); 706 HasFPRegs = false; 707 FPUKind = llvm::ARM::FK_NONE; 708 } else if (FPUKind == llvm::ARM::FK_NONE || 709 ArchArgFPUKind == llvm::ARM::FK_NONE || 710 CPUArgFPUKind == llvm::ARM::FK_NONE) { 711 // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to 712 // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the 713 // FPU, but not the FPU registers, thus MVE-I, which depends only on the 714 // latter, is still supported. 715 Features.insert(Features.end(), 716 {"-dotprod", "-fp16fml", "-bf16", "-mve.fp"}); 717 HasFPRegs = hasIntegerMVE(Features); 718 FPUKind = llvm::ARM::FK_NONE; 719 } 720 if (!HasFPRegs) 721 Features.emplace_back("-fpregs"); 722 723 // En/disable crc code generation. 724 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) { 725 if (A->getOption().matches(options::OPT_mcrc)) 726 Features.push_back("+crc"); 727 else 728 Features.push_back("-crc"); 729 } 730 731 // For Arch >= ARMv8.0 && A or R profile: crypto = sha2 + aes 732 // Rather than replace within the feature vector, determine whether each 733 // algorithm is enabled and append this to the end of the vector. 734 // The algorithms can be controlled by their specific feature or the crypto 735 // feature, so their status can be determined by the last occurance of 736 // either in the vector. This allows one to supercede the other. 737 // e.g. +crypto+noaes in -march/-mcpu should enable sha2, but not aes 738 // FIXME: this needs reimplementation after the TargetParser rewrite 739 bool HasSHA2 = false; 740 bool HasAES = false; 741 const auto ItCrypto = 742 llvm::find_if(llvm::reverse(Features), [](const StringRef F) { 743 return F.contains("crypto"); 744 }); 745 const auto ItSHA2 = 746 llvm::find_if(llvm::reverse(Features), [](const StringRef F) { 747 return F.contains("crypto") || F.contains("sha2"); 748 }); 749 const auto ItAES = 750 llvm::find_if(llvm::reverse(Features), [](const StringRef F) { 751 return F.contains("crypto") || F.contains("aes"); 752 }); 753 const bool FoundSHA2 = ItSHA2 != Features.rend(); 754 const bool FoundAES = ItAES != Features.rend(); 755 if (FoundSHA2) 756 HasSHA2 = ItSHA2->take_front() == "+"; 757 if (FoundAES) 758 HasAES = ItAES->take_front() == "+"; 759 if (ItCrypto != Features.rend()) { 760 if (HasSHA2 && HasAES) 761 Features.push_back("+crypto"); 762 else 763 Features.push_back("-crypto"); 764 if (HasSHA2) 765 Features.push_back("+sha2"); 766 else 767 Features.push_back("-sha2"); 768 if (HasAES) 769 Features.push_back("+aes"); 770 else 771 Features.push_back("-aes"); 772 } 773 774 if (HasSHA2 || HasAES) { 775 StringRef ArchSuffix = arm::getLLVMArchSuffixForARM( 776 arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple); 777 llvm::ARM::ProfileKind ArchProfile = 778 llvm::ARM::parseArchProfile(ArchSuffix); 779 if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) && 780 (ArchProfile == llvm::ARM::ProfileKind::A || 781 ArchProfile == llvm::ARM::ProfileKind::R))) { 782 if (HasSHA2) 783 D.Diag(clang::diag::warn_target_unsupported_extension) 784 << "sha2" 785 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix)); 786 if (HasAES) 787 D.Diag(clang::diag::warn_target_unsupported_extension) 788 << "aes" 789 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix)); 790 // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such 791 // as the GNU assembler will permit the use of crypto instructions as the 792 // fpu will override the architecture. We keep the crypto feature in this 793 // case to preserve compatibility. In all other cases we remove the crypto 794 // feature. 795 if (!Args.hasArg(options::OPT_fno_integrated_as)) { 796 Features.push_back("-sha2"); 797 Features.push_back("-aes"); 798 } 799 } 800 } 801 802 // Propagate frame-chain model selection 803 if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) { 804 StringRef FrameChainOption = A->getValue(); 805 if (FrameChainOption.starts_with("aapcs")) 806 Features.push_back("+aapcs-frame-chain"); 807 } 808 809 // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later. 810 if (Args.getLastArg(options::OPT_mcmse)) 811 Features.push_back("+8msecext"); 812 813 if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465, 814 options::OPT_mno_fix_cmse_cve_2021_35465)) { 815 if (!Args.getLastArg(options::OPT_mcmse)) 816 D.Diag(diag::err_opt_not_valid_without_opt) 817 << A->getOption().getName() << "-mcmse"; 818 819 if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465)) 820 Features.push_back("+fix-cmse-cve-2021-35465"); 821 else 822 Features.push_back("-fix-cmse-cve-2021-35465"); 823 } 824 825 // This also handles the -m(no-)fix-cortex-a72-1655431 arguments via aliases. 826 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098, 827 options::OPT_mno_fix_cortex_a57_aes_1742098)) { 828 if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) { 829 Features.push_back("+fix-cortex-a57-aes-1742098"); 830 } else { 831 Features.push_back("-fix-cortex-a57-aes-1742098"); 832 } 833 } 834 835 // Look for the last occurrence of -mlong-calls or -mno-long-calls. If 836 // neither options are specified, see if we are compiling for kernel/kext and 837 // decide whether to pass "+long-calls" based on the OS and its version. 838 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, 839 options::OPT_mno_long_calls)) { 840 if (A->getOption().matches(options::OPT_mlong_calls)) 841 Features.push_back("+long-calls"); 842 } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) && 843 !Triple.isWatchOS() && !Triple.isXROS()) { 844 Features.push_back("+long-calls"); 845 } 846 847 // Generate execute-only output (no data access to code sections). 848 // This only makes sense for the compiler, not for the assembler. 849 // It's not needed for multilib selection and may hide an unused 850 // argument diagnostic if the code is always run. 851 if (!ForAS && !ForMultilib) { 852 // Supported only on ARMv6T2 and ARMv7 and above. 853 // Cannot be combined with -mno-movt. 854 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) { 855 if (A->getOption().matches(options::OPT_mexecute_only)) { 856 if (getARMSubArchVersionNumber(Triple) < 7 && 857 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 && 858 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M) 859 D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName(); 860 else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) { 861 if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi, 862 options::OPT_fpic, options::OPT_fpie, 863 options::OPT_fPIC, options::OPT_fPIE)) 864 D.Diag(diag::err_opt_not_valid_with_opt_on_target) 865 << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName(); 866 } else if (Arg *B = Args.getLastArg(options::OPT_mno_movt)) 867 D.Diag(diag::err_opt_not_valid_with_opt) 868 << A->getAsString(Args) << B->getAsString(Args); 869 Features.push_back("+execute-only"); 870 } 871 } 872 } 873 874 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, 875 options::OPT_munaligned_access, 876 options::OPT_mstrict_align, 877 options::OPT_mno_strict_align)) { 878 // Kernel code has more strict alignment requirements. 879 if (KernelOrKext || 880 A->getOption().matches(options::OPT_mno_unaligned_access) || 881 A->getOption().matches(options::OPT_mstrict_align)) { 882 Features.push_back("+strict-align"); 883 } else { 884 // No v6M core supports unaligned memory access (v6M ARM ARM A3.2). 885 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) 886 D.Diag(diag::err_target_unsupported_unaligned) << "v6m"; 887 // v8M Baseline follows on from v6M, so doesn't support unaligned memory 888 // access either. 889 else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) 890 D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base"; 891 } 892 } else { 893 // Assume pre-ARMv6 doesn't support unaligned accesses. 894 // 895 // ARMv6 may or may not support unaligned accesses depending on the 896 // SCTLR.U bit, which is architecture-specific. We assume ARMv6 897 // Darwin and NetBSD targets support unaligned accesses, and others don't. 898 // 899 // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit which 900 // raises an alignment fault on unaligned accesses. Assume ARMv7+ supports 901 // unaligned accesses, except ARMv6-M, and ARMv8-M without the Main 902 // Extension. This aligns with the default behavior of ARM's downstream 903 // versions of GCC and Clang. 904 // 905 // Users can change the default behavior via -m[no-]unaliged-access. 906 int VersionNum = getARMSubArchVersionNumber(Triple); 907 if (Triple.isOSDarwin() || Triple.isOSNetBSD()) { 908 if (VersionNum < 6 || 909 Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) 910 Features.push_back("+strict-align"); 911 } else if (VersionNum < 7 || 912 Triple.getSubArch() == 913 llvm::Triple::SubArchType::ARMSubArch_v6m || 914 Triple.getSubArch() == 915 llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) { 916 Features.push_back("+strict-align"); 917 } 918 } 919 920 // llvm does not support reserving registers in general. There is support 921 // for reserving r9 on ARM though (defined as a platform-specific register 922 // in ARM EABI). 923 if (Args.hasArg(options::OPT_ffixed_r9)) 924 Features.push_back("+reserve-r9"); 925 926 // The kext linker doesn't know how to deal with movw/movt. 927 if (KernelOrKext || Args.hasArg(options::OPT_mno_movt)) 928 Features.push_back("+no-movt"); 929 930 if (Args.hasArg(options::OPT_mno_neg_immediates)) 931 Features.push_back("+no-neg-immediates"); 932 933 // Enable/disable straight line speculation hardening. 934 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) { 935 StringRef Scope = A->getValue(); 936 bool EnableRetBr = false; 937 bool EnableBlr = false; 938 bool DisableComdat = false; 939 if (Scope != "none") { 940 SmallVector<StringRef, 4> Opts; 941 Scope.split(Opts, ","); 942 for (auto Opt : Opts) { 943 Opt = Opt.trim(); 944 if (Opt == "all") { 945 EnableBlr = true; 946 EnableRetBr = true; 947 continue; 948 } 949 if (Opt == "retbr") { 950 EnableRetBr = true; 951 continue; 952 } 953 if (Opt == "blr") { 954 EnableBlr = true; 955 continue; 956 } 957 if (Opt == "comdat") { 958 DisableComdat = false; 959 continue; 960 } 961 if (Opt == "nocomdat") { 962 DisableComdat = true; 963 continue; 964 } 965 D.Diag(diag::err_drv_unsupported_option_argument) 966 << A->getSpelling() << Scope; 967 break; 968 } 969 } 970 971 if (EnableRetBr || EnableBlr) 972 if (!(isARMAProfile(Triple) && getARMSubArchVersionNumber(Triple) >= 7)) 973 D.Diag(diag::err_sls_hardening_arm_not_supported) 974 << Scope << A->getAsString(Args); 975 976 if (EnableRetBr) 977 Features.push_back("+harden-sls-retbr"); 978 if (EnableBlr) 979 Features.push_back("+harden-sls-blr"); 980 if (DisableComdat) { 981 Features.push_back("+harden-sls-nocomdat"); 982 } 983 } 984 985 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice)) 986 Features.push_back("+no-bti-at-return-twice"); 987 988 checkARMFloatABI(D, Args, HasFPRegs); 989 990 return FPUKind; 991 } 992 993 std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) { 994 std::string MArch; 995 if (!Arch.empty()) 996 MArch = std::string(Arch); 997 else 998 MArch = std::string(Triple.getArchName()); 999 MArch = StringRef(MArch).split("+").first.lower(); 1000 1001 // Handle -march=native. 1002 if (MArch == "native") { 1003 std::string CPU = std::string(llvm::sys::getHostCPUName()); 1004 if (CPU != "generic") { 1005 // Translate the native cpu into the architecture suffix for that CPU. 1006 StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); 1007 // If there is no valid architecture suffix for this CPU we don't know how 1008 // to handle it, so return no architecture. 1009 if (Suffix.empty()) 1010 MArch = ""; 1011 else 1012 MArch = std::string("arm") + Suffix.str(); 1013 } 1014 } 1015 1016 return MArch; 1017 } 1018 1019 /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. 1020 StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) { 1021 std::string MArch = getARMArch(Arch, Triple); 1022 // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch 1023 // here means an -march=native that we can't handle, so instead return no CPU. 1024 if (MArch.empty()) 1025 return StringRef(); 1026 1027 // We need to return an empty string here on invalid MArch values as the 1028 // various places that call this function can't cope with a null result. 1029 return llvm::ARM::getARMCPUForArch(Triple, MArch); 1030 } 1031 1032 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. 1033 std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch, 1034 const llvm::Triple &Triple) { 1035 // FIXME: Warn on inconsistent use of -mcpu and -march. 1036 // If we have -mcpu=, use that. 1037 if (!CPU.empty()) { 1038 std::string MCPU = StringRef(CPU).split("+").first.lower(); 1039 // Handle -mcpu=native. 1040 if (MCPU == "native") 1041 return std::string(llvm::sys::getHostCPUName()); 1042 else 1043 return MCPU; 1044 } 1045 1046 return std::string(getARMCPUForMArch(Arch, Triple)); 1047 } 1048 1049 /// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a 1050 /// particular CPU (or Arch, if CPU is generic). This is needed to 1051 /// pass to functions like llvm::ARM::getDefaultFPU which need an 1052 /// ArchKind as well as a CPU name. 1053 llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch, 1054 const llvm::Triple &Triple) { 1055 llvm::ARM::ArchKind ArchKind; 1056 if (CPU == "generic" || CPU.empty()) { 1057 std::string ARMArch = tools::arm::getARMArch(Arch, Triple); 1058 ArchKind = llvm::ARM::parseArch(ARMArch); 1059 if (ArchKind == llvm::ARM::ArchKind::INVALID) 1060 // In case of generic Arch, i.e. "arm", 1061 // extract arch from default cpu of the Triple 1062 ArchKind = 1063 llvm::ARM::parseCPUArch(llvm::ARM::getARMCPUForArch(Triple, ARMArch)); 1064 } else { 1065 // FIXME: horrible hack to get around the fact that Cortex-A7 is only an 1066 // armv7k triple if it's actually been specified via "-arch armv7k". 1067 ArchKind = (Arch == "armv7k" || Arch == "thumbv7k") 1068 ? llvm::ARM::ArchKind::ARMV7K 1069 : llvm::ARM::parseCPUArch(CPU); 1070 } 1071 return ArchKind; 1072 } 1073 1074 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 1075 /// CPU (or Arch, if CPU is generic). 1076 // FIXME: This is redundant with -mcpu, why does LLVM use this. 1077 StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, 1078 const llvm::Triple &Triple) { 1079 llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple); 1080 if (ArchKind == llvm::ARM::ArchKind::INVALID) 1081 return ""; 1082 return llvm::ARM::getSubArch(ArchKind); 1083 } 1084 1085 void arm::appendBE8LinkFlag(const ArgList &Args, ArgStringList &CmdArgs, 1086 const llvm::Triple &Triple) { 1087 if (Args.hasArg(options::OPT_r)) 1088 return; 1089 1090 // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker 1091 // to generate BE-8 executables. 1092 if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple)) 1093 CmdArgs.push_back("--be8"); 1094 } 1095