119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//=====- AlphaFrameLowering.cpp - Alpha Frame Information ------*- C++ -*-====// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file contains the Alpha implementation of TargetFrameLowering class. 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "AlphaFrameLowering.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "AlphaInstrInfo.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "AlphaMachineFunctionInfo.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFunction.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Twine.h" 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm; 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic long getUpper16(long l) { 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman long y = l / Alpha::IMM_MULT; 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (l % Alpha::IMM_MULT > Alpha::IMM_HIGH) 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++y; 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return y; 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic long getLower16(long l) { 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman long h = getUpper16(l); 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return l - h * Alpha::IMM_MULT; 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// hasFP - Return true if the specified function should have a dedicated frame 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// pointer register. This is true if the function has variable sized allocas or 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// if frame pointer elimination is disabled. 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool AlphaFrameLowering::hasFP(const MachineFunction &MF) const { 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineFrameInfo *MFI = MF.getFrameInfo(); 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return MFI->hasVarSizedObjects(); 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid AlphaFrameLowering::emitPrologue(MachineFunction &MF) const { 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator MBBI = MBB.begin(); 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *MFI = MF.getFrameInfo(); 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc()); 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool FP = hasFP(MF); 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Handle GOP offset 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAHg), Alpha::R29) 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addGlobalAddress(MF.getFunction()).addReg(Alpha::R27).addImm(++curgpdist); 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAg), Alpha::R29) 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addGlobalAddress(MF.getFunction()).addReg(Alpha::R29).addImm(curgpdist); 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::ALTENT)) 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addGlobalAddress(MF.getFunction()); 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the number of bytes to allocate from the FrameInfo 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman long NumBytes = MFI->getStackSize(); 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FP) 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumBytes += 8; //reserve space for the old FP 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do we need to allocate space on the stack? 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumBytes == 0) return; 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Align = getStackAlignment(); 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumBytes = (NumBytes+Align-1)/Align*Align; 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Update frame info to pretend that this is part of the stack... 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setStackSize(NumBytes); 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // adjust stack pointer: r30 -= numbytes 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumBytes = -NumBytes; 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumBytes >= Alpha::IMM_LOW) { 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes) 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(Alpha::R30); 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (getUpper16(NumBytes) >= Alpha::IMM_LOW) { 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30) 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30) 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(getLower16(NumBytes)).addReg(Alpha::R30); 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("Too big a stack frame at " + Twine(NumBytes)); 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Now if we need to, save the old FP and set the new 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FP) { 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::STQ)) 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This must be the last instr in the prolog 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R15) 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(Alpha::R30).addReg(Alpha::R30); 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid AlphaFrameLowering::emitEpilogue(MachineFunction &MF, 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock &MBB) const { 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineFrameInfo *MFI = MF.getFrameInfo(); 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((MBBI->getOpcode() == Alpha::RETDAG || 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI->getOpcode() == Alpha::RETDAGp) 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && "Can only insert epilog into returning blocks"); 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = MBBI->getDebugLoc(); 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool FP = hasFP(MF); 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the number of bytes allocated from the FrameInfo... 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman long NumBytes = MFI->getStackSize(); 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //now if we need to, restore the old FP 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FP) { 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //copy the FP into the SP (discards allocas) 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15) 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(Alpha::R15); 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //restore the FP 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDQ), Alpha::R15) 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(0).addReg(Alpha::R15); 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumBytes != 0) { 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumBytes <= Alpha::IMM_HIGH) { 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes) 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(Alpha::R30); 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (getUpper16(NumBytes) <= Alpha::IMM_HIGH) { 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30) 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30) 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(getLower16(NumBytes)).addReg(Alpha::R30); 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("Too big a stack frame at " + Twine(NumBytes)); 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 144