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