SystemZRegisterInfo.cpp revision 251607
1//===-- SystemZRegisterInfo.cpp - SystemZ 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#include "SystemZRegisterInfo.h" 11#include "SystemZTargetMachine.h" 12#include "llvm/CodeGen/MachineInstrBuilder.h" 13#include "llvm/CodeGen/MachineRegisterInfo.h" 14 15#define GET_REGINFO_TARGET_DESC 16#include "SystemZGenRegisterInfo.inc" 17 18using namespace llvm; 19 20SystemZRegisterInfo::SystemZRegisterInfo(SystemZTargetMachine &tm, 21 const SystemZInstrInfo &tii) 22 : SystemZGenRegisterInfo(SystemZ::R14D), TM(tm), TII(tii) {} 23 24const uint16_t* 25SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 26 static const uint16_t CalleeSavedRegs[] = { 27 SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D, 28 SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D, 29 SystemZ::R14D, SystemZ::R15D, 30 SystemZ::F8D, SystemZ::F9D, SystemZ::F10D, SystemZ::F11D, 31 SystemZ::F12D, SystemZ::F13D, SystemZ::F14D, SystemZ::F15D, 32 0 33 }; 34 35 return CalleeSavedRegs; 36} 37 38BitVector 39SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 40 BitVector Reserved(getNumRegs()); 41 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 42 43 if (TFI->hasFP(MF)) { 44 // R11D is the frame pointer. Reserve all aliases. 45 Reserved.set(SystemZ::R11D); 46 Reserved.set(SystemZ::R11W); 47 Reserved.set(SystemZ::R10Q); 48 } 49 50 // R15D is the stack pointer. Reserve all aliases. 51 Reserved.set(SystemZ::R15D); 52 Reserved.set(SystemZ::R15W); 53 Reserved.set(SystemZ::R14Q); 54 return Reserved; 55} 56 57bool 58SystemZRegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, 59 MachineBasicBlock::iterator SaveMBBI, 60 MachineBasicBlock::iterator &UseMBBI, 61 const TargetRegisterClass *RC, 62 unsigned Reg) const { 63 MachineFunction &MF = *MBB.getParent(); 64 const SystemZFrameLowering *TFI = 65 static_cast<const SystemZFrameLowering *>(TM.getFrameLowering()); 66 unsigned Base = getFrameRegister(MF); 67 uint64_t Offset = TFI->getEmergencySpillSlotOffset(MF); 68 DebugLoc DL; 69 70 unsigned LoadOpcode, StoreOpcode; 71 TII.getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 72 73 // The offset must always be in range of a 12-bit unsigned displacement. 74 BuildMI(MBB, SaveMBBI, DL, TII.get(StoreOpcode)) 75 .addReg(Reg, RegState::Kill).addReg(Base).addImm(Offset).addReg(0); 76 BuildMI(MBB, UseMBBI, DL, TII.get(LoadOpcode), Reg) 77 .addReg(Base).addImm(Offset).addReg(0); 78 return true; 79} 80 81void 82SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, 83 int SPAdj, unsigned FIOperandNum, 84 RegScavenger *RS) const { 85 assert(SPAdj == 0 && "Outgoing arguments should be part of the frame"); 86 87 MachineBasicBlock &MBB = *MI->getParent(); 88 MachineFunction &MF = *MBB.getParent(); 89 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 90 DebugLoc DL = MI->getDebugLoc(); 91 92 // Decompose the frame index into a base and offset. 93 int FrameIndex = MI->getOperand(FIOperandNum).getIndex(); 94 unsigned BasePtr = getFrameRegister(MF); 95 int64_t Offset = (TFI->getFrameIndexOffset(MF, FrameIndex) + 96 MI->getOperand(FIOperandNum + 1).getImm()); 97 98 // Special handling of dbg_value instructions. 99 if (MI->isDebugValue()) { 100 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false); 101 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 102 return; 103 } 104 105 // See if the offset is in range, or if an equivalent instruction that 106 // accepts the offset exists. 107 unsigned Opcode = MI->getOpcode(); 108 unsigned OpcodeForOffset = TII.getOpcodeForOffset(Opcode, Offset); 109 if (OpcodeForOffset) 110 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 111 else { 112 // Create an anchor point that is in range. Start at 0xffff so that 113 // can use LLILH to load the immediate. 114 int64_t OldOffset = Offset; 115 int64_t Mask = 0xffff; 116 do { 117 Offset = OldOffset & Mask; 118 OpcodeForOffset = TII.getOpcodeForOffset(Opcode, Offset); 119 Mask >>= 1; 120 assert(Mask && "One offset must be OK"); 121 } while (!OpcodeForOffset); 122 123 unsigned ScratchReg = 124 MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass); 125 int64_t HighOffset = OldOffset - Offset; 126 127 if (MI->getDesc().TSFlags & SystemZII::HasIndex 128 && MI->getOperand(FIOperandNum + 2).getReg() == 0) { 129 // Load the offset into the scratch register and use it as an index. 130 // The scratch register then dies here. 131 TII.loadImmediate(MBB, MI, ScratchReg, HighOffset); 132 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 133 MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg, 134 false, false, true); 135 } else { 136 // Load the anchor address into a scratch register. 137 unsigned LAOpcode = TII.getOpcodeForOffset(SystemZ::LA, HighOffset); 138 if (LAOpcode) 139 BuildMI(MBB, MI, DL, TII.get(LAOpcode),ScratchReg) 140 .addReg(BasePtr).addImm(HighOffset).addReg(0); 141 else { 142 // Load the high offset into the scratch register and use it as 143 // an index. 144 TII.loadImmediate(MBB, MI, ScratchReg, HighOffset); 145 BuildMI(MBB, MI, DL, TII.get(SystemZ::AGR),ScratchReg) 146 .addReg(ScratchReg, RegState::Kill).addReg(BasePtr); 147 } 148 149 // Use the scratch register as the base. It then dies here. 150 MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg, 151 false, false, true); 152 } 153 } 154 MI->setDesc(TII.get(OpcodeForOffset)); 155 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 156} 157 158unsigned 159SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 160 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 161 return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D; 162} 163