1234353Sdim//===-- MipsFrameLowering.cpp - Mips Frame Information --------------------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file contains the Mips implementation of TargetFrameLowering class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "MipsFrameLowering.h" 15249423Sdim#include "MCTargetDesc/MipsBaseInfo.h" 16234353Sdim#include "MipsAnalyzeImmediate.h" 17218885Sdim#include "MipsInstrInfo.h" 18218885Sdim#include "MipsMachineFunction.h" 19239462Sdim#include "MipsTargetMachine.h" 20218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 21218885Sdim#include "llvm/CodeGen/MachineFunction.h" 22218885Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 23218885Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 24218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 25249423Sdim#include "llvm/IR/DataLayout.h" 26249423Sdim#include "llvm/IR/Function.h" 27249423Sdim#include "llvm/Support/CommandLine.h" 28218885Sdim#include "llvm/Target/TargetOptions.h" 29218885Sdim 30218885Sdimusing namespace llvm; 31218885Sdim 32218885Sdim 33218885Sdim//===----------------------------------------------------------------------===// 34218885Sdim// 35218885Sdim// Stack Frame Processing methods 36218885Sdim// +----------------------------+ 37218885Sdim// 38218885Sdim// The stack is allocated decrementing the stack pointer on 39218885Sdim// the first instruction of a function prologue. Once decremented, 40218885Sdim// all stack references are done thought a positive offset 41218885Sdim// from the stack/frame pointer, so the stack is considering 42218885Sdim// to grow up! Otherwise terrible hacks would have to be made 43218885Sdim// to get this stack ABI compliant :) 44218885Sdim// 45218885Sdim// The stack frame required by the ABI (after call): 46218885Sdim// Offset 47218885Sdim// 48218885Sdim// 0 ---------- 49218885Sdim// 4 Args to pass 50218885Sdim// . saved $GP (used in PIC) 51218885Sdim// . Alloca allocations 52218885Sdim// . Local Area 53218885Sdim// . CPU "Callee Saved" Registers 54218885Sdim// . saved FP 55218885Sdim// . saved RA 56218885Sdim// . FPU "Callee Saved" Registers 57218885Sdim// StackSize ----------- 58218885Sdim// 59218885Sdim// Offset - offset from sp after stack allocation on function prologue 60218885Sdim// 61218885Sdim// The sp is the stack pointer subtracted/added from the stack size 62218885Sdim// at the Prologue/Epilogue 63218885Sdim// 64218885Sdim// References to the previous stack (to obtain arguments) are done 65218885Sdim// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) 66218885Sdim// 67218885Sdim// Examples: 68218885Sdim// - reference to the actual stack frame 69218885Sdim// for any local area var there is smt like : FI >= 0, StackOffset: 4 70218885Sdim// sw REGX, 4(SP) 71218885Sdim// 72218885Sdim// - reference to previous stack frame 73218885Sdim// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. 74218885Sdim// The emitted instruction will be something like: 75218885Sdim// lw REGX, 16+StackSize(SP) 76218885Sdim// 77218885Sdim// Since the total stack size is unknown on LowerFormalArguments, all 78218885Sdim// stack references (ObjectOffset) created to reference the function 79218885Sdim// arguments, are negative numbers. This way, on eliminateFrameIndex it's 80218885Sdim// possible to detect those references and the offsets are adjusted to 81218885Sdim// their real location. 82218885Sdim// 83218885Sdim//===----------------------------------------------------------------------===// 84218885Sdim 85239462Sdimconst MipsFrameLowering *MipsFrameLowering::create(MipsTargetMachine &TM, 86239462Sdim const MipsSubtarget &ST) { 87239462Sdim if (TM.getSubtargetImpl()->inMips16Mode()) 88239462Sdim return llvm::createMips16FrameLowering(ST); 89239462Sdim 90239462Sdim return llvm::createMipsSEFrameLowering(ST); 91239462Sdim} 92239462Sdim 93218885Sdim// hasFP - Return true if the specified function should have a dedicated frame 94218885Sdim// pointer register. This is true if the function has variable sized allocas or 95218885Sdim// if frame pointer elimination is disabled. 96218885Sdimbool MipsFrameLowering::hasFP(const MachineFunction &MF) const { 97218885Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 98234353Sdim return MF.getTarget().Options.DisableFramePointerElim(MF) || 99234353Sdim MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); 100218885Sdim} 101243830Sdim 102243830Sdimuint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { 103243830Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 104243830Sdim const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); 105243830Sdim 106243830Sdim int64_t Offset = 0; 107243830Sdim 108243830Sdim // Iterate over fixed sized objects. 109243830Sdim for (int I = MFI->getObjectIndexBegin(); I != 0; ++I) 110243830Sdim Offset = std::max(Offset, -MFI->getObjectOffset(I)); 111243830Sdim 112243830Sdim // Conservatively assume all callee-saved registers will be saved. 113243830Sdim for (const uint16_t *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) { 114243830Sdim unsigned Size = TRI.getMinimalPhysRegClass(*R)->getSize(); 115243830Sdim Offset = RoundUpToAlignment(Offset + Size, Size); 116243830Sdim } 117243830Sdim 118243830Sdim unsigned MaxAlign = MFI->getMaxAlignment(); 119243830Sdim 120243830Sdim // Check that MaxAlign is not zero if there is a stack object that is not a 121243830Sdim // callee-saved spill. 122243830Sdim assert(!MFI->getObjectIndexEnd() || MaxAlign); 123243830Sdim 124243830Sdim // Iterate over other objects. 125243830Sdim for (unsigned I = 0, E = MFI->getObjectIndexEnd(); I != E; ++I) 126243830Sdim Offset = RoundUpToAlignment(Offset + MFI->getObjectSize(I), MaxAlign); 127243830Sdim 128243830Sdim // Call frame. 129243830Sdim if (MFI->adjustsStack() && hasReservedCallFrame(MF)) 130243830Sdim Offset = RoundUpToAlignment(Offset + MFI->getMaxCallFrameSize(), 131243830Sdim std::max(MaxAlign, getStackAlignment())); 132243830Sdim 133243830Sdim return RoundUpToAlignment(Offset, getStackAlignment()); 134243830Sdim} 135