//===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise AArch64 hardware features
// such as FPU/CPU/ARCH and extension names.
//
//===----------------------------------------------------------------------===//

#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/ARMTargetParserCommon.h"
#include "llvm/TargetParser/Triple.h"
#include <cctype>
#include <vector>

#define DEBUG_TYPE "target-parser"

using namespace llvm;

#define EMIT_FMV_INFO
#include "llvm/TargetParser/AArch64TargetParserDef.inc"

static unsigned checkArchVersion(llvm::StringRef Arch) {
  if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
    return (Arch[1] - 48);
  return 0;
}

const AArch64::ArchInfo *AArch64::getArchForCpu(StringRef CPU) {
  // Note: this now takes cpu aliases into account
  std::optional<CpuInfo> Cpu = parseCpu(CPU);
  if (!Cpu)
    return nullptr;
  return &Cpu->Arch;
}

std::optional<AArch64::ArchInfo> AArch64::ArchInfo::findBySubArch(StringRef SubArch) {
  for (const auto *A : AArch64::ArchInfos)
    if (A->getSubArch() == SubArch)
      return *A;
  return {};
}

unsigned AArch64::getFMVPriority(ArrayRef<StringRef> Features) {
  constexpr unsigned MaxFMVPriority = 1000;
  unsigned Priority = 0;
  unsigned NumFeatures = 0;
  for (StringRef Feature : Features) {
    if (auto Ext = parseFMVExtension(Feature)) {
      Priority = std::max(Priority, Ext->Priority);
      NumFeatures++;
    }
  }
  return Priority + MaxFMVPriority * NumFeatures;
}

uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> Features) {
  // Transitively enable the Arch Extensions which correspond to each feature.
  ExtensionSet FeatureBits;
  for (const StringRef Feature : Features)
    if (std::optional<FMVInfo> Info = parseFMVExtension(Feature))
      if (Info->ID)
        FeatureBits.enable(*Info->ID);

  // Construct a bitmask for all the transitively enabled Arch Extensions.
  uint64_t FeaturesMask = 0;
  for (const FMVInfo &Info : getFMVInfo())
    if (Info.ID && FeatureBits.Enabled.test(*Info.ID))
      FeaturesMask |= (1ULL << Info.Bit);

  return FeaturesMask;
}

bool AArch64::getExtensionFeatures(
    const AArch64::ExtensionBitset &InputExts,
    std::vector<StringRef> &Features) {
  for (const auto &E : Extensions)
    /* INVALID and NONE have no feature name. */
    if (InputExts.test(E.ID) && !E.PosTargetFeature.empty())
      Features.push_back(E.PosTargetFeature);

  return true;
}

StringRef AArch64::resolveCPUAlias(StringRef Name) {
  for (const auto &A : CpuAliases)
    if (A.AltName == Name)
      return A.Name;
  return Name;
}

StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
  bool IsNegated = ArchExt.starts_with("no");
  StringRef ArchExtBase = IsNegated ? ArchExt.drop_front(2) : ArchExt;

  if (auto AE = parseArchExtension(ArchExtBase)) {
    assert(!(AE.has_value() && AE->NegTargetFeature.empty()));
    return IsNegated ? AE->NegTargetFeature : AE->PosTargetFeature;
  }

  return StringRef();
}

void AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
  for (const auto &C : CpuInfos)
    Values.push_back(C.Name);

  for (const auto &Alias : CpuAliases)
    // The apple-latest alias is backend only, do not expose it to clang's -mcpu.
    if (Alias.AltName != "apple-latest")
      Values.push_back(Alias.AltName);

  llvm::sort(Values);
}

bool AArch64::isX18ReservedByDefault(const Triple &TT) {
  return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() ||
         TT.isOSWindows() || TT.isOHOSFamily();
}

// Allows partial match, ex. "v8a" matches "armv8a".
const AArch64::ArchInfo *AArch64::parseArch(StringRef Arch) {
  Arch = llvm::ARM::getCanonicalArchName(Arch);
  if (checkArchVersion(Arch) < 8)
    return {};

  StringRef Syn = llvm::ARM::getArchSynonym(Arch);
  for (const auto *A : ArchInfos) {
    if (A->Name.ends_with(Syn))
      return A;
  }
  return {};
}

std::optional<AArch64::ExtensionInfo>
AArch64::parseArchExtension(StringRef ArchExt) {
  if (ArchExt.empty())
    return {};
  for (const auto &A : Extensions) {
    if (ArchExt == A.UserVisibleName || ArchExt == A.Alias)
      return A;
  }
  return {};
}

std::optional<AArch64::FMVInfo> AArch64::parseFMVExtension(StringRef FMVExt) {
  // FIXME introduce general alias functionality, or remove this exception.
  if (FMVExt == "rdma")
    FMVExt = "rdm";

  for (const auto &I : getFMVInfo()) {
    if (FMVExt == I.Name)
      return I;
  }
  return {};
}

std::optional<AArch64::ExtensionInfo>
AArch64::targetFeatureToExtension(StringRef TargetFeature) {
  for (const auto &E : Extensions)
    if (TargetFeature == E.PosTargetFeature)
      return E;
  return {};
}

std::optional<AArch64::CpuInfo> AArch64::parseCpu(StringRef Name) {
  // Resolve aliases first.
  Name = resolveCPUAlias(Name);

  // Then find the CPU name.
  for (const auto &C : CpuInfos)
    if (Name == C.Name)
      return C;

  return {};
}

void AArch64::PrintSupportedExtensions() {
  outs() << "All available -march extensions for AArch64\n\n"
         << "    " << left_justify("Name", 20)
         << left_justify("Architecture Feature(s)", 55)
         << "Description\n";
  for (const auto &Ext : Extensions) {
    // Extensions without a feature cannot be used with -march.
    if (!Ext.UserVisibleName.empty() && !Ext.PosTargetFeature.empty()) {
      outs() << "    "
             << format(Ext.Description.empty() ? "%-20s%s\n" : "%-20s%-55s%s\n",
                       Ext.UserVisibleName.str().c_str(),
                       Ext.ArchFeatureName.str().c_str(),
                       Ext.Description.str().c_str());
    }
  }
}

void
AArch64::printEnabledExtensions(const std::set<StringRef> &EnabledFeatureNames) {
  outs() << "Extensions enabled for the given AArch64 target\n\n"
         << "    " << left_justify("Architecture Feature(s)", 55)
         << "Description\n";
  std::vector<ExtensionInfo> EnabledExtensionsInfo;
  for (const auto &FeatureName : EnabledFeatureNames) {
    std::string PosFeatureName = '+' + FeatureName.str();
    if (auto ExtInfo = targetFeatureToExtension(PosFeatureName))
      EnabledExtensionsInfo.push_back(*ExtInfo);
  }

  std::sort(EnabledExtensionsInfo.begin(), EnabledExtensionsInfo.end(),
            [](const ExtensionInfo &Lhs, const ExtensionInfo &Rhs) {
              return Lhs.ArchFeatureName < Rhs.ArchFeatureName;
            });

  for (const auto &Ext : EnabledExtensionsInfo) {
    outs() << "    "
           << format("%-55s%s\n",
                     Ext.ArchFeatureName.str().c_str(),
                     Ext.Description.str().c_str());
  }
}

const llvm::AArch64::ExtensionInfo &
lookupExtensionByID(llvm::AArch64::ArchExtKind ExtID) {
  for (const auto &E : llvm::AArch64::Extensions)
    if (E.ID == ExtID)
      return E;
  llvm_unreachable("Invalid extension ID");
}

void AArch64::ExtensionSet::enable(ArchExtKind E) {
  if (Enabled.test(E))
    return;

  LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).UserVisibleName << "\n");

  Touched.set(E);
  Enabled.set(E);

  // Recursively enable all features that this one depends on. This handles all
  // of the simple cases, where the behaviour doesn't depend on the base
  // architecture version.
  for (auto Dep : ExtensionDependencies)
    if (E == Dep.Later)
      enable(Dep.Earlier);

  // Special cases for dependencies which vary depending on the base
  // architecture version.
  if (BaseArch) {
    // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
    if (E == AEK_FP16 && BaseArch->is_superset(ARMV8_4A) &&
        !BaseArch->is_superset(ARMV9A))
      enable(AEK_FP16FML);

    // For v8.4A+ and v9.0A+, +crypto also enables +sha3 and +sm4.
    if (E == AEK_CRYPTO && BaseArch->is_superset(ARMV8_4A)) {
      enable(AEK_SHA3);
      enable(AEK_SM4);
    }
  }
}

void AArch64::ExtensionSet::disable(ArchExtKind E) {
  // -crypto always disables aes, sha2, sha3 and sm4, even for architectures
  // where the latter two would not be enabled by +crypto.
  if (E == AEK_CRYPTO) {
    disable(AEK_AES);
    disable(AEK_SHA2);
    disable(AEK_SHA3);
    disable(AEK_SM4);
  }

  // sve2-aes was historically associated with both FEAT_SVE2 and FEAT_SVE_AES,
  // the latter is now associated with sve-aes and sve2-aes has become shorthand
  // for +sve2+sve-aes. For backwards compatibility, when we disable sve2-aes we
  // must also disable sve-aes.
  if (E == AEK_SVE2AES)
    disable(AEK_SVEAES);

  if (!Enabled.test(E))
    return;

  LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).UserVisibleName << "\n");

  Touched.set(E);
  Enabled.reset(E);

  // Recursively disable all features that depends on this one.
  for (auto Dep : ExtensionDependencies)
    if (E == Dep.Earlier)
      disable(Dep.Later);
}

void AArch64::ExtensionSet::addCPUDefaults(const CpuInfo &CPU) {
  LLVM_DEBUG(llvm::dbgs() << "addCPUDefaults(" << CPU.Name << ")\n");
  BaseArch = &CPU.Arch;

  AArch64::ExtensionBitset CPUExtensions = CPU.getImpliedExtensions();
  for (const auto &E : Extensions)
    if (CPUExtensions.test(E.ID))
      enable(E.ID);
}

void AArch64::ExtensionSet::addArchDefaults(const ArchInfo &Arch) {
  LLVM_DEBUG(llvm::dbgs() << "addArchDefaults(" << Arch.Name << ")\n");
  BaseArch = &Arch;

  for (const auto &E : Extensions)
    if (Arch.DefaultExts.test(E.ID))
      enable(E.ID);
}

bool AArch64::ExtensionSet::parseModifier(StringRef Modifier,
                                          const bool AllowNoDashForm) {
  LLVM_DEBUG(llvm::dbgs() << "parseModifier(" << Modifier << ")\n");

  size_t NChars = 0;
  // The "no-feat" form is allowed in the target attribute but nowhere else.
  if (AllowNoDashForm && Modifier.starts_with("no-"))
    NChars = 3;
  else if (Modifier.starts_with("no"))
    NChars = 2;
  bool IsNegated = NChars != 0;
  StringRef ArchExt = Modifier.drop_front(NChars);

  if (auto AE = parseArchExtension(ArchExt)) {
    if (AE->PosTargetFeature.empty() || AE->NegTargetFeature.empty())
      return false;
    if (IsNegated)
      disable(AE->ID);
    else
      enable(AE->ID);
    return true;
  }
  return false;
}

void AArch64::ExtensionSet::reconstructFromParsedFeatures(
    const std::vector<std::string> &Features,
    std::vector<std::string> &NonExtensions) {
  assert(Touched.none() && "Bitset already initialized");
  for (auto &F : Features) {
    bool IsNegated = F[0] == '-';
    if (auto AE = targetFeatureToExtension(F)) {
      Touched.set(AE->ID);
      if (IsNegated)
        Enabled.reset(AE->ID);
      else
        Enabled.set(AE->ID);
      continue;
    }
    NonExtensions.push_back(F);
  }
}

void AArch64::ExtensionSet::dump() const {
  std::vector<StringRef> Features;
  toLLVMFeatureList(Features);
  for (StringRef F : Features)
    llvm::outs() << F << " ";
  llvm::outs() << "\n";
}

const AArch64::ExtensionInfo &
AArch64::getExtensionByID(AArch64::ArchExtKind ExtID) {
  return lookupExtensionByID(ExtID);
}
