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