1 //===- MBlazeRegisterInfo.cpp - MBlaze Register 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 the TargetRegisterInfo
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "mblaze-reg-info"
18 #include "MBlazeSubtarget.h"
19 #include "MBlazeRegisterInfo.h"
20 #include "MBlazeMachineFunction.h"
21 #include "llvm/Constants.h"
22 #include "llvm/Type.h"
23 #include "llvm/Function.h"
24 #include "llvm/CodeGen/ValueTypes.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineFunction.h"
27 #include "llvm/CodeGen/MachineFrameInfo.h"
28 #include "llvm/CodeGen/MachineLocation.h"
29 #include "llvm/Target/TargetFrameInfo.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Target/TargetOptions.h"
32 #include "llvm/Target/TargetInstrInfo.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/Debug.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/ADT/BitVector.h"
38 #include "llvm/ADT/STLExtras.h"
43 MBlazeRegisterInfo(const MBlazeSubtarget &ST, const TargetInstrInfo &tii)
44 : MBlazeGenRegisterInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
45 Subtarget(ST), TII(tii) {}
47 /// getRegisterNumbering - Given the enum value for some register, e.g.
48 /// MBlaze::R0, return the number that it corresponds to (e.g. 0).
49 unsigned MBlazeRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
51 case MBlaze::R0 : case MBlaze::F0 : return 0;
52 case MBlaze::R1 : case MBlaze::F1 : return 1;
53 case MBlaze::R2 : case MBlaze::F2 : return 2;
54 case MBlaze::R3 : case MBlaze::F3 : return 3;
55 case MBlaze::R4 : case MBlaze::F4 : return 4;
56 case MBlaze::R5 : case MBlaze::F5 : return 5;
57 case MBlaze::R6 : case MBlaze::F6 : return 6;
58 case MBlaze::R7 : case MBlaze::F7 : return 7;
59 case MBlaze::R8 : case MBlaze::F8 : return 8;
60 case MBlaze::R9 : case MBlaze::F9 : return 9;
61 case MBlaze::R10 : case MBlaze::F10 : return 10;
62 case MBlaze::R11 : case MBlaze::F11 : return 11;
63 case MBlaze::R12 : case MBlaze::F12 : return 12;
64 case MBlaze::R13 : case MBlaze::F13 : return 13;
65 case MBlaze::R14 : case MBlaze::F14 : return 14;
66 case MBlaze::R15 : case MBlaze::F15 : return 15;
67 case MBlaze::R16 : case MBlaze::F16 : return 16;
68 case MBlaze::R17 : case MBlaze::F17 : return 17;
69 case MBlaze::R18 : case MBlaze::F18 : return 18;
70 case MBlaze::R19 : case MBlaze::F19 : return 19;
71 case MBlaze::R20 : case MBlaze::F20 : return 20;
72 case MBlaze::R21 : case MBlaze::F21 : return 21;
73 case MBlaze::R22 : case MBlaze::F22 : return 22;
74 case MBlaze::R23 : case MBlaze::F23 : return 23;
75 case MBlaze::R24 : case MBlaze::F24 : return 24;
76 case MBlaze::R25 : case MBlaze::F25 : return 25;
77 case MBlaze::R26 : case MBlaze::F26 : return 26;
78 case MBlaze::R27 : case MBlaze::F27 : return 27;
79 case MBlaze::R28 : case MBlaze::F28 : return 28;
80 case MBlaze::R29 : case MBlaze::F29 : return 29;
81 case MBlaze::R30 : case MBlaze::F30 : return 30;
82 case MBlaze::R31 : case MBlaze::F31 : return 31;
83 default: llvm_unreachable("Unknown register number!");
85 return 0; // Not reached
88 unsigned MBlazeRegisterInfo::getPICCallReg() {
92 //===----------------------------------------------------------------------===//
93 // Callee Saved Registers methods
94 //===----------------------------------------------------------------------===//
96 /// MBlaze Callee Saved Registers
97 const unsigned* MBlazeRegisterInfo::
98 getCalleeSavedRegs(const MachineFunction *MF) const {
99 // MBlaze callee-save register range is R19 - R31
100 static const unsigned CalleeSavedRegs[] = {
101 MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23,
102 MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27,
103 MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31,
107 return CalleeSavedRegs;
110 /// MBlaze Callee Saved Register Classes
111 const TargetRegisterClass* const* MBlazeRegisterInfo::
112 getCalleeSavedRegClasses(const MachineFunction *MF) const {
113 static const TargetRegisterClass * const CalleeSavedRC[] = {
114 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
115 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
116 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
117 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
118 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
119 &MBlaze::CPURegsRegClass, &MBlaze::CPURegsRegClass,
123 return CalleeSavedRC;
126 BitVector MBlazeRegisterInfo::
127 getReservedRegs(const MachineFunction &MF) const {
128 BitVector Reserved(getNumRegs());
129 Reserved.set(MBlaze::R0);
130 Reserved.set(MBlaze::R1);
131 Reserved.set(MBlaze::R2);
132 Reserved.set(MBlaze::R13);
133 Reserved.set(MBlaze::R14);
134 Reserved.set(MBlaze::R15);
135 Reserved.set(MBlaze::R16);
136 Reserved.set(MBlaze::R17);
137 Reserved.set(MBlaze::R18);
138 Reserved.set(MBlaze::R19);
142 //===----------------------------------------------------------------------===//
144 // Stack Frame Processing methods
145 // +----------------------------+
147 // The stack is allocated decrementing the stack pointer on
148 // the first instruction of a function prologue. Once decremented,
149 // all stack references are are done through a positive offset
150 // from the stack/frame pointer, so the stack is considered
153 //===----------------------------------------------------------------------===//
155 void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
156 MachineFrameInfo *MFI = MF.getFrameInfo();
157 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
159 // See the description at MicroBlazeMachineFunction.h
160 int TopCPUSavedRegOff = -1;
162 // Adjust CPU Callee Saved Registers Area. Registers RA and FP must
163 // be saved in this CPU Area there is the need. This whole Area must
164 // be aligned to the default Stack Alignment requirements.
165 unsigned StackOffset = MFI->getStackSize();
166 unsigned RegSize = 4;
168 // Replace the dummy '0' SPOffset by the negative offsets, as explained on
169 // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
170 // the approach done by calculateFrameObjectOffsets to the stack frame.
171 MBlazeFI->adjustLoadArgsFI(MFI);
172 MBlazeFI->adjustStoreVarArgsFI(MFI);
175 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
177 MBlazeFI->setFPStackOffset(StackOffset);
178 TopCPUSavedRegOff = StackOffset;
179 StackOffset += RegSize;
182 if (MFI->hasCalls()) {
183 MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
185 MBlazeFI->setRAStackOffset(StackOffset);
186 TopCPUSavedRegOff = StackOffset;
187 StackOffset += RegSize;
191 MFI->setStackSize(StackOffset);
193 // Recalculate the final tops offset. The final values must be '0'
194 // if there isn't a callee saved register for CPU or FPU, otherwise
195 // a negative offset is needed.
196 if (TopCPUSavedRegOff >= 0)
197 MBlazeFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset);
200 // hasFP - Return true if the specified function should have a dedicated frame
201 // pointer register. This is true if the function has variable sized allocas or
202 // if frame pointer elimination is disabled.
203 bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const {
204 const MachineFrameInfo *MFI = MF.getFrameInfo();
205 return NoFramePointerElim || MFI->hasVarSizedObjects();
208 // This function eliminate ADJCALLSTACKDOWN,
209 // ADJCALLSTACKUP pseudo instructions
210 void MBlazeRegisterInfo::
211 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
212 MachineBasicBlock::iterator I) const {
213 // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
217 // FrameIndex represent objects inside a abstract stack.
218 // We must replace FrameIndex with an stack/frame pointer
220 unsigned MBlazeRegisterInfo::
221 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
222 int *Value, RegScavenger *RS) const {
223 MachineInstr &MI = *II;
224 MachineFunction &MF = *MI.getParent()->getParent();
227 while (!MI.getOperand(i).isFI()) {
229 assert(i < MI.getNumOperands() &&
230 "Instr doesn't have FrameIndex operand!");
233 unsigned oi = i == 2 ? 1 : 2;
235 DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
236 errs() << "<--------->\n" << MI);
238 int FrameIndex = MI.getOperand(i).getIndex();
239 int stackSize = MF.getFrameInfo()->getStackSize();
240 int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
242 DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
243 << "spOffset : " << spOffset << "\n"
244 << "stackSize : " << stackSize << "\n");
246 // as explained on LowerFormalArguments, detect negative offsets
247 // and adjust SPOffsets considering the final stack size.
248 int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset));
249 Offset += MI.getOperand(oi).getImm();
251 DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
253 MI.getOperand(oi).ChangeToImmediate(Offset);
254 MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
258 void MBlazeRegisterInfo::
259 emitPrologue(MachineFunction &MF) const {
260 MachineBasicBlock &MBB = MF.front();
261 MachineFrameInfo *MFI = MF.getFrameInfo();
262 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
263 MachineBasicBlock::iterator MBBI = MBB.begin();
264 DebugLoc dl = (MBBI != MBB.end() ?
265 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
267 // Get the right frame order for MBlaze.
268 adjustMBlazeStackFrame(MF);
270 // Get the number of bytes to allocate from the FrameInfo.
271 unsigned StackSize = MFI->getStackSize();
273 // No need to allocate space on the stack.
274 if (StackSize == 0 && !MFI->hasCalls()) return;
276 int FPOffset = MBlazeFI->getFPStackOffset();
277 int RAOffset = MBlazeFI->getRAStackOffset();
279 // Adjust stack : addi R1, R1, -imm
280 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
281 .addReg(MBlaze::R1).addImm(-StackSize);
283 // Save the return address only if the function isnt a leaf one.
284 // swi R15, R1, stack_loc
285 if (MFI->hasCalls()) {
286 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
287 .addReg(MBlaze::R15).addImm(RAOffset).addReg(MBlaze::R1);
290 // if framepointer enabled, save it and set it
291 // to point to the stack pointer
293 // swi R19, R1, stack_loc
294 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
295 .addReg(MBlaze::R19).addImm(FPOffset).addReg(MBlaze::R1);
298 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R19)
299 .addReg(MBlaze::R1).addReg(MBlaze::R0);
303 void MBlazeRegisterInfo::
304 emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
305 MachineBasicBlock::iterator MBBI = prior(MBB.end());
306 MachineFrameInfo *MFI = MF.getFrameInfo();
307 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
308 DebugLoc dl = MBBI->getDebugLoc();
310 // Get the number of bytes from FrameInfo
311 int NumBytes = (int) MFI->getStackSize();
313 // Get the FI's where RA and FP are saved.
314 int FPOffset = MBlazeFI->getFPStackOffset();
315 int RAOffset = MBlazeFI->getRAStackOffset();
317 // if framepointer enabled, restore it and restore the
321 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
322 .addReg(MBlaze::R19).addReg(MBlaze::R0);
324 // lwi R19, R1, stack_loc
325 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
326 .addImm(FPOffset).addReg(MBlaze::R1);
329 // Restore the return address only if the function isnt a leaf one.
330 // lwi R15, R1, stack_loc
331 if (MFI->hasCalls()) {
332 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
333 .addImm(RAOffset).addReg(MBlaze::R1);
339 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
340 .addReg(MBlaze::R1).addImm(NumBytes);
345 void MBlazeRegisterInfo::
346 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
347 // Set the stack offset where GP must be saved/loaded from.
348 MachineFrameInfo *MFI = MF.getFrameInfo();
349 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
350 if (MBlazeFI->needGPSaveRestore())
351 MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset());
354 unsigned MBlazeRegisterInfo::getRARegister() const {
358 unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
359 return hasFP(MF) ? MBlaze::R19 : MBlaze::R1;
362 unsigned MBlazeRegisterInfo::getEHExceptionRegister() const {
363 llvm_unreachable("What is the exception register");
367 unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
368 llvm_unreachable("What is the exception handler register");
372 int MBlazeRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
373 llvm_unreachable("What is the dwarf register number");
377 #include "MBlazeGenRegisterInfo.inc"