//===- 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 "PseudoLoweringEmitter.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Debug.h"
#include <vector>
using namespace llvm;

// 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 = dynamic_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)
        throw TGError(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 = dynamic_cast<IntInit*>(Dag->getArg(i))) {
      OperandMap[BaseIdx + i].Kind = OpData::Imm;
      OperandMap[BaseIdx + i].Data.Imm = II->getValue();
      ++OpsAdded;
    } else if (DagInit *SubDag = dynamic_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 = dynamic_cast<DefInit*>(Dag->getOperator());
  if (!OpDef)
    throw TGError(Rec->getLoc(), Rec->getName() +
                  " has unexpected operator type!");
  Record *Operator = OpDef->getDef();
  if (!Operator->isSubClassOf("Instruction"))
    throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
                                 "' is not an instruction!");

  CodeGenInstruction Insn(Operator);

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

  if (Insn.Operands.size() != Dag->getNumArgs())
    throw TGError(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,
  // PredicateOperand and OptionalDefOperand both 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())
      throw TGError(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) {
      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("PseudoInstExpansion");
  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);
}

