blob: afa8411802d3da3ec941a84bb39aecaa6e860c67 [file] [log] [blame]
Jia Liu31d157a2012-02-18 12:03:15 +00001//===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===//
Anton Korobeynikov33464912010-11-15 00:06:54 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000010// This file contains the Sparc implementation of TargetFrameLowering class.
Anton Korobeynikov33464912010-11-15 00:06:54 +000011//
12//===----------------------------------------------------------------------===//
13
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000014#include "SparcFrameLowering.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000015#include "SparcInstrInfo.h"
16#include "SparcMachineFunctionInfo.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000017#include "llvm/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineModuleInfo.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000022#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Function.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000024#include "llvm/Support/CommandLine.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000025#include "llvm/Target/TargetOptions.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000026
27using namespace llvm;
28
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000029void SparcFrameLowering::emitPrologue(MachineFunction &MF) const {
Anton Korobeynikov33464912010-11-15 00:06:54 +000030 MachineBasicBlock &MBB = MF.front();
31 MachineFrameInfo *MFI = MF.getFrameInfo();
32 const SparcInstrInfo &TII =
33 *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo());
34 MachineBasicBlock::iterator MBBI = MBB.begin();
35 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
36
37 // Get the number of bytes to allocate from the FrameInfo
38 int NumBytes = (int) MFI->getStackSize();
39
Jakob Stoklund Olesen6ed92842013-04-09 04:37:47 +000040 if (SubTarget.is64Bit()) {
41 // All 64-bit stack frames must be 16-byte aligned, and must reserve space
42 // for spilling the 16 window registers at %sp+BIAS..%sp+BIAS+128.
43 NumBytes += 128;
44 // Frames with calls must also reserve space for 6 outgoing arguments
45 // whether they are used or not. LowerCall_64 takes care of that.
46 assert(NumBytes % 16 == 0 && "Stack size not 16-byte aligned");
47 } else {
48 // Emit the correct save instruction based on the number of bytes in
49 // the frame. Minimum stack frame size according to V8 ABI is:
50 // 16 words for register window spill
51 // 1 word for address of returned aggregate-value
52 // + 6 words for passing parameters on the stack
53 // ----------
54 // 23 words * 4 bytes per word = 92 bytes
55 NumBytes += 92;
Anton Korobeynikov33464912010-11-15 00:06:54 +000056
Jakob Stoklund Olesen6ed92842013-04-09 04:37:47 +000057 // Round up to next doubleword boundary -- a double-word boundary
58 // is required by the ABI.
59 NumBytes = RoundUpToAlignment(NumBytes, 8);
60 }
Anton Korobeynikov33464912010-11-15 00:06:54 +000061 NumBytes = -NumBytes;
62
63 if (NumBytes >= -4096) {
64 BuildMI(MBB, MBBI, dl, TII.get(SP::SAVEri), SP::O6)
65 .addReg(SP::O6).addImm(NumBytes);
66 } else {
67 // Emit this the hard way. This clobbers G1 which we always know is
68 // available here.
69 unsigned OffHi = (unsigned)NumBytes >> 10U;
70 BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi);
71 // Emit G1 = G1 + I6
72 BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
73 .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1));
74 BuildMI(MBB, MBBI, dl, TII.get(SP::SAVErr), SP::O6)
75 .addReg(SP::O6).addReg(SP::G1);
76 }
77}
78
Eli Bendersky700ed802013-02-21 20:05:00 +000079void SparcFrameLowering::
80eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
81 MachineBasicBlock::iterator I) const {
Jakob Stoklund Olesen6ed92842013-04-09 04:37:47 +000082 if (!hasReservedCallFrame(MF)) {
83 MachineInstr &MI = *I;
84 DebugLoc DL = MI.getDebugLoc();
85 int Size = MI.getOperand(0).getImm();
86 if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
87 Size = -Size;
88 const SparcInstrInfo &TII =
89 *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo());
90 if (Size)
91 BuildMI(MBB, I, DL, TII.get(SP::ADDri), SP::O6).addReg(SP::O6)
92 .addImm(Size);
93 }
Eli Bendersky700ed802013-02-21 20:05:00 +000094 MBB.erase(I);
95}
96
97
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000098void SparcFrameLowering::emitEpilogue(MachineFunction &MF,
Anton Korobeynikov33464912010-11-15 00:06:54 +000099 MachineBasicBlock &MBB) const {
Jakob Stoklund Olesen4f28c1c2011-01-13 21:28:52 +0000100 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
Anton Korobeynikov33464912010-11-15 00:06:54 +0000101 const SparcInstrInfo &TII =
102 *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo());
103 DebugLoc dl = MBBI->getDebugLoc();
104 assert(MBBI->getOpcode() == SP::RETL &&
105 "Can only put epilog before 'retl' instruction!");
106 BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
107 .addReg(SP::G0);
108}
Venkatraman Govindarajua65d3372013-05-17 15:14:34 +0000109
110bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
111 //Reserve call frame if there are no variable sized objects on the stack
112 return !MF.getFrameInfo()->hasVarSizedObjects();
113}
114
115// hasFP - Return true if the specified function should have a dedicated frame
116// pointer register. This is true if the function has variable sized allocas or
117// if frame pointer elimination is disabled.
118bool SparcFrameLowering::hasFP(const MachineFunction &MF) const {
119 const MachineFrameInfo *MFI = MF.getFrameInfo();
120 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
121 MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
122}
123