1 //===- MBlazeRegisterInfo.cpp - MBlaze Register 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 the TargetRegisterInfo 11 // class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #define DEBUG_TYPE "mblaze-frame-info" 16 17 #include "MBlaze.h" 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/Target/TargetFrameLowering.h" 29 #include "llvm/Target/TargetMachine.h" 30 #include "llvm/Target/TargetOptions.h" 31 #include "llvm/Target/TargetInstrInfo.h" 32 #include "llvm/Support/CommandLine.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/raw_ostream.h" 36 #include "llvm/ADT/BitVector.h" 37 #include "llvm/ADT/STLExtras.h" 38 39 #define GET_REGINFO_TARGET_DESC 40 #include "MBlazeGenRegisterInfo.inc" 41 42 using namespace llvm; 43 44 MBlazeRegisterInfo:: 45 MBlazeRegisterInfo(const MBlazeSubtarget &ST, const TargetInstrInfo &tii) 46 : MBlazeGenRegisterInfo(MBlaze::R15), Subtarget(ST), TII(tii) {} 47 48 unsigned MBlazeRegisterInfo::getPICCallReg() { 49 return MBlaze::R20; 50 } 51 52 //===----------------------------------------------------------------------===// 53 // Callee Saved Registers methods 54 //===----------------------------------------------------------------------===// 55 56 /// MBlaze Callee Saved Registers 57 const unsigned* MBlazeRegisterInfo:: 58 getCalleeSavedRegs(const MachineFunction *MF) const { 59 // MBlaze callee-save register range is R20 - R31 60 static const unsigned CalleeSavedRegs[] = { 61 MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23, 62 MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27, 63 MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31, 64 0 65 }; 66 67 return CalleeSavedRegs; 68 } 69 70 BitVector MBlazeRegisterInfo:: 71 getReservedRegs(const MachineFunction &MF) const { 72 BitVector Reserved(getNumRegs()); 73 Reserved.set(MBlaze::R0); 74 Reserved.set(MBlaze::R1); 75 Reserved.set(MBlaze::R2); 76 Reserved.set(MBlaze::R13); 77 Reserved.set(MBlaze::R14); 78 Reserved.set(MBlaze::R15); 79 Reserved.set(MBlaze::R16); 80 Reserved.set(MBlaze::R17); 81 Reserved.set(MBlaze::R18); 82 Reserved.set(MBlaze::R19); 83 return Reserved; 84 } 85 86 // This function eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions 87 void MBlazeRegisterInfo:: 88 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 89 MachineBasicBlock::iterator I) const { 90 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 91 92 if (!TFI->hasReservedCallFrame(MF)) { 93 // If we have a frame pointer, turn the adjcallstackup instruction into a 94 // 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into 95 // 'addi r1, r1, <amt>' 96 MachineInstr *Old = I; 97 int Amount = Old->getOperand(0).getImm() + 4; 98 if (Amount != 0) { 99 // We need to keep the stack aligned properly. To do this, we round the 100 // amount of space needed for the outgoing arguments up to the next 101 // alignment boundary. 102 unsigned Align = TFI->getStackAlignment(); 103 Amount = (Amount+Align-1)/Align*Align; 104 105 MachineInstr *New; 106 if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) { 107 New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1) 108 .addReg(MBlaze::R1).addImm(-Amount); 109 } else { 110 assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP); 111 New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1) 112 .addReg(MBlaze::R1).addImm(Amount); 113 } 114 115 // Replace the pseudo instruction with a new instruction... 116 MBB.insert(I, New); 117 } 118 } 119 120 // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. 121 MBB.erase(I); 122 } 123 124 // FrameIndex represent objects inside a abstract stack. 125 // We must replace FrameIndex with an stack/frame pointer 126 // direct reference. 127 void MBlazeRegisterInfo:: 128 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, 129 RegScavenger *RS) const { 130 MachineInstr &MI = *II; 131 MachineFunction &MF = *MI.getParent()->getParent(); 132 MachineFrameInfo *MFI = MF.getFrameInfo(); 133 134 unsigned i = 0; 135 while (!MI.getOperand(i).isFI()) { 136 ++i; 137 assert(i < MI.getNumOperands() && 138 "Instr doesn't have FrameIndex operand!"); 139 } 140 141 unsigned oi = i == 2 ? 1 : 2; 142 143 DEBUG(dbgs() << "\nFunction : " << MF.getFunction()->getName() << "\n"; 144 dbgs() << "<--------->\n" << MI); 145 146 int FrameIndex = MI.getOperand(i).getIndex(); 147 int stackSize = MFI->getStackSize(); 148 int spOffset = MFI->getObjectOffset(FrameIndex); 149 150 DEBUG(MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 151 dbgs() << "FrameIndex : " << FrameIndex << "\n" 152 << "spOffset : " << spOffset << "\n" 153 << "stackSize : " << stackSize << "\n" 154 << "isFixed : " << MFI->isFixedObjectIndex(FrameIndex) << "\n" 155 << "isLiveIn : " << MBlazeFI->isLiveIn(FrameIndex) << "\n" 156 << "isSpill : " << MFI->isSpillSlotObjectIndex(FrameIndex) 157 << "\n" ); 158 159 // as explained on LowerFormalArguments, detect negative offsets 160 // and adjust SPOffsets considering the final stack size. 161 int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset; 162 Offset += MI.getOperand(oi).getImm(); 163 164 DEBUG(dbgs() << "Offset : " << Offset << "\n" << "<--------->\n"); 165 166 MI.getOperand(oi).ChangeToImmediate(Offset); 167 MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false); 168 } 169 170 void MBlazeRegisterInfo:: 171 processFunctionBeforeFrameFinalized(MachineFunction &MF) const { 172 // Set the stack offset where GP must be saved/loaded from. 173 MachineFrameInfo *MFI = MF.getFrameInfo(); 174 MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 175 if (MBlazeFI->needGPSaveRestore()) 176 MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset()); 177 } 178 179 unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 180 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 181 182 return TFI->hasFP(MF) ? MBlaze::R19 : MBlaze::R1; 183 } 184 185 unsigned MBlazeRegisterInfo::getEHExceptionRegister() const { 186 llvm_unreachable("What is the exception register"); 187 return 0; 188 } 189 190 unsigned MBlazeRegisterInfo::getEHHandlerRegister() const { 191 llvm_unreachable("What is the exception handler register"); 192 return 0; 193 } 194