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