MipsFrameLowering.cpp revision 218885
1107665Simp//=======- MipsFrameLowering.cpp - Mips Frame Information ------*- C++ -*-====// 2113785Simp// 3107665Simp// The LLVM Compiler Infrastructure 4107665Simp// 5107665Simp// This file is distributed under the University of Illinois Open Source 6107665Simp// License. See LICENSE.TXT for details. 7107665Simp// 8107665Simp//===----------------------------------------------------------------------===// 9107665Simp// 10107665Simp// This file contains the Mips implementation of TargetFrameLowering class. 11107665Simp// 12107665Simp//===----------------------------------------------------------------------===// 13107665Simp 14107665Simp#include "MipsFrameLowering.h" 15107665Simp#include "MipsInstrInfo.h" 16107665Simp#include "MipsMachineFunction.h" 17107665Simp#include "llvm/Function.h" 18107665Simp#include "llvm/CodeGen/MachineFrameInfo.h" 19107665Simp#include "llvm/CodeGen/MachineFunction.h" 20107665Simp#include "llvm/CodeGen/MachineInstrBuilder.h" 21107665Simp#include "llvm/CodeGen/MachineModuleInfo.h" 22107665Simp#include "llvm/CodeGen/MachineRegisterInfo.h" 23107665Simp#include "llvm/Target/TargetData.h" 24107665Simp#include "llvm/Target/TargetOptions.h" 25107665Simp#include "llvm/Support/CommandLine.h" 26107665Simp 27107665Simpusing namespace llvm; 28107665Simp 29107665Simp 30107665Simp//===----------------------------------------------------------------------===// 31107665Simp// 32107665Simp// Stack Frame Processing methods 33107665Simp// +----------------------------+ 34107665Simp// 35107665Simp// The stack is allocated decrementing the stack pointer on 36107665Simp// the first instruction of a function prologue. Once decremented, 37107665Simp// all stack references are done thought a positive offset 38107665Simp// from the stack/frame pointer, so the stack is considering 39107665Simp// to grow up! Otherwise terrible hacks would have to be made 40107665Simp// to get this stack ABI compliant :) 41113787Simp// 42107665Simp// The stack frame required by the ABI (after call): 43108014Simp// Offset 44107665Simp// 45107665Simp// 0 ---------- 46107665Simp// 4 Args to pass 47107665Simp// . saved $GP (used in PIC) 48108014Simp// . Alloca allocations 49107665Simp// . Local Area 50107665Simp// . CPU "Callee Saved" Registers 51107665Simp// . saved FP 52107665Simp// . saved RA 53107665Simp// . FPU "Callee Saved" Registers 54108783Simp// StackSize ----------- 55107665Simp// 56107665Simp// Offset - offset from sp after stack allocation on function prologue 57107665Simp// 58107665Simp// The sp is the stack pointer subtracted/added from the stack size 59107665Simp// at the Prologue/Epilogue 60107665Simp// 61107665Simp// References to the previous stack (to obtain arguments) are done 62113787Simp// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) 63107665Simp// 64107665Simp// Examples: 65107665Simp// - reference to the actual stack frame 66107665Simp// for any local area var there is smt like : FI >= 0, StackOffset: 4 67107665Simp// sw REGX, 4(SP) 68107665Simp// 69108783Simp// - reference to previous stack frame 70108783Simp// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. 71108783Simp// The emitted instruction will be something like: 72108783Simp// lw REGX, 16+StackSize(SP) 73107665Simp// 74107665Simp// Since the total stack size is unknown on LowerFormalArguments, all 75107665Simp// stack references (ObjectOffset) created to reference the function 76107665Simp// arguments, are negative numbers. This way, on eliminateFrameIndex it's 77107665Simp// possible to detect those references and the offsets are adjusted to 78107665Simp// their real location. 79108783Simp// 80108783Simp//===----------------------------------------------------------------------===// 81108783Simp 82108783Simp// hasFP - Return true if the specified function should have a dedicated frame 83108783Simp// pointer register. This is true if the function has variable sized allocas or 84108783Simp// if frame pointer elimination is disabled. 85108783Simpbool MipsFrameLowering::hasFP(const MachineFunction &MF) const { 86108783Simp const MachineFrameInfo *MFI = MF.getFrameInfo(); 87108783Simp return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); 88108783Simp} 89107665Simp 90107665Simpvoid MipsFrameLowering::adjustMipsStackFrame(MachineFunction &MF) const { 91107665Simp MachineFrameInfo *MFI = MF.getFrameInfo(); 92107665Simp MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 93107665Simp const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 94107665Simp unsigned StackAlign = getStackAlignment(); 95107665Simp unsigned RegSize = STI.isGP32bit() ? 4 : 8; 96107665Simp bool HasGP = MipsFI->needGPSaveRestore(); 97107665Simp 98107665Simp // Min and Max CSI FrameIndex. 99107665Simp int MinCSFI = -1, MaxCSFI = -1; 100107665Simp 101107665Simp // See the description at MipsMachineFunction.h 102107665Simp int TopCPUSavedRegOff = -1, TopFPUSavedRegOff = -1; 103107665Simp 104107665Simp // Replace the dummy '0' SPOffset by the negative offsets, as explained on 105107665Simp // LowerFormalArguments. Leaving '0' for while is necessary to avoid the 106107665Simp // approach done by calculateFrameObjectOffsets to the stack frame. 107107665Simp MipsFI->adjustLoadArgsFI(MFI); 108107665Simp MipsFI->adjustStoreVarArgsFI(MFI); 109107665Simp 110107665Simp // It happens that the default stack frame allocation order does not directly 111107665Simp // map to the convention used for mips. So we must fix it. We move the callee 112107665Simp // save register slots after the local variables area, as described in the 113107665Simp // stack frame above. 114107665Simp unsigned CalleeSavedAreaSize = 0; 115107665Simp if (!CSI.empty()) { 116107665Simp MinCSFI = CSI[0].getFrameIdx(); 117108014Simp MaxCSFI = CSI[CSI.size()-1].getFrameIdx(); 118107665Simp } 119107665Simp for (unsigned i = 0, e = CSI.size(); i != e; ++i) 120107665Simp CalleeSavedAreaSize += MFI->getObjectAlignment(CSI[i].getFrameIdx()); 121107665Simp 122107665Simp unsigned StackOffset = HasGP ? (MipsFI->getGPStackOffset()+RegSize) 123107665Simp : (STI.isABI_O32() ? 16 : 0); 124108014Simp 125107665Simp // Adjust local variables. They should come on the stack right 126107665Simp // after the arguments. 127107665Simp int LastOffsetFI = -1; 128107665Simp for (int i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 129107665Simp if (i >= MinCSFI && i <= MaxCSFI) 130107665Simp continue; 131107665Simp if (MFI->isDeadObjectIndex(i)) 132107665Simp continue; 133107665Simp unsigned Offset = 134107665Simp StackOffset + MFI->getObjectOffset(i) - CalleeSavedAreaSize; 135107665Simp if (LastOffsetFI == -1) 136107665Simp LastOffsetFI = i; 137107665Simp if (Offset > MFI->getObjectOffset(LastOffsetFI)) 138107665Simp LastOffsetFI = i; 139107665Simp MFI->setObjectOffset(i, Offset); 140107665Simp } 141107665Simp 142107665Simp // Adjust CPU Callee Saved Registers Area. Registers RA and FP must 143108783Simp // be saved in this CPU Area. This whole area must be aligned to the 144107665Simp // default Stack Alignment requirements. 145107665Simp if (LastOffsetFI >= 0) 146107665Simp StackOffset = MFI->getObjectOffset(LastOffsetFI)+ 147107665Simp MFI->getObjectSize(LastOffsetFI); 148107665Simp StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign); 149107665Simp 150107665Simp for (unsigned i = 0, e = CSI.size(); i != e ; ++i) { 151107665Simp unsigned Reg = CSI[i].getReg(); 152107665Simp if (!Mips::CPURegsRegisterClass->contains(Reg)) 153107665Simp break; 154107665Simp MFI->setObjectOffset(CSI[i].getFrameIdx(), StackOffset); 155107665Simp TopCPUSavedRegOff = StackOffset; 156107665Simp StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx()); 157107665Simp } 158107665Simp 159107665Simp // Stack locations for FP and RA. If only one of them is used, 160107665Simp // the space must be allocated for both, otherwise no space at all. 161107665Simp if (hasFP(MF) || MFI->adjustsStack()) { 162107665Simp // FP stack location 163107665Simp MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true), 164107665Simp StackOffset); 165107665Simp MipsFI->setFPStackOffset(StackOffset); 166107665Simp TopCPUSavedRegOff = StackOffset; 167107665Simp StackOffset += RegSize; 168107665Simp 169107665Simp // SP stack location 170108014Simp MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true), 171108783Simp StackOffset); 172108783Simp MipsFI->setRAStackOffset(StackOffset); 173107665Simp StackOffset += RegSize; 174108783Simp 175107665Simp if (MFI->adjustsStack()) 176107665Simp TopCPUSavedRegOff += RegSize; 177108014Simp } 178108783Simp 179108783Simp StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign); 180107665Simp 181107665Simp // Adjust FPU Callee Saved Registers Area. This Area must be 182107665Simp // aligned to the default Stack Alignment requirements. 183107665Simp for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 184107665Simp unsigned Reg = CSI[i].getReg(); 185107665Simp if (Mips::CPURegsRegisterClass->contains(Reg)) 186107665Simp continue; 187107665Simp MFI->setObjectOffset(CSI[i].getFrameIdx(), StackOffset); 188107665Simp TopFPUSavedRegOff = StackOffset; 189107665Simp StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx()); 190107665Simp } 191107665Simp StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign); 192107665Simp 193107665Simp // Update frame info 194107665Simp MFI->setStackSize(StackOffset); 195107665Simp 196107665Simp // Recalculate the final tops offset. The final values must be '0' 197107665Simp // if there isn't a callee saved register for CPU or FPU, otherwise 198107665Simp // a negative offset is needed. 199107665Simp if (TopCPUSavedRegOff >= 0) 200107665Simp MipsFI->setCPUTopSavedRegOff(TopCPUSavedRegOff-StackOffset); 201107665Simp 202107665Simp if (TopFPUSavedRegOff >= 0) 203107665Simp MipsFI->setFPUTopSavedRegOff(TopFPUSavedRegOff-StackOffset); 204107665Simp} 205107665Simp 206107665Simpvoid MipsFrameLowering::emitPrologue(MachineFunction &MF) const { 207107665Simp MachineBasicBlock &MBB = MF.front(); 208107665Simp MachineFrameInfo *MFI = MF.getFrameInfo(); 209107665Simp MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 210107665Simp const MipsRegisterInfo *RegInfo = 211107665Simp static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 212107665Simp const MipsInstrInfo &TII = 213107665Simp *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 214107665Simp MachineBasicBlock::iterator MBBI = MBB.begin(); 215107665Simp DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 216107665Simp bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); 217107665Simp 218107665Simp // Get the right frame order for Mips. 219107665Simp adjustMipsStackFrame(MF); 220107665Simp 221107665Simp // Get the number of bytes to allocate from the FrameInfo. 222107665Simp unsigned StackSize = MFI->getStackSize(); 223107665Simp 224107665Simp // No need to allocate space on the stack. 225107665Simp if (StackSize == 0 && !MFI->adjustsStack()) return; 226107665Simp 227107665Simp int FPOffset = MipsFI->getFPStackOffset(); 228107665Simp int RAOffset = MipsFI->getRAStackOffset(); 229107665Simp 230107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER)); 231107665Simp 232107665Simp // TODO: check need from GP here. 233107665Simp if (isPIC && STI.isABI_O32()) 234107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::CPLOAD)) 235107665Simp .addReg(RegInfo->getPICCallReg()); 236107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); 237107665Simp 238107665Simp // Adjust stack : addi sp, sp, (-imm) 239107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP) 240107665Simp .addReg(Mips::SP).addImm(-StackSize); 241107665Simp 242107665Simp // Save the return address only if the function isnt a leaf one. 243107665Simp // sw $ra, stack_loc($sp) 244107665Simp if (MFI->adjustsStack()) { 245108014Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::SW)) 246107665Simp .addReg(Mips::RA).addImm(RAOffset).addReg(Mips::SP); 247108783Simp } 248108783Simp 249108783Simp // if framepointer enabled, save it and set it 250108783Simp // to point to the stack pointer 251107665Simp if (hasFP(MF)) { 252107665Simp // sw $fp,stack_loc($sp) 253107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::SW)) 254108014Simp .addReg(Mips::FP).addImm(FPOffset).addReg(Mips::SP); 255108783Simp 256107665Simp // move $fp, $sp 257108783Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP) 258108783Simp .addReg(Mips::SP).addReg(Mips::ZERO); 259108783Simp } 260108783Simp 261108783Simp // Restore GP from the saved stack location 262107665Simp if (MipsFI->needGPSaveRestore()) 263107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)) 264107665Simp .addImm(MipsFI->getGPStackOffset()); 265107665Simp} 266108014Simp 267107665Simpvoid MipsFrameLowering::emitEpilogue(MachineFunction &MF, 268107665Simp MachineBasicBlock &MBB) const { 269107665Simp MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 270108014Simp MachineFrameInfo *MFI = MF.getFrameInfo(); 271107665Simp MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 272108014Simp const MipsInstrInfo &TII = 273108014Simp *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 274108014Simp DebugLoc dl = MBBI->getDebugLoc(); 275108783Simp 276108783Simp // Get the number of bytes from FrameInfo 277108783Simp int NumBytes = (int) MFI->getStackSize(); 278108783Simp 279108014Simp // Get the FI's where RA and FP are saved. 280108014Simp int FPOffset = MipsFI->getFPStackOffset(); 281107665Simp int RAOffset = MipsFI->getRAStackOffset(); 282107665Simp 283107665Simp // if framepointer enabled, restore it and restore the 284107665Simp // stack pointer 285107665Simp if (hasFP(MF)) { 286107665Simp // move $sp, $fp 287107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::SP) 288107665Simp .addReg(Mips::FP).addReg(Mips::ZERO); 289107665Simp 290107665Simp // lw $fp,stack_loc($sp) 291107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::FP) 292107665Simp .addImm(FPOffset).addReg(Mips::SP); 293108783Simp } 294107665Simp 295107665Simp // Restore the return address only if the function isnt a leaf one. 296107665Simp // lw $ra, stack_loc($sp) 297107665Simp if (MFI->adjustsStack()) { 298107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::RA) 299107665Simp .addImm(RAOffset).addReg(Mips::SP); 300107665Simp } 301107665Simp 302107665Simp // adjust stack : insert addi sp, sp, (imm) 303107665Simp if (NumBytes) { 304107665Simp BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP) 305107665Simp .addReg(Mips::SP).addImm(NumBytes); 306108783Simp } 307108783Simp} 308107665Simp 309107665Simpvoid MipsFrameLowering:: 310107665SimpprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const { 311107665Simp const MipsRegisterInfo *RegInfo = 312107665Simp static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 313107665Simp RegInfo->processFunctionBeforeFrameFinalized(MF); 314107665Simp} 315108783Simp