//===- 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) {
    OS << "  I.emplace_back(";
    OS << "\"" << Rec->getValueAsString("Name") << "\"";
    OS << ", " << Rec->getValueAsString("FeatureBit");
    OS << ", " << Rec->getValueAsString("PriorityBit");
    auto FeatName = Rec->getValueAsString("BackendFeature");
    const Record *FeatRec = ExtensionMap[FeatName];
    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.");
