//===- TargetFeaturesEmitter.cpp - Generate CPU Target feature ----===//
//
// 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 cpu target features
//  and cpu sub-type.
//
//===----------------------------------------------------------------------===//

#include "TargetFeaturesEmitter.h"
#include "llvm/TableGen/CodeGenHelpers.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/TargetParser/SubtargetFeature.h"

using namespace llvm;

using FeatureMapTy = DenseMap<const Record *, unsigned>;
using ConstRecVec = std::vector<const Record *>;

TargetFeaturesEmitter::TargetFeaturesEmitter(const RecordKeeper &R)
    : Records(R) {
  ArrayRef<const Record *> Targets = Records.getAllDerivedDefinitions("Target");
  if (Targets.size() == 0)
    PrintFatalError("No 'Target' subclasses defined!");
  if (Targets.size() != 1)
    PrintFatalError("Multiple subclasses of Target defined!");
  Target = Targets[0]->getName();
}

FeatureMapTy TargetFeaturesEmitter::enumeration(raw_ostream &OS) {
  ArrayRef<const Record *> DefList =
      Records.getAllDerivedDefinitions("SubtargetFeature");

  unsigned N = DefList.size();
  if (N == 0)
    return FeatureMapTy();

  if (N + 1 > MAX_SUBTARGET_FEATURES)
    PrintFatalError(
        "Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");

  NamespaceEmitter NS(OS, Target);

  OS << "enum {\n";

  FeatureMapTy FeatureMap;
  for (unsigned I = 0; I < N; ++I) {
    const Record *Def = DefList[I];
    // Print the Feature Name.
    OS << "  " << Def->getName() << " = " << I << ",\n";

    FeatureMap[Def] = I;
  }

  OS << "  " << "NumSubtargetFeatures = " << N << "\n";

  // Close enumeration.
  OS << "};\n";
  return FeatureMap;
}

void TargetFeaturesEmitter::printFeatureMask(
    raw_ostream &OS, ArrayRef<const Record *> FeatureList,
    const FeatureMapTy &FeatureMap) {
  std::array<uint64_t, MAX_SUBTARGET_WORDS> Mask = {};
  for (const Record *Feature : FeatureList) {
    unsigned Bit = FeatureMap.lookup(Feature);
    Mask[Bit / 64] |= 1ULL << (Bit % 64);
  }

  OS << "{ { { ";
  for (unsigned I = 0; I != Mask.size(); ++I) {
    OS << "0x";
    OS.write_hex(Mask[I]);
    OS << "ULL, ";
  }
  OS << "} } }";
}

void TargetFeaturesEmitter::printFeatureKeyValues(
    raw_ostream &OS, const FeatureMapTy &FeatureMap) {
  std::vector<const Record *> FeatureList =
      Records.getAllDerivedDefinitions("SubtargetFeature");

  // Remove features with empty name.
  llvm::erase_if(FeatureList, [](const Record *Rec) {
    return Rec->getValueAsString("Name").empty();
  });

  if (FeatureList.empty())
    return;

  llvm::sort(FeatureList, LessRecordFieldName());

  // Begin feature table.
  OS << "// Sorted (by key) array of values for CPU features.\n"
     << "extern const llvm::BasicSubtargetFeatureKV " << "Basic" << Target
     << "FeatureKV[] = {\n";

  for (const Record *Feature : FeatureList) {
    StringRef Name = Feature->getName();
    StringRef ValueName = Feature->getValueAsString("Name");

    OS << "  { " << "\"" << ValueName << "\", " << Target << "::" << Name
       << ", ";

    ConstRecVec ImpliesList = Feature->getValueAsListOfDefs("Implies");

    printFeatureMask(OS, ImpliesList, FeatureMap);

    OS << " },\n";
  }

  // End feature table.
  OS << "};\n";
}

void TargetFeaturesEmitter::printCPUKeyValues(raw_ostream &OS,
                                              const FeatureMapTy &FeatureMap) {
  // Gather and sort processor information
  std::vector<const Record *> ProcessorList =
      Records.getAllDerivedDefinitions("Processor");
  llvm::sort(ProcessorList, LessRecordFieldName());

  // Begin processor table.
  OS << "// Sorted (by key) array of values for CPU subtype.\n"
     << "extern const llvm::BasicSubtargetSubTypeKV " << "Basic" << Target
     << "SubTypeKV[] = {\n";

  for (const Record *Processor : ProcessorList) {
    StringRef Name = Processor->getValueAsString("Name");
    ConstRecVec FeatureList = Processor->getValueAsListOfDefs("Features");

    OS << " { " << "\"" << Name << "\", ";

    printFeatureMask(OS, FeatureList, FeatureMap);
    OS << " },\n";
  }

  // End processor table.
  OS << "};\n";
}

void TargetFeaturesEmitter::run(raw_ostream &OS) {
  OS << "// Autogenerated by TargetFeatureEmitter.cpp\n\n";

  FeatureMapTy FeatureMap;
  {
    IfDefEmitter IfDef(OS, "GET_SUBTARGETFEATURES_ENUM");
    NamespaceEmitter NS(OS, "llvm");
    FeatureMap = enumeration(OS);
  }

  {
    IfDefEmitter IfDef(OS, "GET_SUBTARGETFEATURES_KV");
    NamespaceEmitter NS(OS, "llvm");

    printFeatureKeyValues(OS, FeatureMap);
    OS << "\n";

    printCPUKeyValues(OS, FeatureMap);
    OS << "\n";
  }
}

static TableGen::Emitter::OptClass<TargetFeaturesEmitter>
    X("gen-target-features", "Generate subtarget enumerations");
