//===- PseudoLoweringEmitter.cpp - PseudoLowering Generator -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "pseudo-lowering"
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <vector>
using namespace llvm;

namespace {
class PseudoLoweringEmitter {
  struct OpData {
    enum MapKind { Operand, Imm, Reg };
    MapKind Kind;
    union {
      unsigned Operand;   // Operand number mapped to.
      uint64_t Imm;       // Integer immedate value.
      Record *Reg;        // Physical register.
    } Data;
  };
  struct PseudoExpansion {
    CodeGenInstruction Source;  // The source pseudo instruction definition.
    CodeGenInstruction Dest;    // The destination instruction to lower to.
    IndexedMap<OpData> OperandMap;

    PseudoExpansion(CodeGenInstruction &s, CodeGenInstruction &d,
                    IndexedMap<OpData> &m) :
      Source(s), Dest(d), OperandMap(m) {}
  };

  RecordKeeper &Records;

  // It's overkill to have an instance of the full CodeGenTarget object,
  // but it loads everything on demand, not in the constructor, so it's
  // lightweight in performance, so it works out OK.
  CodeGenTarget Target;

  SmallVector<PseudoExpansion, 64> Expansions;

  unsigned addDagOperandMapping(Record *Rec, DagInit *Dag,
                                CodeGenInstruction &Insn,
                                IndexedMap<OpData> &OperandMap,
                                unsigned BaseIdx);
  void evaluateExpansion(Record *Pseudo);
  void emitLoweringEmitter(raw_ostream &o);
public:
  PseudoLoweringEmitter(RecordKeeper &R) : Records(R), Target(R) {}

  /// run - Output the pseudo-lowerings.
  void run(raw_ostream &o);
};
} // End anonymous namespace

// FIXME: This pass currently can only expand a pseudo to a single instruction.
//        The pseudo expansion really should take a list of dags, not just
//        a single dag, so we can do fancier things.

unsigned PseudoLoweringEmitter::
addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn,
                     IndexedMap<OpData> &OperandMap, unsigned BaseIdx) {
  unsigned OpsAdded = 0;
  for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
    if (DefInit *DI = dyn_cast<DefInit>(Dag->getArg(i))) {
      // Physical register reference. Explicit check for the special case
      // "zero_reg" definition.
      if (DI->getDef()->isSubClassOf("Register") ||
          DI->getDef()->getName() == "zero_reg") {
        OperandMap[BaseIdx + i].Kind = OpData::Reg;
        OperandMap[BaseIdx + i].Data.Reg = DI->getDef();
        ++OpsAdded;
        continue;
      }

      // Normal operands should always have the same type, or we have a
      // problem.
      // FIXME: We probably shouldn't ever get a non-zero BaseIdx here.
      assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!");
      if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec)
        PrintFatalError(Rec->getLoc(),
                      "Pseudo operand type '" + DI->getDef()->getName() +
                      "' does not match expansion operand type '" +
                      Insn.Operands[BaseIdx + i].Rec->getName() + "'");
      // Source operand maps to destination operand. The Data element
      // will be filled in later, just set the Kind for now. Do it
      // for each corresponding MachineInstr operand, not just the first.
      for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)
        OperandMap[BaseIdx + i + I].Kind = OpData::Operand;
      OpsAdded += Insn.Operands[i].MINumOperands;
    } else if (IntInit *II = dyn_cast<IntInit>(Dag->getArg(i))) {
      OperandMap[BaseIdx + i].Kind = OpData::Imm;
      OperandMap[BaseIdx + i].Data.Imm = II->getValue();
      ++OpsAdded;
    } else if (DagInit *SubDag = dyn_cast<DagInit>(Dag->getArg(i))) {
      // Just add the operands recursively. This is almost certainly
      // a constant value for a complex operand (> 1 MI operand).
      unsigned NewOps =
        addDagOperandMapping(Rec, SubDag, Insn, OperandMap, BaseIdx + i);
      OpsAdded += NewOps;
      // Since we added more than one, we also need to adjust the base.
      BaseIdx += NewOps - 1;
    } else
      llvm_unreachable("Unhandled pseudo-expansion argument type!");
  }
  return OpsAdded;
}

void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
  DEBUG(dbgs() << "Pseudo definition: " << Rec->getName() << "\n");

  // Validate that the result pattern has the corrent number and types
  // of arguments for the instruction it references.
  DagInit *Dag = Rec->getValueAsDag("ResultInst");
  assert(Dag && "Missing result instruction in pseudo expansion!");
  DEBUG(dbgs() << "  Result: " << *Dag << "\n");

  DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
  if (!OpDef)
    PrintFatalError(Rec->getLoc(), Rec->getName() +
                  " has unexpected operator type!");
  Record *Operator = OpDef->getDef();
  if (!Operator->isSubClassOf("Instruction"))
    PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
                    "' is not an instruction!");

  CodeGenInstruction Insn(Operator);

  if (Insn.isCodeGenOnly || Insn.isPseudo)
    PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
                    "' cannot be another pseudo instruction!");

  if (Insn.Operands.size() != Dag->getNumArgs())
    PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
                    "' operand count mismatch");

  unsigned NumMIOperands = 0;
  for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i)
    NumMIOperands += Insn.Operands[i].MINumOperands;
  IndexedMap<OpData> OperandMap;
  OperandMap.grow(NumMIOperands);

  addDagOperandMapping(Rec, Dag, Insn, OperandMap, 0);

  // If there are more operands that weren't in the DAG, they have to
  // be operands that have default values, or we have an error. Currently,
  // Operands that are a sublass of OperandWithDefaultOp have default values.


  // Validate that each result pattern argument has a matching (by name)
  // argument in the source instruction, in either the (outs) or (ins) list.
  // Also check that the type of the arguments match.
  //
  // Record the mapping of the source to result arguments for use by
  // the lowering emitter.
  CodeGenInstruction SourceInsn(Rec);
  StringMap<unsigned> SourceOperands;
  for (unsigned i = 0, e = SourceInsn.Operands.size(); i != e; ++i)
    SourceOperands[SourceInsn.Operands[i].Name] = i;

  DEBUG(dbgs() << "  Operand mapping:\n");
  for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i) {
    // We've already handled constant values. Just map instruction operands
    // here.
    if (OperandMap[Insn.Operands[i].MIOperandNo].Kind != OpData::Operand)
      continue;
    StringMap<unsigned>::iterator SourceOp =
      SourceOperands.find(Dag->getArgName(i));
    if (SourceOp == SourceOperands.end())
      PrintFatalError(Rec->getLoc(),
                      "Pseudo output operand '" + Dag->getArgName(i) +
                      "' has no matching source operand.");
    // Map the source operand to the destination operand index for each
    // MachineInstr operand.
    for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)
      OperandMap[Insn.Operands[i].MIOperandNo + I].Data.Operand =
        SourceOp->getValue();

    DEBUG(dbgs() << "    " << SourceOp->getValue() << " ==> " << i << "\n");
  }

  Expansions.push_back(PseudoExpansion(SourceInsn, Insn, OperandMap));
}

void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
  // Emit file header.
  emitSourceFileHeader("Pseudo-instruction MC lowering Source Fragment", o);

  o << "bool " << Target.getName() + "AsmPrinter" << "::\n"
    << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n"
    << "                            const MachineInstr *MI) {\n"
    << "  switch (MI->getOpcode()) {\n"
    << "    default: return false;\n";
  for (unsigned i = 0, e = Expansions.size(); i != e; ++i) {
    PseudoExpansion &Expansion = Expansions[i];
    CodeGenInstruction &Source = Expansion.Source;
    CodeGenInstruction &Dest = Expansion.Dest;
    o << "    case " << Source.Namespace << "::"
      << Source.TheDef->getName() << ": {\n"
      << "      MCInst TmpInst;\n"
      << "      MCOperand MCOp;\n"
      << "      TmpInst.setOpcode(" << Dest.Namespace << "::"
      << Dest.TheDef->getName() << ");\n";

    // Copy the operands from the source instruction.
    // FIXME: Instruction operands with defaults values (predicates and cc_out
    //        in ARM, for example shouldn't need explicit values in the
    //        expansion DAG.
    unsigned MIOpNo = 0;
    for (unsigned OpNo = 0, E = Dest.Operands.size(); OpNo != E;
         ++OpNo) {
      o << "      // Operand: " << Dest.Operands[OpNo].Name << "\n";
      for (unsigned i = 0, e = Dest.Operands[OpNo].MINumOperands;
           i != e; ++i) {
        switch (Expansion.OperandMap[MIOpNo + i].Kind) {
        case OpData::Operand:
          o << "      lowerOperand(MI->getOperand("
            << Source.Operands[Expansion.OperandMap[MIOpNo].Data
                .Operand].MIOperandNo + i
            << "), MCOp);\n"
            << "      TmpInst.addOperand(MCOp);\n";
          break;
        case OpData::Imm:
          o << "      TmpInst.addOperand(MCOperand::CreateImm("
            << Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n";
          break;
        case OpData::Reg: {
          Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg;
          o << "      TmpInst.addOperand(MCOperand::CreateReg(";
          // "zero_reg" is special.
          if (Reg->getName() == "zero_reg")
            o << "0";
          else
            o << Reg->getValueAsString("Namespace") << "::" << Reg->getName();
          o << "));\n";
          break;
        }
        }
      }
      MIOpNo += Dest.Operands[OpNo].MINumOperands;
    }
    if (Dest.Operands.isVariadic) {
      MIOpNo = Source.Operands.size() + 1;
      o << "      // variable_ops\n";
      o << "      for (unsigned i = " << MIOpNo
        << ", e = MI->getNumOperands(); i != e; ++i)\n"
        << "        if (lowerOperand(MI->getOperand(i), MCOp))\n"
        << "          TmpInst.addOperand(MCOp);\n";
    }
    o << "      OutStreamer.EmitInstruction(TmpInst);\n"
      << "      break;\n"
      << "    }\n";
  }
  o << "  }\n  return true;\n}\n\n";
}

void PseudoLoweringEmitter::run(raw_ostream &o) {
  Record *ExpansionClass = Records.getClass("PseudoInstExpansion");
  Record *InstructionClass = Records.getClass("Instruction");
  assert(ExpansionClass && "PseudoInstExpansion class definition missing!");
  assert(InstructionClass && "Instruction class definition missing!");

  std::vector<Record*> Insts;
  for (std::map<std::string, Record*>::const_iterator I =
         Records.getDefs().begin(), E = Records.getDefs().end(); I != E; ++I) {
    if (I->second->isSubClassOf(ExpansionClass) &&
        I->second->isSubClassOf(InstructionClass))
      Insts.push_back(I->second);
  }

  // Process the pseudo expansion definitions, validating them as we do so.
  for (unsigned i = 0, e = Insts.size(); i != e; ++i)
    evaluateExpansion(Insts[i]);

  // Generate expansion code to lower the pseudo to an MCInst of the real
  // instruction.
  emitLoweringEmitter(o);
}

namespace llvm {

void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS) {
  PseudoLoweringEmitter(RK).run(OS);
}

} // End llvm namespace
