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)