//===- ARMTargetDefEmitter.cpp - Generate data about ARM Architectures ----===//
//
// 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 tablegen backend exports information about CPUs, FPUs, architectures,
// and features into a common format that can be used by both TargetParser and
// the ARM and AArch64 backends.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <set>
#include <string>

using namespace llvm;

/// Collect the full set of implied features for a SubtargetFeature.
static void collectImpliedFeatures(std::set<const Record *> &SeenFeats,
                                   const Record *Rec) {
  assert(Rec->isSubClassOf("SubtargetFeature") &&
         "Rec is not a SubtargetFeature");

  SeenFeats.insert(Rec);
  for (const Record *Implied : Rec->getValueAsListOfDefs("Implies"))
    collectImpliedFeatures(SeenFeats, Implied);
}

static void checkFeatureTree(const Record *Root) {
  std::set<const Record *> SeenFeats;
  collectImpliedFeatures(SeenFeats, Root);

  // Check that each of the mandatory (implied) features which is an
  // ExtensionWithMArch is also enabled by default.
  auto DefaultExtsVec = Root->getValueAsListOfDefs("DefaultExts");
  std::set<const Record *> DefaultExts{DefaultExtsVec.begin(),
                                       DefaultExtsVec.end()};
  for (const Record *Feat : SeenFeats) {
    if (Feat->isSubClassOf("ExtensionWithMArch") && !DefaultExts.count(Feat))
      PrintFatalError(Root->getLoc(),
                      "ExtensionWithMArch " + Feat->getName() +
                          " is implied (mandatory) as a SubtargetFeature, but "
                          "is not present in DefaultExts");
  }
}

static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
  OS << "// Autogenerated by ARMTargetDefEmitter.cpp\n\n";

  // Look through all SubtargetFeature defs with the given FieldName, and
  // collect the set of all Values that that FieldName is set to.
  auto GatherSubtargetFeatureFieldValues = [&RK](StringRef FieldName) {
    llvm::StringSet<> Set;
    for (const Record *Rec : RK.getAllDerivedDefinitions("SubtargetFeature")) {
      if (Rec->getValueAsString("FieldName") == FieldName) {
        Set.insert(Rec->getValueAsString("Value"));
      }
    }
    return Set;
  };

  // Sort the extensions alphabetically, so they don't appear in tablegen order.
  std::vector<const Record *> SortedExtensions =
      RK.getAllDerivedDefinitions("Extension");
  auto Alphabetical = [](const Record *A, const Record *B) -> bool {
    const auto NameA = A->getValueAsString("Name");
    const auto NameB = B->getValueAsString("Name");
    return NameA.compare(NameB) < 0; // A lexographically less than B
  };
  sort(SortedExtensions, Alphabetical);

  // Cache Extension records for quick lookup.
  DenseMap<StringRef, const Record *> ExtensionMap;
  for (const Record *Rec : SortedExtensions) {
    auto Name = Rec->getValueAsString("UserVisibleName");
    if (Name.empty())
      Name = Rec->getValueAsString("Name");
    ExtensionMap[Name] = Rec;
  }

  // The ARMProcFamilyEnum values are initialised by SubtargetFeature defs
  // which set the ARMProcFamily field. We can generate the enum from these defs
  // which look like this:
  //
  // def ProcA5      : SubtargetFeature<"a5", "ARMProcFamily", "CortexA5",
  //                                    "Cortex-A5 ARM processors", []>;
  OS << "#ifndef ARM_PROCESSOR_FAMILY\n"
     << "#define ARM_PROCESSOR_FAMILY(ENUM)\n"
     << "#endif\n\n";
  const StringSet<> ARMProcFamilyVals =
      GatherSubtargetFeatureFieldValues("ARMProcFamily");
  for (const StringRef &Family : ARMProcFamilyVals.keys())
    OS << "ARM_PROCESSOR_FAMILY(" << Family << ")\n";
  OS << "\n#undef ARM_PROCESSOR_FAMILY\n\n";

  OS << "#ifndef ARM_ARCHITECTURE\n"
     << "#define ARM_ARCHITECTURE(ENUM)\n"
     << "#endif\n\n";
  // This should correspond to instances of the Architecture tablegen class.
  const StringSet<> ARMArchVals = GatherSubtargetFeatureFieldValues("ARMArch");
  for (const StringRef &Arch : ARMArchVals.keys())
    OS << "ARM_ARCHITECTURE(" << Arch << ")\n";
  OS << "\n#undef ARM_ARCHITECTURE\n\n";

  // Currently only AArch64 (not ARM) is handled beyond this point.
  if (!RK.getClass("Architecture64"))
    return;

  // Emit the ArchExtKind enum
  OS << "#ifdef EMIT_ARCHEXTKIND_ENUM\n"
     << "enum ArchExtKind : unsigned {\n";
  for (const Record *Rec : SortedExtensions) {
    auto AEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
    OS << "  " << AEK << ",\n";
  }
  OS << "  AEK_NUM_EXTENSIONS\n"
     << "};\n"
     << "#undef EMIT_ARCHEXTKIND_ENUM\n"
     << "#endif // EMIT_ARCHEXTKIND_ENUM\n";

  // Emit information for each defined Extension; used to build ArmExtKind.
  OS << "#ifdef EMIT_EXTENSIONS\n"
     << "inline constexpr ExtensionInfo Extensions[] = {\n";
  for (const Record *Rec : SortedExtensions) {
    auto AEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
    OS << "  ";
    OS << "{\"" << Rec->getValueAsString("UserVisibleName") << "\"";
    if (auto Alias = Rec->getValueAsString("UserVisibleAlias"); Alias.empty())
      OS << ", {}";
    else
      OS << ", \"" << Alias << "\"";
    OS << ", AArch64::" << AEK;
    OS << ", \"" << Rec->getValueAsString("ArchFeatureName") << "\"";
    OS << ", \"" << Rec->getValueAsString("Desc") << "\"";
    OS << ", \"+" << Rec->getValueAsString("Name") << "\""; // posfeature
    OS << ", \"-" << Rec->getValueAsString("Name") << "\""; // negfeature
    OS << "},\n";
  };
  OS << "};\n"
     << "#undef EMIT_EXTENSIONS\n"
     << "#endif // EMIT_EXTENSIONS\n"
     << "\n";

  // Emit FMV information
  auto FMVExts = RK.getAllDerivedDefinitionsIfDefined("FMVExtension");
  OS << "#ifdef EMIT_FMV_INFO\n"
     << "const std::vector<llvm::AArch64::FMVInfo>& "
        "llvm::AArch64::getFMVInfo() {\n"
     << "  static std::vector<FMVInfo> I;\n"
     << "  if(I.size()) return I;\n"
     << "  I.reserve(" << FMVExts.size() << ");\n";
  for (const Record *Rec : FMVExts) {
    auto FeatName = Rec->getValueAsString("BackendFeature");
    const Record *FeatRec = ExtensionMap[FeatName];
    OS << "  I.emplace_back(";
    OS << "\"" << Rec->getValueAsString("Name") << "\"";
    if (FeatRec)
      OS << ", " << Rec->getValueAsString("FeatureBit");
    else
      OS << ", std::nullopt";
    OS << ", " << Rec->getValueAsString("PriorityBit");
    if (FeatRec)
      OS << ", " << FeatRec->getValueAsString("ArchExtKindSpelling").upper();
    else
      OS << ", std::nullopt";
    OS << ");\n";
  };
  OS << "  return I;\n"
     << "}\n"
     << "#undef EMIT_FMV_INFO\n"
     << "#endif // EMIT_FMV_INFO\n"
     << "\n";

  // Emit extension dependencies
  OS << "#ifdef EMIT_EXTENSION_DEPENDENCIES\n"
     << "inline constexpr ExtensionDependency ExtensionDependencies[] = {\n";
  for (const Record *Rec : SortedExtensions) {
    auto LaterAEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
    for (const Record *I : Rec->getValueAsListOfDefs("Implies"))
      if (auto EarlierAEK = I->getValueAsOptionalString("ArchExtKindSpelling"))
        OS << "  {" << EarlierAEK->upper() << ", " << LaterAEK << "},\n";
  }
  // FIXME: Tablegen has the Subtarget Feature FeatureRCPC_IMMO which is implied
  // by FeatureRCPC3 and in turn implies FeatureRCPC. The proper fix is to make
  // FeatureRCPC_IMMO an Extension but that will expose it to the command line.
  OS << "  {AEK_RCPC, AEK_RCPC3},\n";
  OS << "};\n"
     << "#undef EMIT_EXTENSION_DEPENDENCIES\n"
     << "#endif // EMIT_EXTENSION_DEPENDENCIES\n"
     << "\n";

  // Emit architecture information
  OS << "#ifdef EMIT_ARCHITECTURES\n";

  // Return the C++ name of the of an ArchInfo object
  auto ArchInfoName = [](int Major, int Minor,
                         StringRef Profile) -> std::string {
    return Minor == 0 ? "ARMV" + std::to_string(Major) + Profile.upper()
                      : "ARMV" + std::to_string(Major) + "_" +
                            std::to_string(Minor) + Profile.upper();
  };

  auto Architectures = RK.getAllDerivedDefinitionsIfDefined("Architecture64");
  std::vector<std::string> CppSpellings;
  for (const Record *Rec : Architectures) {
    const int Major = Rec->getValueAsInt("Major");
    const int Minor = Rec->getValueAsInt("Minor");
    const std::string ProfileLower = Rec->getValueAsString("Profile").str();
    const std::string ProfileUpper = Rec->getValueAsString("Profile").upper();

    if (ProfileLower != "a" && ProfileLower != "r")
      PrintFatalError(Rec->getLoc(),
                      "error: Profile must be one of 'a' or 'r', got '" +
                          ProfileLower + "'");

    // Name of the object in C++
    std::string CppSpelling = ArchInfoName(Major, Minor, ProfileUpper);
    OS << "inline constexpr ArchInfo " << CppSpelling << " = {\n";
    CppSpellings.push_back(std::move(CppSpelling));

    OS << llvm::format("  VersionTuple{%d, %d},\n", Major, Minor);
    OS << llvm::format("  %sProfile,\n", ProfileUpper.c_str());

    // Name as spelled for -march.
    if (Minor == 0)
      OS << llvm::format("  \"armv%d-%s\",\n", Major, ProfileLower.c_str());
    else
      OS << llvm::format("  \"armv%d.%d-%s\",\n", Major, Minor,
                         ProfileLower.c_str());

    // SubtargetFeature::Name, used for -target-feature. Here the "+" is added.
    const auto TargetFeatureName = Rec->getValueAsString("Name");
    OS << "  \"+" << TargetFeatureName << "\",\n";

    // Construct the list of default extensions
    OS << "  (AArch64::ExtensionBitset({";
    for (auto *E : Rec->getValueAsListOfDefs("DefaultExts")) {
      OS << "AArch64::" << E->getValueAsString("ArchExtKindSpelling").upper()
         << ", ";
    }
    OS << "}))\n";

    OS << "};\n";
  }

  OS << "\n"
     << "/// The set of all architectures\n"
     << "static constexpr std::array<const ArchInfo *, " << CppSpellings.size()
     << "> ArchInfos = {\n";
  for (StringRef CppSpelling : CppSpellings)
    OS << "  &" << CppSpelling << ",\n";
  OS << "};\n";

  OS << "#undef EMIT_ARCHITECTURES\n"
     << "#endif // EMIT_ARCHITECTURES\n"
     << "\n";

  // Emit CPU Aliases
  OS << "#ifdef EMIT_CPU_ALIAS\n"
     << "inline constexpr Alias CpuAliases[] = {\n";

  llvm::StringSet<> Processors;
  for (const Record *Rec : RK.getAllDerivedDefinitions("ProcessorModel"))
    Processors.insert(Rec->getValueAsString("Name"));

  llvm::StringSet<> Aliases;
  for (const Record *Rec : RK.getAllDerivedDefinitions("ProcessorAlias")) {
    auto Name = Rec->getValueAsString("Name");
    auto Alias = Rec->getValueAsString("Alias");
    if (!Processors.contains(Alias))
      PrintFatalError(
          Rec, "Alias '" + Name + "' references a non-existent ProcessorModel '" + Alias + "'");
    if (Processors.contains(Name))
      PrintFatalError(
          Rec, "Alias '" + Name + "' duplicates an existing ProcessorModel");
    if (!Aliases.insert(Name).second)
      PrintFatalError(
          Rec, "Alias '" + Name + "' duplicates an existing ProcessorAlias");

    OS << llvm::formatv(R"(  { "{0}", "{1}" },)", Name, Alias) << '\n';
  }

  OS << "};\n"
     << "#undef EMIT_CPU_ALIAS\n"
     << "#endif // EMIT_CPU_ALIAS\n"
     << "\n";

  // Emit CPU information
  OS << "#ifdef EMIT_CPU_INFO\n"
     << "inline constexpr CpuInfo CpuInfos[] = {\n";

  for (const Record *Rec : RK.getAllDerivedDefinitions("ProcessorModel")) {
    auto Name = Rec->getValueAsString("Name");
    auto Features = Rec->getValueAsListOfDefs("Features");

    // "apple-latest" is backend-only, should not be accepted by TargetParser.
    if (Name == "apple-latest")
      continue;

    const Record *Arch;
    if (Name == "generic") {
      // "generic" is an exception. It does not have an architecture, and there
      // are tests that depend on e.g. -mattr=-v8.4a meaning HasV8_0aOps==false.
      // However, in TargetParser CPUInfo, it is written as 8.0-A.
      Arch = RK.getDef("HasV8_0aOps");
    } else {
      // Search for an Architecture64 in the list of features.
      auto IsArch = [](const Record *F) {
        return F->isSubClassOf("Architecture64");
      };
      auto ArchIter = llvm::find_if(Features, IsArch);
      if (ArchIter == Features.end())
        PrintFatalError(Rec, "Features must include an Architecture64.");
      Arch = *ArchIter;

      // Check there is only one Architecture in the list.
      if (llvm::count_if(Features, IsArch) > 1)
        PrintFatalError(Rec, "Features has multiple Architecture64 entries");
    }

    auto Major = Arch->getValueAsInt("Major");
    auto Minor = Arch->getValueAsInt("Minor");
    auto Profile = Arch->getValueAsString("Profile");
    auto ArchInfo = ArchInfoName(Major, Minor, Profile);

    checkFeatureTree(Arch);

    OS << "  {\n"
       << "    \"" << Name << "\",\n"
       << "    " << ArchInfo << ",\n"
       << "    AArch64::ExtensionBitset({\n";

    // Keep track of extensions we have seen
    StringSet<> SeenExts;
    for (const Record *E : Rec->getValueAsListOfDefs("Features"))
      // Only process subclasses of Extension
      if (E->isSubClassOf("Extension")) {
        const auto AEK = E->getValueAsString("ArchExtKindSpelling").upper();
        if (!SeenExts.insert(AEK).second)
          PrintFatalError(Rec, "feature already added: " + E->getName());
        OS << "      AArch64::" << AEK << ",\n";
      }
    OS << "    })\n"
       << "  },\n";
  }
  OS << "};\n";

  OS << "#undef EMIT_CPU_INFO\n"
     << "#endif // EMIT_CPU_INFO\n"
     << "\n";
}

static TableGen::Emitter::Opt
    X("gen-arm-target-def", emitARMTargetDef,
      "Generate the ARM or AArch64 Architecture information header.");
