//====- X86MachineFuctionInfo.h - X86 machine function info -----*- 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 X86-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//

#ifndef X86MACHINEFUNCTIONINFO_H
#define X86MACHINEFUNCTIONINFO_H

#include "llvm/CodeGen/MachineFunction.h"

namespace llvm {

enum NameDecorationStyle {
  None,
  StdCall,
  FastCall
};
  
/// X86MachineFunctionInfo - This class is derived from MachineFunction private
/// X86 target-specific information for each MachineFunction.
class X86MachineFunctionInfo : public MachineFunctionInfo {
  /// ForceFramePointer - True if the function is required to use of frame
  /// pointer for reasons other than it containing dynamic allocation or 
  /// that FP eliminatation is turned off. For example, Cygwin main function
  /// contains stack pointer re-alignment code which requires FP.
  bool ForceFramePointer;

  /// CalleeSavedFrameSize - Size of the callee-saved register portion of the
  /// stack frame in bytes.
  unsigned CalleeSavedFrameSize;

  /// BytesToPopOnReturn - Number of bytes function pops on return.
  /// Used on windows platform for stdcall & fastcall name decoration
  unsigned BytesToPopOnReturn;

  /// DecorationStyle - If the function requires additional name decoration,
  /// DecorationStyle holds the right way to do so.
  NameDecorationStyle DecorationStyle;

  /// ReturnAddrIndex - FrameIndex for return slot.
  int ReturnAddrIndex;

  /// TailCallReturnAddrDelta - Delta the ReturnAddr stack slot is moved
  /// Used for creating an area before the register spill area on the stack
  /// the returnaddr can be savely move to this area
  int TailCallReturnAddrDelta;

  /// 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;

public:
  X86MachineFunctionInfo() : ForceFramePointer(false),
                             CalleeSavedFrameSize(0),
                             BytesToPopOnReturn(0),
                             DecorationStyle(None),
                             ReturnAddrIndex(0),
                             TailCallReturnAddrDelta(0),
                             SRetReturnReg(0) {}
  
  X86MachineFunctionInfo(MachineFunction &MF) : ForceFramePointer(false),
                                                CalleeSavedFrameSize(0),
                                                BytesToPopOnReturn(0),
                                                DecorationStyle(None),
                                                ReturnAddrIndex(0),
                                                TailCallReturnAddrDelta(0),
                                                SRetReturnReg(0) {}
  
  bool getForceFramePointer() const { return ForceFramePointer;} 
  void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; }

  unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
  void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }

  unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
  void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;}

  NameDecorationStyle getDecorationStyle() const { return DecorationStyle; }
  void setDecorationStyle(NameDecorationStyle style) { DecorationStyle = style;}

  int getRAIndex() const { return ReturnAddrIndex; }
  void setRAIndex(int Index) { ReturnAddrIndex = Index; }

  int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; }
  void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;}

  unsigned getSRetReturnReg() const { return SRetReturnReg; }
  void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
};
} // End llvm namespace

#endif
