X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZRegisterInfo.cpp;h=6fd24e3df625e7e9373b0e3b24f5c718fe3db793;hb=08e1ec066dc01294e34e7adbe877a7e06d4f00a7;hp=74633769bf2fcb288b02b4ce9a7aaee78fac2ca1;hpb=3c98c616c51a65c9af2ffcd7498be795049fcfad;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 74633769bf2..6fd24e3df62 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===- SystemZRegisterInfo.cpp - SystemZ Register Information -------*- C++ -*-===// +//===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===// // // The LLVM Compiler Infrastructure // @@ -6,240 +6,135 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file contains the SystemZ implementation of the TargetRegisterInfo class. -// -//===----------------------------------------------------------------------===// -#include "SystemZ.h" +#include "SystemZInstrInfo.h" #include "SystemZRegisterInfo.h" #include "SystemZSubtarget.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/BitVector.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetFrameLowering.h" + using namespace llvm; -SystemZRegisterInfo::SystemZRegisterInfo(SystemZTargetMachine &tm, - const TargetInstrInfo &tii) - : SystemZGenRegisterInfo(SystemZ::NOP, SystemZ::NOP), - TM(tm), TII(tii) { -} +#define GET_REGINFO_TARGET_DESC +#include "SystemZGenRegisterInfo.inc" + +SystemZRegisterInfo::SystemZRegisterInfo() + : SystemZGenRegisterInfo(SystemZ::R14D) {} -const unsigned* +const MCPhysReg * SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { - static const unsigned CalleeSavedRegs[] = { - SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D, - SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D, - SystemZ::F1, SystemZ::F3, SystemZ::F5, SystemZ::F7, - 0 - }; - - return CalleeSavedRegs; + return CSR_SystemZ_SaveList; } -const TargetRegisterClass* const* -SystemZRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { - static const TargetRegisterClass * const CalleeSavedRegClasses[] = { - &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, - &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, - &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, - &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, - &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, - &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0 - }; - return CalleeSavedRegClasses; +const uint32_t * +SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID CC) const { + return CSR_SystemZ_RegMask; } -BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const { +BitVector +SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); - if (hasFP(MF)) - Reserved.set(SystemZ::R11D); - Reserved.set(SystemZ::R14D); - Reserved.set(SystemZ::R15D); - return Reserved; -} - -// needsFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. -// -bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); -} + const SystemZFrameLowering *TFI = getFrameLowering(MF); -void SystemZRegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - assert(0 && "Not implemented yet!"); -} - -int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const { - const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment(); - uint64_t StackSize = MFI->getStackSize(); - - Offset += StackSize - TFI.getOffsetOfLocalArea(); - - // Skip the register save area if we generated the stack frame. - if (StackSize) - Offset -= TFI.getOffsetOfLocalArea(); - - return Offset; -} - -void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { - assert(SPAdj == 0 && "Unxpected"); - - unsigned i = 0; - MachineInstr &MI = *II; - MachineFunction &MF = *MI.getParent()->getParent(); - while (!MI.getOperand(i).isFI()) { - ++i; - assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); - } - - int FrameIndex = MI.getOperand(i).getIndex(); - - unsigned BasePtr = (hasFP(MF) ? SystemZ::R11D : SystemZ::R15D); - - // This must be part of a rri or ri operand memory reference. Replace the - // FrameIndex with base register with BasePtr. Add an offset to the - // displacement field. - MI.getOperand(i).ChangeToRegister(BasePtr, false); - - // Offset is a 20-bit integer. - // FIXME: handle "too long" displacements. - int Offset = getFrameIndexOffset(MF, FrameIndex) + MI.getOperand(i+1).getImm(); - MI.getOperand(i+1).ChangeToImmediate(Offset); -} - -/// emitSPUpdate - Emit a series of instructions to increment / decrement the -/// stack pointer by a constant value. -static -void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - int64_t NumBytes, const TargetInstrInfo &TII) { - // FIXME: Handle different stack sizes here. - bool isSub = NumBytes < 0; - uint64_t Offset = isSub ? -NumBytes : NumBytes; - unsigned Opc = SystemZ::ADD64ri16; - uint64_t Chunk = (1LL << 15) - 1; - DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : - DebugLoc::getUnknownLoc()); - - while (Offset) { - uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; - MachineInstr *MI = - BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D) - .addReg(SystemZ::R15D).addImm((isSub ? -(int64_t)ThisVal : ThisVal)); - // The PSW implicit def is dead. - MI->getOperand(3).setIsDead(); - Offset -= ThisVal; + if (TFI->hasFP(MF)) { + // R11D is the frame pointer. Reserve all aliases. + Reserved.set(SystemZ::R11D); + Reserved.set(SystemZ::R11L); + Reserved.set(SystemZ::R11H); + Reserved.set(SystemZ::R10Q); } -} - -void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock::iterator MBBI = MBB.begin(); - DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : - DebugLoc::getUnknownLoc()); - - // Get the number of bytes to allocate from the FrameInfo. - uint64_t StackSize = MFI->getStackSize(); - - // FIXME: Skip the callee-saved push instructions. - - if (MBBI != MBB.end()) - DL = MBBI->getDebugLoc(); - uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); - - if (StackSize) // adjust stack pointer: R15 -= numbytes - emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII); - - if (hasFP(MF)) { - // Update R11 with the new base value... - BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D) - .addReg(SystemZ::R15D); - - // Mark the FramePtr as live-in in every block except the entry. - for (MachineFunction::iterator I = next(MF.begin()), E = MF.end(); - I != E; ++I) - I->addLiveIn(SystemZ::R11D); - - } + // R15D is the stack pointer. Reserve all aliases. + Reserved.set(SystemZ::R15D); + Reserved.set(SystemZ::R15L); + Reserved.set(SystemZ::R15H); + Reserved.set(SystemZ::R14Q); + return Reserved; } -void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - unsigned RetOpcode = MBBI->getOpcode(); - DebugLoc DL = MBBI->getDebugLoc(); - - switch (RetOpcode) { - case SystemZ::RET: break; // These are ok - default: - assert(0 && "Can only insert epilog into returning blocks"); +void +SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS) const { + assert(SPAdj == 0 && "Outgoing arguments should be part of the frame"); + + MachineBasicBlock &MBB = *MI->getParent(); + MachineFunction &MF = *MBB.getParent(); + auto *TII = + static_cast(MF.getSubtarget().getInstrInfo()); + const SystemZFrameLowering *TFI = getFrameLowering(MF); + DebugLoc DL = MI->getDebugLoc(); + + // Decompose the frame index into a base and offset. + int FrameIndex = MI->getOperand(FIOperandNum).getIndex(); + unsigned BasePtr; + int64_t Offset = (TFI->getFrameIndexReference(MF, FrameIndex, BasePtr) + + MI->getOperand(FIOperandNum + 1).getImm()); + + // Special handling of dbg_value instructions. + if (MI->isDebugValue()) { + MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false); + MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); + return; } - // Get the number of bytes to allocate from the FrameInfo - uint64_t StackSize = MFI->getStackSize(); - uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); - - // Skip the callee-saved regs load instructions. - MachineBasicBlock::iterator LastCSPop = MBBI; - while (MBBI != MBB.begin()) { - MachineBasicBlock::iterator PI = prior(MBBI); - if (!PI->getDesc().isTerminator()) - break; - --MBBI; + // See if the offset is in range, or if an equivalent instruction that + // accepts the offset exists. + unsigned Opcode = MI->getOpcode(); + unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset); + if (OpcodeForOffset) + MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); + else { + // Create an anchor point that is in range. Start at 0xffff so that + // can use LLILH to load the immediate. + int64_t OldOffset = Offset; + int64_t Mask = 0xffff; + do { + Offset = OldOffset & Mask; + OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset); + Mask >>= 1; + assert(Mask && "One offset must be OK"); + } while (!OpcodeForOffset); + + unsigned ScratchReg = + MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass); + int64_t HighOffset = OldOffset - Offset; + + if (MI->getDesc().TSFlags & SystemZII::HasIndex + && MI->getOperand(FIOperandNum + 2).getReg() == 0) { + // Load the offset into the scratch register and use it as an index. + // The scratch register then dies here. + TII->loadImmediate(MBB, MI, ScratchReg, HighOffset); + MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false); + MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg, + false, false, true); + } else { + // Load the anchor address into a scratch register. + unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset); + if (LAOpcode) + BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg) + .addReg(BasePtr).addImm(HighOffset).addReg(0); + else { + // Load the high offset into the scratch register and use it as + // an index. + TII->loadImmediate(MBB, MI, ScratchReg, HighOffset); + BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg) + .addReg(ScratchReg, RegState::Kill).addReg(BasePtr); + } + + // Use the scratch register as the base. It then dies here. + MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg, + false, false, true); + } } - - DL = MBBI->getDebugLoc(); - - if (MFI->hasVarSizedObjects()) { - assert(0 && "Not implemented yet!"); - } else { - // adjust stack pointer back: R15 += numbytes - if (StackSize) - emitSPUpdate(MBB, MBBI, NumBytes, TII); - } -} - -unsigned SystemZRegisterInfo::getRARegister() const { - assert(0 && "What is the return address register"); - return 0; -} - -unsigned SystemZRegisterInfo::getFrameRegister(MachineFunction &MF) const { - assert(0 && "What is the frame register"); - return 0; + MI->setDesc(TII->get(OpcodeForOffset)); + MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); } -unsigned SystemZRegisterInfo::getEHExceptionRegister() const { - assert(0 && "What is the exception register"); - return 0; +unsigned +SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const { + const SystemZFrameLowering *TFI = getFrameLowering(MF); + return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D; } - -unsigned SystemZRegisterInfo::getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); - return 0; -} - -int SystemZRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - assert(0 && "What is the dwarf register number"); - return -1; -} - -#include "SystemZGenRegisterInfo.inc"