1234353Sdim//===-- ARMMachineFuctionInfo.h - ARM machine function info -----*- C++ -*-===//
2198090Srdivacky//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7198090Srdivacky//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file declares ARM-specific per-machine-function information.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#ifndef ARMMACHINEFUNCTIONINFO_H
15193323Sed#define ARMMACHINEFUNCTIONINFO_H
16193323Sed
17193323Sed#include "ARMSubtarget.h"
18249423Sdim#include "llvm/ADT/BitVector.h"
19193323Sed#include "llvm/CodeGen/MachineFunction.h"
20249423Sdim#include "llvm/Target/TargetMachine.h"
21193323Sed#include "llvm/Target/TargetRegisterInfo.h"
22193323Sed
23193323Sednamespace llvm {
24193323Sed
25218893Sdim/// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
26218893Sdim/// contains private ARM-specific information for each MachineFunction.
27193323Sedclass ARMFunctionInfo : public MachineFunctionInfo {
28234353Sdim  virtual void anchor();
29193323Sed
30193323Sed  /// isThumb - True if this function is compiled under Thumb mode.
31193323Sed  /// Used to initialized Align, so must precede it.
32193323Sed  bool isThumb;
33193323Sed
34195340Sed  /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
35195340Sed  /// to determine if function is compiled under Thumb mode, for that use
36195340Sed  /// 'isThumb'.
37195340Sed  bool hasThumb2;
38195340Sed
39263508Sdim  /// StByValParamsPadding - For parameter that is split between
40263508Sdim  /// GPRs and memory; while recovering GPRs part, when
41263508Sdim  /// StackAlignment == 8, and GPRs-part-size mod 8 != 0,
42263508Sdim  /// we need to insert gap before parameter start address. It allows to
43263508Sdim  /// "attach" GPR-part to the part that was passed via stack.
44263508Sdim  unsigned StByValParamsPadding;
45263508Sdim
46193323Sed  /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
47193323Sed  ///
48251662Sdim  unsigned ArgRegsSaveSize;
49193323Sed
50193323Sed  /// HasStackFrame - True if this function has a stack frame. Set by
51193323Sed  /// processFunctionBeforeCalleeSavedScan().
52193323Sed  bool HasStackFrame;
53193323Sed
54212904Sdim  /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
55212904Sdim  /// emitPrologue.
56212904Sdim  bool RestoreSPFromFP;
57212904Sdim
58193323Sed  /// LRSpilledForFarJump - True if the LR register has been for spilled to
59193323Sed  /// enable far jump.
60193323Sed  bool LRSpilledForFarJump;
61193323Sed
62193323Sed  /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
63193323Sed  /// spill stack offset.
64193323Sed  unsigned FramePtrSpillOffset;
65193323Sed
66193323Sed  /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
67193323Sed  /// register spills areas. For Mac OS X:
68193323Sed  ///
69193323Sed  /// GPR callee-saved (1) : r4, r5, r6, r7, lr
70193323Sed  /// --------------------------------------------
71193323Sed  /// GPR callee-saved (2) : r8, r10, r11
72193323Sed  /// --------------------------------------------
73193323Sed  /// DPR callee-saved : d8 - d15
74234353Sdim  ///
75234353Sdim  /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
76234353Sdim  /// Some may be spilled after the stack has been realigned.
77193323Sed  unsigned GPRCS1Offset;
78193323Sed  unsigned GPRCS2Offset;
79193323Sed  unsigned DPRCSOffset;
80193323Sed
81193323Sed  /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
82193323Sed  /// areas.
83193323Sed  unsigned GPRCS1Size;
84193323Sed  unsigned GPRCS2Size;
85193323Sed  unsigned DPRCSSize;
86193323Sed
87234353Sdim  /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
88234353Sdim  /// the aligned portion of the stack frame.  This is always a contiguous
89234353Sdim  /// sequence of D-registers starting from d8.
90234353Sdim  ///
91234353Sdim  /// We do not keep track of the frame indices used for these registers - they
92234353Sdim  /// behave like any other frame index in the aligned stack frame.  These
93234353Sdim  /// registers also aren't included in DPRCSSize above.
94234353Sdim  unsigned NumAlignedDPRCS2Regs;
95234353Sdim
96193323Sed  /// JumpTableUId - Unique id for jumptables.
97193323Sed  ///
98193323Sed  unsigned JumpTableUId;
99193323Sed
100218893Sdim  unsigned PICLabelUId;
101193323Sed
102207618Srdivacky  /// VarArgsFrameIndex - FrameIndex for start of varargs area.
103207618Srdivacky  int VarArgsFrameIndex;
104207618Srdivacky
105210299Sed  /// HasITBlocks - True if IT blocks have been inserted.
106210299Sed  bool HasITBlocks;
107210299Sed
108218893Sdim  /// CPEClones - Track constant pool entries clones created by Constant Island
109218893Sdim  /// pass.
110218893Sdim  DenseMap<unsigned, unsigned> CPEClones;
111218893Sdim
112243830Sdim  /// GlobalBaseReg - keeps track of the virtual register initialized for
113243830Sdim  /// use as the global base register. This is used for PIC in some PIC
114243830Sdim  /// relocation models.
115243830Sdim  unsigned GlobalBaseReg;
116243830Sdim
117193323Sedpublic:
118193323Sed  ARMFunctionInfo() :
119195340Sed    isThumb(false),
120195340Sed    hasThumb2(false),
121251662Sdim    ArgRegsSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
122198090Srdivacky    LRSpilledForFarJump(false),
123193323Sed    FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
124193323Sed    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
125234353Sdim    NumAlignedDPRCS2Regs(0),
126218893Sdim    JumpTableUId(0), PICLabelUId(0),
127243830Sdim    VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
128193323Sed
129193574Sed  explicit ARMFunctionInfo(MachineFunction &MF) :
130193323Sed    isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
131195340Sed    hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
132263508Sdim    StByValParamsPadding(0),
133251662Sdim    ArgRegsSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
134198090Srdivacky    LRSpilledForFarJump(false),
135193323Sed    FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
136193323Sed    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
137218893Sdim    JumpTableUId(0), PICLabelUId(0),
138243830Sdim    VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
139193323Sed
140193323Sed  bool isThumbFunction() const { return isThumb; }
141198090Srdivacky  bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
142195340Sed  bool isThumb2Function() const { return isThumb && hasThumb2; }
143193323Sed
144263508Sdim  unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; }
145263508Sdim  void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; }
146263508Sdim
147263508Sdim  unsigned getArgRegsSaveSize(unsigned Align = 0) const {
148263508Sdim    if (!Align)
149263508Sdim      return ArgRegsSaveSize;
150263508Sdim    return (ArgRegsSaveSize + Align - 1) & ~(Align - 1);
151263508Sdim  }
152251662Sdim  void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
153193323Sed
154193323Sed  bool hasStackFrame() const { return HasStackFrame; }
155193323Sed  void setHasStackFrame(bool s) { HasStackFrame = s; }
156193323Sed
157212904Sdim  bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
158212904Sdim  void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
159212904Sdim
160193323Sed  bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
161193323Sed  void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
162193323Sed
163193323Sed  unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
164193323Sed  void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
165198090Srdivacky
166234353Sdim  unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
167234353Sdim  void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
168234353Sdim
169193323Sed  unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
170193323Sed  unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
171193323Sed  unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
172193323Sed
173193323Sed  void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
174193323Sed  void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
175193323Sed  void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
176193323Sed
177193323Sed  unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
178193323Sed  unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
179193323Sed  unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
180193323Sed
181193323Sed  void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
182193323Sed  void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
183193323Sed  void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
184193323Sed
185193323Sed  unsigned createJumpTableUId() {
186193323Sed    return JumpTableUId++;
187193323Sed  }
188193323Sed
189193323Sed  unsigned getNumJumpTables() const {
190193323Sed    return JumpTableUId;
191193323Sed  }
192193323Sed
193218893Sdim  void initPICLabelUId(unsigned UId) {
194218893Sdim    PICLabelUId = UId;
195193323Sed  }
196193323Sed
197218893Sdim  unsigned getNumPICLabels() const {
198218893Sdim    return PICLabelUId;
199193323Sed  }
200193323Sed
201218893Sdim  unsigned createPICLabelUId() {
202218893Sdim    return PICLabelUId++;
203193323Sed  }
204207618Srdivacky
205207618Srdivacky  int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
206207618Srdivacky  void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
207210299Sed
208210299Sed  bool hasITBlocks() const { return HasITBlocks; }
209210299Sed  void setHasITBlocks(bool h) { HasITBlocks = h; }
210218893Sdim
211243830Sdim  unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
212243830Sdim  void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
213243830Sdim
214218893Sdim  void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
215218893Sdim    if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
216218893Sdim      assert(0 && "Duplicate entries!");
217218893Sdim  }
218218893Sdim
219218893Sdim  unsigned getOriginalCPIdx(unsigned CloneIdx) const {
220218893Sdim    DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
221218893Sdim    if (I != CPEClones.end())
222218893Sdim      return I->second;
223218893Sdim    else
224218893Sdim      return -1U;
225218893Sdim  }
226193323Sed};
227193323Sed} // End llvm namespace
228193323Sed
229193323Sed#endif // ARMMACHINEFUNCTIONINFO_H
230