LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AArch64RegisterInfo.cpp
Go to the documentation of this file.
1 //===- AArch64RegisterInfo.cpp - AArch64 Register Information -------------===//
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 AArch64 implementation of the TargetRegisterInfo
11 // class.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 
16 #include "AArch64RegisterInfo.h"
17 #include "AArch64FrameLowering.h"
19 #include "AArch64TargetMachine.h"
25 #include "llvm/ADT/BitVector.h"
26 
27 #define GET_REGINFO_TARGET_DESC
28 #include "AArch64GenRegisterInfo.inc"
29 
30 using namespace llvm;
31 
33  : AArch64GenRegisterInfo(AArch64::X30) {
34 }
35 
36 const uint16_t *
38  return CSR_PCS_SaveList;
39 }
40 
41 const uint32_t*
43  return CSR_PCS_RegMask;
44 }
45 
47  return TLSDesc_RegMask;
48 }
49 
50 const TargetRegisterClass *
52  if (RC == &AArch64::FlagClassRegClass)
53  return &AArch64::GPR64RegClass;
54 
55  return RC;
56 }
57 
58 
59 
62  BitVector Reserved(getNumRegs());
64 
65  Reserved.set(AArch64::XSP);
66  Reserved.set(AArch64::WSP);
67 
68  Reserved.set(AArch64::XZR);
69  Reserved.set(AArch64::WZR);
70 
71  if (TFI->hasFP(MF)) {
72  Reserved.set(AArch64::X29);
73  Reserved.set(AArch64::W29);
74  }
75 
76  return Reserved;
77 }
78 
79 void
81  int SPAdj,
82  unsigned FIOperandNum,
83  RegScavenger *RS) const {
84  assert(SPAdj == 0 && "Cannot deal with nonzero SPAdj yet");
85  MachineInstr &MI = *MBBI;
86  MachineBasicBlock &MBB = *MI.getParent();
87  MachineFunction &MF = *MBB.getParent();
88  MachineFrameInfo *MFI = MF.getFrameInfo();
89  const AArch64FrameLowering *TFI =
90  static_cast<const AArch64FrameLowering *>(MF.getTarget().getFrameLowering());
91 
92  // In order to work out the base and offset for addressing, the FrameLowering
93  // code needs to know (sometimes) whether the instruction is storing/loading a
94  // callee-saved register, or whether it's a more generic
95  // operation. Fortunately the frame indices are used *only* for that purpose
96  // and are contiguous, so we can check here.
97  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
98  int MinCSFI = 0;
99  int MaxCSFI = -1;
100 
101  if (CSI.size()) {
102  MinCSFI = CSI[0].getFrameIdx();
103  MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
104  }
105 
106  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
107  bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI;
108 
109  unsigned FrameReg;
110  int64_t Offset;
111  Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj,
112  IsCalleeSaveOp);
113 
114  Offset += MI.getOperand(FIOperandNum + 1).getImm();
115 
116  // DBG_VALUE instructions have no real restrictions so they can be handled
117  // easily.
118  if (MI.isDebugValue()) {
119  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/ false);
120  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
121  return;
122  }
123 
124  const AArch64InstrInfo &TII =
125  *static_cast<const AArch64InstrInfo*>(MF.getTarget().getInstrInfo());
126  int MinOffset, MaxOffset, OffsetScale;
127  if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) {
128  MinOffset = 0;
129  MaxOffset = 0xfff;
130  OffsetScale = 1;
131  } else {
132  // Load/store of a stack object
133  TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset);
134  }
135 
136  // The frame lowering has told us a base and offset it thinks we should use to
137  // access this variable, but it's still up to us to make sure the values are
138  // legal for the instruction in question.
139  if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) {
140  unsigned BaseReg =
141  MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
142  emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII,
143  BaseReg, FrameReg, BaseReg, Offset);
144  FrameReg = BaseReg;
145  Offset = 0;
146  }
147 
148  // Negative offsets are expected if we address from FP, but for
149  // now this checks nothing has gone horribly wrong.
150  assert(Offset >= 0 && "Unexpected negative offset from SP");
151 
152  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, true);
153  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale);
154 }
155 
156 unsigned
158  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
159 
160  if (TFI->hasFP(MF))
161  return AArch64::X29;
162  else
163  return AArch64::XSP;
164 }
165 
166 bool
168  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
169  const AArch64FrameLowering *AFI
170  = static_cast<const AArch64FrameLowering*>(TFI);
171  return AFI->useFPForAddressing(MF);
172 }
const MachineFunction * getParent() const
BitVector & set()
Definition: BitVector.h:236
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
unsigned MaxOffset
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const
const uint32_t * getCallPreservedMask(CallingConv::ID) const
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
unsigned getFrameRegister(const MachineFunction &MF) const
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
BitVector getReservedRegs(const MachineFunction &MF) const
const uint32_t * getTLSDescCallPreservedMask() const
int getOpcode() const
Definition: MachineInstr.h:261
int64_t getImm() const
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *Rs=NULL) const
void ChangeToImmediate(int64_t ImmVal)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bool isDebugValue() const
Definition: MachineInstr.h:639
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
int64_t resolveFrameIndexReference(MachineFunction &MF, int FrameIndex, unsigned &FrameReg, int SPAdj, bool IsCalleeSaveOp) const
virtual const TargetFrameLowering * getFrameLowering() const
virtual bool useFPForAddressing(const MachineFunction &MF) const
virtual const TargetInstrInfo * getInstrInfo() const
MachineFrameInfo * getFrameInfo()
MachineRegisterInfo & getRegInfo()
void getAddressConstraints(const MachineInstr &MI, int &AccessScale, int &MinOffset, int &MaxOffset) const
const TargetMachine & getTarget() const
bool useFPForScavengingIndex(const MachineFunction &MF) const
void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned DstReg, unsigned SrcReg, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const