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