MBlazeFrameLowering.cpp revision 16c29b5f285f375be53dabaa73e3e91107485fe4
116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov//=======- MBlazeFrameLowering.cpp - MBlaze Frame Information ------*- C++ -*-====// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the MBlaze implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#define DEBUG_TYPE "mblaze-frame-lowering" 15b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 1616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "MBlazeFrameLowering.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MBlazeInstrInfo.h" 1833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MBlazeMachineFunction.h" 19eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck#include "InstPrinter/MBlazeInstPrinter.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetData.h" 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 29b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck#include "llvm/Support/Debug.h" 30b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck#include "llvm/Support/ErrorHandling.h" 31b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck#include "llvm/Support/raw_ostream.h" 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Pecknamespace llvm { 36eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck cl::opt<bool> DisableStackAdjust( 37eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck "disable-mblaze-stack-adjust", 38eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck cl::init(false), 39eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck cl::desc("Disable MBlaze stack layout adjustment."), 40eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck cl::Hidden); 41eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck} 42eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 43b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peckstatic void replaceFrameIndexes(MachineFunction &MF, 44b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16> &FR) { 45b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 463d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 47b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin(); 48b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end(); 49b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 50b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB; 51b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (; FRI != FRE; ++FRI) { 52b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MFI->RemoveStackObject(FRI->first); 53b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck int NFI = MFI->CreateFixedObject(4, FRI->second, true); 543d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck MBlazeFI->recordReplacement(FRI->first, NFI); 55b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 56b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) { 57b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineBasicBlock::iterator MBB = MB->begin(); 58b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const MachineBasicBlock::iterator MBE = MB->end(); 59b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 60b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (; MBB != MBE; ++MBB) { 61b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineInstr::mop_iterator MIB = MBB->operands_begin(); 62b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const MachineInstr::mop_iterator MIE = MBB->operands_end(); 63b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 64b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) { 65b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck if (!MII->isFI() || MII->getIndex() != FRI->first) continue; 66b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n"); 67b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MII->setIndex(NFI); 68b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 69b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 70b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 71b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 72b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck} 73b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Stack Frame Processing methods 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// +----------------------------+ 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack is allocated decrementing the stack pointer on 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the first instruction of a function prologue. Once decremented, 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// all stack references are are done through a positive offset 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// from the stack/frame pointer, so the stack is considered 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to grow up. 8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 8533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 8633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 87eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peckstatic void analyzeFrameIndexes(MachineFunction &MF) { 88eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (DisableStackAdjust) return; 89eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 90eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 91eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 92eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck const MachineRegisterInfo &MRI = MF.getRegInfo(); 93eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 94eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineRegisterInfo::livein_iterator LII = MRI.livein_begin(); 95eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineRegisterInfo::livein_iterator LIE = MRI.livein_end(); 96eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn(); 97eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck SmallVector<MachineInstr*, 16> EraseInstr; 98b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16> FrameRelocate; 99eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 100eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock *MBB = MF.getBlockNumbered(0); 101eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator MIB = MBB->begin(); 102eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator MIE = MBB->end(); 103eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 104eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int StackAdjust = 0; 105eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int StackOffset = -28; 106b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 107b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // In this loop we are searching frame indexes that corrospond to incoming 108b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // arguments that are already in the stack. We look for instruction sequences 109b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // like the following: 110b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 111b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // LWI REG, FI1, 0 112b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // ... 113b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // SWI REG, FI2, 0 114b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 115b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // As long as there are no defs of REG in the ... part, we can eliminate 116b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // the SWI instruction because the value has already been stored to the 117b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack by the caller. All we need to do is locate FI at the correct 118b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack location according to the calling convensions. 119b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 120b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // Additionally, if the SWI operation kills the def of REG then we don't 121b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // need the LWI operation so we can erase it as well. 122eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) { 123eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { 124eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 || 125eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || 126eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck I->getOperand(1).getIndex() != LiveInFI[i]) continue; 127eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 128eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned FIReg = I->getOperand(0).getReg(); 129eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator SI = I; 130eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (SI++; SI != MIE; ++SI) { 131b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (!SI->getOperand(0).isReg() || 132b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck !SI->getOperand(1).isFI() || 133b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck SI->getOpcode() != MBlaze::SWI) continue; 134eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 135eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int FI = SI->getOperand(1).getIndex(); 136b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (SI->getOperand(0).getReg() != FIReg || 137b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MFI->isFixedObjectIndex(FI) || 138b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MFI->getObjectSize(FI) != 4) continue; 139b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 140eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (SI->getOperand(0).isDef()) break; 141eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 142b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (SI->getOperand(0).isKill()) { 143b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex() 144b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck << " removed\n"); 145eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck EraseInstr.push_back(I); 146b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck } 147b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 148eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck EraseInstr.push_back(SI); 149b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n"); 150b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 151b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck FrameRelocate.push_back(std::make_pair(FI,StackOffset)); 152b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n"); 153b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 154eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck StackOffset -= 4; 155eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck StackAdjust += 4; 156eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck break; 157eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 158eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 159eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 160b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 161b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // In this loop we are searching for frame indexes that corrospond to 162b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // incoming arguments that are in registers. We look for instruction 163b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // sequences like the following: 164b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 165b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // ... SWI REG, FI, 0 166b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 167b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // As long as the ... part does not define REG and if REG is an incoming 168b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // parameter register then we know that, according to ABI convensions, the 169b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // caller has allocated stack space for it already. Instead of allocating 170b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack space on our frame, we record the correct location in the callers 171b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // frame. 172b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { 173b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { 174b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (I->definesRegister(LI->first)) 175b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck break; 176eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 177b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 || 178b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || 179b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck I->getOperand(1).getIndex() < 0) continue; 180eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 181eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (I->getOperand(0).getReg() == LI->first) { 182b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck int FI = I->getOperand(1).getIndex(); 183b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MBlazeFI->recordLiveIn(FI); 184b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 185b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck int FILoc = 0; 186b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck switch (LI->first) { 187b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck default: llvm_unreachable("invalid incoming parameter!"); 188b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R5: FILoc = -4; break; 189b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R6: FILoc = -8; break; 190b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R7: FILoc = -12; break; 191b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R8: FILoc = -16; break; 192b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R9: FILoc = -20; break; 193b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R10: FILoc = -24; break; 194b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck } 195eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 196b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck StackAdjust += 4; 197b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck FrameRelocate.push_back(std::make_pair(FI,FILoc)); 198b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n"); 199b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck break; 200eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 201eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 202eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 203eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 204b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // Go ahead and erase all of the instructions that we determined were 205b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // no longer needed. 206eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (int i = 0, e = EraseInstr.size(); i < e; ++i) 207eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBB->erase(EraseInstr[i]); 208eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 209b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck // Replace all of the frame indexes that we have relocated with new 210b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck // fixed object frame indexes. 211b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck replaceFrameIndexes(MF, FrameRelocate); 212eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck} 213eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 214dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peckstatic void interruptFrameLayout(MachineFunction &MF) { 215dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const Function *F = MF.getFunction(); 216dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = F->getCallingConv(); 217dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 218dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // If this function is not using either the interrupt_handler 219dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // calling convention or the save_volatiles calling convention 220dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // then we don't need to do any additional frame layout. 221dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (CallConv != llvm::CallingConv::MBLAZE_INTR && 222dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck CallConv != llvm::CallingConv::MBLAZE_SVOL) 223dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck return; 224dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 225dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 226dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const MachineRegisterInfo &MRI = MF.getRegInfo(); 227dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const MBlazeInstrInfo &TII = 228dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 229dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 230dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Determine if the calling convention is the interrupt_handler 231dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // calling convention. Some pieces of the prologue and epilogue 232dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // only need to be emitted if we are lowering and interrupt handler. 233dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool isIntr = CallConv == llvm::CallingConv::MBLAZE_INTR; 234dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 235dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Determine where to put prologue and epilogue additions 236dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock &MENT = MF.front(); 237dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock &MEXT = MF.back(); 238dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 239dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock::iterator MENTI = MENT.begin(); 240dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock::iterator MEXTI = prior(MEXT.end()); 241dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 242dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc(); 243dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc(); 244dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 245dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Store the frame indexes generated during prologue additions for use 246dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // when we are generating the epilogue additions. 247dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck SmallVector<int, 10> VFI; 248dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 249dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the prologue SWI for R3 - R12 if needed. Note that R11 must 250dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // always have a SWI because it is used when processing RMSR. 251dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) { 252dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue; 253dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 254dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int FI = MFI->CreateStackObject(4,4,false,false); 255dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck VFI.push_back(FI); 256dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 257dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r) 258dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(FI).addImm(0); 259dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 260dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 261dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the prologue SWI for R17, R18 262dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int R17FI = MFI->CreateStackObject(4,4,false,false); 263dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int R18FI = MFI->CreateStackObject(4,4,false,false); 264dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 265dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17) 266dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R17FI).addImm(0); 267dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 268dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18) 269dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R18FI).addImm(0); 270dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 271dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Buid the prologue SWI and the epilogue LWI for RMSR if needed 272dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (isIntr) { 273dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int MSRFI = MFI->CreateStackObject(4,4,false,false); 274dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11) 275dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addReg(MBlaze::RMSR); 276dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11) 277dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(MSRFI).addImm(0); 278dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 279dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11) 280dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(MSRFI).addImm(0); 281dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR) 282dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addReg(MBlaze::R11); 283dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 284dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 285dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the epilogue LWI for R17, R18 286dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18) 287dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R18FI).addImm(0); 288dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 289dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17) 290dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R17FI).addImm(0); 291dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 292dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the epilogue LWI for R3 - R12 if needed 293dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) { 294dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (!MRI.isPhysRegUsed(r)) continue; 295dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r) 296dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(VFI[--i]).addImm(0); 297dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 298dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck} 299dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 300eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peckstatic void determineFrameLayout(MachineFunction &MF) { 301eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 302eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 303eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 304eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Replace the dummy '0' SPOffset by the negative offsets, as explained on 305eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid 306eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // the approach done by calculateFrameObjectOffsets to the stack frame. 307eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFI->adjustLoadArgsFI(MFI); 308eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFI->adjustStoreVarArgsFI(MFI); 309eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 310eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Get the number of bytes to allocate from the FrameInfo 311eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned FrameSize = MFI->getStackSize(); 312b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" ); 313b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 314eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Get the alignments provided by the target, and the maximum alignment 315eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // (if any) of the fixed frame objects. 316eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // unsigned MaxAlign = MFI->getMaxAlignment(); 31716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); 318eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned AlignMask = TargetAlign - 1; 319eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 320eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Make sure the frame is aligned. 321eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck FrameSize = (FrameSize + AlignMask) & ~AlignMask; 322eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MFI->setStackSize(FrameSize); 323b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" ); 324eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck} 325eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 3263d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peckint MBlazeFrameInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) 3273d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck const { 3283d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck const MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 3293d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck if (MBlazeFI->hasReplacement(FI)) 3303d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck FI = MBlazeFI->getReplacement(FI); 3313d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck return TargetFrameInfo::getFrameIndexOffset(MF,FI); 3323d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck} 3333d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck 334d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function should have a dedicated frame 335d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// pointer register. This is true if the function has variable sized allocas or 336d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// if frame pointer elimination is disabled. 33716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MBlazeFrameLowering::hasFP(const MachineFunction &MF) const { 338d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 339d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); 340d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 341d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 34216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const { 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 351dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 352dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 353dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 354eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Determine the correct frame layout 355eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck determineFrameLayout(MF); 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackSize = MFI->getStackSize(); 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // No need to allocate space on the stack. 361dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack : addi R1, R1, -imm 367a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1) 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(-StackSize); 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R15, R1, stack_loc 371dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 37233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 376d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R19, R1, stack_loc 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset); 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R19, R1, R0 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19) 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addReg(MBlaze::R0); 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 38633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering::emitEpilogue(MachineFunction &MF, 38833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = prior(MBB.end()); 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 391d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 39433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI->getDebugLoc(); 39633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 397dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 398dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 399dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the FI's where RA and FP are saved. 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 404d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 40533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R1, R19, R0 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1) 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R0); 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R19, R1, stack_loc 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19) 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(FPOffset); 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R15, R1, stack_loc 415dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15) 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(RAOffset); 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes from FrameInfo 42133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackSize = (int) MFI->getStackSize(); 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // addi R1, R1, imm 42433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 425a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1) 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(StackSize); 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 4298397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 43016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering:: 43116c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 43216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov RegScavenger *RS) const { 4338397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 4348397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 435dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 436dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 4378397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 438dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 4398397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setRAStackOffset(0); 4408397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,0,true); 4418397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 4428397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 4438397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (hasFP(MF)) { 4448397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setFPStackOffset(4); 4458397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,4,true); 4468397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 447eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 448dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck interruptFrameLayout(MF); 449eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck analyzeFrameIndexes(MF); 4508397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck} 451