1 //===-- SparcV9PrologEpilogCodeInserter.cpp - Insert Fn Prolog & Epilog ---===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Insert SAVE/RESTORE instructions for the function
12 // Insert prolog code at the unique function entry point.
13 // Insert epilog code at each function exit point.
14 // InsertPrologEpilog invokes these only if the function is not compiled
15 // with the leaf function optimization.
17 //===----------------------------------------------------------------------===//
19 #include "SparcV9Internals.h"
20 #include "SparcV9RegClassInfo.h"
21 #include "SparcV9RegisterInfo.h"
22 #include "SparcV9FrameInfo.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineFunctionInfo.h"
25 #include "llvm/CodeGen/MachineCodeForInstruction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/Pass.h"
28 #include "llvm/Function.h"
29 #include "llvm/DerivedTypes.h"
30 #include "llvm/Intrinsics.h"
35 struct InsertPrologEpilogCode : public MachineFunctionPass {
36 const char *getPassName() const { return "SparcV9 Prolog/Epilog Inserter"; }
38 bool runOnMachineFunction(MachineFunction &F) {
39 if (!F.getInfo()->isCompiledAsLeafMethod()) {
46 void InsertPrologCode(MachineFunction &F);
47 void InsertEpilogCode(MachineFunction &F);
50 } // End anonymous namespace
52 //------------------------------------------------------------------------
53 // Create prolog and epilog code for procedure entry and exit
54 //------------------------------------------------------------------------
56 static unsigned getStaticStackSize (MachineFunction &MF) {
57 const TargetFrameInfo& frameInfo = *MF.getTarget().getFrameInfo();
59 unsigned staticStackSize = MF.getInfo()->getStaticStackSize();
61 if (staticStackSize < (unsigned)SparcV9FrameInfo::MinStackFrameSize)
62 staticStackSize = SparcV9FrameInfo::MinStackFrameSize;
63 if (unsigned padsz = staticStackSize %
64 SparcV9FrameInfo::StackFrameSizeAlignment)
65 staticStackSize += SparcV9FrameInfo::StackFrameSizeAlignment - padsz;
67 return staticStackSize;
70 void InsertPrologEpilogCode::InsertPrologCode(MachineFunction &MF)
72 std::vector<MachineInstr*> mvec;
73 const TargetMachine &TM = MF.getTarget();
74 const TargetFrameInfo& frameInfo = *TM.getFrameInfo();
76 // The second operand is the stack size. If it does not fit in the
77 // immediate field, we have to use a free register to hold the size.
78 // See the comments below for the choice of this register.
80 unsigned staticStackSize = getStaticStackSize (MF);
81 int32_t C = - (int) staticStackSize;
82 int SP = TM.getRegInfo()->getStackPointer();
83 if (TM.getInstrInfo()->constantFitsInImmedField(V9::SAVEi,staticStackSize)) {
84 mvec.push_back(BuildMI(V9::SAVEi, 3).addMReg(SP).addSImm(C)
85 .addMReg(SP, MachineOperand::Def));
87 // We have to put the stack size value into a register before SAVE.
88 // Use register %g1 since it is volatile across calls. Note that the
89 // local (%l) and in (%i) registers cannot be used before the SAVE!
90 // Do this by creating a code sequence equivalent to:
91 // SETSW -(stackSize), %g1
92 int uregNum = TM.getRegInfo()->getUnifiedRegNum(
93 TM.getRegInfo()->getRegClassIDOfType(Type::IntTy),
94 SparcV9IntRegClass::g1);
96 MachineInstr* M = BuildMI(V9::SETHI, 2).addSImm(C)
97 .addMReg(uregNum, MachineOperand::Def);
98 M->getOperand(0).markHi32();
101 M = BuildMI(V9::ORi, 3).addMReg(uregNum).addSImm(C)
102 .addMReg(uregNum, MachineOperand::Def);
103 M->getOperand(1).markLo32();
106 M = BuildMI(V9::SRAi5, 3).addMReg(uregNum).addZImm(0)
107 .addMReg(uregNum, MachineOperand::Def);
110 // Now generate the SAVE using the value in register %g1
111 M = BuildMI(V9::SAVEr,3).addMReg(SP).addMReg(uregNum)
112 .addMReg(SP,MachineOperand::Def);
116 // For varargs function bodies, insert instructions to copy incoming
117 // register arguments for the ... list to the stack.
118 // The first K=6 arguments are always received via int arg regs
119 // (%i0 ... %i5 if K=6) .
120 // By copying the varargs arguments to the stack, va_arg() then can
121 // simply assume that all vararg arguments are in an array on the stack.
123 if (MF.getFunction()->getFunctionType()->isVarArg()) {
124 int numFixedArgs = MF.getFunction()->getFunctionType()->getNumParams();
125 int numArgRegs = TM.getRegInfo()->getNumOfIntArgRegs();
126 if (numFixedArgs < numArgRegs) {
127 const TargetFrameInfo &FI = *TM.getFrameInfo();
128 int firstArgReg = TM.getRegInfo()->getUnifiedRegNum(
129 TM.getRegInfo()->getRegClassIDOfType(Type::IntTy),
130 SparcV9IntRegClass::i0);
131 int fpReg = SparcV9::i6;
133 int firstArgOffset= SparcV9FrameInfo::FirstIncomingArgOffsetFromFP;
134 int nextArgOffset = firstArgOffset + numFixedArgs * argSize;
136 for (int i=numFixedArgs; i < numArgRegs; ++i) {
137 mvec.push_back(BuildMI(V9::STXi, 3).addMReg(firstArgReg+i).
138 addMReg(fpReg).addSImm(nextArgOffset));
139 nextArgOffset += argSize;
144 MF.front().insert(MF.front().begin(), mvec.begin(), mvec.end());
147 void InsertPrologEpilogCode::InsertEpilogCode(MachineFunction &MF)
149 const TargetMachine &TM = MF.getTarget();
150 const TargetInstrInfo &MII = *TM.getInstrInfo();
152 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
153 MachineBasicBlock &MBB = *I;
154 const BasicBlock &BB = *I->getBasicBlock();
155 const Instruction *TermInst = (Instruction*)BB.getTerminator();
156 if (TermInst->getOpcode() == Instruction::Ret)
158 int ZR = TM.getRegInfo()->getZeroRegNum();
159 MachineInstr *Restore =
160 BuildMI(V9::RESTOREi, 3).addMReg(ZR).addSImm(0)
161 .addMReg(ZR, MachineOperand::Def);
163 MachineCodeForInstruction &termMvec =
164 MachineCodeForInstruction::get(TermInst);
166 // Remove the NOPs in the delay slots of the return instruction
167 unsigned numNOPs = 0;
168 while (termMvec.back()->getOpcode() == V9::NOP)
170 assert( termMvec.back() == &MBB.back());
172 MBB.erase(&MBB.back());
175 assert(termMvec.back() == &MBB.back());
177 // Check that we found the right number of NOPs and have the right
178 // number of instructions to replace them.
179 unsigned ndelays = MII.getNumDelaySlots(termMvec.back()->getOpcode());
180 assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
181 assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
183 // Append the epilog code to the end of the basic block.
184 MBB.push_back(Restore);
189 FunctionPass *createPrologEpilogInsertionPass() {
190 return new InsertPrologEpilogCode();
193 } // End llvm namespace