//===- 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/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.");

  OS << "namespace " << Target << " {\n";

  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 and namespace
  OS << "};\n";
  OS << "} // end namespace " << Target << "\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";

  OS << "\n#ifdef GET_SUBTARGETFEATURES_ENUM\n";
  OS << "#undef GET_SUBTARGETFEATURES_ENUM\n\n";

  OS << "namespace llvm {\n";
  auto FeatureMap = enumeration(OS);
  OS << "} // end namespace llvm\n\n";
  OS << "#endif // GET_SUBTARGETFEATURES_ENUM\n\n";

  OS << "\n#ifdef GET_SUBTARGETFEATURES_KV\n";
  OS << "#undef GET_SUBTARGETFEATURES_KV\n\n";

  OS << "namespace llvm {\n";
  printFeatureKeyValues(OS, FeatureMap);
  OS << "\n";

  printCPUKeyValues(OS, FeatureMap);
  OS << "\n";
  OS << "} // end namespace llvm\n\n";
  OS << "#endif // GET_SUBTARGETFEATURES_KV\n\n";
}

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