1 //=======- MBlazeFrameInfo.cpp - MBlaze Frame Information ------*- C++ -*-====//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the MBlaze implementation of TargetFrameInfo class.
12 //===----------------------------------------------------------------------===//
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"
30 //===----------------------------------------------------------------------===//
32 // Stack Frame Processing methods
33 // +----------------------------+
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
41 //===----------------------------------------------------------------------===//
43 // 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.
46 bool MBlazeFrameInfo::hasFP(const MachineFunction &MF) const {
47 const MachineFrameInfo *MFI = MF.getFrameInfo();
48 return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
51 void MBlazeFrameInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
52 MachineFrameInfo *MFI = MF.getFrameInfo();
53 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
55 // See the description at MicroBlazeMachineFunction.h
56 int TopCPUSavedRegOff = -1;
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();
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);
71 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
73 MBlazeFI->setFPStackOffset(StackOffset);
74 TopCPUSavedRegOff = StackOffset;
75 StackOffset += RegSize;
78 if (MFI->adjustsStack()) {
79 MBlazeFI->setRAStackOffset(0);
80 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
82 TopCPUSavedRegOff = StackOffset;
83 StackOffset += RegSize;
87 MFI->setStackSize(StackOffset);
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);
96 void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
97 MachineBasicBlock &MBB = MF.front();
98 MachineFrameInfo *MFI = MF.getFrameInfo();
99 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();
105 // Get the right frame order for MBlaze.
106 adjustMBlazeStackFrame(MF);
108 // Get the number of bytes to allocate from the FrameInfo.
109 unsigned StackSize = MFI->getStackSize();
111 // No need to allocate space on the stack.
112 if (StackSize == 0 && !MFI->adjustsStack()) return;
113 if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
115 int FPOffset = MBlazeFI->getFPStackOffset();
116 int RAOffset = MBlazeFI->getRAStackOffset();
118 // Adjust stack : addi R1, R1, -imm
119 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDI), MBlaze::R1)
120 .addReg(MBlaze::R1).addImm(-StackSize);
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);
129 // if framepointer enabled, save it and set it
130 // to point to the stack pointer
132 // swi R19, R1, stack_loc
133 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
134 .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset);
137 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
138 .addReg(MBlaze::R1).addReg(MBlaze::R0);
142 void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF,
143 MachineBasicBlock &MBB) const {
144 MachineBasicBlock::iterator MBBI = prior(MBB.end());
145 MachineFrameInfo *MFI = MF.getFrameInfo();
146 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
147 const MBlazeInstrInfo &TII =
148 *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
150 DebugLoc dl = MBBI->getDebugLoc();
152 // Get the FI's where RA and FP are saved.
153 int FPOffset = MBlazeFI->getFPStackOffset();
154 int RAOffset = MBlazeFI->getRAStackOffset();
156 // if framepointer enabled, restore it and restore the
160 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
161 .addReg(MBlaze::R19).addReg(MBlaze::R0);
163 // lwi R19, R1, stack_loc
164 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
165 .addReg(MBlaze::R1).addImm(FPOffset);
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);
175 // Get the number of bytes from FrameInfo
176 int StackSize = (int) MFI->getStackSize();
177 if (StackSize < 28 && MFI->adjustsStack()) StackSize = 28;
182 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
183 .addReg(MBlaze::R1).addImm(StackSize);