172062f5744557e270a38192554c3126ea5f97434Tim Northover//===- AArch64RegisterInfo.cpp - AArch64 Register Information -------------===// 272062f5744557e270a38192554c3126ea5f97434Tim Northover// 372062f5744557e270a38192554c3126ea5f97434Tim Northover// The LLVM Compiler Infrastructure 472062f5744557e270a38192554c3126ea5f97434Tim Northover// 572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source 672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details. 772062f5744557e270a38192554c3126ea5f97434Tim Northover// 872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 972062f5744557e270a38192554c3126ea5f97434Tim Northover// 10dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover// This file contains the AArch64 implementation of the TargetRegisterInfo 11dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover// class. 1272062f5744557e270a38192554c3126ea5f97434Tim Northover// 1372062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 1472062f5744557e270a38192554c3126ea5f97434Tim Northover 1572062f5744557e270a38192554c3126ea5f97434Tim Northover 1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64RegisterInfo.h" 1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64FrameLowering.h" 1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MachineFunctionInfo.h" 1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64TargetMachine.h" 2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCTargetDesc.h" 2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFrameInfo.h" 2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineInstrBuilder.h" 2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineRegisterInfo.h" 2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/RegisterScavenging.h" 2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/BitVector.h" 2672062f5744557e270a38192554c3126ea5f97434Tim Northover 2772062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_REGINFO_TARGET_DESC 2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenRegisterInfo.inc" 2972062f5744557e270a38192554c3126ea5f97434Tim Northover 3072062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm; 3172062f5744557e270a38192554c3126ea5f97434Tim Northover 3272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo &tii, 3372062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64Subtarget &sti) 3472062f5744557e270a38192554c3126ea5f97434Tim Northover : AArch64GenRegisterInfo(AArch64::X30), TII(tii) { 3572062f5744557e270a38192554c3126ea5f97434Tim Northover} 3672062f5744557e270a38192554c3126ea5f97434Tim Northover 3772062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint16_t * 3872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 3972062f5744557e270a38192554c3126ea5f97434Tim Northover return CSR_PCS_SaveList; 4072062f5744557e270a38192554c3126ea5f97434Tim Northover} 4172062f5744557e270a38192554c3126ea5f97434Tim Northover 4272062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint32_t* 4372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const { 4472062f5744557e270a38192554c3126ea5f97434Tim Northover return CSR_PCS_RegMask; 4572062f5744557e270a38192554c3126ea5f97434Tim Northover} 4672062f5744557e270a38192554c3126ea5f97434Tim Northover 4772062f5744557e270a38192554c3126ea5f97434Tim Northoverconst uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const { 4872062f5744557e270a38192554c3126ea5f97434Tim Northover return TLSDesc_RegMask; 4972062f5744557e270a38192554c3126ea5f97434Tim Northover} 5072062f5744557e270a38192554c3126ea5f97434Tim Northover 5172062f5744557e270a38192554c3126ea5f97434Tim Northoverconst TargetRegisterClass * 5272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 5372062f5744557e270a38192554c3126ea5f97434Tim Northover if (RC == &AArch64::FlagClassRegClass) 5472062f5744557e270a38192554c3126ea5f97434Tim Northover return &AArch64::GPR64RegClass; 5572062f5744557e270a38192554c3126ea5f97434Tim Northover 5672062f5744557e270a38192554c3126ea5f97434Tim Northover return RC; 5772062f5744557e270a38192554c3126ea5f97434Tim Northover} 5872062f5744557e270a38192554c3126ea5f97434Tim Northover 5972062f5744557e270a38192554c3126ea5f97434Tim Northover 6072062f5744557e270a38192554c3126ea5f97434Tim Northover 6172062f5744557e270a38192554c3126ea5f97434Tim NorthoverBitVector 6272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const { 6372062f5744557e270a38192554c3126ea5f97434Tim Northover BitVector Reserved(getNumRegs()); 6472062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 6572062f5744557e270a38192554c3126ea5f97434Tim Northover 6672062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::XSP); 6772062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::WSP); 6872062f5744557e270a38192554c3126ea5f97434Tim Northover 6972062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::XZR); 7072062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::WZR); 7172062f5744557e270a38192554c3126ea5f97434Tim Northover 7272062f5744557e270a38192554c3126ea5f97434Tim Northover if (TFI->hasFP(MF)) { 7372062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::X29); 7472062f5744557e270a38192554c3126ea5f97434Tim Northover Reserved.set(AArch64::W29); 7572062f5744557e270a38192554c3126ea5f97434Tim Northover } 7672062f5744557e270a38192554c3126ea5f97434Tim Northover 7772062f5744557e270a38192554c3126ea5f97434Tim Northover return Reserved; 7872062f5744557e270a38192554c3126ea5f97434Tim Northover} 7972062f5744557e270a38192554c3126ea5f97434Tim Northover 8072062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 8172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI, 82a9da5c50e246966c04784756e2083dbfe606c448Tim Northover int SPAdj, 83a9da5c50e246966c04784756e2083dbfe606c448Tim Northover unsigned FIOperandNum, 84a9da5c50e246966c04784756e2083dbfe606c448Tim Northover RegScavenger *RS) const { 8572062f5744557e270a38192554c3126ea5f97434Tim Northover assert(SPAdj == 0 && "Cannot deal with nonzero SPAdj yet"); 8672062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr &MI = *MBBI; 8772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock &MBB = *MI.getParent(); 8872062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFunction &MF = *MBB.getParent(); 8972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 9072062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64FrameLowering *TFI = 91dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover static_cast<const AArch64FrameLowering *>(MF.getTarget().getFrameLowering()); 9272062f5744557e270a38192554c3126ea5f97434Tim Northover 9372062f5744557e270a38192554c3126ea5f97434Tim Northover // In order to work out the base and offset for addressing, the FrameLowering 9472062f5744557e270a38192554c3126ea5f97434Tim Northover // code needs to know (sometimes) whether the instruction is storing/loading a 9572062f5744557e270a38192554c3126ea5f97434Tim Northover // callee-saved register, or whether it's a more generic 9672062f5744557e270a38192554c3126ea5f97434Tim Northover // operation. Fortunately the frame indices are used *only* for that purpose 9772062f5744557e270a38192554c3126ea5f97434Tim Northover // and are contiguous, so we can check here. 9872062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 9972062f5744557e270a38192554c3126ea5f97434Tim Northover int MinCSFI = 0; 10072062f5744557e270a38192554c3126ea5f97434Tim Northover int MaxCSFI = -1; 10172062f5744557e270a38192554c3126ea5f97434Tim Northover 10272062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.size()) { 10372062f5744557e270a38192554c3126ea5f97434Tim Northover MinCSFI = CSI[0].getFrameIdx(); 10472062f5744557e270a38192554c3126ea5f97434Tim Northover MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 10572062f5744557e270a38192554c3126ea5f97434Tim Northover } 10672062f5744557e270a38192554c3126ea5f97434Tim Northover 107a9da5c50e246966c04784756e2083dbfe606c448Tim Northover int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 10872062f5744557e270a38192554c3126ea5f97434Tim Northover bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI; 10972062f5744557e270a38192554c3126ea5f97434Tim Northover 11072062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned FrameReg; 11172062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t Offset; 11272062f5744557e270a38192554c3126ea5f97434Tim Northover Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj, 11372062f5744557e270a38192554c3126ea5f97434Tim Northover IsCalleeSaveOp); 11472062f5744557e270a38192554c3126ea5f97434Tim Northover 115a9da5c50e246966c04784756e2083dbfe606c448Tim Northover Offset += MI.getOperand(FIOperandNum + 1).getImm(); 11672062f5744557e270a38192554c3126ea5f97434Tim Northover 11772062f5744557e270a38192554c3126ea5f97434Tim Northover // DBG_VALUE instructions have no real restrictions so they can be handled 11872062f5744557e270a38192554c3126ea5f97434Tim Northover // easily. 11972062f5744557e270a38192554c3126ea5f97434Tim Northover if (MI.isDebugValue()) { 120a9da5c50e246966c04784756e2083dbfe606c448Tim Northover MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/ false); 121a9da5c50e246966c04784756e2083dbfe606c448Tim Northover MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 12272062f5744557e270a38192554c3126ea5f97434Tim Northover return; 12372062f5744557e270a38192554c3126ea5f97434Tim Northover } 12472062f5744557e270a38192554c3126ea5f97434Tim Northover 12572062f5744557e270a38192554c3126ea5f97434Tim Northover int MinOffset, MaxOffset, OffsetScale; 12672062f5744557e270a38192554c3126ea5f97434Tim Northover if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) { 12772062f5744557e270a38192554c3126ea5f97434Tim Northover MinOffset = 0; 12872062f5744557e270a38192554c3126ea5f97434Tim Northover MaxOffset = 0xfff; 12972062f5744557e270a38192554c3126ea5f97434Tim Northover OffsetScale = 1; 13072062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 13172062f5744557e270a38192554c3126ea5f97434Tim Northover // Load/store of a stack object 13272062f5744557e270a38192554c3126ea5f97434Tim Northover TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset); 13372062f5744557e270a38192554c3126ea5f97434Tim Northover } 13472062f5744557e270a38192554c3126ea5f97434Tim Northover 13572062f5744557e270a38192554c3126ea5f97434Tim Northover // The frame lowering has told us a base and offset it thinks we should use to 13672062f5744557e270a38192554c3126ea5f97434Tim Northover // access this variable, but it's still up to us to make sure the values are 13772062f5744557e270a38192554c3126ea5f97434Tim Northover // legal for the instruction in question. 13872062f5744557e270a38192554c3126ea5f97434Tim Northover if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) { 13972062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned BaseReg = 14072062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass); 14172062f5744557e270a38192554c3126ea5f97434Tim Northover emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII, 14272062f5744557e270a38192554c3126ea5f97434Tim Northover BaseReg, FrameReg, BaseReg, Offset); 14372062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = BaseReg; 14472062f5744557e270a38192554c3126ea5f97434Tim Northover Offset = 0; 14572062f5744557e270a38192554c3126ea5f97434Tim Northover } 14672062f5744557e270a38192554c3126ea5f97434Tim Northover 14772062f5744557e270a38192554c3126ea5f97434Tim Northover // Negative offsets are expected if we address from FP, but for 14872062f5744557e270a38192554c3126ea5f97434Tim Northover // now this checks nothing has gone horribly wrong. 14972062f5744557e270a38192554c3126ea5f97434Tim Northover assert(Offset >= 0 && "Unexpected negative offset from SP"); 15072062f5744557e270a38192554c3126ea5f97434Tim Northover 151a9da5c50e246966c04784756e2083dbfe606c448Tim Northover MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, true); 152a9da5c50e246966c04784756e2083dbfe606c448Tim Northover MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale); 15372062f5744557e270a38192554c3126ea5f97434Tim Northover} 15472062f5744557e270a38192554c3126ea5f97434Tim Northover 15572062f5744557e270a38192554c3126ea5f97434Tim Northoverunsigned 15672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const { 15772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 15872062f5744557e270a38192554c3126ea5f97434Tim Northover 15972062f5744557e270a38192554c3126ea5f97434Tim Northover if (TFI->hasFP(MF)) 16072062f5744557e270a38192554c3126ea5f97434Tim Northover return AArch64::X29; 16172062f5744557e270a38192554c3126ea5f97434Tim Northover else 16272062f5744557e270a38192554c3126ea5f97434Tim Northover return AArch64::XSP; 16372062f5744557e270a38192554c3126ea5f97434Tim Northover} 16472062f5744557e270a38192554c3126ea5f97434Tim Northover 16572062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 16672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 16772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 168dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover const AArch64FrameLowering *AFI 169dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover = static_cast<const AArch64FrameLowering*>(TFI); 17072062f5744557e270a38192554c3126ea5f97434Tim Northover return AFI->useFPForAddressing(MF); 17172062f5744557e270a38192554c3126ea5f97434Tim Northover} 172