1//====- BlackfinFrameLowering.cpp - Blackfin Frame Information --*- C++ -*-===// 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// This file contains the Blackfin implementation of TargetFrameLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "BlackfinFrameLowering.h" 15#include "BlackfinInstrInfo.h" 16#include "llvm/CodeGen/MachineFrameInfo.h" 17#include "llvm/CodeGen/MachineFunction.h" 18#include "llvm/CodeGen/MachineInstrBuilder.h" 19#include "llvm/CodeGen/RegisterScavenging.h" 20#include "llvm/Target/TargetOptions.h" 21 22using namespace llvm; 23 24 25// hasFP - Return true if the specified function should have a dedicated frame 26// pointer register. This is true if the function has variable sized allocas or 27// if frame pointer elimination is disabled. 28bool BlackfinFrameLowering::hasFP(const MachineFunction &MF) const { 29 const MachineFrameInfo *MFI = MF.getFrameInfo(); 30 return DisableFramePointerElim(MF) || 31 MFI->adjustsStack() || MFI->hasVarSizedObjects(); 32} 33 34// Always reserve a call frame. We dont have enough registers to adjust SP. 35bool BlackfinFrameLowering:: 36hasReservedCallFrame(const MachineFunction &MF) const { 37 return true; 38} 39 40// Emit a prologue that sets up a stack frame. 41// On function entry, R0-R2 and P0 may hold arguments. 42// R3, P1, and P2 may be used as scratch registers 43void BlackfinFrameLowering::emitPrologue(MachineFunction &MF) const { 44 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 45 MachineBasicBlock::iterator MBBI = MBB.begin(); 46 MachineFrameInfo *MFI = MF.getFrameInfo(); 47 const BlackfinRegisterInfo *RegInfo = 48 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo()); 49 const BlackfinInstrInfo &TII = 50 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo()); 51 52 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 53 54 int FrameSize = MFI->getStackSize(); 55 if (FrameSize%4) { 56 FrameSize = (FrameSize+3) & ~3; 57 MFI->setStackSize(FrameSize); 58 } 59 60 if (!hasFP(MF)) { 61 assert(!MFI->adjustsStack() && 62 "FP elimination on a non-leaf function is not supported"); 63 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, -FrameSize); 64 return; 65 } 66 67 // emit a LINK instruction 68 if (FrameSize <= 0x3ffff) { 69 BuildMI(MBB, MBBI, dl, TII.get(BF::LINK)).addImm(FrameSize); 70 return; 71 } 72 73 // Frame is too big, do a manual LINK: 74 // [--SP] = RETS; 75 // [--SP] = FP; 76 // FP = SP; 77 // P1 = -FrameSize; 78 // SP = SP + P1; 79 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH)) 80 .addReg(BF::RETS, RegState::Kill); 81 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH)) 82 .addReg(BF::FP, RegState::Kill); 83 BuildMI(MBB, MBBI, dl, TII.get(BF::MOVE), BF::FP) 84 .addReg(BF::SP); 85 RegInfo->loadConstant(MBB, MBBI, dl, BF::P1, -FrameSize); 86 BuildMI(MBB, MBBI, dl, TII.get(BF::ADDpp), BF::SP) 87 .addReg(BF::SP, RegState::Kill) 88 .addReg(BF::P1, RegState::Kill); 89 90} 91 92void BlackfinFrameLowering::emitEpilogue(MachineFunction &MF, 93 MachineBasicBlock &MBB) const { 94 MachineFrameInfo *MFI = MF.getFrameInfo(); 95 const BlackfinRegisterInfo *RegInfo = 96 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo()); 97 const BlackfinInstrInfo &TII = 98 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo()); 99 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 100 DebugLoc dl = MBBI->getDebugLoc(); 101 102 int FrameSize = MFI->getStackSize(); 103 assert(FrameSize%4 == 0 && "Misaligned frame size"); 104 105 if (!hasFP(MF)) { 106 assert(!MFI->adjustsStack() && 107 "FP elimination on a non-leaf function is not supported"); 108 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, FrameSize); 109 return; 110 } 111 112 // emit an UNLINK instruction 113 BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK)); 114} 115 116void BlackfinFrameLowering:: 117processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 118 RegScavenger *RS) const { 119 MachineFrameInfo *MFI = MF.getFrameInfo(); 120 const BlackfinRegisterInfo *RegInfo = 121 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo()); 122 const TargetRegisterClass *RC = BF::DPRegisterClass; 123 124 if (RegInfo->requiresRegisterScavenging(MF)) { 125 // Reserve a slot close to SP or frame pointer. 126 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 127 RC->getAlignment(), 128 false)); 129 } 130} 131