Implement ELF object file writing support for the MBlaze backend. Its not perfect...
[oota-llvm.git] / lib / Target / MBlaze / MBlazeFrameInfo.cpp
1 //=======- 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
27 using 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
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();
49 }
50
51 void MBlazeFrameInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
52   MachineFrameInfo *MFI = MF.getFrameInfo();
53   MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
54
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
70   if (hasFP(MF)) {
71     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
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();
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
131   if (hasFP(MF)) {
132     // 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
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());
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
158   if (hasFP(MF)) {
159     // 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 }