ARMBaseRegisterInfo.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //===-- ARMBaseRegisterInfo.h - ARM Register Information Impl ---*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains the base ARM implementation of TargetRegisterInfo class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
  13. #define LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
  14. #include "MCTargetDesc/ARMBaseInfo.h"
  15. #include "llvm/CodeGen/MachineBasicBlock.h"
  16. #include "llvm/CodeGen/MachineInstr.h"
  17. #include "llvm/CodeGen/TargetRegisterInfo.h"
  18. #include "llvm/IR/CallingConv.h"
  19. #include "llvm/MC/MCRegisterInfo.h"
  20. #include <cstdint>
  21. #define GET_REGINFO_HEADER
  22. #include "ARMGenRegisterInfo.inc"
  23. namespace llvm {
  24. class LiveIntervals;
  25. /// Register allocation hints.
  26. namespace ARMRI {
  27. enum {
  28. // Used for LDRD register pairs
  29. RegPairOdd = 1,
  30. RegPairEven = 2,
  31. // Used to hint for lr in t2DoLoopStart
  32. RegLR = 3
  33. };
  34. } // end namespace ARMRI
  35. /// isARMArea1Register - Returns true if the register is a low register (r0-r7)
  36. /// or a stack/pc register that we should push/pop.
  37. static inline bool isARMArea1Register(unsigned Reg, bool SplitFramePushPop) {
  38. using namespace ARM;
  39. switch (Reg) {
  40. case R0: case R1: case R2: case R3:
  41. case R4: case R5: case R6: case R7:
  42. case LR: case SP: case PC:
  43. return true;
  44. case R8: case R9: case R10: case R11: case R12:
  45. // For iOS we want r7 and lr to be next to each other.
  46. return !SplitFramePushPop;
  47. default:
  48. return false;
  49. }
  50. }
  51. static inline bool isARMArea2Register(unsigned Reg, bool SplitFramePushPop) {
  52. using namespace ARM;
  53. switch (Reg) {
  54. case R8: case R9: case R10: case R11: case R12:
  55. // iOS has this second area.
  56. return SplitFramePushPop;
  57. default:
  58. return false;
  59. }
  60. }
  61. static inline bool isSplitFPArea1Register(unsigned Reg,
  62. bool SplitFramePushPop) {
  63. using namespace ARM;
  64. switch (Reg) {
  65. case R0: case R1: case R2: case R3:
  66. case R4: case R5: case R6: case R7:
  67. case R8: case R9: case R10: case R12:
  68. case SP: case PC:
  69. return true;
  70. default:
  71. return false;
  72. }
  73. }
  74. static inline bool isSplitFPArea2Register(unsigned Reg,
  75. bool SplitFramePushPop) {
  76. using namespace ARM;
  77. switch (Reg) {
  78. case R11: case LR:
  79. return true;
  80. default:
  81. return false;
  82. }
  83. }
  84. static inline bool isARMArea3Register(unsigned Reg, bool SplitFramePushPop) {
  85. using namespace ARM;
  86. switch (Reg) {
  87. case D15: case D14: case D13: case D12:
  88. case D11: case D10: case D9: case D8:
  89. case D7: case D6: case D5: case D4:
  90. case D3: case D2: case D1: case D0:
  91. case D31: case D30: case D29: case D28:
  92. case D27: case D26: case D25: case D24:
  93. case D23: case D22: case D21: case D20:
  94. case D19: case D18: case D17: case D16:
  95. return true;
  96. default:
  97. return false;
  98. }
  99. }
  100. static inline bool isCalleeSavedRegister(unsigned Reg,
  101. const MCPhysReg *CSRegs) {
  102. for (unsigned i = 0; CSRegs[i]; ++i)
  103. if (Reg == CSRegs[i])
  104. return true;
  105. return false;
  106. }
  107. class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
  108. protected:
  109. /// BasePtr - ARM physical register used as a base ptr in complex stack
  110. /// frames. I.e., when we need a 3rd base, not just SP and FP, due to
  111. /// variable size stack objects.
  112. unsigned BasePtr = ARM::R6;
  113. // Can be only subclassed.
  114. explicit ARMBaseRegisterInfo();
  115. // Return the opcode that implements 'Op', or 0 if no opcode
  116. unsigned getOpcode(int Op) const;
  117. public:
  118. /// Code Generation virtual methods...
  119. const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
  120. const MCPhysReg *
  121. getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
  122. const uint32_t *getCallPreservedMask(const MachineFunction &MF,
  123. CallingConv::ID) const override;
  124. const uint32_t *getNoPreservedMask() const override;
  125. const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const;
  126. const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const;
  127. /// getThisReturnPreservedMask - Returns a call preserved mask specific to the
  128. /// case that 'returned' is on an i32 first argument if the calling convention
  129. /// is one that can (partially) model this attribute with a preserved mask
  130. /// (i.e. it is a calling convention that uses the same register for the first
  131. /// i32 argument and an i32 return value)
  132. ///
  133. /// Should return NULL in the case that the calling convention does not have
  134. /// this property
  135. const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF,
  136. CallingConv::ID) const;
  137. ArrayRef<MCPhysReg>
  138. getIntraCallClobberedRegs(const MachineFunction *MF) const override;
  139. BitVector getReservedRegs(const MachineFunction &MF) const override;
  140. bool isAsmClobberable(const MachineFunction &MF,
  141. MCRegister PhysReg) const override;
  142. bool isInlineAsmReadOnlyReg(const MachineFunction &MF,
  143. unsigned PhysReg) const override;
  144. const TargetRegisterClass *
  145. getPointerRegClass(const MachineFunction &MF,
  146. unsigned Kind = 0) const override;
  147. const TargetRegisterClass *
  148. getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
  149. const TargetRegisterClass *
  150. getLargestLegalSuperClass(const TargetRegisterClass *RC,
  151. const MachineFunction &MF) const override;
  152. unsigned getRegPressureLimit(const TargetRegisterClass *RC,
  153. MachineFunction &MF) const override;
  154. bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
  155. SmallVectorImpl<MCPhysReg> &Hints,
  156. const MachineFunction &MF, const VirtRegMap *VRM,
  157. const LiveRegMatrix *Matrix) const override;
  158. void updateRegAllocHint(Register Reg, Register NewReg,
  159. MachineFunction &MF) const override;
  160. bool hasBasePointer(const MachineFunction &MF) const;
  161. bool canRealignStack(const MachineFunction &MF) const override;
  162. int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
  163. int Idx) const override;
  164. bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
  165. Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
  166. int64_t Offset) const override;
  167. void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
  168. int64_t Offset) const override;
  169. bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
  170. int64_t Offset) const override;
  171. bool cannotEliminateFrame(const MachineFunction &MF) const;
  172. // Debug information queries.
  173. Register getFrameRegister(const MachineFunction &MF) const override;
  174. Register getBaseRegister() const { return BasePtr; }
  175. /// emitLoadConstPool - Emits a load from constpool to materialize the
  176. /// specified immediate.
  177. virtual void
  178. emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
  179. const DebugLoc &dl, Register DestReg, unsigned SubIdx,
  180. int Val, ARMCC::CondCodes Pred = ARMCC::AL,
  181. Register PredReg = Register(),
  182. unsigned MIFlags = MachineInstr::NoFlags) const;
  183. /// Code Generation virtual methods...
  184. bool requiresRegisterScavenging(const MachineFunction &MF) const override;
  185. bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
  186. bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;
  187. bool eliminateFrameIndex(MachineBasicBlock::iterator II,
  188. int SPAdj, unsigned FIOperandNum,
  189. RegScavenger *RS = nullptr) const override;
  190. /// SrcRC and DstRC will be morphed into NewRC if this returns true
  191. bool shouldCoalesce(MachineInstr *MI,
  192. const TargetRegisterClass *SrcRC,
  193. unsigned SubReg,
  194. const TargetRegisterClass *DstRC,
  195. unsigned DstSubReg,
  196. const TargetRegisterClass *NewRC,
  197. LiveIntervals &LIS) const override;
  198. bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
  199. unsigned DefSubReg,
  200. const TargetRegisterClass *SrcRC,
  201. unsigned SrcSubReg) const override;
  202. int getSEHRegNum(unsigned i) const { return getEncodingValue(i); }
  203. };
  204. } // end namespace llvm
  205. #endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H