131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MBlazeFrameLowering.cpp - MBlaze Frame Information ---------------====// 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 350861f5793a1834f02b522fb86fb037cd592c134fBenjamin Kramerstatic cl::opt<bool> MBDisableStackAdjust( 360861f5793a1834f02b522fb86fb037cd592c134fBenjamin Kramer "disable-mblaze-stack-adjust", 370861f5793a1834f02b522fb86fb037cd592c134fBenjamin Kramer cl::init(false), 380861f5793a1834f02b522fb86fb037cd592c134fBenjamin Kramer cl::desc("Disable MBlaze stack layout adjustment."), 390861f5793a1834f02b522fb86fb037cd592c134fBenjamin Kramer cl::Hidden); 40eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 41b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peckstatic void replaceFrameIndexes(MachineFunction &MF, 42b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16> &FR) { 43b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 443d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 45b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin(); 46b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end(); 47b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 48b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB; 49b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (; FRI != FRE; ++FRI) { 50b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MFI->RemoveStackObject(FRI->first); 51b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck int NFI = MFI->CreateFixedObject(4, FRI->second, true); 523d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck MBlazeFI->recordReplacement(FRI->first, NFI); 53b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 54b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) { 55b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineBasicBlock::iterator MBB = MB->begin(); 56b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const MachineBasicBlock::iterator MBE = MB->end(); 57b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 58b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (; MBB != MBE; ++MBB) { 59b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MachineInstr::mop_iterator MIB = MBB->operands_begin(); 60b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const MachineInstr::mop_iterator MIE = MBB->operands_end(); 61b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 62b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) { 63b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck if (!MII->isFI() || MII->getIndex() != FRI->first) continue; 64b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n"); 65b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MII->setIndex(NFI); 66b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 67b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 68b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 69b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck } 70b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck} 71b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Stack Frame Processing methods 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// +----------------------------+ 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack is allocated decrementing the stack pointer on 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the first instruction of a function prologue. Once decremented, 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// all stack references are are done through a positive offset 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// from the stack/frame pointer, so the stack is considered 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to grow up. 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 85eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peckstatic void analyzeFrameIndexes(MachineFunction &MF) { 86a18f08318afddc7352609c1765c39734c3e3c779Wesley Peck if (MBDisableStackAdjust) return; 87eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 88eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 89eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 90eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck const MachineRegisterInfo &MRI = MF.getRegInfo(); 91eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 92eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineRegisterInfo::livein_iterator LII = MRI.livein_begin(); 93eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineRegisterInfo::livein_iterator LIE = MRI.livein_end(); 94eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn(); 95eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck SmallVector<MachineInstr*, 16> EraseInstr; 96b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16> FrameRelocate; 97eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 98eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock *MBB = MF.getBlockNumbered(0); 99eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator MIB = MBB->begin(); 100eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator MIE = MBB->end(); 101eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 102eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int StackAdjust = 0; 103eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int StackOffset = -28; 104b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 105b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // In this loop we are searching frame indexes that corrospond to incoming 106b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // arguments that are already in the stack. We look for instruction sequences 107b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // like the following: 108b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 109b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // LWI REG, FI1, 0 110b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // ... 111b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // SWI REG, FI2, 0 112b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 113b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // As long as there are no defs of REG in the ... part, we can eliminate 114b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // the SWI instruction because the value has already been stored to the 115b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack by the caller. All we need to do is locate FI at the correct 116b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack location according to the calling convensions. 117b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 118b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // Additionally, if the SWI operation kills the def of REG then we don't 119b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // need the LWI operation so we can erase it as well. 120eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) { 121eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { 122eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 || 123eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || 124eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck I->getOperand(1).getIndex() != LiveInFI[i]) continue; 125eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 126eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned FIReg = I->getOperand(0).getReg(); 127eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineBasicBlock::iterator SI = I; 128eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (SI++; SI != MIE; ++SI) { 129b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (!SI->getOperand(0).isReg() || 130b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck !SI->getOperand(1).isFI() || 131b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck SI->getOpcode() != MBlaze::SWI) continue; 132eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 133eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck int FI = SI->getOperand(1).getIndex(); 134b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (SI->getOperand(0).getReg() != FIReg || 135b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MFI->isFixedObjectIndex(FI) || 136b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MFI->getObjectSize(FI) != 4) continue; 137b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 138eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (SI->getOperand(0).isDef()) break; 139eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 140b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (SI->getOperand(0).isKill()) { 141b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex() 142b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck << " removed\n"); 143eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck EraseInstr.push_back(I); 144b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck } 145b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 146eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck EraseInstr.push_back(SI); 147b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n"); 148b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 149b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck FrameRelocate.push_back(std::make_pair(FI,StackOffset)); 150b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n"); 151b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 152eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck StackOffset -= 4; 153eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck StackAdjust += 4; 154eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck break; 155eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 156eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 157eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 158b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 159b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // In this loop we are searching for frame indexes that corrospond to 160b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // incoming arguments that are in registers. We look for instruction 161b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // sequences like the following: 162b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 163b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // ... SWI REG, FI, 0 164b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // 165b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // As long as the ... part does not define REG and if REG is an incoming 166b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // parameter register then we know that, according to ABI convensions, the 167b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // caller has allocated stack space for it already. Instead of allocating 168b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // stack space on our frame, we record the correct location in the callers 169b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // frame. 170b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) { 171b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) { 172b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (I->definesRegister(LI->first)) 173b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck break; 174eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 175b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 || 176b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck !I->getOperand(1).isFI() || !I->getOperand(0).isReg() || 177b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck I->getOperand(1).getIndex() < 0) continue; 178eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 179eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (I->getOperand(0).getReg() == LI->first) { 180b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck int FI = I->getOperand(1).getIndex(); 181b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck MBlazeFI->recordLiveIn(FI); 182b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 183b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck int FILoc = 0; 184b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck switch (LI->first) { 185b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck default: llvm_unreachable("invalid incoming parameter!"); 186b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R5: FILoc = -4; break; 187b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R6: FILoc = -8; break; 188b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R7: FILoc = -12; break; 189b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R8: FILoc = -16; break; 190b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R9: FILoc = -20; break; 191b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck case MBlaze::R10: FILoc = -24; break; 192b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck } 193eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 194b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck StackAdjust += 4; 195b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck FrameRelocate.push_back(std::make_pair(FI,FILoc)); 196b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n"); 197b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck break; 198eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 199eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 200eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck } 201eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 202b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // Go ahead and erase all of the instructions that we determined were 203b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck // no longer needed. 204eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck for (int i = 0, e = EraseInstr.size(); i < e; ++i) 205eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBB->erase(EraseInstr[i]); 206eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 207b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck // Replace all of the frame indexes that we have relocated with new 208b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck // fixed object frame indexes. 209b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck replaceFrameIndexes(MF, FrameRelocate); 210eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck} 211eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 212dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peckstatic void interruptFrameLayout(MachineFunction &MF) { 213dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const Function *F = MF.getFunction(); 214c89c744b69cecac576317a98322fd295e36e9886Craig Topper CallingConv::ID CallConv = F->getCallingConv(); 215dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 216dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // If this function is not using either the interrupt_handler 217dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // calling convention or the save_volatiles calling convention 218dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // then we don't need to do any additional frame layout. 219c89c744b69cecac576317a98322fd295e36e9886Craig Topper if (CallConv != CallingConv::MBLAZE_INTR && 220c89c744b69cecac576317a98322fd295e36e9886Craig Topper CallConv != CallingConv::MBLAZE_SVOL) 221dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck return; 222dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 223dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 224dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const MachineRegisterInfo &MRI = MF.getRegInfo(); 225dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck const MBlazeInstrInfo &TII = 226dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 227dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 228dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Determine if the calling convention is the interrupt_handler 229dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // calling convention. Some pieces of the prologue and epilogue 230dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // only need to be emitted if we are lowering and interrupt handler. 231c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool isIntr = CallConv == CallingConv::MBLAZE_INTR; 232dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 233dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Determine where to put prologue and epilogue additions 234dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock &MENT = MF.front(); 235dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock &MEXT = MF.back(); 236dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 237dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock::iterator MENTI = MENT.begin(); 238dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck MachineBasicBlock::iterator MEXTI = prior(MEXT.end()); 239dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 240dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc(); 241dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc(); 242dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 243dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Store the frame indexes generated during prologue additions for use 244dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // when we are generating the epilogue additions. 245dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck SmallVector<int, 10> VFI; 246dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 247dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the prologue SWI for R3 - R12 if needed. Note that R11 must 248dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // always have a SWI because it is used when processing RMSR. 249dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) { 250dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue; 251dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 252dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int FI = MFI->CreateStackObject(4,4,false,false); 253dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck VFI.push_back(FI); 254dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 255dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r) 256dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(FI).addImm(0); 257dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 258dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 259dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the prologue SWI for R17, R18 260dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int R17FI = MFI->CreateStackObject(4,4,false,false); 261dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int R18FI = MFI->CreateStackObject(4,4,false,false); 262dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 263dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17) 264dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R17FI).addImm(0); 265dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 266dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18) 267dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R18FI).addImm(0); 268dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 269dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Buid the prologue SWI and the epilogue LWI for RMSR if needed 270dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (isIntr) { 271dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck int MSRFI = MFI->CreateStackObject(4,4,false,false); 272dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11) 273dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addReg(MBlaze::RMSR); 274dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11) 275dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(MSRFI).addImm(0); 276dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 277dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11) 278dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(MSRFI).addImm(0); 279dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR) 280dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addReg(MBlaze::R11); 281dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 282dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 283dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the epilogue LWI for R17, R18 284dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18) 285dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R18FI).addImm(0); 286dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 287dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17) 288dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(R17FI).addImm(0); 289dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 290dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck // Build the epilogue LWI for R3 - R12 if needed 291dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) { 292dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (!MRI.isPhysRegUsed(r)) continue; 293dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r) 294dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck .addFrameIndex(VFI[--i]).addImm(0); 295dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck } 296dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck} 297dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 298eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peckstatic void determineFrameLayout(MachineFunction &MF) { 299eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 300eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 301eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 302eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Replace the dummy '0' SPOffset by the negative offsets, as explained on 303eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid 304eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // the approach done by calculateFrameObjectOffsets to the stack frame. 305eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFI->adjustLoadArgsFI(MFI); 306eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFI->adjustStoreVarArgsFI(MFI); 307eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 308eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Get the number of bytes to allocate from the FrameInfo 309eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned FrameSize = MFI->getStackSize(); 310b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" ); 311b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 312eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Get the alignments provided by the target, and the maximum alignment 313eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // (if any) of the fixed frame objects. 314eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // unsigned MaxAlign = MFI->getMaxAlignment(); 31516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); 316eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned AlignMask = TargetAlign - 1; 317eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 318eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Make sure the frame is aligned. 319eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck FrameSize = (FrameSize + AlignMask) & ~AlignMask; 320eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MFI->setStackSize(FrameSize); 321b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" ); 322eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck} 323eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 3242c8bd754ded25cb5b33f48a794014e452bcdf59fAnton Korobeynikovint MBlazeFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) 3253d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck const { 3263d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck const MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 3273d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck if (MBlazeFI->hasReplacement(FI)) 3283d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck FI = MBlazeFI->getReplacement(FI); 3292c8bd754ded25cb5b33f48a794014e452bcdf59fAnton Korobeynikov return TargetFrameLowering::getFrameIndexOffset(MF,FI); 3303d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck} 3313d2148f5ace1292dcc12c37e9d0e13dee5220a5aWesley Peck 332d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function should have a dedicated frame 333d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// pointer register. This is true if the function has variable sized allocas or 334d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// if frame pointer elimination is disabled. 33516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MBlazeFrameLowering::hasFP(const MachineFunction &MF) const { 336d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 3378a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return MF.getTarget().Options.DisableFramePointerElim(MF) || 3388a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MFI->hasVarSizedObjects(); 339d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 340d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 34116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const { 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 350c89c744b69cecac576317a98322fd295e36e9886Craig Topper CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 351c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; 352dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 353eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Determine the correct frame layout 354eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck determineFrameLayout(MF); 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackSize = MFI->getStackSize(); 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // No need to allocate space on the stack. 360dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; 36133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack : addi R1, R1, -imm 366a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1) 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(-StackSize); 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R15, R1, stack_loc 370dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 37133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 37233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 375d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 37633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R19, R1, stack_loc 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset); 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R19, R1, R0 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19) 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addReg(MBlaze::R0); 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering::emitEpilogue(MachineFunction &MF, 38733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 3884f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 390d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI->getDebugLoc(); 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 396c89c744b69cecac576317a98322fd295e36e9886Craig Topper CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 397c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; 398dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 39933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the FI's where RA and FP are saved. 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 403d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 40433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R1, R19, R0 40533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1) 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R0); 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R19, R1, stack_loc 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19) 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(FPOffset); 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R15, R1, stack_loc 414dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 41533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15) 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(RAOffset); 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes from FrameInfo 42033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackSize = (int) MFI->getStackSize(); 42133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // addi R1, R1, imm 42333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 424a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1) 42533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(StackSize); 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 4288397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 42916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MBlazeFrameLowering:: 43016c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 43116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov RegScavenger *RS) const { 4328397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 4338397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 434c89c744b69cecac576317a98322fd295e36e9886Craig Topper CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 435c89c744b69cecac576317a98322fd295e36e9886Craig Topper bool requiresRA = CallConv == CallingConv::MBLAZE_INTR; 4368397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 437dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 4388397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setRAStackOffset(0); 4398397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,0,true); 4408397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 4418397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 4428397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (hasFP(MF)) { 4438397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setFPStackOffset(4); 4448397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,4,true); 4458397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 446eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 447dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck interruptFrameLayout(MF); 448eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck analyzeFrameIndexes(MF); 4498397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck} 450