blob: 83f28b0a8d1b62c50a925a0b0a2f808607fa5762 [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"
19
20using namespace llvm;
21
22
23// Emit a prologue that sets up a stack frame.
24// On function entry, R0-R2 and P0 may hold arguments.
25// R3, P1, and P2 may be used as scratch registers
26void BlackfinFrameInfo::emitPrologue(MachineFunction &MF) const {
27 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
28 MachineBasicBlock::iterator MBBI = MBB.begin();
29 MachineFrameInfo *MFI = MF.getFrameInfo();
30 const BlackfinRegisterInfo *RegInfo =
31 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
32 const BlackfinInstrInfo &TII =
33 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
34
35 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
36
37 int FrameSize = MFI->getStackSize();
38 if (FrameSize%4) {
39 FrameSize = (FrameSize+3) & ~3;
40 MFI->setStackSize(FrameSize);
41 }
42
43 if (!RegInfo->hasFP(MF)) {
44 assert(!MFI->adjustsStack() &&
45 "FP elimination on a non-leaf function is not supported");
46 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, -FrameSize);
47 return;
48 }
49
50 // emit a LINK instruction
51 if (FrameSize <= 0x3ffff) {
52 BuildMI(MBB, MBBI, dl, TII.get(BF::LINK)).addImm(FrameSize);
53 return;
54 }
55
56 // Frame is too big, do a manual LINK:
57 // [--SP] = RETS;
58 // [--SP] = FP;
59 // FP = SP;
60 // P1 = -FrameSize;
61 // SP = SP + P1;
62 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
63 .addReg(BF::RETS, RegState::Kill);
64 BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
65 .addReg(BF::FP, RegState::Kill);
66 BuildMI(MBB, MBBI, dl, TII.get(BF::MOVE), BF::FP)
67 .addReg(BF::SP);
68 RegInfo->loadConstant(MBB, MBBI, dl, BF::P1, -FrameSize);
69 BuildMI(MBB, MBBI, dl, TII.get(BF::ADDpp), BF::SP)
70 .addReg(BF::SP, RegState::Kill)
71 .addReg(BF::P1, RegState::Kill);
72
73}
74
75void BlackfinFrameInfo::emitEpilogue(MachineFunction &MF,
76 MachineBasicBlock &MBB) const {
77 MachineFrameInfo *MFI = MF.getFrameInfo();
78 const BlackfinRegisterInfo *RegInfo =
79 static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
80 const BlackfinInstrInfo &TII =
81 *static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
82 MachineBasicBlock::iterator MBBI = prior(MBB.end());
83 DebugLoc dl = MBBI->getDebugLoc();
84
85 int FrameSize = MFI->getStackSize();
86 assert(FrameSize%4 == 0 && "Misaligned frame size");
87
88 if (!RegInfo->hasFP(MF)) {
89 assert(!MFI->adjustsStack() &&
90 "FP elimination on a non-leaf function is not supported");
91 RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, FrameSize);
92 return;
93 }
94
95 // emit an UNLINK instruction
96 BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK));
97}