//===-- MBlazeMachineFunctionInfo.h - Private data ----------------*- C++ -*-=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the MBlaze specific subclass of MachineFunctionInfo.
//
//===----------------------------------------------------------------------===//

#ifndef MBLAZE_MACHINE_FUNCTION_INFO_H
#define MBLAZE_MACHINE_FUNCTION_INFO_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"

namespace llvm {

/// MBlazeFunctionInfo - This class is derived from MachineFunction private
/// MBlaze target-specific information for each MachineFunction.
class MBlazeFunctionInfo : public MachineFunctionInfo {

private:
  /// Holds for each function where on the stack the Frame Pointer must be 
  /// saved. This is used on Prologue and Epilogue to emit FP save/restore
  int FPStackOffset;

  /// Holds for each function where on the stack the Return Address must be 
  /// saved. This is used on Prologue and Epilogue to emit RA save/restore
  int RAStackOffset;

  /// At each function entry a special bitmask directive must be emitted
  /// to help in debugging CPU callee saved registers. It needs a negative
  /// offset from the final stack size and its higher register location on
  /// the stack.
  int CPUTopSavedRegOff;

  /// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
  struct MBlazeFIHolder {

    int FI;
    int SPOffset;

    MBlazeFIHolder(int FrameIndex, int StackPointerOffset)
      : FI(FrameIndex), SPOffset(StackPointerOffset) {}
  };

  /// When PIC is used the GP must be saved on the stack on the function 
  /// prologue and must be reloaded from this stack location after every 
  /// call. A reference to its stack location and frame index must be kept 
  /// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
  MBlazeFIHolder GPHolder;

  /// On LowerFormalArguments the stack size is unknown, so the Stack
  /// Pointer Offset calculation of "not in register arguments" must be 
  /// postponed to emitPrologue. 
  SmallVector<MBlazeFIHolder, 16> FnLoadArgs;
  bool HasLoadArgs;

  // When VarArgs, we must write registers back to caller stack, preserving 
  // on register arguments. Since the stack size is unknown on 
  // LowerFormalArguments, the Stack Pointer Offset calculation must be
  // postponed to emitPrologue. 
  SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs;
  bool HasStoreVarArgs;

  /// SRetReturnReg - Some subtargets require that sret lowering includes
  /// returning the value of the returned struct in a register. This field
  /// holds the virtual register into which the sret argument is passed.
  unsigned SRetReturnReg;

  /// GlobalBaseReg - keeps track of the virtual register initialized for
  /// use as the global base register. This is used for PIC in some PIC
  /// relocation models.
  unsigned GlobalBaseReg;

public:
  MBlazeFunctionInfo(MachineFunction& MF) 
  : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0), 
    GPHolder(-1,-1), HasLoadArgs(false), HasStoreVarArgs(false),
    SRetReturnReg(0), GlobalBaseReg(0)
  {}

  int getFPStackOffset() const { return FPStackOffset; }
  void setFPStackOffset(int Off) { FPStackOffset = Off; }

  int getRAStackOffset() const { return RAStackOffset; }
  void setRAStackOffset(int Off) { RAStackOffset = Off; }

  int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
  void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }

  int getGPStackOffset() const { return GPHolder.SPOffset; }
  int getGPFI() const { return GPHolder.FI; }
  void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
  void setGPFI(int FI) { GPHolder.FI = FI; }
  bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; }

  bool hasLoadArgs() const { return HasLoadArgs; }
  bool hasStoreVarArgs() const { return HasStoreVarArgs; } 

  void recordLoadArgsFI(int FI, int SPOffset) {
    if (!HasLoadArgs) HasLoadArgs=true;
    FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
  }
  void recordStoreVarArgsFI(int FI, int SPOffset) {
    if (!HasStoreVarArgs) HasStoreVarArgs=true;
    FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset));
  }

  void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
    if (!hasLoadArgs()) return;
    for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i) 
      MFI->setObjectOffset( FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset );
  }
  void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
    if (!hasStoreVarArgs()) return; 
    for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i) 
      MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset );
  }

  unsigned getSRetReturnReg() const { return SRetReturnReg; }
  void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }

  unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
  void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
};

} // end of namespace llvm

#endif // MBLAZE_MACHINE_FUNCTION_INFO_H
