blob: 09f8e43d78ffedb04d40ee3a32c4ef916b15e61c [file] [log] [blame]
Anton Korobeynikov33464912010-11-15 00:06:54 +00001//=======- MBlazeFrameInfo.cpp - MBlaze 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 MBlaze implementation of TargetFrameInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MBlazeFrameInfo.h"
15#include "MBlazeInstrInfo.h"
16#include "MBlazeMachineFunction.h"
17#include "llvm/Function.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineModuleInfo.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/Target/TargetData.h"
24#include "llvm/Target/TargetOptions.h"
25#include "llvm/Support/CommandLine.h"
26
27using namespace llvm;
28
29
30//===----------------------------------------------------------------------===//
31//
32// Stack Frame Processing methods
33// +----------------------------+
34//
35// The stack is allocated decrementing the stack pointer on
36// the first instruction of a function prologue. Once decremented,
37// all stack references are are done through a positive offset
38// from the stack/frame pointer, so the stack is considered
39// to grow up.
40//
41//===----------------------------------------------------------------------===//
42
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000043// hasFP - Return true if the specified function should have a dedicated frame
44// pointer register. This is true if the function has variable sized allocas or
45// if frame pointer elimination is disabled.
46bool MBlazeFrameInfo::hasFP(const MachineFunction &MF) const {
47 const MachineFrameInfo *MFI = MF.getFrameInfo();
48 return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
49}
50
Anton Korobeynikov33464912010-11-15 00:06:54 +000051void MBlazeFrameInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
52 MachineFrameInfo *MFI = MF.getFrameInfo();
53 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
Anton Korobeynikov33464912010-11-15 00:06:54 +000054
55 // See the description at MicroBlazeMachineFunction.h
56 int TopCPUSavedRegOff = -1;
57
58 // Adjust CPU Callee Saved Registers Area. Registers RA and FP must
59 // be saved in this CPU Area there is the need. This whole Area must
60 // be aligned to the default Stack Alignment requirements.
61 unsigned StackOffset = MFI->getStackSize();
62 unsigned RegSize = 4;
63
64 // Replace the dummy '0' SPOffset by the negative offsets, as explained on
65 // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
66 // the approach done by calculateFrameObjectOffsets to the stack frame.
67 MBlazeFI->adjustLoadArgsFI(MFI);
68 MBlazeFI->adjustStoreVarArgsFI(MFI);
69
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000070 if (hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +000071 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
72 StackOffset);
73 MBlazeFI->setFPStackOffset(StackOffset);
74 TopCPUSavedRegOff = StackOffset;
75 StackOffset += RegSize;
76 }
77
78 if (MFI->adjustsStack()) {
79 MBlazeFI->setRAStackOffset(0);
80 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
81 StackOffset);
82 TopCPUSavedRegOff = StackOffset;
83 StackOffset += RegSize;
84 }
85
86 // Update frame info
87 MFI->setStackSize(StackOffset);
88
89 // Recalculate the final tops offset. The final values must be '0'
90 // if there isn't a callee saved register for CPU or FPU, otherwise
91 // a negative offset is needed.
92 if (TopCPUSavedRegOff >= 0)
93 MBlazeFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset);
94}
95
96void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
97 MachineBasicBlock &MBB = MF.front();
98 MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikov33464912010-11-15 00:06:54 +000099 const MBlazeInstrInfo &TII =
100 *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
101 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
102 MachineBasicBlock::iterator MBBI = MBB.begin();
103 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
104
105 // Get the right frame order for MBlaze.
106 adjustMBlazeStackFrame(MF);
107
108 // Get the number of bytes to allocate from the FrameInfo.
109 unsigned StackSize = MFI->getStackSize();
110
111 // No need to allocate space on the stack.
112 if (StackSize == 0 && !MFI->adjustsStack()) return;
113 if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
114
115 int FPOffset = MBlazeFI->getFPStackOffset();
116 int RAOffset = MBlazeFI->getRAStackOffset();
117
118 // Adjust stack : addi R1, R1, -imm
119 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDI), MBlaze::R1)
120 .addReg(MBlaze::R1).addImm(-StackSize);
121
122 // Save the return address only if the function isnt a leaf one.
123 // swi R15, R1, stack_loc
124 if (MFI->adjustsStack()) {
125 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
126 .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset);
127 }
128
129 // if framepointer enabled, save it and set it
130 // to point to the stack pointer
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000131 if (hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +0000132 // swi R19, R1, stack_loc
133 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
134 .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset);
135
136 // add R19, R1, R0
137 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
138 .addReg(MBlaze::R1).addReg(MBlaze::R0);
139 }
140}
141
142void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF,
143 MachineBasicBlock &MBB) const {
144 MachineBasicBlock::iterator MBBI = prior(MBB.end());
145 MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000146 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
Anton Korobeynikov33464912010-11-15 00:06:54 +0000147 const MBlazeInstrInfo &TII =
148 *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
149
150 DebugLoc dl = MBBI->getDebugLoc();
151
152 // Get the FI's where RA and FP are saved.
153 int FPOffset = MBlazeFI->getFPStackOffset();
154 int RAOffset = MBlazeFI->getRAStackOffset();
155
156 // if framepointer enabled, restore it and restore the
157 // stack pointer
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000158 if (hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +0000159 // add R1, R19, R0
160 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
161 .addReg(MBlaze::R19).addReg(MBlaze::R0);
162
163 // lwi R19, R1, stack_loc
164 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
165 .addReg(MBlaze::R1).addImm(FPOffset);
166 }
167
168 // Restore the return address only if the function isnt a leaf one.
169 // lwi R15, R1, stack_loc
170 if (MFI->adjustsStack()) {
171 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
172 .addReg(MBlaze::R1).addImm(RAOffset);
173 }
174
175 // Get the number of bytes from FrameInfo
176 int StackSize = (int) MFI->getStackSize();
177 if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
178
179 // adjust stack.
180 // addi R1, R1, imm
181 if (StackSize) {
182 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
183 .addReg(MBlaze::R1).addImm(StackSize);
184 }
185}