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/ADT/BitVector.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/Target/TargetMachine.h" 21 #include "llvm/Target/TargetRegisterInfo.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 /// StByValParamsPadding - For parameter that is split between 40 /// GPRs and memory; while recovering GPRs part, when 41 /// StackAlignment == 8, and GPRs-part-size mod 8 != 0, 42 /// we need to insert gap before parameter start address. It allows to 43 /// "attach" GPR-part to the part that was passed via stack. 44 unsigned StByValParamsPadding; 45 46 /// VarArgsRegSaveSize - Size of the register save area for vararg functions. 47 /// 48 unsigned ArgRegsSaveSize; 49 50 /// HasStackFrame - True if this function has a stack frame. Set by 51 /// processFunctionBeforeCalleeSavedScan(). 52 bool HasStackFrame; 53 54 /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by 55 /// emitPrologue. 56 bool RestoreSPFromFP; 57 58 /// LRSpilledForFarJump - True if the LR register has been for spilled to 59 /// enable far jump. 60 bool LRSpilledForFarJump; 61 62 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer 63 /// spill stack offset. 64 unsigned FramePtrSpillOffset; 65 66 /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved 67 /// register spills areas. For Mac OS X: 68 /// 69 /// GPR callee-saved (1) : r4, r5, r6, r7, lr 70 /// -------------------------------------------- 71 /// GPR callee-saved (2) : r8, r10, r11 72 /// -------------------------------------------- 73 /// DPR callee-saved : d8 - d15 74 /// 75 /// Also see AlignedDPRCSRegs below. Not all D-regs need to go in area 3. 76 /// Some may be spilled after the stack has been realigned. 77 unsigned GPRCS1Offset; 78 unsigned GPRCS2Offset; 79 unsigned DPRCSOffset; 80 81 /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills 82 /// areas. 83 unsigned GPRCS1Size; 84 unsigned GPRCS2Size; 85 unsigned DPRCSSize; 86 87 /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices 88 /// which belong to these spill areas. 89 BitVector GPRCS1Frames; 90 BitVector GPRCS2Frames; 91 BitVector DPRCSFrames; 92 93 /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in 94 /// the aligned portion of the stack frame. This is always a contiguous 95 /// sequence of D-registers starting from d8. 96 /// 97 /// We do not keep track of the frame indices used for these registers - they 98 /// behave like any other frame index in the aligned stack frame. These 99 /// registers also aren't included in DPRCSSize above. 100 unsigned NumAlignedDPRCS2Regs; 101 102 /// JumpTableUId - Unique id for jumptables. 103 /// 104 unsigned JumpTableUId; 105 106 unsigned PICLabelUId; 107 108 /// VarArgsFrameIndex - FrameIndex for start of varargs area. 109 int VarArgsFrameIndex; 110 111 /// HasITBlocks - True if IT blocks have been inserted. 112 bool HasITBlocks; 113 114 /// CPEClones - Track constant pool entries clones created by Constant Island 115 /// pass. 116 DenseMap<unsigned, unsigned> CPEClones; 117 118 /// GlobalBaseReg - keeps track of the virtual register initialized for 119 /// use as the global base register. This is used for PIC in some PIC 120 /// relocation models. 121 unsigned GlobalBaseReg; 122 123 public: 124 ARMFunctionInfo() : 125 isThumb(false), 126 hasThumb2(false), 127 ArgRegsSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false), 128 LRSpilledForFarJump(false), 129 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), 130 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), 131 GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0), 132 NumAlignedDPRCS2Regs(0), 133 JumpTableUId(0), PICLabelUId(0), 134 VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {} 135 136 explicit ARMFunctionInfo(MachineFunction &MF) : 137 isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()), 138 hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()), 139 StByValParamsPadding(0), 140 ArgRegsSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false), 141 LRSpilledForFarJump(false), 142 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), 143 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), 144 GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32), 145 JumpTableUId(0), PICLabelUId(0), 146 VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {} 147 148 bool isThumbFunction() const { return isThumb; } 149 bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; } 150 bool isThumb2Function() const { return isThumb && hasThumb2; } 151 152 unsigned getStoredByValParamsPadding() const { return StByValParamsPadding; } 153 void setStoredByValParamsPadding(unsigned p) { StByValParamsPadding = p; } 154 155 unsigned getArgRegsSaveSize(unsigned Align = 0) const { 156 if (!Align) 157 return ArgRegsSaveSize; 158 return (ArgRegsSaveSize + Align - 1) & ~(Align - 1); 159 } 160 void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; } 161 162 bool hasStackFrame() const { return HasStackFrame; } 163 void setHasStackFrame(bool s) { HasStackFrame = s; } 164 165 bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; } 166 void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; } 167 168 bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; } 169 void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; } 170 171 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; } 172 void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; } 173 174 unsigned getNumAlignedDPRCS2Regs() const { return NumAlignedDPRCS2Regs; } 175 void setNumAlignedDPRCS2Regs(unsigned n) { NumAlignedDPRCS2Regs = n; } 176 177 unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; } 178 unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; } 179 unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; } 180 181 void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; } 182 void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; } 183 void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; } 184 185 unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; } 186 unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; } 187 unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; } 188 189 void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; } 190 void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; } 191 void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; } 192 193 bool isGPRCalleeSavedArea1Frame(int fi) const { 194 if (fi < 0 || fi >= (int)GPRCS1Frames.size()) 195 return false; 196 return GPRCS1Frames[fi]; 197 } 198 bool isGPRCalleeSavedArea2Frame(int fi) const { 199 if (fi < 0 || fi >= (int)GPRCS2Frames.size()) 200 return false; 201 return GPRCS2Frames[fi]; 202 } 203 bool isDPRCalleeSavedAreaFrame(int fi) const { 204 if (fi < 0 || fi >= (int)DPRCSFrames.size()) 205 return false; 206 return DPRCSFrames[fi]; 207 } 208 209 void addGPRCalleeSavedArea1Frame(int fi) { 210 if (fi >= 0) { 211 int Size = GPRCS1Frames.size(); 212 if (fi >= Size) { 213 Size *= 2; 214 if (fi >= Size) 215 Size = fi+1; 216 GPRCS1Frames.resize(Size); 217 } 218 GPRCS1Frames[fi] = true; 219 } 220 } 221 void addGPRCalleeSavedArea2Frame(int fi) { 222 if (fi >= 0) { 223 int Size = GPRCS2Frames.size(); 224 if (fi >= Size) { 225 Size *= 2; 226 if (fi >= Size) 227 Size = fi+1; 228 GPRCS2Frames.resize(Size); 229 } 230 GPRCS2Frames[fi] = true; 231 } 232 } 233 void addDPRCalleeSavedAreaFrame(int fi) { 234 if (fi >= 0) { 235 int Size = DPRCSFrames.size(); 236 if (fi >= Size) { 237 Size *= 2; 238 if (fi >= Size) 239 Size = fi+1; 240 DPRCSFrames.resize(Size); 241 } 242 DPRCSFrames[fi] = true; 243 } 244 } 245 246 unsigned createJumpTableUId() { 247 return JumpTableUId++; 248 } 249 250 unsigned getNumJumpTables() const { 251 return JumpTableUId; 252 } 253 254 void initPICLabelUId(unsigned UId) { 255 PICLabelUId = UId; 256 } 257 258 unsigned getNumPICLabels() const { 259 return PICLabelUId; 260 } 261 262 unsigned createPICLabelUId() { 263 return PICLabelUId++; 264 } 265 266 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } 267 void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } 268 269 bool hasITBlocks() const { return HasITBlocks; } 270 void setHasITBlocks(bool h) { HasITBlocks = h; } 271 272 unsigned getGlobalBaseReg() const { return GlobalBaseReg; } 273 void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; } 274 275 void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) { 276 if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second) 277 assert(0 && "Duplicate entries!"); 278 } 279 280 unsigned getOriginalCPIdx(unsigned CloneIdx) const { 281 DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx); 282 if (I != CPEClones.end()) 283 return I->second; 284 else 285 return -1U; 286 } 287 }; 288 } // End llvm namespace 289 290 #endif // ARMMACHINEFUNCTIONINFO_H 291