//===- SystemZInsnDirectiveEmitter.cpp - Generate .insn match table -------===//
//
// 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 emits a match table for SystemZ .insn directives.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <string>

using namespace llvm;

namespace {

struct InsnMatchEntry {
  std::string Format;
  std::string Opcode;
  unsigned NumOptionalOperands;
  SmallVector<std::string, 8> OperandKinds;
};

static StringRef getFormatName(const Record &Def) {
  StringRef AsmString = Def.getValueAsString("AsmString");
  if (!AsmString.consume_front(".insn "))
    PrintFatalError(&Def, "expected .insn asm string");
  return AsmString.take_until([](char C) { return C == ','; });
}

static std::string getMatchClassKind(const Record &Def, const Init *Arg,
                                     unsigned OperandIndex) {

  // Obtain record of operand.
  const Record *OpRec;
  if (const DefInit *DefOp = dyn_cast<DefInit>(Arg))
    OpRec = DefOp->getDef();
  else if (const DagInit *DagOp = dyn_cast<DagInit>(Arg))
    OpRec = DagOp->getOperatorAsDef(Def.getLoc());
  else
    PrintFatalError(&Def, "Unexpected Init Type (neither def nor dag) in .insn "
                          "directive operand");

  // Get name of ParserMatchClass associated with operand.
  StringRef MC =
      OpRec->getValueAsDef("ParserMatchClass")->getValueAsString("Name");

  // Prepend MCK_ and return.
  return "MCK_" + std::string(MC);
}

static InsnMatchEntry buildInsnMatchEntry(const Record &Def, unsigned &MaxNum) {
  const DagInit *OutOperands = Def.getValueAsDag("OutOperandList");
  const DagInit *InOperands = Def.getValueAsDag("InOperandList");
  if (OutOperands->getNumArgs() > 0)
    PrintFatalError(&Def, ".insn directive may not have output operands");
  unsigned InOps = InOperands->getNumArgs();
  if (InOps == 0)
    PrintFatalError(&Def, ".insn directive missing encoding operand");

  InsnMatchEntry Entry;
  Entry.Format = getFormatName(Def).str();
  Entry.Opcode = ("SystemZ::" + Def.getName()).str();

  for (unsigned I = 0; I < InOps; ++I)
    Entry.OperandKinds.push_back(
        getMatchClassKind(Def, InOperands->getArg(I), I));

  Entry.NumOptionalOperands =
      (unsigned)Def.getValueAsInt("NumOptionalOperands");
  if (Entry.NumOptionalOperands > InOps)
    PrintFatalError(&Def, "NumOptionalOperands exceeds operand count");

  if (MaxNum < InOps)
    MaxNum = InOps;

  return Entry;
}

static void emitInsnDirectiveMatchTable(const RecordKeeper &RK,
                                        raw_ostream &OS) {
  emitSourceFileHeader("Match Table for SystemZ .insn directive operand types",
                       OS);
  unsigned MaxOperandCount = 0;
  // This will hold all .insn directive definitions (~100 plus margin).
  SmallVector<InsnMatchEntry, 128> Entries;
  // Collect all InstSystemZ records that have IsInsnDirective set to 1.
  for (const Record *Def : RK.getAllDerivedDefinitions("InstSystemZ"))
    if (Def->getValueAsBit("IsInsnDirective"))
      Entries.push_back(buildInsnMatchEntry(*Def, MaxOperandCount));

  // Sort entries by format name.
  llvm::sort(Entries, [](const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {
    return LHS.Format < RHS.Format;
  });

  OS << "constexpr unsigned MAX_INSN_OPERANDNUM = " << MaxOperandCount << ";\n";
  OS << "\n";
  OS << "struct InsnMatchEntry {\n";
  OS << "  StringRef Format;\n";
  OS << "  uint64_t Opcode;\n";
  OS << "  uint32_t NumOperands;\n";
  OS << "  uint32_t NumOptionalOperands;\n";
  OS << "  MatchClassKind OperandKinds[MAX_INSN_OPERANDNUM];\n";
  OS << "};\n";
  OS << "\n";
  OS << "struct CompareInsn {\n";
  OS << "  bool operator()(const InsnMatchEntry &LHS, StringRef RHS) {\n";
  OS << "    return LHS.Format < RHS;\n";
  OS << "  }\n";
  OS << "  bool operator()(StringRef LHS, const InsnMatchEntry &RHS) {\n";
  OS << "    return LHS < RHS.Format;\n";
  OS << "  }\n";
  OS << "  bool operator()(const InsnMatchEntry &LHS,\n";
  OS << "                  const InsnMatchEntry &RHS) {\n";
  OS << "    return LHS.Format < RHS.Format;\n";
  OS << "  }\n";
  OS << "};\n";
  OS << "\n";
  OS << "/* Format, Opcode, NumOperands, NumOptionalOperands, OperandKinds "
        "*/\n";
  OS << "static InsnMatchEntry InsnMatchTable[] = {\n";
  for (const InsnMatchEntry &Entry : Entries) {
    OS << "  {\"" << Entry.Format << "\", " << Entry.Opcode << ", "
       << Entry.OperandKinds.size() << ", " << Entry.NumOptionalOperands
       << ", {";
    for (unsigned I = 0; I < Entry.OperandKinds.size(); ++I) {
      if (I != 0)
        OS << ", ";
      OS << Entry.OperandKinds[I];
    }
    OS << "}},\n";
  }
  OS << "};\n";
}
} // namespace

static TableGen::Emitter::Opt X("gen-insn-directive-match-table",
                                emitInsnDirectiveMatchTable,
                                "Generate SystemZ .insn match table.");
