MBlazeFrameLowering.cpp revision b020808f0d29433e84d6ab4c57a7ec54eed41860
133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//=======- MBlazeFrameInfo.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// 1033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file contains the MBlaze implementation of TargetFrameInfo class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 14b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck#define DEBUG_TYPE "mblaze-frame-info" 15b4aec92453f2ba1db8a9534fb38a99c01a96ffabWesley Peck 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MBlazeFrameInfo.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(); 46b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin(); 47b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end(); 48b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck 49b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB; 50b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck for (; FRI != FRE; ++FRI) { 51b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck MFI->RemoveStackObject(FRI->first); 52b020808f0d29433e84d6ab4c57a7ec54eed41860Wesley Peck int NFI = MFI->CreateFixedObject(4, FRI->second, true); 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) { 86eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck if (DisableStackAdjust) 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(); 214dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::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. 219dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (CallConv != llvm::CallingConv::MBLAZE_INTR && 220dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck CallConv != llvm::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. 231dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool isIntr = CallConv == llvm::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(); 315eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck unsigned TargetAlign = MF.getTarget().getFrameInfo()->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 324d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function should have a dedicated frame 325d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// pointer register. This is true if the function has variable sized allocas or 326d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// if frame pointer elimination is disabled. 327d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikovbool MBlazeFrameInfo::hasFP(const MachineFunction &MF) const { 328d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 329d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); 330d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 331d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const { 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 341dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 342dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 343dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 344eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck // Determine the correct frame layout 345eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck determineFrameLayout(MF); 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackSize = MFI->getStackSize(); 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // No need to allocate space on the stack. 351dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; 35233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 35433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack : addi R1, R1, -imm 357a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1) 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(-StackSize); 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R15, R1, stack_loc 361dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 366d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // swi R19, R1, stack_loc 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset); 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R19, R1, R0 37233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19) 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addReg(MBlaze::R0); 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 37633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid MBlazeFrameInfo::emitEpilogue(MachineFunction &MF, 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = prior(MBB.end()); 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 381d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MBlazeInstrInfo &TII = 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI->getDebugLoc(); 38633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 387dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 388dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 389dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the FI's where RA and FP are saved. 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = MBlazeFI->getFPStackOffset(); 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int RAOffset = MBlazeFI->getRAStackOffset(); 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 394d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // add R1, R19, R0 39633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1) 39733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R19).addReg(MBlaze::R0); 39833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R19, R1, stack_loc 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19) 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(FPOffset); 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 40433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // lwi R15, R1, stack_loc 405dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15) 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(RAOffset); 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes from FrameInfo 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackSize = (int) MFI->getStackSize(); 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // addi R1, R1, imm 41433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 415a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1) 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MBlaze::R1).addImm(StackSize); 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 4198397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 4208397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peckvoid MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) 4218397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck const { 4228397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 4238397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 424dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); 425dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; 4268397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 427dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck if (MFI->adjustsStack() || requiresRA) { 4288397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setRAStackOffset(0); 4298397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,0,true); 4308397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 4318397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 4328397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (hasFP(MF)) { 4338397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->setFPStackOffset(4); 4348397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(4,4,true); 4358397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck } 436eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck 437dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck interruptFrameLayout(MF); 438eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck analyzeFrameIndexes(MF); 4398397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck} 440