//===-- MBlazeAsmPrinter.cpp - MBlaze LLVM assembly writer ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format MBlaze assembly language.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mblaze-asm-printer"

#include "MBlaze.h"
#include "MBlazeSubtarget.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeTargetMachine.h"
#include "MBlazeMachineFunction.h"
#include "MBlazeMCInstLower.h"
#include "InstPrinter/MBlazeInstPrinter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>

using namespace llvm;

namespace {
  class MBlazeAsmPrinter : public AsmPrinter {
    const MBlazeSubtarget *Subtarget;
  public:
    explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
      : AsmPrinter(TM, Streamer) {
      Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
    }

    virtual const char *getPassName() const {
      return "MBlaze Assembly Printer";
    }

    void printSavedRegsBitmask();
    void emitFrameDirective();
    virtual void EmitFunctionBodyStart();
    virtual void EmitFunctionBodyEnd();
    virtual void EmitFunctionEntryLabel();

    virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
      const;

    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                         unsigned AsmVariant, const char *ExtraCode,
                         raw_ostream &O);
    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
    void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O);
    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
                         const char *Modifier = 0);

    void EmitInstruction(const MachineInstr *MI);
  };
} // end of anonymous namespace

// #include "MBlazeGenAsmWriter.inc"

//===----------------------------------------------------------------------===//
//
//  MBlaze Asm Directives
//
//  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
//  Describe the stack frame.
//
//  -- Mask directives "mask  bitmask, offset"
//  Tells the assembler which registers are saved and where.
//  bitmask - contain a little endian bitset indicating which registers are
//            saved on function prologue (e.g. with a 0x80000000 mask, the
//            assembler knows the register 31 (RA) is saved at prologue.
//  offset  - the position before stack pointer subtraction indicating where
//            the first saved register on prologue is located. (e.g. with a
//
//  Consider the following function prologue:
//
//    .frame  R19,48,R15
//    .mask   0xc0000000,-8
//       addiu R1, R1, -48
//       sw R15, 40(R1)
//       sw R19, 36(R1)
//
//    With a 0xc0000000 mask, the assembler knows the register 15 (R15) and
//    19 (R19) are saved at prologue. As the save order on prologue is from
//    left to right, R15 is saved first. A -8 offset means that after the
//    stack pointer subtration, the first register in the mask (R15) will be
//    saved at address 48-8=40.
//
//===----------------------------------------------------------------------===//

// Print a 32 bit hex number with all numbers.
static void printHex32(unsigned int Value, raw_ostream &O) {
  O << "0x";
  for (int i = 7; i >= 0; i--)
    O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
}

// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
void MBlazeAsmPrinter::printSavedRegsBitmask() {
  const TargetFrameLowering *TFI = TM.getFrameLowering();
  const TargetRegisterInfo &RI = *TM.getRegisterInfo();

  // CPU Saved Registers Bitmasks
  unsigned int CPUBitmask = 0;

  // Set the CPU Bitmasks
  const MachineFrameInfo *MFI = MF->getFrameInfo();
  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(Reg);
    if (MBlaze::GPRRegisterClass->contains(Reg))
      CPUBitmask |= (1 << RegNum);
  }

  // Return Address and Frame registers must also be set in CPUBitmask.
  if (TFI->hasFP(*MF))
    CPUBitmask |= (1 << MBlazeRegisterInfo::
                getRegisterNumbering(RI.getFrameRegister(*MF)));

  if (MFI->adjustsStack())
    CPUBitmask |= (1 << MBlazeRegisterInfo::
                getRegisterNumbering(RI.getRARegister()));

  // Print CPUBitmask
  OutStreamer.EmitRawText("\t.mask\t0x" + Twine::utohexstr(CPUBitmask));
}

/// Frame Directive
void MBlazeAsmPrinter::emitFrameDirective() {
  if (!OutStreamer.hasRawTextSupport())
    return;

  const TargetRegisterInfo &RI = *TM.getRegisterInfo();
  unsigned stkReg = RI.getFrameRegister(*MF);
  unsigned retReg = RI.getRARegister();
  unsigned stkSze = MF->getFrameInfo()->getStackSize();

  OutStreamer.EmitRawText("\t.frame\t" +
                          Twine(MBlazeInstPrinter::getRegisterName(stkReg)) +
                          "," + Twine(stkSze) + "," +
                          Twine(MBlazeInstPrinter::getRegisterName(retReg)));
}

void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
  if (OutStreamer.hasRawTextSupport())
    OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
  AsmPrinter::EmitFunctionEntryLabel();
}

void MBlazeAsmPrinter::EmitFunctionBodyStart() {
  if (!OutStreamer.hasRawTextSupport())
    return;

  emitFrameDirective();
  printSavedRegsBitmask();
}

void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
  if (OutStreamer.hasRawTextSupport())
    OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
}

//===----------------------------------------------------------------------===//
void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MBlazeMCInstLower MCInstLowering(OutContext, *Mang, *this);

  MCInst TmpInst;
  MCInstLowering.Lower(MI, TmpInst);
  OutStreamer.EmitInstruction(TmpInst);
}

// Print out an operand for an inline asm expression.
bool MBlazeAsmPrinter::
PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) {
  // Does this asm operand have a single letter operand modifier?
  if (ExtraCode && ExtraCode[0])
    return true; // Unknown modifier.

  printOperand(MI, OpNo, O);
  return false;
}

void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
                                    raw_ostream &O) {
  const MachineOperand &MO = MI->getOperand(opNum);

  switch (MO.getType()) {
  case MachineOperand::MO_Register:
    O << MBlazeInstPrinter::getRegisterName(MO.getReg());
    break;

  case MachineOperand::MO_Immediate:
    O << (int32_t)MO.getImm();
    break;

  case MachineOperand::MO_FPImmediate: {
    const ConstantFP *fp = MO.getFPImm();
    printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O);
    O << ";\t# immediate = " << *fp;
    break;
  }

  case MachineOperand::MO_MachineBasicBlock:
    O << *MO.getMBB()->getSymbol();
    return;

  case MachineOperand::MO_GlobalAddress:
    O << *Mang->getSymbol(MO.getGlobal());
    break;

  case MachineOperand::MO_ExternalSymbol:
    O << *GetExternalSymbolSymbol(MO.getSymbolName());
    break;

  case MachineOperand::MO_JumpTableIndex:
    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
      << '_' << MO.getIndex();
    break;

  case MachineOperand::MO_ConstantPoolIndex:
    O << MAI->getPrivateGlobalPrefix() << "CPI"
      << getFunctionNumber() << "_" << MO.getIndex();
    if (MO.getOffset())
      O << "+" << MO.getOffset();
    break;

  default:
    llvm_unreachable("<unknown operand type>");
  }
}

void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
                                        raw_ostream &O) {
  const MachineOperand &MO = MI->getOperand(opNum);
  if (MO.isImm())
    O << (uint32_t)MO.getImm();
  else
    printOperand(MI, opNum, O);
}

void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum,
                                   raw_ostream &O) {
  const MachineOperand &MO = MI->getOperand(opNum);
  if (MO.isImm())
    O << "rfsl" << (unsigned int)MO.getImm();
  else
    printOperand(MI, opNum, O);
}

void MBlazeAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
                const char *Modifier) {
  printOperand(MI, opNum, O);
  O << ", ";
  printOperand(MI, opNum+1, O);
}

/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
bool MBlazeAsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
  // If this is a landing pad, it isn't a fall through.  If it has no preds,
  // then nothing falls through to it.
  if (MBB->isLandingPad() || MBB->pred_empty())
    return false;

  // If there isn't exactly one predecessor, it can't be a fall through.
  MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
  ++PI2;
  if (PI2 != MBB->pred_end())
    return false;

  // The predecessor has to be immediately before this block.
  const MachineBasicBlock *Pred = *PI;

  if (!Pred->isLayoutSuccessor(MBB))
    return false;

  // If the block is completely empty, then it definitely does fall through.
  if (Pred->empty())
    return true;

  // Check if the last terminator is an unconditional branch.
  MachineBasicBlock::const_iterator I = Pred->end();
  while (I != Pred->begin() && !(--I)->getDesc().isTerminator())
    ; // Noop
  return I == Pred->end() || !I->getDesc().isBarrier();
}

static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
                                                unsigned SyntaxVariant,
                                                const MCAsmInfo &MAI) {
  if (SyntaxVariant == 0)
    return new MBlazeInstPrinter(MAI);
  return 0;
}

// Force static initialization.
extern "C" void LLVMInitializeMBlazeAsmPrinter() {
  RegisterAsmPrinter<MBlazeAsmPrinter> X(TheMBlazeTarget);
  TargetRegistry::RegisterMCInstPrinter(TheMBlazeTarget,
                                        createMBlazeMCInstPrinter);

}
