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 30using namespace llvm; 31 32AArch64RegisterInfo::AArch64RegisterInfo() 33 : AArch64GenRegisterInfo(AArch64::X30) { 34} 35 36const uint16_t * 37AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 38 return CSR_PCS_SaveList; 39} 40 41const uint32_t* 42AArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const { 43 return CSR_PCS_RegMask; 44} 45 46const uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const { 47 return TLSDesc_RegMask; 48} 49 50const TargetRegisterClass * 51AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 52 if (RC == &AArch64::FlagClassRegClass) 53 return &AArch64::GPR64RegClass; 54 55 return RC; 56} 57 58 59 60BitVector 61AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 62 BitVector Reserved(getNumRegs()); 63 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 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 79void 80AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI, 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 156unsigned 157AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 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 166bool 167AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 168 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 169 const AArch64FrameLowering *AFI 170 = static_cast<const AArch64FrameLowering*>(TFI); 171 return AFI->useFPForAddressing(MF); 172} 173