SparcFrameLowering.cpp revision 700ed80d3da5e98e05ceb90e9bfb66058581a6db
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains the Sparc implementation of TargetFrameLowering class. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SparcFrameLowering.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "SparcInstrInfo.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "SparcMachineFunctionInfo.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineModuleInfo.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineRegisterInfo.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/IR/DataLayout.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/IR/Function.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/CommandLine.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetOptions.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock &MBB = MF.front(); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineFrameInfo *MFI = MF.getFrameInfo(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SparcInstrInfo &TII = 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock::iterator MBBI = MBB.begin(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the number of bytes to allocate from the FrameInfo 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumBytes = (int) MFI->getStackSize(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit the correct save instruction based on the number of bytes in 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // the frame. Minimum stack frame size according to V8 ABI is: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 16 words for register window spill 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1 word for address of returned aggregate-value 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // + 6 words for passing parameters on the stack 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ---------- 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 23 words * 4 bytes per word = 92 bytes 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NumBytes += 92; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Round up to next doubleword boundary -- a double-word boundary 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is required by the ABI. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NumBytes = (NumBytes + 7) & ~7; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NumBytes = -NumBytes; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NumBytes >= -4096) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, MBBI, dl, TII.get(SP::SAVEri), SP::O6) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .addReg(SP::O6).addImm(NumBytes); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit this the hard way. This clobbers G1 which we always know is 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // available here. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned OffHi = (unsigned)NumBytes >> 10U; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit G1 = G1 + I6 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1)); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, MBBI, dl, TII.get(SP::SAVErr), SP::O6) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .addReg(SP::O6).addReg(SP::G1); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SparcFrameLowering:: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock::iterator I) const { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineInstr &MI = *I; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugLoc dl = MI.getDebugLoc(); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int Size = MI.getOperand(0).getImm(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MI.getOpcode() == SP::ADJCALLSTACKDOWN) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Size = -Size; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SparcInstrInfo &TII = 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Size) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, I, dl, TII.get(SP::ADDri), SP::O6).addReg(SP::O6).addImm(Size); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MBB.erase(I); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SparcFrameLowering::emitEpilogue(MachineFunction &MF, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock &MBB) const { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SparcInstrInfo &TII = 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugLoc dl = MBBI->getDebugLoc(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(MBBI->getOpcode() == SP::RETL && 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Can only put epilog before 'retl' instruction!"); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .addReg(SP::G0); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)