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