//===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
//
// 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 file implements the CodeGenInstAlias class.
//
//===----------------------------------------------------------------------===//

#include "CodeGenInstAlias.h"
#include "CodeGenInstruction.h"
#include "CodeGenRegisters.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Error.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;

unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
  if (!isRecord())
    return 1;

  const Record *Rec = getRecord();
  if (!Rec->isSubClassOf("Operand"))
    return 1;

  const DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
  if (MIOpInfo->getNumArgs() == 0) {
    // Unspecified, so it defaults to 1
    return 1;
  }

  return MIOpInfo->getNumArgs();
}

using ResultOperand = CodeGenInstAlias::ResultOperand;

static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,
                                                  const StringInit *ArgName,
                                                  const Record *Op,
                                                  const CodeGenTarget &T) {
  if (Op->isSubClassOf("RegisterClass") ||
      Op->isSubClassOf("RegisterOperand")) {
    const Record *OpRC =
        Op->isSubClassOf("RegisterClass") ? Op : Op->getValueAsDef("RegClass");

    if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) {
      const Record *ArgRec = ArgDef->getDef();

      // Match 'RegClass:$name' or 'RegOp:$name'.
      if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) {
        if (ArgRC->isSubClassOf("RegisterClass")) {
          if (!T.getRegisterClass(OpRC).hasSubClass(&T.getRegisterClass(ArgRC)))
            return createStringError(
                "argument register class" + ArgRC->getName() +
                " is not a subclass of operand register class " +
                OpRC->getName());
          if (!ArgName)
            return createStringError(
                "register class argument must have a name");
        }

        // TODO: Verify RegClassByHwMode usage

        return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
                                           ArgRec);
      }

      // Match 'Reg'.
      if (ArgRec->isSubClassOf("Register")) {
        if (!T.getRegisterClass(OpRC).contains(T.getRegBank().getReg(ArgRec)))
          return createStringError(
              "register argument " + ArgRec->getName() +
              " is not a member of operand register class " + OpRC->getName());
        if (ArgName)
          return createStringError("register argument must not have a name");
        return ResultOperand::createRegister(ArgRec);
      }

      // Match 'zero_reg'.
      if (ArgRec->getName() == "zero_reg") {
        if (ArgName)
          return createStringError("register argument must not have a name");
        return ResultOperand::createRegister(nullptr);
      }
    }

    return createStringError("argument must be a subclass of RegisterClass, "
                             "RegisterOperand, or zero_reg");
  }

  if (Op->isSubClassOf("Operand")) {
    // Match integer or bits.
    if (const auto *ArgInt = dyn_cast_or_null<IntInit>(
            Arg->convertInitializerTo(IntRecTy::get(Arg->getRecordKeeper())))) {
      if (ArgName)
        return createStringError("integer argument must not have a name");
      return ResultOperand::createImmediate(ArgInt->getValue());
    }

    // Match a subclass of Operand.
    if (const auto *ArgDef = dyn_cast<DefInit>(Arg);
        ArgDef && ArgDef->getDef()->isSubClassOf("Operand")) {
      if (!ArgName)
        return createStringError("argument must have a name");
      return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
                                         ArgDef->getDef());
    }

    return createStringError("argument must be a subclass of Operand");
  }

  llvm_unreachable("Unknown operand kind");
}

static Expected<ResultOperand> matchComplexOperand(const Init *Arg,
                                                   const StringInit *ArgName,
                                                   const Record *Op) {
  assert(Op->isSubClassOf("Operand"));
  const auto *ArgDef = dyn_cast<DefInit>(Arg);
  if (!ArgDef || !ArgDef->getDef()->isSubClassOf("Operand"))
    return createStringError("argument must be a subclass of Operand");
  if (!ArgName)
    return createStringError("argument must have a name");
  return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
                                     ArgDef->getDef());
}

CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
    : TheDef(R) {
  Result = R->getValueAsDag("ResultInst");
  AsmString = R->getValueAsString("AsmString");

  // Verify that the root of the result is an instruction.
  const DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
  if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
    PrintFatalError(R->getLoc(),
                    "result of inst alias should be an instruction");

  ResultInst = &T.getInstruction(DI->getDef());

  // NameClass - If argument names are repeated, we need to verify they have
  // the same class.
  StringMap<const Record *> NameClass;
  for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
    const DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
    if (!ADI || !Result->getArgName(i))
      continue;
    // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
    // $foo can exist multiple times in the result list, but it must have the
    // same type.
    const Record *&Entry = NameClass[Result->getArgNameStr(i)];
    if (Entry && Entry != ADI->getDef())
      PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
                                       " is both " + Entry->getName() +
                                       " and " + ADI->getDef()->getName() +
                                       "!");
    Entry = ADI->getDef();
  }

  // Decode and validate the arguments of the result.
  unsigned ArgIdx = 0;
  for (auto [OpIdx, OpInfo] : enumerate(ResultInst->Operands)) {
    // Tied registers don't have an entry in the result dag unless they're part
    // of a complex operand, in which case we include them anyways, as we
    // don't have any other way to specify the whole operand.
    if (OpInfo.MINumOperands == 1 && OpInfo.getTiedRegister() != -1) {
      // Tied operands of different RegisterClass should be explicit within an
      // instruction's syntax and so cannot be skipped.
      int TiedOpNum = OpInfo.getTiedRegister();
      if (OpInfo.Rec->getName() ==
          ResultInst->Operands[TiedOpNum].Rec->getName())
        continue;
    }

    if (ArgIdx >= Result->getNumArgs())
      PrintFatalError(R->getLoc(), "not enough arguments for instruction!");

    const Record *Op = OpInfo.Rec;
    if (Op->isSubClassOf("Operand") && !OpInfo.MIOperandInfo->arg_empty()) {
      // Complex operand (a subclass of Operand with non-empty MIOperandInfo).
      // The argument can be a DAG or a subclass of Operand.
      if (auto *ArgDag = dyn_cast<DagInit>(Result->getArg(ArgIdx))) {
        // The argument is a DAG. The operator must be the name of the operand.
        if (auto *Operator = dyn_cast<DefInit>(ArgDag->getOperator());
            !Operator || Operator->getDef()->getName() != Op->getName())
          PrintFatalError(R, "argument #" + Twine(ArgIdx) +
                                 " operator must be " + Op->getName());
        // The number of sub-arguments and the number of sub-operands
        // must match exactly.
        unsigned NumSubOps = OpInfo.MIOperandInfo->getNumArgs();
        unsigned NumSubArgs = ArgDag->getNumArgs();
        if (NumSubArgs != NumSubOps)
          PrintFatalError(R, "argument #" + Twine(ArgIdx) +
                                 " must have exactly " + Twine(NumSubOps) +
                                 " sub-arguments");
        // Match sub-operands individually.
        for (unsigned SubOpIdx = 0; SubOpIdx != NumSubOps; ++SubOpIdx) {
          const Record *SubOp =
              cast<DefInit>(OpInfo.MIOperandInfo->getArg(SubOpIdx))->getDef();
          Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
              ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T);
          if (!ResOpOrErr)
            PrintFatalError(R, "in argument #" + Twine(ArgIdx) + "." +
                                   Twine(SubOpIdx) + ": " +
                                   toString(ResOpOrErr.takeError()));
          ResultOperands.push_back(*ResOpOrErr);
          ResultInstOperandIndex.emplace_back(OpIdx, SubOpIdx);
        }
      } else {
        // Match complex operand as a whole.
        Expected<ResultOperand> ResOpOrErr = matchComplexOperand(
            Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op);
        if (!ResOpOrErr)
          PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +
                                 toString(ResOpOrErr.takeError()));
        ResultOperands.push_back(*ResOpOrErr);
        ResultInstOperandIndex.emplace_back(OpIdx, -1);
      }
    } else {
      // Simple operand (RegisterClass, RegisterOperand or Operand with empty
      // MIOperandInfo).
      Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
          Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op, T);
      if (!ResOpOrErr)
        PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +
                               toString(ResOpOrErr.takeError()));
      ResultOperands.push_back(*ResOpOrErr);
      ResultInstOperandIndex.emplace_back(OpIdx, -1);
    }
    ArgIdx++;
  }

  if (ArgIdx != Result->getNumArgs())
    PrintFatalError(R->getLoc(), "too many operands for instruction!");
}
