1 //===--- ARM.cpp - Implement ARM target feature support -------------------===// 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 // This file implements ARM TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARM.h" 14 #include "clang/Basic/Builtins.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/TargetBuiltins.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/StringSwitch.h" 20 21 using namespace clang; 22 using namespace clang::targets; 23 24 void ARMTargetInfo::setABIAAPCS() { 25 IsAAPCS = true; 26 27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 28 const llvm::Triple &T = getTriple(); 29 30 bool IsNetBSD = T.isOSNetBSD(); 31 bool IsOpenBSD = T.isOSOpenBSD(); 32 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD) 33 WCharType = UnsignedInt; 34 35 UseBitFieldTypeAlignment = true; 36 37 ZeroLengthBitfieldBoundary = 0; 38 39 // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 40 // so set preferred for small types to 32. 41 if (T.isOSBinFormatMachO()) { 42 resetDataLayout(BigEndian 43 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 44 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 45 } else if (T.isOSWindows()) { 46 assert(!BigEndian && "Windows on ARM does not support big endian"); 47 resetDataLayout("e" 48 "-m:w" 49 "-p:32:32" 50 "-Fi8" 51 "-i64:64" 52 "-v128:64:128" 53 "-a:0:32" 54 "-n32" 55 "-S64"); 56 } else if (T.isOSNaCl()) { 57 assert(!BigEndian && "NaCl on ARM does not support big endian"); 58 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"); 59 } else { 60 resetDataLayout(BigEndian 61 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 62 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 63 } 64 65 // FIXME: Enumerated types are variable width in straight AAPCS. 66 } 67 68 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { 69 const llvm::Triple &T = getTriple(); 70 71 IsAAPCS = false; 72 73 if (IsAAPCS16) 74 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 75 else 76 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; 77 78 WCharType = SignedInt; 79 80 // Do not respect the alignment of bit-field types when laying out 81 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. 82 UseBitFieldTypeAlignment = false; 83 84 /// gcc forces the alignment to 4 bytes, regardless of the type of the 85 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in 86 /// gcc. 87 ZeroLengthBitfieldBoundary = 32; 88 89 if (T.isOSBinFormatMachO() && IsAAPCS16) { 90 assert(!BigEndian && "AAPCS16 does not support big-endian"); 91 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"); 92 } else if (T.isOSBinFormatMachO()) 93 resetDataLayout( 94 BigEndian 95 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 96 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); 97 else 98 resetDataLayout( 99 BigEndian 100 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 101 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); 102 103 // FIXME: Override "preferred align" for double and long long. 104 } 105 106 void ARMTargetInfo::setArchInfo() { 107 StringRef ArchName = getTriple().getArchName(); 108 109 ArchISA = llvm::ARM::parseArchISA(ArchName); 110 CPU = std::string(llvm::ARM::getDefaultCPU(ArchName)); 111 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName); 112 if (AK != llvm::ARM::ArchKind::INVALID) 113 ArchKind = AK; 114 setArchInfo(ArchKind); 115 } 116 117 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) { 118 StringRef SubArch; 119 120 // cache TargetParser info 121 ArchKind = Kind; 122 SubArch = llvm::ARM::getSubArch(ArchKind); 123 ArchProfile = llvm::ARM::parseArchProfile(SubArch); 124 ArchVersion = llvm::ARM::parseArchVersion(SubArch); 125 126 // cache CPU related strings 127 CPUAttr = getCPUAttr(); 128 CPUProfile = getCPUProfile(); 129 } 130 131 void ARMTargetInfo::setAtomic() { 132 // when triple does not specify a sub arch, 133 // then we are not using inline atomics 134 bool ShouldUseInlineAtomic = 135 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) || 136 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7); 137 // Cortex M does not support 8 byte atomics, while general Thumb2 does. 138 if (ArchProfile == llvm::ARM::ProfileKind::M) { 139 MaxAtomicPromoteWidth = 32; 140 if (ShouldUseInlineAtomic) 141 MaxAtomicInlineWidth = 32; 142 } else { 143 MaxAtomicPromoteWidth = 64; 144 if (ShouldUseInlineAtomic) 145 MaxAtomicInlineWidth = 64; 146 } 147 } 148 149 bool ARMTargetInfo::hasMVE() const { 150 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0; 151 } 152 153 bool ARMTargetInfo::hasMVEFloat() const { 154 return hasMVE() && (MVE & MVE_FP); 155 } 156 157 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; } 158 159 bool ARMTargetInfo::isThumb() const { 160 return ArchISA == llvm::ARM::ISAKind::THUMB; 161 } 162 163 bool ARMTargetInfo::supportsThumb() const { 164 return CPUAttr.count('T') || ArchVersion >= 6; 165 } 166 167 bool ARMTargetInfo::supportsThumb2() const { 168 return CPUAttr.equals("6T2") || 169 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE")); 170 } 171 172 StringRef ARMTargetInfo::getCPUAttr() const { 173 // For most sub-arches, the build attribute CPU name is enough. 174 // For Cortex variants, it's slightly different. 175 switch (ArchKind) { 176 default: 177 return llvm::ARM::getCPUAttr(ArchKind); 178 case llvm::ARM::ArchKind::ARMV6M: 179 return "6M"; 180 case llvm::ARM::ArchKind::ARMV7S: 181 return "7S"; 182 case llvm::ARM::ArchKind::ARMV7A: 183 return "7A"; 184 case llvm::ARM::ArchKind::ARMV7R: 185 return "7R"; 186 case llvm::ARM::ArchKind::ARMV7M: 187 return "7M"; 188 case llvm::ARM::ArchKind::ARMV7EM: 189 return "7EM"; 190 case llvm::ARM::ArchKind::ARMV7VE: 191 return "7VE"; 192 case llvm::ARM::ArchKind::ARMV8A: 193 return "8A"; 194 case llvm::ARM::ArchKind::ARMV8_1A: 195 return "8_1A"; 196 case llvm::ARM::ArchKind::ARMV8_2A: 197 return "8_2A"; 198 case llvm::ARM::ArchKind::ARMV8_3A: 199 return "8_3A"; 200 case llvm::ARM::ArchKind::ARMV8_4A: 201 return "8_4A"; 202 case llvm::ARM::ArchKind::ARMV8_5A: 203 return "8_5A"; 204 case llvm::ARM::ArchKind::ARMV8_6A: 205 return "8_6A"; 206 case llvm::ARM::ArchKind::ARMV8MBaseline: 207 return "8M_BASE"; 208 case llvm::ARM::ArchKind::ARMV8MMainline: 209 return "8M_MAIN"; 210 case llvm::ARM::ArchKind::ARMV8R: 211 return "8R"; 212 case llvm::ARM::ArchKind::ARMV8_1MMainline: 213 return "8_1M_MAIN"; 214 } 215 } 216 217 StringRef ARMTargetInfo::getCPUProfile() const { 218 switch (ArchProfile) { 219 case llvm::ARM::ProfileKind::A: 220 return "A"; 221 case llvm::ARM::ProfileKind::R: 222 return "R"; 223 case llvm::ARM::ProfileKind::M: 224 return "M"; 225 default: 226 return ""; 227 } 228 } 229 230 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, 231 const TargetOptions &Opts) 232 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), 233 HW_FP(0) { 234 bool IsOpenBSD = Triple.isOSOpenBSD(); 235 bool IsNetBSD = Triple.isOSNetBSD(); 236 237 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like 238 // environment where size_t is `unsigned long` rather than `unsigned int` 239 240 PtrDiffType = IntPtrType = 241 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 242 IsNetBSD) 243 ? SignedLong 244 : SignedInt; 245 246 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 247 IsNetBSD) 248 ? UnsignedLong 249 : UnsignedInt; 250 251 // ptrdiff_t is inconsistent on Darwin 252 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) && 253 !Triple.isWatchABI()) 254 PtrDiffType = SignedInt; 255 256 // Cache arch related info. 257 setArchInfo(); 258 259 // {} in inline assembly are neon specifiers, not assembly variant 260 // specifiers. 261 NoAsmVariants = true; 262 263 // FIXME: This duplicates code from the driver that sets the -target-abi 264 // option - this code is used if -target-abi isn't passed and should 265 // be unified in some way. 266 if (Triple.isOSBinFormatMachO()) { 267 // The backend is hardwired to assume AAPCS for M-class processors, ensure 268 // the frontend matches that. 269 if (Triple.getEnvironment() == llvm::Triple::EABI || 270 Triple.getOS() == llvm::Triple::UnknownOS || 271 ArchProfile == llvm::ARM::ProfileKind::M) { 272 setABI("aapcs"); 273 } else if (Triple.isWatchABI()) { 274 setABI("aapcs16"); 275 } else { 276 setABI("apcs-gnu"); 277 } 278 } else if (Triple.isOSWindows()) { 279 // FIXME: this is invalid for WindowsCE 280 setABI("aapcs"); 281 } else { 282 // Select the default based on the platform. 283 switch (Triple.getEnvironment()) { 284 case llvm::Triple::Android: 285 case llvm::Triple::GNUEABI: 286 case llvm::Triple::GNUEABIHF: 287 case llvm::Triple::MuslEABI: 288 case llvm::Triple::MuslEABIHF: 289 setABI("aapcs-linux"); 290 break; 291 case llvm::Triple::EABIHF: 292 case llvm::Triple::EABI: 293 setABI("aapcs"); 294 break; 295 case llvm::Triple::GNU: 296 setABI("apcs-gnu"); 297 break; 298 default: 299 if (IsNetBSD) 300 setABI("apcs-gnu"); 301 else if (IsOpenBSD) 302 setABI("aapcs-linux"); 303 else 304 setABI("aapcs"); 305 break; 306 } 307 } 308 309 // ARM targets default to using the ARM C++ ABI. 310 TheCXXABI.set(TargetCXXABI::GenericARM); 311 312 // ARM has atomics up to 8 bytes 313 setAtomic(); 314 315 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) 316 // as well the default alignment 317 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android)) 318 DefaultAlignForAttributeAligned = MaxVectorAlign = 64; 319 320 // Do force alignment of members that follow zero length bitfields. If 321 // the alignment of the zero-length bitfield is greater than the member 322 // that follows it, `bar', `bar' will be aligned as the type of the 323 // zero length bitfield. 324 UseZeroLengthBitfieldAlignment = true; 325 326 if (Triple.getOS() == llvm::Triple::Linux || 327 Triple.getOS() == llvm::Triple::UnknownOS) 328 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU 329 ? "llvm.arm.gnu.eabi.mcount" 330 : "\01mcount"; 331 332 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi"); 333 } 334 335 StringRef ARMTargetInfo::getABI() const { return ABI; } 336 337 bool ARMTargetInfo::setABI(const std::string &Name) { 338 ABI = Name; 339 340 // The defaults (above) are for AAPCS, check if we need to change them. 341 // 342 // FIXME: We need support for -meabi... we could just mangle it into the 343 // name. 344 if (Name == "apcs-gnu" || Name == "aapcs16") { 345 setABIAPCS(Name == "aapcs16"); 346 return true; 347 } 348 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") { 349 setABIAAPCS(); 350 return true; 351 } 352 return false; 353 } 354 355 // FIXME: This should be based on Arch attributes, not CPU names. 356 bool ARMTargetInfo::initFeatureMap( 357 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 358 const std::vector<std::string> &FeaturesVec) const { 359 360 std::string ArchFeature; 361 std::vector<StringRef> TargetFeatures; 362 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName()); 363 364 // Map the base architecture to an appropriate target feature, so we don't 365 // rely on the target triple. 366 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU); 367 if (CPUArch == llvm::ARM::ArchKind::INVALID) 368 CPUArch = Arch; 369 if (CPUArch != llvm::ARM::ArchKind::INVALID) { 370 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str(); 371 TargetFeatures.push_back(ArchFeature); 372 } 373 374 // get default FPU features 375 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); 376 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); 377 378 // get default Extension features 379 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); 380 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); 381 382 for (auto Feature : TargetFeatures) 383 if (Feature[0] == '+') 384 Features[Feature.drop_front(1)] = true; 385 386 // Enable or disable thumb-mode explicitly per function to enable mixed 387 // ARM and Thumb code generation. 388 if (isThumb()) 389 Features["thumb-mode"] = true; 390 else 391 Features["thumb-mode"] = false; 392 393 // Convert user-provided arm and thumb GNU target attributes to 394 // [-|+]thumb-mode target features respectively. 395 std::vector<std::string> UpdatedFeaturesVec; 396 for (const auto &Feature : FeaturesVec) { 397 // Skip soft-float-abi; it's something we only use to initialize a bit of 398 // class state, and is otherwise unrecognized. 399 if (Feature == "+soft-float-abi") 400 continue; 401 402 StringRef FixedFeature; 403 if (Feature == "+arm") 404 FixedFeature = "-thumb-mode"; 405 else if (Feature == "+thumb") 406 FixedFeature = "+thumb-mode"; 407 else 408 FixedFeature = Feature; 409 UpdatedFeaturesVec.push_back(FixedFeature.str()); 410 } 411 412 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); 413 } 414 415 416 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 417 DiagnosticsEngine &Diags) { 418 FPU = 0; 419 MVE = 0; 420 CRC = 0; 421 Crypto = 0; 422 DSP = 0; 423 Unaligned = 1; 424 SoftFloat = false; 425 // Note that SoftFloatABI is initialized in our constructor. 426 HWDiv = 0; 427 DotProd = 0; 428 HasMatMul = 0; 429 HasFloat16 = true; 430 ARMCDECoprocMask = 0; 431 432 // This does not diagnose illegal cases like having both 433 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". 434 for (const auto &Feature : Features) { 435 if (Feature == "+soft-float") { 436 SoftFloat = true; 437 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") { 438 FPU |= VFP2FPU; 439 HW_FP |= HW_FP_SP; 440 if (Feature == "+vfp2") 441 HW_FP |= HW_FP_DP; 442 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" || 443 Feature == "+vfp3" || Feature == "+vfp3d16") { 444 FPU |= VFP3FPU; 445 HW_FP |= HW_FP_SP; 446 if (Feature == "+vfp3" || Feature == "+vfp3d16") 447 HW_FP |= HW_FP_DP; 448 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" || 449 Feature == "+vfp4" || Feature == "+vfp4d16") { 450 FPU |= VFP4FPU; 451 HW_FP |= HW_FP_SP | HW_FP_HP; 452 if (Feature == "+vfp4" || Feature == "+vfp4d16") 453 HW_FP |= HW_FP_DP; 454 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" || 455 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") { 456 FPU |= FPARMV8; 457 HW_FP |= HW_FP_SP | HW_FP_HP; 458 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16") 459 HW_FP |= HW_FP_DP; 460 } else if (Feature == "+neon") { 461 FPU |= NeonFPU; 462 HW_FP |= HW_FP_SP; 463 } else if (Feature == "+hwdiv") { 464 HWDiv |= HWDivThumb; 465 } else if (Feature == "+hwdiv-arm") { 466 HWDiv |= HWDivARM; 467 } else if (Feature == "+crc") { 468 CRC = 1; 469 } else if (Feature == "+crypto") { 470 Crypto = 1; 471 } else if (Feature == "+dsp") { 472 DSP = 1; 473 } else if (Feature == "+fp64") { 474 HW_FP |= HW_FP_DP; 475 } else if (Feature == "+8msecext") { 476 if (CPUProfile != "M" || ArchVersion != 8) { 477 Diags.Report(diag::err_target_unsupported_mcmse) << CPU; 478 return false; 479 } 480 } else if (Feature == "+strict-align") { 481 Unaligned = 0; 482 } else if (Feature == "+fp16") { 483 HW_FP |= HW_FP_HP; 484 } else if (Feature == "+fullfp16") { 485 HasLegalHalfType = true; 486 } else if (Feature == "+dotprod") { 487 DotProd = true; 488 } else if (Feature == "+mve") { 489 MVE |= MVE_INT; 490 } else if (Feature == "+mve.fp") { 491 HasLegalHalfType = true; 492 FPU |= FPARMV8; 493 MVE |= MVE_INT | MVE_FP; 494 HW_FP |= HW_FP_SP | HW_FP_HP; 495 } else if (Feature == "+i8mm") { 496 HasMatMul = 1; 497 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" && 498 Feature <= "+cdecp7") { 499 unsigned Coproc = Feature.back() - '0'; 500 ARMCDECoprocMask |= (1U << Coproc); 501 } 502 } 503 504 switch (ArchVersion) { 505 case 6: 506 if (ArchProfile == llvm::ARM::ProfileKind::M) 507 LDREX = 0; 508 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K) 509 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 510 else 511 LDREX = LDREX_W; 512 break; 513 case 7: 514 if (ArchProfile == llvm::ARM::ProfileKind::M) 515 LDREX = LDREX_W | LDREX_H | LDREX_B; 516 else 517 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 518 break; 519 case 8: 520 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 521 } 522 523 if (!(FPU & NeonFPU) && FPMath == FP_Neon) { 524 Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; 525 return false; 526 } 527 528 if (FPMath == FP_Neon) 529 Features.push_back("+neonfp"); 530 else if (FPMath == FP_VFP) 531 Features.push_back("-neonfp"); 532 533 return true; 534 } 535 536 bool ARMTargetInfo::hasFeature(StringRef Feature) const { 537 return llvm::StringSwitch<bool>(Feature) 538 .Case("arm", true) 539 .Case("aarch32", true) 540 .Case("softfloat", SoftFloat) 541 .Case("thumb", isThumb()) 542 .Case("neon", (FPU & NeonFPU) && !SoftFloat) 543 .Case("vfp", FPU && !SoftFloat) 544 .Case("hwdiv", HWDiv & HWDivThumb) 545 .Case("hwdiv-arm", HWDiv & HWDivARM) 546 .Case("mve", hasMVE()) 547 .Default(false); 548 } 549 550 bool ARMTargetInfo::isValidCPUName(StringRef Name) const { 551 return Name == "generic" || 552 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; 553 } 554 555 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 556 llvm::ARM::fillValidCPUArchList(Values); 557 } 558 559 bool ARMTargetInfo::setCPU(const std::string &Name) { 560 if (Name != "generic") 561 setArchInfo(llvm::ARM::parseCPUArch(Name)); 562 563 if (ArchKind == llvm::ARM::ArchKind::INVALID) 564 return false; 565 setAtomic(); 566 CPU = Name; 567 return true; 568 } 569 570 bool ARMTargetInfo::setFPMath(StringRef Name) { 571 if (Name == "neon") { 572 FPMath = FP_Neon; 573 return true; 574 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" || 575 Name == "vfp4") { 576 FPMath = FP_VFP; 577 return true; 578 } 579 return false; 580 } 581 582 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 583 MacroBuilder &Builder) const { 584 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 585 } 586 587 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 588 MacroBuilder &Builder) const { 589 // Also include the ARMv8.1-A defines 590 getTargetDefinesARMV81A(Opts, Builder); 591 } 592 593 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 594 MacroBuilder &Builder) const { 595 // Also include the ARMv8.2-A defines 596 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 597 getTargetDefinesARMV82A(Opts, Builder); 598 } 599 600 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, 601 MacroBuilder &Builder) const { 602 // Target identification. 603 Builder.defineMacro("__arm"); 604 Builder.defineMacro("__arm__"); 605 // For bare-metal none-eabi. 606 if (getTriple().getOS() == llvm::Triple::UnknownOS && 607 (getTriple().getEnvironment() == llvm::Triple::EABI || 608 getTriple().getEnvironment() == llvm::Triple::EABIHF)) 609 Builder.defineMacro("__ELF__"); 610 611 // Target properties. 612 Builder.defineMacro("__REGISTER_PREFIX__", ""); 613 614 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU 615 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__. 616 if (getTriple().isWatchABI()) 617 Builder.defineMacro("__ARM_ARCH_7K__", "2"); 618 619 if (!CPUAttr.empty()) 620 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); 621 622 // ACLE 6.4.1 ARM/Thumb instruction set architecture 623 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA 624 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); 625 626 if (ArchVersion >= 8) { 627 // ACLE 6.5.7 Crypto Extension 628 if (Crypto) 629 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 630 // ACLE 6.5.8 CRC32 Extension 631 if (CRC) 632 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 633 // ACLE 6.5.10 Numeric Maximum and Minimum 634 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 635 // ACLE 6.5.9 Directed Rounding 636 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 637 } 638 639 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It 640 // is not defined for the M-profile. 641 // NOTE that the default profile is assumed to be 'A' 642 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M) 643 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1"); 644 645 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original 646 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the 647 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all 648 // v7 and v8 architectures excluding v8-M Baseline. 649 if (supportsThumb2()) 650 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); 651 else if (supportsThumb()) 652 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1"); 653 654 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit 655 // instruction set such as ARM or Thumb. 656 Builder.defineMacro("__ARM_32BIT_STATE", "1"); 657 658 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex) 659 660 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset. 661 if (!CPUProfile.empty()) 662 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'"); 663 664 // ACLE 6.4.3 Unaligned access supported in hardware 665 if (Unaligned) 666 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 667 668 // ACLE 6.4.4 LDREX/STREX 669 if (LDREX) 670 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX)); 671 672 // ACLE 6.4.5 CLZ 673 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") || 674 ArchVersion > 6) 675 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 676 677 // ACLE 6.5.1 Hardware Floating Point 678 if (HW_FP) 679 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP)); 680 681 // ACLE predefines. 682 Builder.defineMacro("__ARM_ACLE", "200"); 683 684 // FP16 support (we currently only support IEEE format). 685 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 686 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 687 688 // ACLE 6.5.3 Fused multiply-accumulate (FMA) 689 if (ArchVersion >= 7 && (FPU & VFP4FPU)) 690 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 691 692 // Subtarget options. 693 694 // FIXME: It's more complicated than this and we don't really support 695 // interworking. 696 // Windows on ARM does not "support" interworking 697 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows()) 698 Builder.defineMacro("__THUMB_INTERWORK__"); 699 700 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { 701 // Embedded targets on Darwin follow AAPCS, but not EABI. 702 // Windows on ARM follows AAPCS VFP, but does not conform to EABI. 703 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows()) 704 Builder.defineMacro("__ARM_EABI__"); 705 Builder.defineMacro("__ARM_PCS", "1"); 706 } 707 708 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16") 709 Builder.defineMacro("__ARM_PCS_VFP", "1"); 710 711 if (SoftFloat) 712 Builder.defineMacro("__SOFTFP__"); 713 714 // ACLE position independent code macros. 715 if (Opts.ROPI) 716 Builder.defineMacro("__ARM_ROPI", "1"); 717 if (Opts.RWPI) 718 Builder.defineMacro("__ARM_RWPI", "1"); 719 720 if (ArchKind == llvm::ARM::ArchKind::XSCALE) 721 Builder.defineMacro("__XSCALE__"); 722 723 if (isThumb()) { 724 Builder.defineMacro("__THUMBEL__"); 725 Builder.defineMacro("__thumb__"); 726 if (supportsThumb2()) 727 Builder.defineMacro("__thumb2__"); 728 } 729 730 // ACLE 6.4.9 32-bit SIMD instructions 731 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP)) 732 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1"); 733 734 // ACLE 6.4.10 Hardware Integer Divide 735 if (((HWDiv & HWDivThumb) && isThumb()) || 736 ((HWDiv & HWDivARM) && !isThumb())) { 737 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); 738 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1"); 739 } 740 741 // Note, this is always on in gcc, even though it doesn't make sense. 742 Builder.defineMacro("__APCS_32__"); 743 744 if (FPUModeIsVFP((FPUMode)FPU)) { 745 Builder.defineMacro("__VFP_FP__"); 746 if (FPU & VFP2FPU) 747 Builder.defineMacro("__ARM_VFPV2__"); 748 if (FPU & VFP3FPU) 749 Builder.defineMacro("__ARM_VFPV3__"); 750 if (FPU & VFP4FPU) 751 Builder.defineMacro("__ARM_VFPV4__"); 752 if (FPU & FPARMV8) 753 Builder.defineMacro("__ARM_FPV5__"); 754 } 755 756 // This only gets set when Neon instructions are actually available, unlike 757 // the VFP define, hence the soft float and arch check. This is subtly 758 // different from gcc, we follow the intent which was that it should be set 759 // when Neon instructions are actually available. 760 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { 761 Builder.defineMacro("__ARM_NEON", "1"); 762 Builder.defineMacro("__ARM_NEON__"); 763 // current AArch32 NEON implementations do not support double-precision 764 // floating-point even when it is present in VFP. 765 Builder.defineMacro("__ARM_NEON_FP", 766 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); 767 } 768 769 if (hasMVE()) { 770 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); 771 } 772 773 if (hasCDE()) { 774 Builder.defineMacro("__ARM_FEATURE_CDE", "1"); 775 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", 776 "0x" + Twine::utohexstr(getARMCDECoprocMask())); 777 } 778 779 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 780 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 781 782 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 783 784 // CMSE 785 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) 786 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); 787 788 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { 789 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 790 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 791 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 792 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 793 } 794 795 // ACLE 6.4.7 DSP instructions 796 if (DSP) { 797 Builder.defineMacro("__ARM_FEATURE_DSP", "1"); 798 } 799 800 // ACLE 6.4.8 Saturation instructions 801 bool SAT = false; 802 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) { 803 Builder.defineMacro("__ARM_FEATURE_SAT", "1"); 804 SAT = true; 805 } 806 807 // ACLE 6.4.6 Q (saturation) flag 808 if (DSP || SAT) 809 Builder.defineMacro("__ARM_FEATURE_QBIT", "1"); 810 811 if (Opts.UnsafeFPMath) 812 Builder.defineMacro("__ARM_FP_FAST", "1"); 813 814 // Armv8.2-A FP16 vector intrinsic 815 if ((FPU & NeonFPU) && HasLegalHalfType) 816 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 817 818 // Armv8.2-A FP16 scalar intrinsics 819 if (HasLegalHalfType) 820 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 821 822 // Armv8.2-A dot product intrinsics 823 if (DotProd) 824 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 825 826 if (HasMatMul) 827 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 828 829 switch (ArchKind) { 830 default: 831 break; 832 case llvm::ARM::ArchKind::ARMV8_1A: 833 getTargetDefinesARMV81A(Opts, Builder); 834 break; 835 case llvm::ARM::ArchKind::ARMV8_2A: 836 getTargetDefinesARMV82A(Opts, Builder); 837 break; 838 case llvm::ARM::ArchKind::ARMV8_3A: 839 case llvm::ARM::ArchKind::ARMV8_4A: 840 case llvm::ARM::ArchKind::ARMV8_5A: 841 case llvm::ARM::ArchKind::ARMV8_6A: 842 getTargetDefinesARMV83A(Opts, Builder); 843 break; 844 } 845 } 846 847 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { 848 #define BUILTIN(ID, TYPE, ATTRS) \ 849 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 850 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 851 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 852 #include "clang/Basic/BuiltinsNEON.def" 853 854 #define BUILTIN(ID, TYPE, ATTRS) \ 855 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 856 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 857 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 858 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 859 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 860 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 861 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 862 #include "clang/Basic/BuiltinsARM.def" 863 }; 864 865 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 866 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin - 867 Builtin::FirstTSBuiltin); 868 } 869 870 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 871 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 872 return IsAAPCS 873 ? AAPCSABIBuiltinVaList 874 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 875 : TargetInfo::VoidPtrBuiltinVaList); 876 } 877 878 const char *const ARMTargetInfo::GCCRegNames[] = { 879 // Integer registers 880 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 881 "r12", "sp", "lr", "pc", 882 883 // Float registers 884 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 885 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 886 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 887 888 // Double registers 889 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 890 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 891 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 892 893 // Quad registers 894 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 895 "q12", "q13", "q14", "q15"}; 896 897 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 898 return llvm::makeArrayRef(GCCRegNames); 899 } 900 901 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 902 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 903 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 904 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 905 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 906 // The S, D and Q registers overlap, but aren't really aliases; we 907 // don't want to substitute one of these for a different-sized one. 908 }; 909 910 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 911 return llvm::makeArrayRef(GCCRegAliases); 912 } 913 914 bool ARMTargetInfo::validateAsmConstraint( 915 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 916 switch (*Name) { 917 default: 918 break; 919 case 'l': // r0-r7 if thumb, r0-r15 if ARM 920 Info.setAllowsRegister(); 921 return true; 922 case 'h': // r8-r15, thumb only 923 if (isThumb()) { 924 Info.setAllowsRegister(); 925 return true; 926 } 927 break; 928 case 's': // An integer constant, but allowing only relocatable values. 929 return true; 930 case 't': // s0-s31, d0-d31, or q0-q15 931 case 'w': // s0-s15, d0-d7, or q0-q3 932 case 'x': // s0-s31, d0-d15, or q0-q7 933 Info.setAllowsRegister(); 934 return true; 935 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 936 // only available in ARMv6T2 and above 937 if (CPUAttr.equals("6T2") || ArchVersion >= 7) { 938 Info.setRequiresImmediate(0, 65535); 939 return true; 940 } 941 break; 942 case 'I': 943 if (isThumb()) { 944 if (!supportsThumb2()) 945 Info.setRequiresImmediate(0, 255); 946 else 947 // FIXME: should check if immediate value would be valid for a Thumb2 948 // data-processing instruction 949 Info.setRequiresImmediate(); 950 } else 951 // FIXME: should check if immediate value would be valid for an ARM 952 // data-processing instruction 953 Info.setRequiresImmediate(); 954 return true; 955 case 'J': 956 if (isThumb() && !supportsThumb2()) 957 Info.setRequiresImmediate(-255, -1); 958 else 959 Info.setRequiresImmediate(-4095, 4095); 960 return true; 961 case 'K': 962 if (isThumb()) { 963 if (!supportsThumb2()) 964 // FIXME: should check if immediate value can be obtained from shifting 965 // a value between 0 and 255 left by any amount 966 Info.setRequiresImmediate(); 967 else 968 // FIXME: should check if immediate value would be valid for a Thumb2 969 // data-processing instruction when inverted 970 Info.setRequiresImmediate(); 971 } else 972 // FIXME: should check if immediate value would be valid for an ARM 973 // data-processing instruction when inverted 974 Info.setRequiresImmediate(); 975 return true; 976 case 'L': 977 if (isThumb()) { 978 if (!supportsThumb2()) 979 Info.setRequiresImmediate(-7, 7); 980 else 981 // FIXME: should check if immediate value would be valid for a Thumb2 982 // data-processing instruction when negated 983 Info.setRequiresImmediate(); 984 } else 985 // FIXME: should check if immediate value would be valid for an ARM 986 // data-processing instruction when negated 987 Info.setRequiresImmediate(); 988 return true; 989 case 'M': 990 if (isThumb() && !supportsThumb2()) 991 // FIXME: should check if immediate value is a multiple of 4 between 0 and 992 // 1020 993 Info.setRequiresImmediate(); 994 else 995 // FIXME: should check if immediate value is a power of two or a integer 996 // between 0 and 32 997 Info.setRequiresImmediate(); 998 return true; 999 case 'N': 1000 // Thumb1 only 1001 if (isThumb() && !supportsThumb2()) { 1002 Info.setRequiresImmediate(0, 31); 1003 return true; 1004 } 1005 break; 1006 case 'O': 1007 // Thumb1 only 1008 if (isThumb() && !supportsThumb2()) { 1009 // FIXME: should check if immediate value is a multiple of 4 between -508 1010 // and 508 1011 Info.setRequiresImmediate(); 1012 return true; 1013 } 1014 break; 1015 case 'Q': // A memory address that is a single base register. 1016 Info.setAllowsMemory(); 1017 return true; 1018 case 'T': 1019 switch (Name[1]) { 1020 default: 1021 break; 1022 case 'e': // Even general-purpose register 1023 case 'o': // Odd general-purpose register 1024 Info.setAllowsRegister(); 1025 Name++; 1026 return true; 1027 } 1028 break; 1029 case 'U': // a memory reference... 1030 switch (Name[1]) { 1031 case 'q': // ...ARMV4 ldrsb 1032 case 'v': // ...VFP load/store (reg+constant offset) 1033 case 'y': // ...iWMMXt load/store 1034 case 't': // address valid for load/store opaque types wider 1035 // than 128-bits 1036 case 'n': // valid address for Neon doubleword vector load/store 1037 case 'm': // valid address for Neon element and structure load/store 1038 case 's': // valid address for non-offset loads/stores of quad-word 1039 // values in four ARM registers 1040 Info.setAllowsMemory(); 1041 Name++; 1042 return true; 1043 } 1044 break; 1045 } 1046 return false; 1047 } 1048 1049 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1050 std::string R; 1051 switch (*Constraint) { 1052 case 'U': // Two-character constraint; add "^" hint for later parsing. 1053 case 'T': 1054 R = std::string("^") + std::string(Constraint, 2); 1055 Constraint++; 1056 break; 1057 case 'p': // 'p' should be translated to 'r' by default. 1058 R = std::string("r"); 1059 break; 1060 default: 1061 return std::string(1, *Constraint); 1062 } 1063 return R; 1064 } 1065 1066 bool ARMTargetInfo::validateConstraintModifier( 1067 StringRef Constraint, char Modifier, unsigned Size, 1068 std::string &SuggestedModifier) const { 1069 bool isOutput = (Constraint[0] == '='); 1070 bool isInOut = (Constraint[0] == '+'); 1071 1072 // Strip off constraint modifiers. 1073 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1074 Constraint = Constraint.substr(1); 1075 1076 switch (Constraint[0]) { 1077 default: 1078 break; 1079 case 'r': { 1080 switch (Modifier) { 1081 default: 1082 return (isInOut || isOutput || Size <= 64); 1083 case 'q': 1084 // A register of size 32 cannot fit a vector type. 1085 return false; 1086 } 1087 } 1088 } 1089 1090 return true; 1091 } 1092 const char *ARMTargetInfo::getClobbers() const { 1093 // FIXME: Is this really right? 1094 return ""; 1095 } 1096 1097 TargetInfo::CallingConvCheckResult 1098 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1099 switch (CC) { 1100 case CC_AAPCS: 1101 case CC_AAPCS_VFP: 1102 case CC_Swift: 1103 case CC_OpenCLKernel: 1104 return CCCR_OK; 1105 default: 1106 return CCCR_Warning; 1107 } 1108 } 1109 1110 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1111 if (RegNo == 0) 1112 return 0; 1113 if (RegNo == 1) 1114 return 1; 1115 return -1; 1116 } 1117 1118 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1119 1120 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1121 const TargetOptions &Opts) 1122 : ARMTargetInfo(Triple, Opts) {} 1123 1124 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1125 MacroBuilder &Builder) const { 1126 Builder.defineMacro("__ARMEL__"); 1127 ARMTargetInfo::getTargetDefines(Opts, Builder); 1128 } 1129 1130 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1131 const TargetOptions &Opts) 1132 : ARMTargetInfo(Triple, Opts) {} 1133 1134 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1135 MacroBuilder &Builder) const { 1136 Builder.defineMacro("__ARMEB__"); 1137 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1138 ARMTargetInfo::getTargetDefines(Opts, Builder); 1139 } 1140 1141 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1142 const TargetOptions &Opts) 1143 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1144 } 1145 1146 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1147 MacroBuilder &Builder) const { 1148 // FIXME: this is invalid for WindowsCE 1149 Builder.defineMacro("_M_ARM_NT", "1"); 1150 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1151 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1152 1153 assert((Triple.getArch() == llvm::Triple::arm || 1154 Triple.getArch() == llvm::Triple::thumb) && 1155 "invalid architecture for Windows ARM target info"); 1156 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1157 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1158 1159 // TODO map the complete set of values 1160 // 31: VFPv3 40: VFPv4 1161 Builder.defineMacro("_M_ARM_FP", "31"); 1162 } 1163 1164 TargetInfo::BuiltinVaListKind 1165 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1166 return TargetInfo::CharPtrBuiltinVaList; 1167 } 1168 1169 TargetInfo::CallingConvCheckResult 1170 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1171 switch (CC) { 1172 case CC_X86StdCall: 1173 case CC_X86ThisCall: 1174 case CC_X86FastCall: 1175 case CC_X86VectorCall: 1176 return CCCR_Ignore; 1177 case CC_C: 1178 case CC_OpenCLKernel: 1179 case CC_PreserveMost: 1180 case CC_PreserveAll: 1181 case CC_Swift: 1182 return CCCR_OK; 1183 default: 1184 return CCCR_Warning; 1185 } 1186 } 1187 1188 // Windows ARM + Itanium C++ ABI Target 1189 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1190 const llvm::Triple &Triple, const TargetOptions &Opts) 1191 : WindowsARMTargetInfo(Triple, Opts) { 1192 TheCXXABI.set(TargetCXXABI::GenericARM); 1193 } 1194 1195 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1196 const LangOptions &Opts, MacroBuilder &Builder) const { 1197 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1198 1199 if (Opts.MSVCCompat) 1200 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1201 } 1202 1203 // Windows ARM, MS (C++) ABI 1204 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1205 const TargetOptions &Opts) 1206 : WindowsARMTargetInfo(Triple, Opts) { 1207 TheCXXABI.set(TargetCXXABI::Microsoft); 1208 } 1209 1210 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1211 MacroBuilder &Builder) const { 1212 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1213 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1214 } 1215 1216 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1217 const TargetOptions &Opts) 1218 : WindowsARMTargetInfo(Triple, Opts) { 1219 TheCXXABI.set(TargetCXXABI::GenericARM); 1220 } 1221 1222 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1223 MacroBuilder &Builder) const { 1224 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1225 Builder.defineMacro("_ARM_"); 1226 } 1227 1228 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1229 const TargetOptions &Opts) 1230 : ARMleTargetInfo(Triple, Opts) { 1231 this->WCharType = TargetInfo::UnsignedShort; 1232 TLSSupported = false; 1233 DoubleAlign = LongLongAlign = 64; 1234 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1235 } 1236 1237 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1238 MacroBuilder &Builder) const { 1239 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1240 Builder.defineMacro("_ARM_"); 1241 Builder.defineMacro("__CYGWIN__"); 1242 Builder.defineMacro("__CYGWIN32__"); 1243 DefineStd(Builder, "unix", Opts); 1244 if (Opts.CPlusPlus) 1245 Builder.defineMacro("_GNU_SOURCE"); 1246 } 1247 1248 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1249 const TargetOptions &Opts) 1250 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1251 HasAlignMac68kSupport = true; 1252 // iOS always has 64-bit atomic instructions. 1253 // FIXME: This should be based off of the target features in 1254 // ARMleTargetInfo. 1255 MaxAtomicInlineWidth = 64; 1256 1257 if (Triple.isWatchABI()) { 1258 // Darwin on iOS uses a variant of the ARM C++ ABI. 1259 TheCXXABI.set(TargetCXXABI::WatchOS); 1260 1261 // BOOL should be a real boolean on the new ABI 1262 UseSignedCharForObjCBool = false; 1263 } else 1264 TheCXXABI.set(TargetCXXABI::iOS); 1265 } 1266 1267 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1268 const llvm::Triple &Triple, 1269 MacroBuilder &Builder) const { 1270 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1271 } 1272 1273 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 1274 const TargetOptions &Opts) 1275 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 1276 Triple.getOSName(), 1277 Triple.getEnvironmentName()), 1278 Opts) { 1279 IsRenderScriptTarget = true; 1280 LongWidth = LongAlign = 64; 1281 } 1282 1283 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 1284 MacroBuilder &Builder) const { 1285 Builder.defineMacro("__RENDERSCRIPT__"); 1286 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1287 } 1288