blob: 4f9054bf62204f1f384c7ed622c71c9ce17e8b5f [file] [log] [blame]
Anton Korobeynikov33464912010-11-15 00:06:54 +00001//====- BlackfinFrameInfo.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 TargetFrameInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BlackfinFrameInfo.h"
15#include "BlackfinInstrInfo.h"
16#include "llvm/CodeGen/MachineFrameInfo.h"
17#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000019#include "llvm/Target/TargetOptions.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000020
21using namespace llvm;
22
23
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000024// hasFP - Return true if the specified function should have a dedicated frame
25// pointer register. This is true if the function has variable sized allocas or
26// if frame pointer elimination is disabled.
27bool BlackfinFrameInfo::hasFP(const MachineFunction &MF) const {
28 const MachineFrameInfo *MFI = MF.getFrameInfo();
29 return DisableFramePointerElim(MF) ||
30 MFI->adjustsStack() || MFI->hasVarSizedObjects();
31}
32
Anton Korobeynikov33464912010-11-15 00:06:54 +000033// Emit a prologue that sets up a stack frame.
34// On function entry, R0-R2 and P0 may hold arguments.
35// R3, P1, and P2 may be used as scratch registers
36void BlackfinFrameInfo::emitPrologue(MachineFunction &MF) const {
37 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
38 MachineBasicBlock::iterator MBBI = MBB.begin();
39 MachineFrameInfo *MFI = MF.getFrameInfo();
40 const BlackfinRegisterInfo *RegInfo =
41 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
42 const BlackfinInstrInfo &TII =
43 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
44
45 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
46
47 int FrameSize = MFI->getStackSize();
48 if (FrameSize%4) {
49 FrameSize = (FrameSize+3) & ~3;
50 MFI->setStackSize(FrameSize);
51 }
52
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000053 if (!hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +000054 assert(!MFI->adjustsStack() &&
55 "FP elimination on a non-leaf function is not supported");
56 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, -FrameSize);
57 return;
58 }
59
60 // emit a LINK instruction
61 if (FrameSize <= 0x3ffff) {
62 BuildMI(MBB, MBBI, dl, TII.get(BF::LINK)).addImm(FrameSize);
63 return;
64 }
65
66 // Frame is too big, do a manual LINK:
67 // [--SP] = RETS;
68 // [--SP] = FP;
69 // FP = SP;
70 // P1 = -FrameSize;
71 // SP = SP + P1;
72 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
73 .addReg(BF::RETS, RegState::Kill);
74 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
75 .addReg(BF::FP, RegState::Kill);
76 BuildMI(MBB, MBBI, dl, TII.get(BF::MOVE), BF::FP)
77 .addReg(BF::SP);
78 RegInfo->loadConstant(MBB, MBBI, dl, BF::P1, -FrameSize);
79 BuildMI(MBB, MBBI, dl, TII.get(BF::ADDpp), BF::SP)
80 .addReg(BF::SP, RegState::Kill)
81 .addReg(BF::P1, RegState::Kill);
82
83}
84
85void BlackfinFrameInfo::emitEpilogue(MachineFunction &MF,
86 MachineBasicBlock &MBB) const {
87 MachineFrameInfo *MFI = MF.getFrameInfo();
88 const BlackfinRegisterInfo *RegInfo =
89 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
90 const BlackfinInstrInfo &TII =
91 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
92 MachineBasicBlock::iterator MBBI = prior(MBB.end());
93 DebugLoc dl = MBBI->getDebugLoc();
94
95 int FrameSize = MFI->getStackSize();
96 assert(FrameSize%4 == 0 && "Misaligned frame size");
97
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000098 if (!hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +000099 assert(!MFI->adjustsStack() &&
100 "FP elimination on a non-leaf function is not supported");
101 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, FrameSize);
102 return;
103 }
104
105 // emit an UNLINK instruction
106 BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK));
107}