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