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" 18 #include "AArch64MachineFunctionInfo.h" 19 #include "AArch64TargetMachine.h" 20 #include "MCTargetDesc/AArch64MCTargetDesc.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/RegisterScavenging.h" 25 #include "llvm/ADT/BitVector.h" 26 27 #define GET_REGINFO_TARGET_DESC 28 #include "AArch64GenRegisterInfo.inc" 29 30 using namespace llvm; 31 32 AArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo &tii, 33 const AArch64Subtarget &sti) 34 : AArch64GenRegisterInfo(AArch64::X30), TII(tii) { 35 } 36 37 const uint16_t * 38 AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 39 return CSR_PCS_SaveList; 40 } 41 42 const uint32_t* 43 AArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const { 44 return CSR_PCS_RegMask; 45 } 46 47 const uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const { 48 return TLSDesc_RegMask; 49 } 50 51 const TargetRegisterClass * 52 AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 53 if (RC == &AArch64::FlagClassRegClass) 54 return &AArch64::GPR64RegClass; 55 56 return RC; 57 } 58 59 60 61 BitVector 62 AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 63 BitVector Reserved(getNumRegs()); 64 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 65 66 Reserved.set(AArch64::XSP); 67 Reserved.set(AArch64::WSP); 68 69 Reserved.set(AArch64::XZR); 70 Reserved.set(AArch64::WZR); 71 72 if (TFI->hasFP(MF)) { 73 Reserved.set(AArch64::X29); 74 Reserved.set(AArch64::W29); 75 } 76 77 return Reserved; 78 } 79 80 void 81 AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI, 82 int SPAdj, 83 unsigned FIOperandNum, 84 RegScavenger *RS) const { 85 assert(SPAdj == 0 && "Cannot deal with nonzero SPAdj yet"); 86 MachineInstr &MI = *MBBI; 87 MachineBasicBlock &MBB = *MI.getParent(); 88 MachineFunction &MF = *MBB.getParent(); 89 MachineFrameInfo *MFI = MF.getFrameInfo(); 90 const AArch64FrameLowering *TFI = 91 static_cast<const AArch64FrameLowering *>(MF.getTarget().getFrameLowering()); 92 93 // In order to work out the base and offset for addressing, the FrameLowering 94 // code needs to know (sometimes) whether the instruction is storing/loading a 95 // callee-saved register, or whether it's a more generic 96 // operation. Fortunately the frame indices are used *only* for that purpose 97 // and are contiguous, so we can check here. 98 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 99 int MinCSFI = 0; 100 int MaxCSFI = -1; 101 102 if (CSI.size()) { 103 MinCSFI = CSI[0].getFrameIdx(); 104 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 105 } 106 107 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 108 bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI; 109 110 unsigned FrameReg; 111 int64_t Offset; 112 Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj, 113 IsCalleeSaveOp); 114 115 Offset += MI.getOperand(FIOperandNum + 1).getImm(); 116 117 // DBG_VALUE instructions have no real restrictions so they can be handled 118 // easily. 119 if (MI.isDebugValue()) { 120 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/ false); 121 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 122 return; 123 } 124 125 int MinOffset, MaxOffset, OffsetScale; 126 if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) { 127 MinOffset = 0; 128 MaxOffset = 0xfff; 129 OffsetScale = 1; 130 } else { 131 // Load/store of a stack object 132 TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset); 133 } 134 135 // The frame lowering has told us a base and offset it thinks we should use to 136 // access this variable, but it's still up to us to make sure the values are 137 // legal for the instruction in question. 138 if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) { 139 unsigned BaseReg = 140 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass); 141 emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII, 142 BaseReg, FrameReg, BaseReg, Offset); 143 FrameReg = BaseReg; 144 Offset = 0; 145 } 146 147 // Negative offsets are expected if we address from FP, but for 148 // now this checks nothing has gone horribly wrong. 149 assert(Offset >= 0 && "Unexpected negative offset from SP"); 150 151 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, true); 152 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale); 153 } 154 155 unsigned 156 AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 157 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 158 159 if (TFI->hasFP(MF)) 160 return AArch64::X29; 161 else 162 return AArch64::XSP; 163 } 164 165 bool 166 AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 167 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 168 const AArch64FrameLowering *AFI 169 = static_cast<const AArch64FrameLowering*>(TFI); 170 return AFI->useFPForAddressing(MF); 171 } 172