Jia Liu | 31d157a | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 1 | //===-- MBlazeFrameLowering.cpp - MBlaze Frame Information ---------------====// |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 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 | // |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 10 | // This file contains the MBlaze implementation of TargetFrameLowering class. |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 14 | #define DEBUG_TYPE "mblaze-frame-lowering" |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 15 | |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 16 | #include "MBlazeFrameLowering.h" |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 17 | #include "MBlazeInstrInfo.h" |
| 18 | #include "MBlazeMachineFunction.h" |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 19 | #include "InstPrinter/MBlazeInstPrinter.h" |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 20 | #include "llvm/Function.h" |
| 21 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| 22 | #include "llvm/CodeGen/MachineFunction.h" |
| 23 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 24 | #include "llvm/CodeGen/MachineModuleInfo.h" |
| 25 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 26 | #include "llvm/Target/TargetData.h" |
| 27 | #include "llvm/Target/TargetOptions.h" |
| 28 | #include "llvm/Support/CommandLine.h" |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Debug.h" |
| 30 | #include "llvm/Support/ErrorHandling.h" |
| 31 | #include "llvm/Support/raw_ostream.h" |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 32 | |
| 33 | using namespace llvm; |
| 34 | |
Benjamin Kramer | 0861f57 | 2011-11-26 23:01:57 +0000 | [diff] [blame] | 35 | static cl::opt<bool> MBDisableStackAdjust( |
| 36 | "disable-mblaze-stack-adjust", |
| 37 | cl::init(false), |
| 38 | cl::desc("Disable MBlaze stack layout adjustment."), |
| 39 | cl::Hidden); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 40 | |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 41 | static void replaceFrameIndexes(MachineFunction &MF, |
| 42 | SmallVector<std::pair<int,int64_t>, 16> &FR) { |
| 43 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Wesley Peck | 3d2148f | 2011-01-05 17:34:20 +0000 | [diff] [blame] | 44 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 45 | const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin(); |
| 46 | const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end(); |
| 47 | |
| 48 | SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB; |
| 49 | for (; FRI != FRE; ++FRI) { |
| 50 | MFI->RemoveStackObject(FRI->first); |
| 51 | int NFI = MFI->CreateFixedObject(4, FRI->second, true); |
Wesley Peck | 3d2148f | 2011-01-05 17:34:20 +0000 | [diff] [blame] | 52 | MBlazeFI->recordReplacement(FRI->first, NFI); |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 53 | |
| 54 | for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) { |
| 55 | MachineBasicBlock::iterator MBB = MB->begin(); |
| 56 | const MachineBasicBlock::iterator MBE = MB->end(); |
| 57 | |
| 58 | for (; MBB != MBE; ++MBB) { |
| 59 | MachineInstr::mop_iterator MIB = MBB->operands_begin(); |
| 60 | const MachineInstr::mop_iterator MIE = MBB->operands_end(); |
| 61 | |
| 62 | for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) { |
| 63 | if (!MII->isFI() || MII->getIndex() != FRI->first) continue; |
| 64 | DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n"); |
| 65 | MII->setIndex(NFI); |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 72 | //===----------------------------------------------------------------------===// |
| 73 | // |
| 74 | // Stack Frame Processing methods |
| 75 | // +----------------------------+ |
| 76 | // |
| 77 | // The stack is allocated decrementing the stack pointer on |
| 78 | // the first instruction of a function prologue. Once decremented, |
| 79 | // all stack references are are done through a positive offset |
| 80 | // from the stack/frame pointer, so the stack is considered |
| 81 | // to grow up. |
| 82 | // |
| 83 | //===----------------------------------------------------------------------===// |
| 84 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 85 | static void analyzeFrameIndexes(MachineFunction &MF) { |
Wesley Peck | a18f083 | 2011-11-26 21:50:38 +0000 | [diff] [blame] | 86 | if (MBDisableStackAdjust) return; |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 87 | |
| 88 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 89 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
| 90 | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 91 | |
| 92 | MachineRegisterInfo::livein_iterator LII = MRI.livein_begin(); |
| 93 | MachineRegisterInfo::livein_iterator LIE = MRI.livein_end(); |
| 94 | const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn(); |
| 95 | SmallVector<MachineInstr*, 16> EraseInstr; |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 96 | SmallVector<std::pair<int,int64_t>, 16> FrameRelocate; |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 97 | |
| 98 | MachineBasicBlock *MBB = MF.getBlockNumbered(0); |
| 99 | MachineBasicBlock::iterator MIB = MBB->begin(); |
| 100 | MachineBasicBlock::iterator MIE = MBB->end(); |
| 101 | |
| 102 | int StackAdjust = 0; |
| 103 | int StackOffset = -28; |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 104 | |
| 105 | // In this loop we are searching frame indexes that corrospond to incoming |
| 106 | // arguments that are already in the stack. We look for instruction sequences |
| 107 | // like the following: |
| 108 | // |
| 109 | // LWI REG, FI1, 0 |
| 110 | // ... |
| 111 | // SWI REG, FI2, 0 |
| 112 | // |
| 113 | // As long as there are no defs of REG in the ... part, we can eliminate |
| 114 | // the SWI instruction because the value has already been stored to the |
| 115 | // stack by the caller. All we need to do is locate FI at the correct |
| 116 | // stack location according to the calling convensions. |
| 117 | // |
| 118 | // Additionally, if the SWI operation kills the def of REG then we don't |
| 119 | // need the LWI operation so we can erase it as well. |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 120 | for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) { |
| 121 | for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { |
| 122 | if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 || |
| 123 | !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || |
| 124 | I->getOperand(1).getIndex() != LiveInFI[i]) continue; |
| 125 | |
| 126 | unsigned FIReg = I->getOperand(0).getReg(); |
| 127 | MachineBasicBlock::iterator SI = I; |
| 128 | for (SI++; SI != MIE; ++SI) { |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 129 | if (!SI->getOperand(0).isReg() || |
| 130 | !SI->getOperand(1).isFI() || |
| 131 | SI->getOpcode() != MBlaze::SWI) continue; |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 132 | |
| 133 | int FI = SI->getOperand(1).getIndex(); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 134 | if (SI->getOperand(0).getReg() != FIReg || |
| 135 | MFI->isFixedObjectIndex(FI) || |
| 136 | MFI->getObjectSize(FI) != 4) continue; |
| 137 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 138 | if (SI->getOperand(0).isDef()) break; |
| 139 | |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 140 | if (SI->getOperand(0).isKill()) { |
| 141 | DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex() |
| 142 | << " removed\n"); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 143 | EraseInstr.push_back(I); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 146 | EraseInstr.push_back(SI); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 147 | DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n"); |
| 148 | |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 149 | FrameRelocate.push_back(std::make_pair(FI,StackOffset)); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 150 | DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n"); |
| 151 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 152 | StackOffset -= 4; |
| 153 | StackAdjust += 4; |
| 154 | break; |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 | |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 159 | // In this loop we are searching for frame indexes that corrospond to |
| 160 | // incoming arguments that are in registers. We look for instruction |
| 161 | // sequences like the following: |
| 162 | // |
| 163 | // ... SWI REG, FI, 0 |
| 164 | // |
| 165 | // As long as the ... part does not define REG and if REG is an incoming |
| 166 | // parameter register then we know that, according to ABI convensions, the |
| 167 | // caller has allocated stack space for it already. Instead of allocating |
| 168 | // stack space on our frame, we record the correct location in the callers |
| 169 | // frame. |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 170 | for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { |
| 171 | for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { |
| 172 | if (I->definesRegister(LI->first)) |
| 173 | break; |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 174 | |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 175 | if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 || |
| 176 | !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || |
| 177 | I->getOperand(1).getIndex() < 0) continue; |
| 178 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 179 | if (I->getOperand(0).getReg() == LI->first) { |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 180 | int FI = I->getOperand(1).getIndex(); |
| 181 | MBlazeFI->recordLiveIn(FI); |
| 182 | |
| 183 | int FILoc = 0; |
| 184 | switch (LI->first) { |
| 185 | default: llvm_unreachable("invalid incoming parameter!"); |
| 186 | case MBlaze::R5: FILoc = -4; break; |
| 187 | case MBlaze::R6: FILoc = -8; break; |
| 188 | case MBlaze::R7: FILoc = -12; break; |
| 189 | case MBlaze::R8: FILoc = -16; break; |
| 190 | case MBlaze::R9: FILoc = -20; break; |
| 191 | case MBlaze::R10: FILoc = -24; break; |
| 192 | } |
| 193 | |
| 194 | StackAdjust += 4; |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 195 | FrameRelocate.push_back(std::make_pair(FI,FILoc)); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 196 | DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n"); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 197 | break; |
| 198 | } |
| 199 | } |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 200 | } |
| 201 | |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 202 | // Go ahead and erase all of the instructions that we determined were |
| 203 | // no longer needed. |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 204 | for (int i = 0, e = EraseInstr.size(); i < e; ++i) |
| 205 | MBB->erase(EraseInstr[i]); |
| 206 | |
Wesley Peck | b020808 | 2011-01-03 21:40:26 +0000 | [diff] [blame] | 207 | // Replace all of the frame indexes that we have relocated with new |
| 208 | // fixed object frame indexes. |
| 209 | replaceFrameIndexes(MF, FrameRelocate); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 210 | } |
| 211 | |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 212 | static void interruptFrameLayout(MachineFunction &MF) { |
| 213 | const Function *F = MF.getFunction(); |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 214 | CallingConv::ID CallConv = F->getCallingConv(); |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 215 | |
| 216 | // If this function is not using either the interrupt_handler |
| 217 | // calling convention or the save_volatiles calling convention |
| 218 | // then we don't need to do any additional frame layout. |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 219 | if (CallConv != CallingConv::MBLAZE_INTR && |
| 220 | CallConv != CallingConv::MBLAZE_SVOL) |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 221 | return; |
| 222 | |
| 223 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 224 | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 225 | const MBlazeInstrInfo &TII = |
| 226 | *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); |
| 227 | |
| 228 | // Determine if the calling convention is the interrupt_handler |
| 229 | // calling convention. Some pieces of the prologue and epilogue |
| 230 | // only need to be emitted if we are lowering and interrupt handler. |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 231 | bool isIntr = CallConv == CallingConv::MBLAZE_INTR; |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 232 | |
| 233 | // Determine where to put prologue and epilogue additions |
| 234 | MachineBasicBlock &MENT = MF.front(); |
| 235 | MachineBasicBlock &MEXT = MF.back(); |
| 236 | |
| 237 | MachineBasicBlock::iterator MENTI = MENT.begin(); |
| 238 | MachineBasicBlock::iterator MEXTI = prior(MEXT.end()); |
| 239 | |
| 240 | DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc(); |
| 241 | DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc(); |
| 242 | |
| 243 | // Store the frame indexes generated during prologue additions for use |
| 244 | // when we are generating the epilogue additions. |
| 245 | SmallVector<int, 10> VFI; |
| 246 | |
| 247 | // Build the prologue SWI for R3 - R12 if needed. Note that R11 must |
| 248 | // always have a SWI because it is used when processing RMSR. |
| 249 | for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) { |
| 250 | if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue; |
| 251 | |
| 252 | int FI = MFI->CreateStackObject(4,4,false,false); |
| 253 | VFI.push_back(FI); |
| 254 | |
| 255 | BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r) |
| 256 | .addFrameIndex(FI).addImm(0); |
| 257 | } |
| 258 | |
| 259 | // Build the prologue SWI for R17, R18 |
| 260 | int R17FI = MFI->CreateStackObject(4,4,false,false); |
| 261 | int R18FI = MFI->CreateStackObject(4,4,false,false); |
| 262 | |
| 263 | BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17) |
| 264 | .addFrameIndex(R17FI).addImm(0); |
| 265 | |
| 266 | BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18) |
| 267 | .addFrameIndex(R18FI).addImm(0); |
| 268 | |
| 269 | // Buid the prologue SWI and the epilogue LWI for RMSR if needed |
| 270 | if (isIntr) { |
| 271 | int MSRFI = MFI->CreateStackObject(4,4,false,false); |
| 272 | BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11) |
| 273 | .addReg(MBlaze::RMSR); |
| 274 | BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11) |
| 275 | .addFrameIndex(MSRFI).addImm(0); |
| 276 | |
| 277 | BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11) |
| 278 | .addFrameIndex(MSRFI).addImm(0); |
| 279 | BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR) |
| 280 | .addReg(MBlaze::R11); |
| 281 | } |
| 282 | |
| 283 | // Build the epilogue LWI for R17, R18 |
| 284 | BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18) |
| 285 | .addFrameIndex(R18FI).addImm(0); |
| 286 | |
| 287 | BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17) |
| 288 | .addFrameIndex(R17FI).addImm(0); |
| 289 | |
| 290 | // Build the epilogue LWI for R3 - R12 if needed |
| 291 | for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) { |
| 292 | if (!MRI.isPhysRegUsed(r)) continue; |
| 293 | BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r) |
| 294 | .addFrameIndex(VFI[--i]).addImm(0); |
| 295 | } |
| 296 | } |
| 297 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 298 | static void determineFrameLayout(MachineFunction &MF) { |
| 299 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 300 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
| 301 | |
| 302 | // Replace the dummy '0' SPOffset by the negative offsets, as explained on |
| 303 | // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid |
| 304 | // the approach done by calculateFrameObjectOffsets to the stack frame. |
| 305 | MBlazeFI->adjustLoadArgsFI(MFI); |
| 306 | MBlazeFI->adjustStoreVarArgsFI(MFI); |
| 307 | |
| 308 | // Get the number of bytes to allocate from the FrameInfo |
| 309 | unsigned FrameSize = MFI->getStackSize(); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 310 | DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" ); |
| 311 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 312 | // Get the alignments provided by the target, and the maximum alignment |
| 313 | // (if any) of the fixed frame objects. |
| 314 | // unsigned MaxAlign = MFI->getMaxAlignment(); |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 315 | unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 316 | unsigned AlignMask = TargetAlign - 1; |
| 317 | |
| 318 | // Make sure the frame is aligned. |
| 319 | FrameSize = (FrameSize + AlignMask) & ~AlignMask; |
| 320 | MFI->setStackSize(FrameSize); |
Wesley Peck | b4aec92 | 2010-12-29 19:46:28 +0000 | [diff] [blame] | 321 | DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" ); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 322 | } |
| 323 | |
Anton Korobeynikov | 2c8bd75 | 2011-01-10 12:56:18 +0000 | [diff] [blame] | 324 | int MBlazeFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) |
Wesley Peck | 3d2148f | 2011-01-05 17:34:20 +0000 | [diff] [blame] | 325 | const { |
| 326 | const MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
| 327 | if (MBlazeFI->hasReplacement(FI)) |
| 328 | FI = MBlazeFI->getReplacement(FI); |
Anton Korobeynikov | 2c8bd75 | 2011-01-10 12:56:18 +0000 | [diff] [blame] | 329 | return TargetFrameLowering::getFrameIndexOffset(MF,FI); |
Wesley Peck | 3d2148f | 2011-01-05 17:34:20 +0000 | [diff] [blame] | 330 | } |
| 331 | |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 332 | // hasFP - Return true if the specified function should have a dedicated frame |
| 333 | // pointer register. This is true if the function has variable sized allocas or |
| 334 | // if frame pointer elimination is disabled. |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 335 | bool MBlazeFrameLowering::hasFP(const MachineFunction &MF) const { |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 336 | const MachineFrameInfo *MFI = MF.getFrameInfo(); |
Nick Lewycky | 8a8d479 | 2011-12-02 22:16:29 +0000 | [diff] [blame] | 337 | return MF.getTarget().Options.DisableFramePointerElim(MF) || |
| 338 | MFI->hasVarSizedObjects(); |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 339 | } |
| 340 | |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 341 | void MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const { |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 342 | MachineBasicBlock &MBB = MF.front(); |
| 343 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 344 | const MBlazeInstrInfo &TII = |
| 345 | *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); |
| 346 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
| 347 | MachineBasicBlock::iterator MBBI = MBB.begin(); |
| 348 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); |
| 349 | |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 350 | CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); |
| 351 | bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 352 | |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 353 | // Determine the correct frame layout |
| 354 | determineFrameLayout(MF); |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 355 | |
| 356 | // Get the number of bytes to allocate from the FrameInfo. |
| 357 | unsigned StackSize = MFI->getStackSize(); |
| 358 | |
| 359 | // No need to allocate space on the stack. |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 360 | if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 361 | |
| 362 | int FPOffset = MBlazeFI->getFPStackOffset(); |
| 363 | int RAOffset = MBlazeFI->getRAStackOffset(); |
| 364 | |
| 365 | // Adjust stack : addi R1, R1, -imm |
Wesley Peck | a7c7b9d | 2010-12-12 22:02:31 +0000 | [diff] [blame] | 366 | BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1) |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 367 | .addReg(MBlaze::R1).addImm(-StackSize); |
| 368 | |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 369 | // swi R15, R1, stack_loc |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 370 | if (MFI->adjustsStack() || requiresRA) { |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 371 | BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) |
| 372 | .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); |
| 373 | } |
| 374 | |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 375 | if (hasFP(MF)) { |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 376 | // swi R19, R1, stack_loc |
| 377 | BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) |
| 378 | .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset); |
| 379 | |
| 380 | // add R19, R1, R0 |
| 381 | BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19) |
| 382 | .addReg(MBlaze::R1).addReg(MBlaze::R0); |
| 383 | } |
| 384 | } |
| 385 | |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 386 | void MBlazeFrameLowering::emitEpilogue(MachineFunction &MF, |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 387 | MachineBasicBlock &MBB) const { |
Jakob Stoklund Olesen | 4f28c1c | 2011-01-13 21:28:52 +0000 | [diff] [blame] | 388 | MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 389 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 390 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 391 | const MBlazeInstrInfo &TII = |
| 392 | *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); |
| 393 | |
| 394 | DebugLoc dl = MBBI->getDebugLoc(); |
| 395 | |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 396 | CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); |
| 397 | bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 398 | |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 399 | // Get the FI's where RA and FP are saved. |
| 400 | int FPOffset = MBlazeFI->getFPStackOffset(); |
| 401 | int RAOffset = MBlazeFI->getRAStackOffset(); |
| 402 | |
Anton Korobeynikov | d0c3817 | 2010-11-18 21:19:35 +0000 | [diff] [blame] | 403 | if (hasFP(MF)) { |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 404 | // add R1, R19, R0 |
| 405 | BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1) |
| 406 | .addReg(MBlaze::R19).addReg(MBlaze::R0); |
| 407 | |
| 408 | // lwi R19, R1, stack_loc |
| 409 | BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19) |
| 410 | .addReg(MBlaze::R1).addImm(FPOffset); |
| 411 | } |
| 412 | |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 413 | // lwi R15, R1, stack_loc |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 414 | if (MFI->adjustsStack() || requiresRA) { |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 415 | BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15) |
| 416 | .addReg(MBlaze::R1).addImm(RAOffset); |
| 417 | } |
| 418 | |
| 419 | // Get the number of bytes from FrameInfo |
| 420 | int StackSize = (int) MFI->getStackSize(); |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 421 | |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 422 | // addi R1, R1, imm |
| 423 | if (StackSize) { |
Wesley Peck | a7c7b9d | 2010-12-12 22:02:31 +0000 | [diff] [blame] | 424 | BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1) |
Anton Korobeynikov | 3346491 | 2010-11-15 00:06:54 +0000 | [diff] [blame] | 425 | .addReg(MBlaze::R1).addImm(StackSize); |
| 426 | } |
| 427 | } |
Wesley Peck | 8397be0 | 2010-12-09 03:42:04 +0000 | [diff] [blame] | 428 | |
Anton Korobeynikov | 16c29b5 | 2011-01-10 12:39:04 +0000 | [diff] [blame] | 429 | void MBlazeFrameLowering:: |
| 430 | processFunctionBeforeCalleeSavedScan(MachineFunction &MF, |
| 431 | RegScavenger *RS) const { |
Wesley Peck | 8397be0 | 2010-12-09 03:42:04 +0000 | [diff] [blame] | 432 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 433 | MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); |
Craig Topper | c89c744 | 2012-03-27 07:21:54 +0000 | [diff] [blame] | 434 | CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); |
| 435 | bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; |
Wesley Peck | 8397be0 | 2010-12-09 03:42:04 +0000 | [diff] [blame] | 436 | |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 437 | if (MFI->adjustsStack() || requiresRA) { |
Wesley Peck | 8397be0 | 2010-12-09 03:42:04 +0000 | [diff] [blame] | 438 | MBlazeFI->setRAStackOffset(0); |
| 439 | MFI->CreateFixedObject(4,0,true); |
| 440 | } |
| 441 | |
| 442 | if (hasFP(MF)) { |
| 443 | MBlazeFI->setFPStackOffset(4); |
| 444 | MFI->CreateFixedObject(4,4,true); |
| 445 | } |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 446 | |
Wesley Peck | dc9d87a | 2010-12-15 20:27:28 +0000 | [diff] [blame] | 447 | interruptFrameLayout(MF); |
Wesley Peck | eb13382 | 2010-12-12 20:52:31 +0000 | [diff] [blame] | 448 | analyzeFrameIndexes(MF); |
Wesley Peck | 8397be0 | 2010-12-09 03:42:04 +0000 | [diff] [blame] | 449 | } |