[arm-fast-isel] Add support for ELF PIC.
[oota-llvm.git] / lib / Target / ARM / ARMMachineFunctionInfo.h
1 //===-- ARMMachineFuctionInfo.h - ARM machine function info -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares ARM-specific per-machine-function information.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef ARMMACHINEFUNCTIONINFO_H
15 #define ARMMACHINEFUNCTIONINFO_H
16
17 #include "ARMSubtarget.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/ADT/BitVector.h"
22
23 namespace llvm {
24
25 /// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
26 /// contains private ARM-specific information for each MachineFunction.
27 class ARMFunctionInfo : public MachineFunctionInfo {
28   virtual void anchor();
29
30   /// isThumb - True if this function is compiled under Thumb mode.
31   /// Used to initialized Align, so must precede it.
32   bool isThumb;
33
34   /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
35   /// to determine if function is compiled under Thumb mode, for that use
36   /// 'isThumb'.
37   bool hasThumb2;
38
39   /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
40   ///
41   unsigned VarArgsRegSaveSize;
42
43   /// HasStackFrame - True if this function has a stack frame. Set by
44   /// processFunctionBeforeCalleeSavedScan().
45   bool HasStackFrame;
46
47   /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
48   /// emitPrologue.
49   bool RestoreSPFromFP;
50
51   /// LRSpilledForFarJump - True if the LR register has been for spilled to
52   /// enable far jump.
53   bool LRSpilledForFarJump;
54
55   /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
56   /// spill stack offset.
57   unsigned FramePtrSpillOffset;
58
59   /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
60   /// register spills areas. For Mac OS X:
61   ///
62   /// GPR callee-saved (1) : r4, r5, r6, r7, lr
63   /// --------------------------------------------
64   /// GPR callee-saved (2) : r8, r10, r11
65   /// --------------------------------------------
66   /// DPR callee-saved : d8 - d15
67   ///
68   /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3.
69   /// Some may be spilled after the stack has been realigned.
70   unsigned GPRCS1Offset;
71   unsigned GPRCS2Offset;
72   unsigned DPRCSOffset;
73
74   /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
75   /// areas.
76   unsigned GPRCS1Size;
77   unsigned GPRCS2Size;
78   unsigned DPRCSSize;
79
80   /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
81   /// which belong to these spill areas.
82   BitVector GPRCS1Frames;
83   BitVector GPRCS2Frames;
84   BitVector DPRCSFrames;
85
86   /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
87   /// the aligned portion of the stack frame.  This is always a contiguous
88   /// sequence of D-registers starting from d8.
89   ///
90   /// We do not keep track of the frame indices used for these registers - they
91   /// behave like any other frame index in the aligned stack frame.  These
92   /// registers also aren't included in DPRCSSize above.
93   unsigned NumAlignedDPRCS2Regs;
94
95   /// JumpTableUId - Unique id for jumptables.
96   ///
97   unsigned JumpTableUId;
98
99   unsigned PICLabelUId;
100
101   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
102   int VarArgsFrameIndex;
103
104   /// HasITBlocks - True if IT blocks have been inserted.
105   bool HasITBlocks;
106
107   /// CPEClones - Track constant pool entries clones created by Constant Island
108   /// pass.
109   DenseMap<unsigned, unsigned> CPEClones;
110
111   /// GlobalBaseReg - keeps track of the virtual register initialized for
112   /// use as the global base register. This is used for PIC in some PIC
113   /// relocation models.
114   unsigned GlobalBaseReg;
115
116 public:
117   ARMFunctionInfo() :
118     isThumb(false),
119     hasThumb2(false),
120     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
121     LRSpilledForFarJump(false),
122     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
123     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
124     GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
125     NumAlignedDPRCS2Regs(0),
126     JumpTableUId(0), PICLabelUId(0),
127     VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
128
129   explicit ARMFunctionInfo(MachineFunction &MF) :
130     isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
131     hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
132     VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
133     LRSpilledForFarJump(false),
134     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
135     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
136     GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
137     JumpTableUId(0), PICLabelUId(0),
138     VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
139
140   bool isThumbFunction() const { return isThumb; }
141   bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
142   bool isThumb2Function() const { return isThumb && hasThumb2; }
143
144   unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
145   void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
146
147   bool hasStackFrame() const { return HasStackFrame; }
148   void setHasStackFrame(bool s) { HasStackFrame = s; }
149
150   bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
151   void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
152
153   bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
154   void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
155
156   unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
157   void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
158
159   unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; }
160   void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; }
161
162   unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
163   unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
164   unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
165
166   void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
167   void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
168   void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
169
170   unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
171   unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
172   unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
173
174   void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
175   void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
176   void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
177
178   bool isGPRCalleeSavedArea1Frame(int fi) const {
179     if (fi < 0 || fi >= (int)GPRCS1Frames.size())
180       return false;
181     return GPRCS1Frames[fi];
182   }
183   bool isGPRCalleeSavedArea2Frame(int fi) const {
184     if (fi < 0 || fi >= (int)GPRCS2Frames.size())
185       return false;
186     return GPRCS2Frames[fi];
187   }
188   bool isDPRCalleeSavedAreaFrame(int fi) const {
189     if (fi < 0 || fi >= (int)DPRCSFrames.size())
190       return false;
191     return DPRCSFrames[fi];
192   }
193
194   void addGPRCalleeSavedArea1Frame(int fi) {
195     if (fi >= 0) {
196       int Size = GPRCS1Frames.size();
197       if (fi >= Size) {
198         Size *= 2;
199         if (fi >= Size)
200           Size = fi+1;
201         GPRCS1Frames.resize(Size);
202       }
203       GPRCS1Frames[fi] = true;
204     }
205   }
206   void addGPRCalleeSavedArea2Frame(int fi) {
207     if (fi >= 0) {
208       int Size = GPRCS2Frames.size();
209       if (fi >= Size) {
210         Size *= 2;
211         if (fi >= Size)
212           Size = fi+1;
213         GPRCS2Frames.resize(Size);
214       }
215       GPRCS2Frames[fi] = true;
216     }
217   }
218   void addDPRCalleeSavedAreaFrame(int fi) {
219     if (fi >= 0) {
220       int Size = DPRCSFrames.size();
221       if (fi >= Size) {
222         Size *= 2;
223         if (fi >= Size)
224           Size = fi+1;
225         DPRCSFrames.resize(Size);
226       }
227       DPRCSFrames[fi] = true;
228     }
229   }
230
231   unsigned createJumpTableUId() {
232     return JumpTableUId++;
233   }
234
235   unsigned getNumJumpTables() const {
236     return JumpTableUId;
237   }
238
239   void initPICLabelUId(unsigned UId) {
240     PICLabelUId = UId;
241   }
242
243   unsigned getNumPICLabels() const {
244     return PICLabelUId;
245   }
246
247   unsigned createPICLabelUId() {
248     return PICLabelUId++;
249   }
250
251   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
252   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
253
254   bool hasITBlocks() const { return HasITBlocks; }
255   void setHasITBlocks(bool h) { HasITBlocks = h; }
256
257   unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
258   void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
259
260   void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
261     if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
262       assert(0 && "Duplicate entries!");
263   }
264
265   unsigned getOriginalCPIdx(unsigned CloneIdx) const {
266     DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
267     if (I != CPEClones.end())
268       return I->second;
269     else
270       return -1U;
271   }
272 };
273 } // End llvm namespace
274
275 #endif // ARMMACHINEFUNCTIONINFO_H