1 //===- AArch64RegisterInfo.cpp - AArch64 Register Information -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the AArch64 implementation of the TargetRegisterInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "AArch64RegisterInfo.h"
16 #include "AArch64FrameLowering.h"
17 #include "AArch64MachineFunctionInfo.h"
18 #include "AArch64TargetMachine.h"
19 #include "MCTargetDesc/AArch64MCTargetDesc.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/RegisterScavenging.h"
24 #include "llvm/ADT/BitVector.h"
26 #define GET_REGINFO_TARGET_DESC
27 #include "AArch64GenRegisterInfo.inc"
31 AArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo &tii,
32 const AArch64Subtarget &sti)
33 : AArch64GenRegisterInfo(AArch64::X30), TII(tii) {
37 AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
38 return CSR_PCS_SaveList;
42 AArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const {
43 return CSR_PCS_RegMask;
46 const uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const {
47 return TLSDesc_RegMask;
50 const TargetRegisterClass *
51 AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
52 if (RC == &AArch64::FlagClassRegClass)
53 return &AArch64::GPR64RegClass;
61 AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
62 BitVector Reserved(getNumRegs());
63 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
65 Reserved.set(AArch64::XSP);
66 Reserved.set(AArch64::WSP);
68 Reserved.set(AArch64::XZR);
69 Reserved.set(AArch64::WZR);
72 Reserved.set(AArch64::X29);
73 Reserved.set(AArch64::W29);
80 AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI,
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());
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();
102 MinCSFI = CSI[0].getFrameIdx();
103 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
106 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
107 bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI;
111 Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj,
114 Offset += MI.getOperand(FIOperandNum + 1).getImm();
116 // DBG_VALUE instructions have no real restrictions so they can be handled
118 if (MI.isDebugValue()) {
119 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/ false);
120 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
124 int MinOffset, MaxOffset, OffsetScale;
125 if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) {
130 // Load/store of a stack object
131 TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset);
134 // The frame lowering has told us a base and offset it thinks we should use to
135 // access this variable, but it's still up to us to make sure the values are
136 // legal for the instruction in question.
137 if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) {
139 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
140 emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII,
141 BaseReg, FrameReg, BaseReg, Offset);
146 // Negative offsets are expected if we address from FP, but for
147 // now this checks nothing has gone horribly wrong.
148 assert(Offset >= 0 && "Unexpected negative offset from SP");
150 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, true);
151 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale);
155 AArch64RegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
156 MachineBasicBlock &MBB,
157 MachineBasicBlock::iterator MI) const {
158 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
159 DebugLoc dl = MI->getDebugLoc();
160 int Opcode = MI->getOpcode();
161 bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
162 uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0;
164 if (!TFI->hasReservedCallFrame(MF)) {
165 unsigned Align = TFI->getStackAlignment();
167 uint64_t Amount = MI->getOperand(0).getImm();
168 Amount = (Amount + Align - 1)/Align * Align;
169 if (!IsDestroy) Amount = -Amount;
171 // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
172 // doesn't have to pop anything), then the first operand will be zero too so
173 // this adjustment is a no-op.
174 if (CalleePopAmount == 0) {
175 // FIXME: in-function stack adjustment for calls is limited to 12-bits
176 // because there's no guaranteed temporary register available. Mostly call
177 // frames will be allocated at the start of a function so this is OK, but
178 // it is a limitation that needs dealing with.
179 assert(abs(Amount) < 0xfff && "call frame too large");
180 emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount);
182 } else if (CalleePopAmount != 0) {
183 // If the calling convention demands that the callee pops arguments from the
184 // stack, we want to add it back if we have a reserved call frame.
185 assert(CalleePopAmount < 0xfff && "call frame too large");
186 emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount);
193 AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
194 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
203 AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
204 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
205 const AArch64FrameLowering *AFI = static_cast<const AArch64FrameLowering*>(TFI);
206 return AFI->useFPForAddressing(MF);