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 22 using 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. 28 bool 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. 35 bool BlackfinFrameLowering:: 36 hasReservedCallFrame(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 43 void 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 92 void 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 116 void BlackfinFrameLowering:: 117 processFunctionBeforeCalleeSavedScan(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