brintos

brintos / llvm-project-archived public Read only

0
0
Text · 52.2 KiB · 394b50b Raw
1591 lines · cpp
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-exception6//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/StringRef.h"18#include "llvm/ADT/StringSwitch.h"19#include "llvm/TargetParser/ARMTargetParser.h"20 21using namespace clang;22using namespace clang::targets;23 24void ARMTargetInfo::setABIAAPCS() {25  IsAAPCS = true;26 27  DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;28  BFloat16Width = BFloat16Align = 16;29  BFloat16Format = &llvm::APFloat::BFloat();30 31  const llvm::Triple &T = getTriple();32 33  bool IsNetBSD = T.isOSNetBSD();34  bool IsOpenBSD = T.isOSOpenBSD();35  if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)36    WCharType = UnsignedInt;37 38  UseBitFieldTypeAlignment = true;39 40  ZeroLengthBitfieldBoundary = 0;41 42  // Thumb1 add sp, #imm requires the immediate value be multiple of 4,43  // so set preferred for small types to 32.44  if (T.isOSBinFormatMachO()) {45    resetDataLayout(BigEndian46                        ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"47                        : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",48                    "_");49  } else if (T.isOSWindows()) {50    assert(!BigEndian && "Windows on ARM does not support big endian");51    resetDataLayout("e"52                    "-m:w"53                    "-p:32:32"54                    "-Fi8"55                    "-i64:64"56                    "-v128:64:128"57                    "-a:0:32"58                    "-n32"59                    "-S64");60  } else {61    resetDataLayout(BigEndian62                        ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"63                        : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");64  }65 66  // FIXME: Enumerated types are variable width in straight AAPCS.67}68 69void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {70  const llvm::Triple &T = getTriple();71 72  IsAAPCS = false;73 74  if (IsAAPCS16)75    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;76  else77    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;78  BFloat16Width = BFloat16Align = 16;79  BFloat16Format = &llvm::APFloat::BFloat();80 81  WCharType = SignedInt;82 83  // Do not respect the alignment of bit-field types when laying out84  // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.85  UseBitFieldTypeAlignment = false;86 87  /// gcc forces the alignment to 4 bytes, regardless of the type of the88  /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in89  /// gcc.90  ZeroLengthBitfieldBoundary = 32;91 92  if (T.isOSBinFormatMachO() && IsAAPCS16) {93    assert(!BigEndian && "AAPCS16 does not support big-endian");94    resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");95  } else if (T.isOSBinFormatMachO())96    resetDataLayout(97        BigEndian98            ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"99            : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",100        "_");101  else102    resetDataLayout(103        BigEndian104            ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"105            : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");106 107  // FIXME: Override "preferred align" for double and long long.108}109 110void ARMTargetInfo::setArchInfo() {111  StringRef ArchName = getTriple().getArchName();112 113  ArchISA = llvm::ARM::parseArchISA(ArchName);114  CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));115  llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);116  if (AK != llvm::ARM::ArchKind::INVALID)117    ArchKind = AK;118  setArchInfo(ArchKind);119}120 121void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {122  StringRef SubArch;123 124  // cache TargetParser info125  ArchKind = Kind;126  SubArch = llvm::ARM::getSubArch(ArchKind);127  ArchProfile = llvm::ARM::parseArchProfile(SubArch);128  ArchVersion = llvm::ARM::parseArchVersion(SubArch);129 130  // cache CPU related strings131  CPUAttr = getCPUAttr();132  CPUProfile = getCPUProfile();133}134 135void ARMTargetInfo::setAtomic() {136  if (ArchProfile == llvm::ARM::ProfileKind::M) {137    // M-class only ever supports 32-bit atomics. Cortex-M0 doesn't have138    // any atomics.139    MaxAtomicPromoteWidth = 32;140    if (ArchVersion >= 7)141      MaxAtomicInlineWidth = 32;142  } else {143    // A-class targets have up to 64-bit atomics.144    //145    // On Linux, 64-bit atomics are always available through kernel helpers146    // (which are lock-free). Otherwise, atomics are available on v6 or later.147    //148    // (Thumb doesn't matter; for Thumbv6, we just use a library call which149    // switches out of Thumb mode.)150    //151    // This should match setMaxAtomicSizeInBitsSupported() in the backend.152    MaxAtomicPromoteWidth = 64;153    if (getTriple().getOS() == llvm::Triple::Linux || ArchVersion >= 6)154      MaxAtomicInlineWidth = 64;155  }156}157 158bool ARMTargetInfo::hasMVE() const {159  return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;160}161 162bool ARMTargetInfo::hasMVEFloat() const {163  return hasMVE() && (MVE & MVE_FP);164}165 166bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }167 168bool ARMTargetInfo::isThumb() const {169  return ArchISA == llvm::ARM::ISAKind::THUMB;170}171 172bool ARMTargetInfo::supportsThumb() const {173  return CPUAttr.count('T') || ArchVersion >= 6;174}175 176bool ARMTargetInfo::supportsThumb2() const {177  return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE");178}179 180StringRef ARMTargetInfo::getCPUAttr() const {181  // For most sub-arches, the build attribute CPU name is enough.182  // For Cortex variants, it's slightly different.183  switch (ArchKind) {184  default:185    return llvm::ARM::getCPUAttr(ArchKind);186  case llvm::ARM::ArchKind::ARMV6M:187    return "6M";188  case llvm::ARM::ArchKind::ARMV7S:189    return "7S";190  case llvm::ARM::ArchKind::ARMV7A:191    return "7A";192  case llvm::ARM::ArchKind::ARMV7R:193    return "7R";194  case llvm::ARM::ArchKind::ARMV7M:195    return "7M";196  case llvm::ARM::ArchKind::ARMV7EM:197    return "7EM";198  case llvm::ARM::ArchKind::ARMV7VE:199    return "7VE";200  case llvm::ARM::ArchKind::ARMV8A:201    return "8A";202  case llvm::ARM::ArchKind::ARMV8_1A:203    return "8_1A";204  case llvm::ARM::ArchKind::ARMV8_2A:205    return "8_2A";206  case llvm::ARM::ArchKind::ARMV8_3A:207    return "8_3A";208  case llvm::ARM::ArchKind::ARMV8_4A:209    return "8_4A";210  case llvm::ARM::ArchKind::ARMV8_5A:211    return "8_5A";212  case llvm::ARM::ArchKind::ARMV8_6A:213    return "8_6A";214  case llvm::ARM::ArchKind::ARMV8_7A:215    return "8_7A";216  case llvm::ARM::ArchKind::ARMV8_8A:217    return "8_8A";218  case llvm::ARM::ArchKind::ARMV8_9A:219    return "8_9A";220  case llvm::ARM::ArchKind::ARMV9A:221    return "9A";222  case llvm::ARM::ArchKind::ARMV9_1A:223    return "9_1A";224  case llvm::ARM::ArchKind::ARMV9_2A:225    return "9_2A";226  case llvm::ARM::ArchKind::ARMV9_3A:227    return "9_3A";228  case llvm::ARM::ArchKind::ARMV9_4A:229    return "9_4A";230  case llvm::ARM::ArchKind::ARMV9_5A:231    return "9_5A";232  case llvm::ARM::ArchKind::ARMV9_6A:233    return "9_6A";234  case llvm::ARM::ArchKind::ARMV9_7A:235    return "9_7A";236  case llvm::ARM::ArchKind::ARMV8MBaseline:237    return "8M_BASE";238  case llvm::ARM::ArchKind::ARMV8MMainline:239    return "8M_MAIN";240  case llvm::ARM::ArchKind::ARMV8R:241    return "8R";242  case llvm::ARM::ArchKind::ARMV8_1MMainline:243    return "8_1M_MAIN";244  }245}246 247StringRef ARMTargetInfo::getCPUProfile() const {248  switch (ArchProfile) {249  case llvm::ARM::ProfileKind::A:250    return "A";251  case llvm::ARM::ProfileKind::R:252    return "R";253  case llvm::ARM::ProfileKind::M:254    return "M";255  default:256    return "";257  }258}259 260ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,261                             const TargetOptions &Opts)262    : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),263      HW_FP(0) {264  bool IsFreeBSD = Triple.isOSFreeBSD();265  bool IsFuchsia = Triple.isOSFuchsia();266  bool IsOpenBSD = Triple.isOSOpenBSD();267  bool IsNetBSD = Triple.isOSNetBSD();268  bool IsHaiku = Triple.isOSHaiku();269  bool IsOHOS = Triple.isOHOSFamily();270 271  // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like272  // environment where size_t is `unsigned long` rather than `unsigned int`273 274  PtrDiffType = IntPtrType =275      (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||276       IsNetBSD)277          ? SignedLong278          : SignedInt;279 280  SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||281              IsNetBSD)282                 ? UnsignedLong283                 : UnsignedInt;284 285  // ptrdiff_t is inconsistent on Darwin286  if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&287      !Triple.isWatchABI())288    PtrDiffType = SignedInt;289 290  // Cache arch related info.291  setArchInfo();292 293  // {} in inline assembly are neon specifiers, not assembly variant294  // specifiers.295  NoAsmVariants = true;296 297  // FIXME: This duplicates code from the driver that sets the -target-abi298  // option - this code is used if -target-abi isn't passed and should299  // be unified in some way.300  if (Triple.isOSBinFormatMachO()) {301    // The backend is hardwired to assume AAPCS for M-class processors, ensure302    // the frontend matches that.303    if (Triple.getEnvironment() == llvm::Triple::EABI ||304        Triple.getOS() == llvm::Triple::UnknownOS ||305        ArchProfile == llvm::ARM::ProfileKind::M) {306      setABI("aapcs");307    } else if (Triple.isWatchABI()) {308      setABI("aapcs16");309    } else {310      setABI("apcs-gnu");311    }312  } else if (Triple.isOSWindows()) {313    // FIXME: this is invalid for WindowsCE314    setABI("aapcs");315  } else {316    // Select the default based on the platform.317    switch (Triple.getEnvironment()) {318    case llvm::Triple::Android:319    case llvm::Triple::GNUEABI:320    case llvm::Triple::GNUEABIT64:321    case llvm::Triple::GNUEABIHF:322    case llvm::Triple::GNUEABIHFT64:323    case llvm::Triple::MuslEABI:324    case llvm::Triple::MuslEABIHF:325    case llvm::Triple::OpenHOS:326      setABI("aapcs-linux");327      break;328    case llvm::Triple::EABIHF:329    case llvm::Triple::EABI:330      setABI("aapcs");331      break;332    case llvm::Triple::GNU:333      setABI("apcs-gnu");334      break;335    default:336      if (IsNetBSD)337        setABI("apcs-gnu");338      else if (IsFreeBSD || IsFuchsia || IsOpenBSD || IsHaiku || IsOHOS)339        setABI("aapcs-linux");340      else341        setABI("aapcs");342      break;343    }344  }345 346  // ARM targets default to using the ARM C++ ABI.347  TheCXXABI.set(TargetCXXABI::GenericARM);348 349  // ARM has atomics up to 8 bytes350  setAtomic();351 352  // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)353  // as well the default alignment354  if (IsAAPCS && !Triple.isAndroid())355    DefaultAlignForAttributeAligned = MaxVectorAlign = 64;356 357  // Do force alignment of members that follow zero length bitfields.  If358  // the alignment of the zero-length bitfield is greater than the member359  // that follows it, `bar', `bar' will be aligned as the  type of the360  // zero length bitfield.361  UseZeroLengthBitfieldAlignment = true;362 363  if (Triple.getOS() == llvm::Triple::Linux ||364      Triple.getOS() == llvm::Triple::UnknownOS)365    this->MCountName = Opts.EABIVersion == llvm::EABI::GNU366                           ? "llvm.arm.gnu.eabi.mcount"367                           : "\01mcount";368 369  SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");370}371 372StringRef ARMTargetInfo::getABI() const { return ABI; }373 374bool ARMTargetInfo::setABI(const std::string &Name) {375  ABI = Name;376 377  // The defaults (above) are for AAPCS, check if we need to change them.378  //379  // FIXME: We need support for -meabi... we could just mangle it into the380  // name.381  if (Name == "apcs-gnu" || Name == "aapcs16") {382    setABIAPCS(Name == "aapcs16");383    return true;384  }385  if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {386    setABIAAPCS();387    return true;388  }389  return false;390}391 392bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {393  llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);394  if (CPUArch == llvm::ARM::ArchKind::INVALID)395    CPUArch = llvm::ARM::parseArch(getTriple().getArchName());396 397  if (CPUArch == llvm::ARM::ArchKind::INVALID)398    return false;399 400  StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);401  auto a =402      llvm::Triple(ArchFeature, getTriple().getVendorName(),403                   getTriple().getOSName(), getTriple().getEnvironmentName());404 405  StringRef SubArch = llvm::ARM::getSubArch(CPUArch);406  llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);407  return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);408}409 410bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,411                                             BranchProtectionInfo &BPI,412                                             const LangOptions &LO,413                                             StringRef &Err) const {414  llvm::ARM::ParsedBranchProtection PBP;415  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))416    return false;417 418  if (!isBranchProtectionSupportedArch(Arch))419    return false;420 421  BPI.SignReturnAddr =422      llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)423          .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)424          .Case("all", LangOptions::SignReturnAddressScopeKind::All)425          .Default(LangOptions::SignReturnAddressScopeKind::None);426 427  // Don't care for the sign key, beyond issuing a warning.428  if (PBP.Key == "b_key")429    Err = "b-key";430  BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;431 432  BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;433  BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;434  return true;435}436 437// FIXME: This should be based on Arch attributes, not CPU names.438bool ARMTargetInfo::initFeatureMap(439    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,440    const std::vector<std::string> &FeaturesVec) const {441 442  std::string ArchFeature;443  std::vector<StringRef> TargetFeatures;444  llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());445 446  // Map the base architecture to an appropriate target feature, so we don't447  // rely on the target triple.448  llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);449  if (CPUArch == llvm::ARM::ArchKind::INVALID)450    CPUArch = Arch;451  if (CPUArch != llvm::ARM::ArchKind::INVALID) {452    ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();453    TargetFeatures.push_back(ArchFeature);454 455    // These features are added to allow arm_neon.h target(..) attributes to456    // match with both arm and aarch64. We need to add all previous architecture457    // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the458    // v8.x counterparts are added too. We only need these for anything > 8.0-A.459    for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);460         I != llvm::ARM::ArchKind::INVALID; --I)461      Features[llvm::ARM::getSubArch(I)] = true;462    if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&463        CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)464      for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;465           --I)466        Features[llvm::ARM::getSubArch(I)] = true;467  }468 469  // get default FPU features470  llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);471  llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);472 473  // get default Extension features474  uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);475  llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);476 477  for (auto Feature : TargetFeatures)478    if (Feature[0] == '+')479      Features[Feature.drop_front(1)] = true;480 481  // Enable or disable thumb-mode explicitly per function to enable mixed482  // ARM and Thumb code generation.483  if (isThumb())484    Features["thumb-mode"] = true;485  else486    Features["thumb-mode"] = false;487 488  // Convert user-provided arm and thumb GNU target attributes to489  // [-|+]thumb-mode target features respectively.490  std::vector<std::string> UpdatedFeaturesVec;491  for (const auto &Feature : FeaturesVec) {492    // Skip soft-float-abi; it's something we only use to initialize a bit of493    // class state, and is otherwise unrecognized.494    if (Feature == "+soft-float-abi")495      continue;496 497    StringRef FixedFeature;498    if (Feature == "+arm")499      FixedFeature = "-thumb-mode";500    else if (Feature == "+thumb")501      FixedFeature = "+thumb-mode";502    else503      FixedFeature = Feature;504    UpdatedFeaturesVec.push_back(FixedFeature.str());505  }506 507  return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);508}509 510 511bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,512                                         DiagnosticsEngine &Diags) {513  FPU = 0;514  MVE = 0;515  CRC = 0;516  Crypto = 0;517  SHA2 = 0;518  AES = 0;519  DSP = 0;520  HasUnalignedAccess = true;521  SoftFloat = false;522  // Note that SoftFloatABI is initialized in our constructor.523  HWDiv = 0;524  DotProd = 0;525  HasMatMul = 0;526  HasPAC = 0;527  HasBTI = 0;528  HasFloat16 = true;529  ARMCDECoprocMask = 0;530  HasBFloat16 = false;531  HasFullBFloat16 = false;532  FPRegsDisabled = false;533 534  // This does not diagnose illegal cases like having both535  // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".536  for (const auto &Feature : Features) {537    if (Feature == "+soft-float") {538      SoftFloat = true;539    } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {540      FPU |= VFP2FPU;541      HW_FP |= HW_FP_SP;542      if (Feature == "+vfp2")543          HW_FP |= HW_FP_DP;544    } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||545               Feature == "+vfp3" || Feature == "+vfp3d16") {546      FPU |= VFP3FPU;547      HW_FP |= HW_FP_SP;548      if (Feature == "+vfp3" || Feature == "+vfp3d16")549          HW_FP |= HW_FP_DP;550    } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||551               Feature == "+vfp4" || Feature == "+vfp4d16") {552      FPU |= VFP4FPU;553      HW_FP |= HW_FP_SP | HW_FP_HP;554      if (Feature == "+vfp4" || Feature == "+vfp4d16")555          HW_FP |= HW_FP_DP;556    } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||557               Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {558      FPU |= FPARMV8;559      HW_FP |= HW_FP_SP | HW_FP_HP;560      if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")561          HW_FP |= HW_FP_DP;562    } else if (Feature == "+neon") {563      FPU |= NeonFPU;564      HW_FP |= HW_FP_SP;565    } else if (Feature == "+hwdiv") {566      HWDiv |= HWDivThumb;567    } else if (Feature == "+hwdiv-arm") {568      HWDiv |= HWDivARM;569    } else if (Feature == "+crc") {570      CRC = 1;571    } else if (Feature == "+crypto") {572      Crypto = 1;573    } else if (Feature == "+sha2") {574      SHA2 = 1;575    } else if (Feature == "+aes") {576      AES = 1;577    } else if (Feature == "+dsp") {578      DSP = 1;579    } else if (Feature == "+fp64") {580      HW_FP |= HW_FP_DP;581    } else if (Feature == "+8msecext") {582      if (CPUProfile != "M" || ArchVersion != 8) {583        Diags.Report(diag::err_target_unsupported_mcmse) << CPU;584        return false;585      }586    } else if (Feature == "+strict-align") {587      HasUnalignedAccess = false;588    } else if (Feature == "+fp16") {589      HW_FP |= HW_FP_HP;590    } else if (Feature == "+fullfp16") {591      HasFastHalfType = true;592    } else if (Feature == "+dotprod") {593      DotProd = true;594    } else if (Feature == "+mve") {595      MVE |= MVE_INT;596    } else if (Feature == "+mve.fp") {597      HasFastHalfType = true;598      FPU |= FPARMV8;599      MVE |= MVE_INT | MVE_FP;600      HW_FP |= HW_FP_SP | HW_FP_HP;601    } else if (Feature == "+i8mm") {602      HasMatMul = 1;603    } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&604               Feature <= "+cdecp7") {605      unsigned Coproc = Feature.back() - '0';606      ARMCDECoprocMask |= (1U << Coproc);607    } else if (Feature == "+bf16") {608      HasBFloat16 = true;609    } else if (Feature == "-fpregs") {610      FPRegsDisabled = true;611    } else if (Feature == "+pacbti") {612      HasPAC = 1;613      HasBTI = 1;614    } else if (Feature == "+fullbf16") {615      HasFullBFloat16 = true;616    } else if (Feature == "+execute-only") {617      TLSSupported = false;618    }619  }620 621  HalfArgsAndReturns = true;622 623  switch (ArchVersion) {624  case 6:625    if (ArchProfile == llvm::ARM::ProfileKind::M)626      LDREX = 0;627    else if (ArchKind == llvm::ARM::ArchKind::ARMV6K ||628             ArchKind == llvm::ARM::ArchKind::ARMV6KZ)629      LDREX = ARM_LDREX_D | ARM_LDREX_W | ARM_LDREX_H | ARM_LDREX_B;630    else631      LDREX = ARM_LDREX_W;632    break;633  case 7:634  case 8:635    if (ArchProfile == llvm::ARM::ProfileKind::M)636      LDREX = ARM_LDREX_W | ARM_LDREX_H | ARM_LDREX_B;637    else638      LDREX = ARM_LDREX_D | ARM_LDREX_W | ARM_LDREX_H | ARM_LDREX_B;639    break;640  case 9:641    assert(ArchProfile != llvm::ARM::ProfileKind::M &&642           "No Armv9-M architectures defined");643    LDREX = ARM_LDREX_D | ARM_LDREX_W | ARM_LDREX_H | ARM_LDREX_B;644  }645 646  if (!(FPU & NeonFPU) && FPMath == FP_Neon) {647    Diags.Report(diag::err_target_unsupported_fpmath) << "neon";648    return false;649  }650 651  if (FPMath == FP_Neon)652    Features.push_back("+neonfp");653  else if (FPMath == FP_VFP)654    Features.push_back("-neonfp");655 656  return true;657}658 659bool ARMTargetInfo::hasFeature(StringRef Feature) const {660  return llvm::StringSwitch<bool>(Feature)661      .Case("arm", true)662      .Case("aarch32", true)663      .Case("softfloat", SoftFloat)664      .Case("thumb", isThumb())665      .Case("neon", (FPU & NeonFPU) && !SoftFloat)666      .Case("vfp", FPU && !SoftFloat)667      .Case("hwdiv", HWDiv & HWDivThumb)668      .Case("hwdiv-arm", HWDiv & HWDivARM)669      .Case("mve", hasMVE())670      .Default(false);671}672 673bool ARMTargetInfo::hasBFloat16Type() const {674  // The __bf16 type is generally available so long as we have any fp registers.675  return HasBFloat16 || (FPU && !SoftFloat);676}677 678bool ARMTargetInfo::isValidCPUName(StringRef Name) const {679  return Name == "generic" ||680         llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;681}682 683void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {684  llvm::ARM::fillValidCPUArchList(Values);685}686 687bool ARMTargetInfo::setCPU(const std::string &Name) {688  if (Name != "generic")689    setArchInfo(llvm::ARM::parseCPUArch(Name));690 691  if (ArchKind == llvm::ARM::ArchKind::INVALID)692    return false;693  setAtomic();694  CPU = Name;695  return true;696}697 698bool ARMTargetInfo::setFPMath(StringRef Name) {699  if (Name == "neon") {700    FPMath = FP_Neon;701    return true;702  } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||703             Name == "vfp4") {704    FPMath = FP_VFP;705    return true;706  }707  return false;708}709 710void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,711                                            MacroBuilder &Builder) const {712  Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");713}714 715void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,716                                            MacroBuilder &Builder) const {717  // Also include the ARMv8.1-A defines718  getTargetDefinesARMV81A(Opts, Builder);719}720 721void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,722                                            MacroBuilder &Builder) const {723  // Also include the ARMv8.2-A defines724  Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");725  getTargetDefinesARMV82A(Opts, Builder);726}727 728void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,729                                     MacroBuilder &Builder) const {730  // Target identification.731  Builder.defineMacro("__arm");732  Builder.defineMacro("__arm__");733  // For bare-metal none-eabi.734  if (getTriple().getOS() == llvm::Triple::UnknownOS &&735      (getTriple().getEnvironment() == llvm::Triple::EABI ||736       getTriple().getEnvironment() == llvm::Triple::EABIHF) &&737      Opts.CPlusPlus) {738    Builder.defineMacro("_GNU_SOURCE");739  }740 741  // Target properties.742  Builder.defineMacro("__REGISTER_PREFIX__", "");743 744  // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU745  // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.746  if (getTriple().isWatchABI())747    Builder.defineMacro("__ARM_ARCH_7K__", "2");748 749  if (!CPUAttr.empty())750    Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");751 752  // ACLE 6.4.1 ARM/Thumb instruction set architecture753  // __ARM_ARCH is defined as an integer value indicating the current ARM ISA754  Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));755 756  if (ArchVersion >= 8) {757    // ACLE 6.5.7 Crypto Extension758    // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained759    // feature macros for AES and SHA2760    if (SHA2 && AES)761      Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");762    if (SHA2)763      Builder.defineMacro("__ARM_FEATURE_SHA2", "1");764    if (AES)765      Builder.defineMacro("__ARM_FEATURE_AES", "1");766    // ACLE 6.5.8 CRC32 Extension767    if (CRC)768      Builder.defineMacro("__ARM_FEATURE_CRC32", "1");769    // ACLE 6.5.10 Numeric Maximum and Minimum770    Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");771    // ACLE 6.5.9 Directed Rounding772    Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");773  }774 775  // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It776  // is not defined for the M-profile.777  // NOTE that the default profile is assumed to be 'A'778  if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)779    Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");780 781  // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original782  // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the783  // core supports the Thumb-2 ISA as found in the v6T2 architecture and all784  // v7 and v8 architectures excluding v8-M Baseline.785  if (supportsThumb2())786    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");787  else if (supportsThumb())788    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");789 790  // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit791  // instruction set such as ARM or Thumb.792  Builder.defineMacro("__ARM_32BIT_STATE", "1");793 794  // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)795 796  // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.797  if (!CPUProfile.empty())798    Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");799 800  // ACLE 6.4.3 Unaligned access supported in hardware801  if (HasUnalignedAccess)802    Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");803 804  // ACLE 6.4.4 LDREX/STREX805  if (LDREX)806    Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));807 808  // ACLE 6.4.5 CLZ809  if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||810      ArchVersion > 6)811    Builder.defineMacro("__ARM_FEATURE_CLZ", "1");812 813  // ACLE 6.5.1 Hardware Floating Point814  if (HW_FP)815    Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));816 817  // ACLE predefines.818  Builder.defineMacro("__ARM_ACLE", "200");819 820  // FP16 support (we currently only support IEEE format).821  Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");822  Builder.defineMacro("__ARM_FP16_ARGS", "1");823 824  // ACLE 6.5.3 Fused multiply-accumulate (FMA)825  if (ArchVersion >= 7 && (FPU & VFP4FPU))826    Builder.defineMacro("__ARM_FEATURE_FMA", "1");827 828  // Subtarget options.829 830  // FIXME: It's more complicated than this and we don't really support831  // interworking.832  // Windows on ARM does not "support" interworking833  if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())834    Builder.defineMacro("__THUMB_INTERWORK__");835 836  if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {837    // Embedded targets on Darwin follow AAPCS, but not EABI.838    // Windows on ARM follows AAPCS VFP, but does not conform to EABI.839    if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())840      Builder.defineMacro("__ARM_EABI__");841    Builder.defineMacro("__ARM_PCS", "1");842  }843 844  if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")845    Builder.defineMacro("__ARM_PCS_VFP", "1");846 847  if (SoftFloat || (SoftFloatABI && !FPU))848    Builder.defineMacro("__SOFTFP__");849 850  // ACLE position independent code macros.851  if (Opts.ROPI)852    Builder.defineMacro("__ARM_ROPI", "1");853  if (Opts.RWPI)854    Builder.defineMacro("__ARM_RWPI", "1");855 856  // Macros for enabling co-proc intrinsics857  uint64_t FeatureCoprocBF = 0;858  switch (ArchKind) {859  default:860    break;861  case llvm::ARM::ArchKind::ARMV4:862  case llvm::ARM::ArchKind::ARMV4T:863    // Filter __arm_ldcl and __arm_stcl in acle.h864    FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;865    break;866  case llvm::ARM::ArchKind::ARMV5T:867    FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;868    break;869  case llvm::ARM::ArchKind::ARMV5TE:870  case llvm::ARM::ArchKind::ARMV5TEJ:871    if (!isThumb())872      FeatureCoprocBF =873          FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;874    break;875  case llvm::ARM::ArchKind::ARMV6:876  case llvm::ARM::ArchKind::ARMV6K:877  case llvm::ARM::ArchKind::ARMV6KZ:878  case llvm::ARM::ArchKind::ARMV6T2:879    if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)880      FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |881                        FEATURE_COPROC_B3 | FEATURE_COPROC_B4;882    break;883  case llvm::ARM::ArchKind::ARMV7A:884  case llvm::ARM::ArchKind::ARMV7R:885  case llvm::ARM::ArchKind::ARMV7M:886  case llvm::ARM::ArchKind::ARMV7S:887  case llvm::ARM::ArchKind::ARMV7EM:888    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |889                      FEATURE_COPROC_B3 | FEATURE_COPROC_B4;890    break;891  case llvm::ARM::ArchKind::ARMV8A:892  case llvm::ARM::ArchKind::ARMV8R:893  case llvm::ARM::ArchKind::ARMV8_1A:894  case llvm::ARM::ArchKind::ARMV8_2A:895  case llvm::ARM::ArchKind::ARMV8_3A:896  case llvm::ARM::ArchKind::ARMV8_4A:897  case llvm::ARM::ArchKind::ARMV8_5A:898  case llvm::ARM::ArchKind::ARMV8_6A:899  case llvm::ARM::ArchKind::ARMV8_7A:900  case llvm::ARM::ArchKind::ARMV8_8A:901  case llvm::ARM::ArchKind::ARMV8_9A:902  case llvm::ARM::ArchKind::ARMV9A:903  case llvm::ARM::ArchKind::ARMV9_1A:904  case llvm::ARM::ArchKind::ARMV9_2A:905  case llvm::ARM::ArchKind::ARMV9_3A:906  case llvm::ARM::ArchKind::ARMV9_4A:907  case llvm::ARM::ArchKind::ARMV9_5A:908  case llvm::ARM::ArchKind::ARMV9_6A:909  case llvm::ARM::ArchKind::ARMV9_7A:910    // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h911    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;912    break;913  case llvm::ARM::ArchKind::ARMV8MMainline:914  case llvm::ARM::ArchKind::ARMV8_1MMainline:915    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |916                      FEATURE_COPROC_B3 | FEATURE_COPROC_B4;917    break;918  }919  Builder.defineMacro("__ARM_FEATURE_COPROC",920                      "0x" + Twine::utohexstr(FeatureCoprocBF));921 922  if (ArchKind == llvm::ARM::ArchKind::XSCALE)923    Builder.defineMacro("__XSCALE__");924 925  if (isThumb()) {926    Builder.defineMacro("__THUMBEL__");927    Builder.defineMacro("__thumb__");928    if (supportsThumb2())929      Builder.defineMacro("__thumb2__");930  }931 932  // ACLE 6.4.9 32-bit SIMD instructions933  if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))934    Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");935 936  // ACLE 6.4.10 Hardware Integer Divide937  if (((HWDiv & HWDivThumb) && isThumb()) ||938      ((HWDiv & HWDivARM) && !isThumb())) {939    Builder.defineMacro("__ARM_FEATURE_IDIV", "1");940    Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");941  }942 943  // Note, this is always on in gcc, even though it doesn't make sense.944  Builder.defineMacro("__APCS_32__");945 946  // __VFP_FP__ means that the floating-point format is VFP, not that a hardware947  // FPU is present. Moreover, the VFP format is the only one supported by948  // clang. For these reasons, this macro is always defined.949  Builder.defineMacro("__VFP_FP__");950 951  if (FPUModeIsVFP((FPUMode)FPU)) {952    if (FPU & VFP2FPU)953      Builder.defineMacro("__ARM_VFPV2__");954    if (FPU & VFP3FPU)955      Builder.defineMacro("__ARM_VFPV3__");956    if (FPU & VFP4FPU)957      Builder.defineMacro("__ARM_VFPV4__");958    if (FPU & FPARMV8)959      Builder.defineMacro("__ARM_FPV5__");960  }961 962  // This only gets set when Neon instructions are actually available, unlike963  // the VFP define, hence the soft float and arch check. This is subtly964  // different from gcc, we follow the intent which was that it should be set965  // when Neon instructions are actually available.966  if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {967    Builder.defineMacro("__ARM_NEON", "1");968    Builder.defineMacro("__ARM_NEON__");969    // current AArch32 NEON implementations do not support double-precision970    // floating-point even when it is present in VFP.971    Builder.defineMacro("__ARM_NEON_FP",972                        "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));973  }974 975  if (hasMVE()) {976    Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");977  }978 979  if (hasCDE()) {980    Builder.defineMacro("__ARM_FEATURE_CDE", "1");981    Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",982                        "0x" + Twine::utohexstr(getARMCDECoprocMask()));983  }984 985  Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",986                      Twine(Opts.WCharSize ? Opts.WCharSize : 4));987 988  Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");989 990  // CMSE991  if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)992    Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");993 994  if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {995    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");996    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");997    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");998    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");999  }1000 1001  // ACLE 6.4.7 DSP instructions1002  if (DSP) {1003    Builder.defineMacro("__ARM_FEATURE_DSP", "1");1004  }1005 1006  // ACLE 6.4.8 Saturation instructions1007  bool SAT = false;1008  if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {1009    Builder.defineMacro("__ARM_FEATURE_SAT", "1");1010    SAT = true;1011  }1012 1013  // ACLE 6.4.6 Q (saturation) flag1014  if (DSP || SAT)1015    Builder.defineMacro("__ARM_FEATURE_QBIT", "1");1016 1017  if (Opts.UnsafeFPMath)1018    Builder.defineMacro("__ARM_FP_FAST", "1");1019 1020  // Armv8.2-A FP16 vector intrinsic1021  if ((FPU & NeonFPU) && HasFastHalfType)1022    Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");1023 1024  // Armv8.2-A FP16 scalar intrinsics1025  if (HasFastHalfType)1026    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");1027 1028  // Armv8.2-A dot product intrinsics1029  if (DotProd)1030    Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");1031 1032  if (HasMatMul)1033    Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");1034 1035  if (HasPAC)1036    Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");1037 1038  if (HasBTI)1039    Builder.defineMacro("__ARM_FEATURE_BTI", "1");1040 1041  if (HasBFloat16) {1042    Builder.defineMacro("__ARM_FEATURE_BF16", "1");1043    Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");1044    Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");1045  }1046 1047  if (Opts.BranchTargetEnforcement)1048    Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");1049 1050  if (Opts.hasSignReturnAddress()) {1051    unsigned Value = 1;1052    if (Opts.isSignReturnAddressScopeAll())1053      Value |= 1 << 2;1054    Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));1055  }1056 1057  switch (ArchKind) {1058  default:1059    break;1060  case llvm::ARM::ArchKind::ARMV8_1A:1061    getTargetDefinesARMV81A(Opts, Builder);1062    break;1063  case llvm::ARM::ArchKind::ARMV8_2A:1064    getTargetDefinesARMV82A(Opts, Builder);1065    break;1066  case llvm::ARM::ArchKind::ARMV8_3A:1067  case llvm::ARM::ArchKind::ARMV8_4A:1068  case llvm::ARM::ArchKind::ARMV8_5A:1069  case llvm::ARM::ArchKind::ARMV8_6A:1070  case llvm::ARM::ArchKind::ARMV8_7A:1071  case llvm::ARM::ArchKind::ARMV8_8A:1072  case llvm::ARM::ArchKind::ARMV8_9A:1073  case llvm::ARM::ArchKind::ARMV9A:1074  case llvm::ARM::ArchKind::ARMV9_1A:1075  case llvm::ARM::ArchKind::ARMV9_2A:1076  case llvm::ARM::ArchKind::ARMV9_3A:1077  case llvm::ARM::ArchKind::ARMV9_4A:1078  case llvm::ARM::ArchKind::ARMV9_5A:1079  case llvm::ARM::ArchKind::ARMV9_6A:1080  case llvm::ARM::ArchKind::ARMV9_7A:1081    getTargetDefinesARMV83A(Opts, Builder);1082    break;1083  }1084}1085 1086static constexpr int NumBuiltins = ARM::LastTSBuiltin - Builtin::FirstTSBuiltin;1087static constexpr int NumNeonBuiltins =1088    NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin;1089static constexpr int NumFp16Builtins =1090    NEON::FirstTSBuiltin - NEON::FirstFp16Builtin;1091static constexpr int NumMVEBuiltins =1092    ARM::FirstCDEBuiltin - NEON::FirstTSBuiltin;1093static constexpr int NumCDEBuiltins =1094    ARM::FirstARMBuiltin - ARM::FirstCDEBuiltin;1095static constexpr int NumARMBuiltins = ARM::LastTSBuiltin - ARM::FirstARMBuiltin;1096static_assert(NumBuiltins ==1097              (NumNeonBuiltins + NumFp16Builtins + NumMVEBuiltins +1098               NumCDEBuiltins + NumARMBuiltins));1099 1100namespace clang {1101namespace NEON {1102#define GET_NEON_BUILTIN_STR_TABLE1103#include "clang/Basic/arm_neon.inc"1104#undef GET_NEON_BUILTIN_STR_TABLE1105 1106static constexpr std::array<Builtin::Info, NumNeonBuiltins> BuiltinInfos = {1107#define GET_NEON_BUILTIN_INFOS1108#include "clang/Basic/arm_neon.inc"1109#undef GET_NEON_BUILTIN_INFOS1110};1111 1112namespace FP16 {1113#define GET_NEON_BUILTIN_STR_TABLE1114#include "clang/Basic/arm_fp16.inc"1115#undef GET_NEON_BUILTIN_STR_TABLE1116 1117static constexpr std::array<Builtin::Info, NumFp16Builtins> BuiltinInfos = {1118#define GET_NEON_BUILTIN_INFOS1119#include "clang/Basic/arm_fp16.inc"1120#undef GET_NEON_BUILTIN_INFOS1121};1122} // namespace FP161123} // namespace NEON1124} // namespace clang1125 1126namespace {1127namespace MVE {1128#define GET_MVE_BUILTIN_STR_TABLE1129#include "clang/Basic/arm_mve_builtins.inc"1130#undef GET_MVE_BUILTIN_STR_TABLE1131 1132static constexpr std::array<Builtin::Info, NumMVEBuiltins> BuiltinInfos = {1133#define GET_MVE_BUILTIN_INFOS1134#include "clang/Basic/arm_mve_builtins.inc"1135#undef GET_MVE_BUILTIN_INFOS1136};1137} // namespace MVE1138 1139namespace CDE {1140#define GET_CDE_BUILTIN_STR_TABLE1141#include "clang/Basic/arm_cde_builtins.inc"1142#undef GET_CDE_BUILTIN_STR_TABLE1143 1144static constexpr std::array<Builtin::Info, NumCDEBuiltins> BuiltinInfos = {1145#define GET_CDE_BUILTIN_INFOS1146#include "clang/Basic/arm_cde_builtins.inc"1147#undef GET_CDE_BUILTIN_INFOS1148};1149} // namespace CDE1150} // namespace1151 1152static constexpr llvm::StringTable BuiltinStrings =1153    CLANG_BUILTIN_STR_TABLE_START1154#define BUILTIN CLANG_BUILTIN_STR_TABLE1155#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE1156#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE1157#include "clang/Basic/BuiltinsARM.def"1158    ; // namespace clang1159 1160static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumARMBuiltins>({1161#define BUILTIN CLANG_BUILTIN_ENTRY1162#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY1163#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY1164#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY1165#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY1166#include "clang/Basic/BuiltinsARM.def"1167});1168 1169llvm::SmallVector<Builtin::InfosShard>1170ARMTargetInfo::getTargetBuiltins() const {1171  return {1172      {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"},1173      {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos,1174       "__builtin_neon_"},1175      {&MVE::BuiltinStrings, MVE::BuiltinInfos, "__builtin_arm_mve_"},1176      {&CDE::BuiltinStrings, CDE::BuiltinInfos, "__builtin_arm_cde_"},1177      {&BuiltinStrings, BuiltinInfos},1178  };1179}1180 1181bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }1182TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {1183  return IsAAPCS1184             ? AAPCSABIBuiltinVaList1185             : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList1186                                         : TargetInfo::VoidPtrBuiltinVaList);1187}1188 1189const char *const ARMTargetInfo::GCCRegNames[] = {1190    // Integer registers1191    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",1192    "r12", "sp", "lr", "pc",1193 1194    // Float registers1195    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",1196    "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",1197    "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",1198 1199    // Double registers1200    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",1201    "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",1202    "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",1203 1204    // Quad registers1205    "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",1206    "q12", "q13", "q14", "q15"};1207 1208ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {1209  return llvm::ArrayRef(GCCRegNames);1210}1211 1212const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {1213    {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},1214    {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},1215    {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},1216    {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},1217    // The S, D and Q registers overlap, but aren't really aliases; we1218    // don't want to substitute one of these for a different-sized one.1219};1220 1221ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {1222  return llvm::ArrayRef(GCCRegAliases);1223}1224 1225bool ARMTargetInfo::validateAsmConstraint(1226    const char *&Name, TargetInfo::ConstraintInfo &Info) const {1227  switch (*Name) {1228  default:1229    break;1230  case 'l': // r0-r7 if thumb, r0-r15 if ARM1231    Info.setAllowsRegister();1232    return true;1233  case 'h': // r8-r15, thumb only1234    if (isThumb()) {1235      Info.setAllowsRegister();1236      return true;1237    }1238    break;1239  case 's': // An integer constant, but allowing only relocatable values.1240    return true;1241  case 't': // s0-s31, d0-d31, or q0-q151242  case 'w': // s0-s15, d0-d7, or q0-q31243  case 'x': // s0-s31, d0-d15, or q0-q71244    if (FPRegsDisabled)1245      return false;1246    Info.setAllowsRegister();1247    return true;1248  case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)1249    // only available in ARMv6T2 and above1250    if (CPUAttr == "6T2" || ArchVersion >= 7) {1251      Info.setRequiresImmediate(0, 65535);1252      return true;1253    }1254    break;1255  case 'I':1256    if (isThumb()) {1257      if (!supportsThumb2())1258        Info.setRequiresImmediate(0, 255);1259      else1260        // FIXME: should check if immediate value would be valid for a Thumb21261        // data-processing instruction1262        Info.setRequiresImmediate();1263    } else1264      // FIXME: should check if immediate value would be valid for an ARM1265      // data-processing instruction1266      Info.setRequiresImmediate();1267    return true;1268  case 'J':1269    if (isThumb() && !supportsThumb2())1270      Info.setRequiresImmediate(-255, -1);1271    else1272      Info.setRequiresImmediate(-4095, 4095);1273    return true;1274  case 'K':1275    if (isThumb()) {1276      if (!supportsThumb2())1277        // FIXME: should check if immediate value can be obtained from shifting1278        // a value between 0 and 255 left by any amount1279        Info.setRequiresImmediate();1280      else1281        // FIXME: should check if immediate value would be valid for a Thumb21282        // data-processing instruction when inverted1283        Info.setRequiresImmediate();1284    } else1285      // FIXME: should check if immediate value would be valid for an ARM1286      // data-processing instruction when inverted1287      Info.setRequiresImmediate();1288    return true;1289  case 'L':1290    if (isThumb()) {1291      if (!supportsThumb2())1292        Info.setRequiresImmediate(-7, 7);1293      else1294        // FIXME: should check if immediate value would be valid for a Thumb21295        // data-processing instruction when negated1296        Info.setRequiresImmediate();1297    } else1298      // FIXME: should check if immediate value  would be valid for an ARM1299      // data-processing instruction when negated1300      Info.setRequiresImmediate();1301    return true;1302  case 'M':1303    if (isThumb() && !supportsThumb2())1304      // FIXME: should check if immediate value is a multiple of 4 between 0 and1305      // 10201306      Info.setRequiresImmediate();1307    else1308      // FIXME: should check if immediate value is a power of two or a integer1309      // between 0 and 321310      Info.setRequiresImmediate();1311    return true;1312  case 'N':1313    // Thumb1 only1314    if (isThumb() && !supportsThumb2()) {1315      Info.setRequiresImmediate(0, 31);1316      return true;1317    }1318    break;1319  case 'O':1320    // Thumb1 only1321    if (isThumb() && !supportsThumb2()) {1322      // FIXME: should check if immediate value is a multiple of 4 between -5081323      // and 5081324      Info.setRequiresImmediate();1325      return true;1326    }1327    break;1328  case 'Q': // A memory address that is a single base register.1329    Info.setAllowsMemory();1330    return true;1331  case 'T':1332    switch (Name[1]) {1333    default:1334      break;1335    case 'e': // Even general-purpose register1336    case 'o': // Odd general-purpose register1337      Info.setAllowsRegister();1338      Name++;1339      return true;1340    }1341    break;1342  case 'U': // a memory reference...1343    switch (Name[1]) {1344    case 'q': // ...ARMV4 ldrsb1345    case 'v': // ...VFP load/store (reg+constant offset)1346    case 'y': // ...iWMMXt load/store1347    case 't': // address valid for load/store opaque types wider1348              // than 128-bits1349    case 'n': // valid address for Neon doubleword vector load/store1350    case 'm': // valid address for Neon element and structure load/store1351    case 's': // valid address for non-offset loads/stores of quad-word1352              // values in four ARM registers1353      Info.setAllowsMemory();1354      Name++;1355      return true;1356    }1357    break;1358  }1359  return false;1360}1361 1362std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {1363  std::string R;1364  switch (*Constraint) {1365  case 'U': // Two-character constraint; add "^" hint for later parsing.1366  case 'T':1367    R = std::string("^") + std::string(Constraint, 2);1368    Constraint++;1369    break;1370  case 'p': // 'p' should be translated to 'r' by default.1371    R = std::string("r");1372    break;1373  default:1374    return std::string(1, *Constraint);1375  }1376  return R;1377}1378 1379bool ARMTargetInfo::validateConstraintModifier(1380    StringRef Constraint, char Modifier, unsigned Size,1381    std::string &SuggestedModifier) const {1382  bool isOutput = (Constraint[0] == '=');1383  bool isInOut = (Constraint[0] == '+');1384 1385  // Strip off constraint modifiers.1386  Constraint = Constraint.ltrim("=+&");1387 1388  switch (Constraint[0]) {1389  default:1390    break;1391  case 'r': {1392    switch (Modifier) {1393    default:1394      return (isInOut || isOutput || Size <= 64);1395    case 'q':1396      // A register of size 32 cannot fit a vector type.1397      return false;1398    }1399  }1400  }1401 1402  return true;1403}1404std::string_view ARMTargetInfo::getClobbers() const {1405  // FIXME: Is this really right?1406  return "";1407}1408 1409TargetInfo::CallingConvCheckResult1410ARMTargetInfo::checkCallingConvention(CallingConv CC) const {1411  switch (CC) {1412  case CC_AAPCS:1413  case CC_AAPCS_VFP:1414  case CC_Swift:1415  case CC_SwiftAsync:1416  case CC_DeviceKernel:1417    return CCCR_OK;1418  default:1419    return CCCR_Warning;1420  }1421}1422 1423int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {1424  if (RegNo == 0)1425    return 0;1426  if (RegNo == 1)1427    return 1;1428  return -1;1429}1430 1431bool ARMTargetInfo::hasSjLjLowering() const { return true; }1432 1433ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,1434                                 const TargetOptions &Opts)1435    : ARMTargetInfo(Triple, Opts) {}1436 1437void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,1438                                       MacroBuilder &Builder) const {1439  Builder.defineMacro("__ARMEL__");1440  ARMTargetInfo::getTargetDefines(Opts, Builder);1441}1442 1443ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,1444                                 const TargetOptions &Opts)1445    : ARMTargetInfo(Triple, Opts) {}1446 1447void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,1448                                       MacroBuilder &Builder) const {1449  Builder.defineMacro("__ARMEB__");1450  Builder.defineMacro("__ARM_BIG_ENDIAN");1451  ARMTargetInfo::getTargetDefines(Opts, Builder);1452}1453 1454WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,1455                                           const TargetOptions &Opts)1456    : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {1457}1458 1459void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,1460                                                  MacroBuilder &Builder) const {1461  // FIXME: this is invalid for WindowsCE1462  Builder.defineMacro("_M_ARM_NT", "1");1463  Builder.defineMacro("_M_ARMT", "_M_ARM");1464  Builder.defineMacro("_M_THUMB", "_M_ARM");1465 1466  assert((Triple.getArch() == llvm::Triple::arm ||1467          Triple.getArch() == llvm::Triple::thumb) &&1468         "invalid architecture for Windows ARM target info");1469  unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;1470  Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));1471 1472  // TODO map the complete set of values1473  // 31: VFPv3 40: VFPv41474  Builder.defineMacro("_M_ARM_FP", "31");1475}1476 1477TargetInfo::BuiltinVaListKind1478WindowsARMTargetInfo::getBuiltinVaListKind() const {1479  return TargetInfo::CharPtrBuiltinVaList;1480}1481 1482TargetInfo::CallingConvCheckResult1483WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {1484  switch (CC) {1485  case CC_X86StdCall:1486  case CC_X86ThisCall:1487  case CC_X86FastCall:1488  case CC_X86VectorCall:1489    return CCCR_Ignore;1490  case CC_C:1491  case CC_DeviceKernel:1492  case CC_PreserveMost:1493  case CC_PreserveAll:1494  case CC_Swift:1495  case CC_SwiftAsync:1496    return CCCR_OK;1497  default:1498    return CCCR_Warning;1499  }1500}1501 1502// Windows ARM + Itanium C++ ABI Target1503ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(1504    const llvm::Triple &Triple, const TargetOptions &Opts)1505    : WindowsARMTargetInfo(Triple, Opts) {1506  TheCXXABI.set(TargetCXXABI::GenericARM);1507}1508 1509void ItaniumWindowsARMleTargetInfo::getTargetDefines(1510    const LangOptions &Opts, MacroBuilder &Builder) const {1511  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);1512 1513  if (Opts.MSVCCompat)1514    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);1515}1516 1517// Windows ARM, MS (C++) ABI1518MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,1519                                                   const TargetOptions &Opts)1520    : WindowsARMTargetInfo(Triple, Opts) {1521  TheCXXABI.set(TargetCXXABI::Microsoft);1522}1523 1524void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,1525                                                MacroBuilder &Builder) const {1526  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);1527  WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);1528}1529 1530MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,1531                                       const TargetOptions &Opts)1532    : WindowsARMTargetInfo(Triple, Opts) {1533  TheCXXABI.set(TargetCXXABI::GenericARM);1534}1535 1536void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,1537                                          MacroBuilder &Builder) const {1538  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);1539  Builder.defineMacro("_ARM_");1540}1541 1542CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,1543                                         const TargetOptions &Opts)1544    : ARMleTargetInfo(Triple, Opts) {1545  this->WCharType = TargetInfo::UnsignedShort;1546  TLSSupported = false;1547  DoubleAlign = LongLongAlign = 64;1548  resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");1549}1550 1551void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,1552                                           MacroBuilder &Builder) const {1553  ARMleTargetInfo::getTargetDefines(Opts, Builder);1554  Builder.defineMacro("_ARM_");1555  Builder.defineMacro("__CYGWIN__");1556  Builder.defineMacro("__CYGWIN32__");1557  DefineStd(Builder, "unix", Opts);1558  if (Opts.CPlusPlus)1559    Builder.defineMacro("_GNU_SOURCE");1560}1561 1562AppleMachOARMTargetInfo::AppleMachOARMTargetInfo(const llvm::Triple &Triple,1563                                                 const TargetOptions &Opts)1564    : AppleMachOTargetInfo<ARMleTargetInfo>(Triple, Opts) {}1565 1566void AppleMachOARMTargetInfo::getOSDefines(const LangOptions &Opts,1567                                           const llvm::Triple &Triple,1568                                           MacroBuilder &Builder) const {1569  getAppleMachODefines(Builder, Opts, Triple);1570}1571 1572DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,1573                                         const TargetOptions &Opts)1574    : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {1575  HasAlignMac68kSupport = true;1576  if (Triple.isWatchABI()) {1577    // Darwin on iOS uses a variant of the ARM C++ ABI.1578    TheCXXABI.set(TargetCXXABI::WatchOS);1579 1580    // BOOL should be a real boolean on the new ABI1581    UseSignedCharForObjCBool = false;1582  } else1583    TheCXXABI.set(TargetCXXABI::iOS);1584}1585 1586void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,1587                                       const llvm::Triple &Triple,1588                                       MacroBuilder &Builder) const {1589  getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);1590}1591