//===-- PrologEpilogCodeInserter.cpp - Insert Prolog & Epilog code for fn -===//
//
// Insert SAVE/RESTORE instructions for the function
//
// Insert prolog code at the unique function entry point.
// Insert epilog code at each function exit point.
// InsertPrologEpilog invokes these only if the function is not compiled
// with the leaf function optimization.
//
//===----------------------------------------------------------------------===//

#include "SparcInternals.h"
#include "SparcRegClassInfo.h"
#include "llvm/CodeGen/MachineCodeForMethod.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instruction.h"

namespace {

class InsertPrologEpilogCode : public MethodPass {
  TargetMachine &Target;
public:
  InsertPrologEpilogCode(TargetMachine &T) : Target(T) {}
  bool runOnMethod(Function *F) {
    MachineCodeForMethod &mcodeInfo = MachineCodeForMethod::get(F);
    if (!mcodeInfo.isCompiledAsLeafMethod()) {
      InsertPrologCode(F);
      InsertEpilogCode(F);
    }
    return false;
  }

  void InsertPrologCode(Function *F);
  void InsertEpilogCode(Function *F);
};

}  // End anonymous namespace

//------------------------------------------------------------------------ 
// External Function: GetInstructionsForProlog
// External Function: GetInstructionsForEpilog
//
// Purpose:
//   Create prolog and epilog code for procedure entry and exit
//------------------------------------------------------------------------ 

void InsertPrologEpilogCode::InsertPrologCode(Function *F)
{
  BasicBlock *entryBB = F->getEntryNode();

  vector<MachineInstr*> mvec;
  MachineInstr* M;
  const MachineFrameInfo& frameInfo = Target.getFrameInfo();
  
  // The second operand is the stack size. If it does not fit in the
  // immediate field, we have to use a free register to hold the size.
  // We will assume that local register `l0' is unused since the SAVE
  // instruction must be the first instruction in each procedure.
  // 
  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(F);
  unsigned int staticStackSize = mcInfo.getStaticStackSize();
  
  if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize())
    staticStackSize = (unsigned) frameInfo.getMinStackFrameSize();
  
  if (unsigned padsz = (staticStackSize %
                        (unsigned) frameInfo.getStackFrameSizeAlignment()))
    staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
  
  if (Target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize))
    {
      M = new MachineInstr(SAVE);
      M->SetMachineOperandReg(0, Target.getRegInfo().getStackPointer());
      M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
                                   - (int) staticStackSize);
      M->SetMachineOperandReg(2, Target.getRegInfo().getStackPointer());
      mvec.push_back(M);
    }
  else
    {
      M = new MachineInstr(SETSW);
      M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed,
                                - (int) staticStackSize);
      M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
                                 Target.getRegInfo().getUnifiedRegNum(
                           Target.getRegInfo().getRegClassIDOfType(Type::IntTy),
                                  SparcIntRegOrder::l0));
      mvec.push_back(M);
      
      M = new MachineInstr(SAVE);
      M->SetMachineOperandReg(0, Target.getRegInfo().getStackPointer());
      M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
                                 Target.getRegInfo().getUnifiedRegNum(
                           Target.getRegInfo().getRegClassIDOfType(Type::IntTy),
                                  SparcIntRegOrder::l0));
      M->SetMachineOperandReg(2, Target.getRegInfo().getStackPointer());
      mvec.push_back(M);
    }

  MachineCodeForBasicBlock& bbMvec = entryBB->getMachineInstrVec();
  bbMvec.insert(entryBB->getMachineInstrVec().begin(),
                mvec.begin(), mvec.end());
}

void InsertPrologEpilogCode::InsertEpilogCode(Function *F)
{
  for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
    Instruction *TermInst = (Instruction*)(*I)->getTerminator();
    if (TermInst->getOpcode() == Instruction::Ret)
      {
        BasicBlock* exitBB = *I;

        MachineInstr *Restore = new MachineInstr(RESTORE);
        Restore->SetMachineOperandReg(0, Target.getRegInfo().getZeroRegNum());
        Restore->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
                                        (int64_t)0);
        Restore->SetMachineOperandReg(2, Target.getRegInfo().getZeroRegNum());
        
        MachineCodeForBasicBlock& bbMvec = exitBB->getMachineInstrVec();
        MachineCodeForInstruction &termMvec =
          MachineCodeForInstruction::get(TermInst);
        
        // Remove the NOPs in the delay slots of the return instruction
        const MachineInstrInfo &mii = Target.getInstrInfo();
        unsigned numNOPs = 0;
        while (termMvec.back()->getOpCode() == NOP)
          {
            assert( termMvec.back() == bbMvec.back());
            delete bbMvec.pop_back();
            termMvec.pop_back();
            ++numNOPs;
          }
        assert(termMvec.back() == bbMvec.back());
        
        // Check that we found the right number of NOPs and have the right
        // number of instructions to replace them.
        unsigned ndelays = mii.getNumDelaySlots(termMvec.back()->getOpCode());
        assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
        assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
        
        // Append the epilog code to the end of the basic block.
        bbMvec.push_back(Restore);
      }
  }
}

Pass *createPrologEpilogCodeInserter(TargetMachine &TM) {
  return new InsertPrologEpilogCode(TM);
}
