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