1235633Sdim//===-- ARMBaseRegisterInfo.h - ARM Register Information Impl ---*- C++ -*-===//
2198090Srdivacky//
3198090Srdivacky//                     The LLVM Compiler Infrastructure
4198090Srdivacky//
5198090Srdivacky// This file is distributed under the University of Illinois Open Source
6198090Srdivacky// License. See LICENSE.TXT for details.
7198090Srdivacky//
8198090Srdivacky//===----------------------------------------------------------------------===//
9198090Srdivacky//
10198090Srdivacky// This file contains the base ARM implementation of TargetRegisterInfo class.
11198090Srdivacky//
12198090Srdivacky//===----------------------------------------------------------------------===//
13198090Srdivacky
14198090Srdivacky#ifndef ARMBASEREGISTERINFO_H
15198090Srdivacky#define ARMBASEREGISTERINFO_H
16198090Srdivacky
17198090Srdivacky#include "ARM.h"
18198090Srdivacky#include "llvm/Target/TargetRegisterInfo.h"
19198090Srdivacky
20224145Sdim#define GET_REGINFO_HEADER
21224145Sdim#include "ARMGenRegisterInfo.inc"
22224145Sdim
23198090Srdivackynamespace llvm {
24198090Srdivacky  class ARMSubtarget;
25198090Srdivacky  class ARMBaseInstrInfo;
26198090Srdivacky  class Type;
27198090Srdivacky
28198090Srdivacky/// Register allocation hints.
29198090Srdivackynamespace ARMRI {
30198090Srdivacky  enum {
31198090Srdivacky    RegPairOdd  = 1,
32198090Srdivacky    RegPairEven = 2
33198090Srdivacky  };
34198090Srdivacky}
35198090Srdivacky
36218893Sdim/// isARMArea1Register - Returns true if the register is a low register (r0-r7)
37218893Sdim/// or a stack/pc register that we should push/pop.
38235633Sdimstatic inline bool isARMArea1Register(unsigned Reg, bool isIOS) {
39218893Sdim  using namespace ARM;
40218893Sdim  switch (Reg) {
41218893Sdim    case R0:  case R1:  case R2:  case R3:
42218893Sdim    case R4:  case R5:  case R6:  case R7:
43218893Sdim    case LR:  case SP:  case PC:
44218893Sdim      return true;
45218893Sdim    case R8:  case R9:  case R10: case R11:
46235633Sdim      // For iOS we want r7 and lr to be next to each other.
47235633Sdim      return !isIOS;
48218893Sdim    default:
49218893Sdim      return false;
50218893Sdim  }
51218893Sdim}
52218893Sdim
53235633Sdimstatic inline bool isARMArea2Register(unsigned Reg, bool isIOS) {
54218893Sdim  using namespace ARM;
55218893Sdim  switch (Reg) {
56218893Sdim    case R8: case R9: case R10: case R11:
57235633Sdim      // iOS has this second area.
58235633Sdim      return isIOS;
59218893Sdim    default:
60218893Sdim      return false;
61218893Sdim  }
62218893Sdim}
63218893Sdim
64235633Sdimstatic inline bool isARMArea3Register(unsigned Reg, bool isIOS) {
65218893Sdim  using namespace ARM;
66218893Sdim  switch (Reg) {
67218893Sdim    case D15: case D14: case D13: case D12:
68218893Sdim    case D11: case D10: case D9:  case D8:
69218893Sdim      return true;
70218893Sdim    default:
71218893Sdim      return false;
72218893Sdim  }
73218893Sdim}
74218893Sdim
75263509Sdimstatic inline bool isCalleeSavedRegister(unsigned Reg,
76263509Sdim                                         const MCPhysReg *CSRegs) {
77263509Sdim  for (unsigned i = 0; CSRegs[i]; ++i)
78263509Sdim    if (Reg == CSRegs[i])
79263509Sdim      return true;
80263509Sdim  return false;
81263509Sdim}
82263509Sdim
83212904Sdimclass ARMBaseRegisterInfo : public ARMGenRegisterInfo {
84198090Srdivackyprotected:
85198090Srdivacky  const ARMSubtarget &STI;
86198090Srdivacky
87198090Srdivacky  /// FramePtr - ARM physical register used as frame ptr.
88198090Srdivacky  unsigned FramePtr;
89198090Srdivacky
90212904Sdim  /// BasePtr - ARM physical register used as a base ptr in complex stack
91212904Sdim  /// frames. I.e., when we need a 3rd base, not just SP and FP, due to
92212904Sdim  /// variable size stack objects.
93212904Sdim  unsigned BasePtr;
94212904Sdim
95198090Srdivacky  // Can be only subclassed.
96263509Sdim  explicit ARMBaseRegisterInfo(const ARMSubtarget &STI);
97198090Srdivacky
98198090Srdivacky  // Return the opcode that implements 'Op', or 0 if no opcode
99198090Srdivacky  unsigned getOpcode(int Op) const;
100198090Srdivacky
101198090Srdivackypublic:
102198090Srdivacky  /// Code Generation virtual methods...
103235633Sdim  const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
104235633Sdim  const uint32_t *getCallPreservedMask(CallingConv::ID) const;
105245431Sdim  const uint32_t *getNoPreservedMask() const;
106198090Srdivacky
107263509Sdim  /// getThisReturnPreservedMask - Returns a call preserved mask specific to the
108263509Sdim  /// case that 'returned' is on an i32 first argument if the calling convention
109263509Sdim  /// is one that can (partially) model this attribute with a preserved mask
110263509Sdim  /// (i.e. it is a calling convention that uses the same register for the first
111263509Sdim  /// i32 argument and an i32 return value)
112263509Sdim  ///
113263509Sdim  /// Should return NULL in the case that the calling convention does not have
114263509Sdim  /// this property
115263509Sdim  const uint32_t *getThisReturnPreservedMask(CallingConv::ID) const;
116263509Sdim
117198090Srdivacky  BitVector getReservedRegs(const MachineFunction &MF) const;
118198090Srdivacky
119226890Sdim  const TargetRegisterClass*
120245431Sdim  getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const;
121245431Sdim  const TargetRegisterClass*
122226890Sdim  getCrossCopyRegClass(const TargetRegisterClass *RC) const;
123198090Srdivacky
124221345Sdim  const TargetRegisterClass*
125221345Sdim  getLargestLegalSuperClass(const TargetRegisterClass *RC) const;
126221345Sdim
127221345Sdim  unsigned getRegPressureLimit(const TargetRegisterClass *RC,
128221345Sdim                               MachineFunction &MF) const;
129221345Sdim
130252723Sdim  void getRegAllocationHints(unsigned VirtReg,
131252723Sdim                             ArrayRef<MCPhysReg> Order,
132252723Sdim                             SmallVectorImpl<MCPhysReg> &Hints,
133252723Sdim                             const MachineFunction &MF,
134252723Sdim                             const VirtRegMap *VRM) const;
135198090Srdivacky
136198090Srdivacky  void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
137198090Srdivacky                          MachineFunction &MF) const;
138198090Srdivacky
139221345Sdim  virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const;
140221345Sdim
141212904Sdim  bool hasBasePointer(const MachineFunction &MF) const;
142198090Srdivacky
143202878Srdivacky  bool canRealignStack(const MachineFunction &MF) const;
144198892Srdivacky  bool needsStackRealignment(const MachineFunction &MF) const;
145212904Sdim  int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const;
146212904Sdim  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const;
147218893Sdim  void materializeFrameBaseRegister(MachineBasicBlock *MBB,
148212904Sdim                                    unsigned BaseReg, int FrameIdx,
149212904Sdim                                    int64_t Offset) const;
150212904Sdim  void resolveFrameIndex(MachineBasicBlock::iterator I,
151212904Sdim                         unsigned BaseReg, int64_t Offset) const;
152212904Sdim  bool isFrameOffsetLegal(const MachineInstr *MI, int64_t Offset) const;
153198892Srdivacky
154198090Srdivacky  bool cannotEliminateFrame(const MachineFunction &MF) const;
155198090Srdivacky
156198090Srdivacky  // Debug information queries.
157199481Srdivacky  unsigned getFrameRegister(const MachineFunction &MF) const;
158218893Sdim  unsigned getBaseRegister() const { return BasePtr; }
159198090Srdivacky
160198090Srdivacky  bool isLowRegister(unsigned Reg) const;
161198090Srdivacky
162198090Srdivacky
163198090Srdivacky  /// emitLoadConstPool - Emits a load from constpool to materialize the
164198090Srdivacky  /// specified immediate.
165198090Srdivacky  virtual void emitLoadConstPool(MachineBasicBlock &MBB,
166198090Srdivacky                                 MachineBasicBlock::iterator &MBBI,
167198090Srdivacky                                 DebugLoc dl,
168198090Srdivacky                                 unsigned DestReg, unsigned SubIdx,
169198090Srdivacky                                 int Val,
170198090Srdivacky                                 ARMCC::CondCodes Pred = ARMCC::AL,
171221345Sdim                                 unsigned PredReg = 0,
172221345Sdim                                 unsigned MIFlags = MachineInstr::NoFlags)const;
173198090Srdivacky
174198090Srdivacky  /// Code Generation virtual methods...
175198090Srdivacky  virtual bool requiresRegisterScavenging(const MachineFunction &MF) const;
176198090Srdivacky
177245431Sdim  virtual bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const;
178245431Sdim
179198396Srdivacky  virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const;
180198396Srdivacky
181212904Sdim  virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const;
182198090Srdivacky
183212904Sdim  virtual void eliminateFrameIndex(MachineBasicBlock::iterator II,
184252723Sdim                                   int SPAdj, unsigned FIOperandNum,
185252723Sdim                                   RegScavenger *RS = NULL) const;
186198090Srdivacky};
187198090Srdivacky
188198090Srdivacky} // end namespace llvm
189198090Srdivacky
190198090Srdivacky#endif
191