LLVM API Documentation
00001 //===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "SystemZInstrInfo.h" 00011 #include "SystemZRegisterInfo.h" 00012 #include "SystemZSubtarget.h" 00013 #include "llvm/CodeGen/MachineInstrBuilder.h" 00014 #include "llvm/CodeGen/MachineRegisterInfo.h" 00015 #include "llvm/Target/TargetFrameLowering.h" 00016 00017 using namespace llvm; 00018 00019 #define GET_REGINFO_TARGET_DESC 00020 #include "SystemZGenRegisterInfo.inc" 00021 00022 SystemZRegisterInfo::SystemZRegisterInfo() 00023 : SystemZGenRegisterInfo(SystemZ::R14D) {} 00024 00025 const MCPhysReg * 00026 SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 00027 return CSR_SystemZ_SaveList; 00028 } 00029 00030 const uint32_t * 00031 SystemZRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const { 00032 return CSR_SystemZ_RegMask; 00033 } 00034 00035 BitVector 00036 SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 00037 BitVector Reserved(getNumRegs()); 00038 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 00039 00040 if (TFI->hasFP(MF)) { 00041 // R11D is the frame pointer. Reserve all aliases. 00042 Reserved.set(SystemZ::R11D); 00043 Reserved.set(SystemZ::R11L); 00044 Reserved.set(SystemZ::R11H); 00045 Reserved.set(SystemZ::R10Q); 00046 } 00047 00048 // R15D is the stack pointer. Reserve all aliases. 00049 Reserved.set(SystemZ::R15D); 00050 Reserved.set(SystemZ::R15L); 00051 Reserved.set(SystemZ::R15H); 00052 Reserved.set(SystemZ::R14Q); 00053 return Reserved; 00054 } 00055 00056 void 00057 SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, 00058 int SPAdj, unsigned FIOperandNum, 00059 RegScavenger *RS) const { 00060 assert(SPAdj == 0 && "Outgoing arguments should be part of the frame"); 00061 00062 MachineBasicBlock &MBB = *MI->getParent(); 00063 MachineFunction &MF = *MBB.getParent(); 00064 auto *TII = 00065 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00066 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 00067 DebugLoc DL = MI->getDebugLoc(); 00068 00069 // Decompose the frame index into a base and offset. 00070 int FrameIndex = MI->getOperand(FIOperandNum).getIndex(); 00071 unsigned BasePtr = getFrameRegister(MF); 00072 int64_t Offset = (TFI->getFrameIndexOffset(MF, FrameIndex) + 00073 MI->getOperand(FIOperandNum + 1).getImm()); 00074 00075 // Special handling of dbg_value instructions. 00076 if (MI->isDebugValue()) { 00077 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false); 00078 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 00079 return; 00080 } 00081 00082 // See if the offset is in range, or if an equivalent instruction that 00083 // accepts the offset exists. 00084 unsigned Opcode = MI->getOpcode(); 00085 unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset); 00086 if (OpcodeForOffset) 00087 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 00088 else { 00089 // Create an anchor point that is in range. Start at 0xffff so that 00090 // can use LLILH to load the immediate. 00091 int64_t OldOffset = Offset; 00092 int64_t Mask = 0xffff; 00093 do { 00094 Offset = OldOffset & Mask; 00095 OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset); 00096 Mask >>= 1; 00097 assert(Mask && "One offset must be OK"); 00098 } while (!OpcodeForOffset); 00099 00100 unsigned ScratchReg = 00101 MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass); 00102 int64_t HighOffset = OldOffset - Offset; 00103 00104 if (MI->getDesc().TSFlags & SystemZII::HasIndex 00105 && MI->getOperand(FIOperandNum + 2).getReg() == 0) { 00106 // Load the offset into the scratch register and use it as an index. 00107 // The scratch register then dies here. 00108 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset); 00109 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); 00110 MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg, 00111 false, false, true); 00112 } else { 00113 // Load the anchor address into a scratch register. 00114 unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset); 00115 if (LAOpcode) 00116 BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg) 00117 .addReg(BasePtr).addImm(HighOffset).addReg(0); 00118 else { 00119 // Load the high offset into the scratch register and use it as 00120 // an index. 00121 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset); 00122 BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg) 00123 .addReg(ScratchReg, RegState::Kill).addReg(BasePtr); 00124 } 00125 00126 // Use the scratch register as the base. It then dies here. 00127 MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg, 00128 false, false, true); 00129 } 00130 } 00131 MI->setDesc(TII->get(OpcodeForOffset)); 00132 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 00133 } 00134 00135 unsigned 00136 SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 00137 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 00138 return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D; 00139 }