be55e3b0a20baedb91f9b129dc14df5b9474ced3
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9PrologEpilogInserter.cpp
1 //===-- PrologEpilogCodeInserter.cpp - Insert Prolog & Epilog code for fn -===//
2 //
3 // Insert SAVE/RESTORE instructions for the function
4 //
5 // Insert prolog code at the unique function entry point.
6 // Insert epilog code at each function exit point.
7 // InsertPrologEpilog invokes these only if the function is not compiled
8 // with the leaf function optimization.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #include "SparcInternals.h"
13 #include "SparcRegClassInfo.h"
14 #include "llvm/CodeGen/MachineFunctionPass.h"
15 #include "llvm/CodeGen/MachineFunctionInfo.h"
16 #include "llvm/CodeGen/MachineCodeForInstruction.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Function.h"
20
21 namespace {
22   struct InsertPrologEpilogCode : public MachineFunctionPass {
23     const char *getPassName() const { return "Sparc Prolog/Epilog Inserter"; }
24     
25     bool runOnMachineFunction(MachineFunction &F) {
26       if (!F.getInfo()->isCompiledAsLeafMethod()) {
27         InsertPrologCode(F);
28         InsertEpilogCode(F);
29       }
30       return false;
31     }
32     
33     void InsertPrologCode(MachineFunction &F);
34     void InsertEpilogCode(MachineFunction &F);
35   };
36
37 }  // End anonymous namespace
38
39 //------------------------------------------------------------------------ 
40 //   Create prolog and epilog code for procedure entry and exit
41 //------------------------------------------------------------------------ 
42
43 void InsertPrologEpilogCode::InsertPrologCode(MachineFunction &MF)
44 {
45   std::vector<MachineInstr*> mvec;
46   const TargetMachine &TM = MF.getTarget();
47   const TargetFrameInfo& frameInfo = TM.getFrameInfo();
48   
49   // The second operand is the stack size. If it does not fit in the
50   // immediate field, we have to use a free register to hold the size.
51   // See the comments below for the choice of this register.
52   // 
53   unsigned staticStackSize = MF.getInfo()->getStaticStackSize();
54   
55   if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize())
56     staticStackSize = (unsigned) frameInfo.getMinStackFrameSize();
57
58   if (unsigned padsz = (staticStackSize %
59                         (unsigned) frameInfo.getStackFrameSizeAlignment()))
60     staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
61   
62   int32_t C = - (int) staticStackSize;
63   int SP = TM.getRegInfo().getStackPointer();
64   if (TM.getInstrInfo().constantFitsInImmedField(V9::SAVE,staticStackSize)) {
65     mvec.push_back(BuildMI(V9::SAVE, 3).addMReg(SP).addSImm(C).addMReg(SP,
66                                                                     MOTy::Def));
67   } else {
68     // We have to put the stack size value into a register before SAVE.
69     // Use register %g1 since it is volatile across calls.  Note that the
70     // local (%l) and in (%i) registers cannot be used before the SAVE!
71     // Do this by creating a code sequence equivalent to:
72     //        SETSW -(stackSize), %g1
73     int uregNum = TM.getRegInfo().getUnifiedRegNum(
74                          TM.getRegInfo().getRegClassIDOfType(Type::IntTy),
75                          SparcIntRegClass::g1);
76
77     MachineInstr* M = BuildMI(V9::SETHI, 2).addSImm(C)
78       .addMReg(uregNum, MOTy::Def);
79     M->setOperandHi32(0);
80     mvec.push_back(M);
81     
82     M = BuildMI(V9::OR, 3).addMReg(uregNum).addSImm(C)
83       .addMReg(uregNum, MOTy::Def);
84     M->setOperandLo32(1);
85     mvec.push_back(M);
86     
87     M = BuildMI(V9::SRA, 3).addMReg(uregNum).addZImm(0)
88       .addMReg(uregNum, MOTy::Def);
89     mvec.push_back(M);
90     
91     // Now generate the SAVE using the value in register %g1
92     M = BuildMI(V9::SAVE, 3).addMReg(SP).addMReg(uregNum).addMReg(SP,MOTy::Def);
93     mvec.push_back(M);
94   }
95
96   MF.front().insert(MF.front().begin(), mvec.begin(), mvec.end());
97 }
98
99 void InsertPrologEpilogCode::InsertEpilogCode(MachineFunction &MF)
100 {
101   const TargetMachine &TM = MF.getTarget();
102   const TargetInstrInfo &MII = TM.getInstrInfo();
103
104   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
105     MachineBasicBlock &MBB = *I;
106     BasicBlock &BB = *I->getBasicBlock();
107     Instruction *TermInst = (Instruction*)BB.getTerminator();
108     if (TermInst->getOpcode() == Instruction::Ret)
109     {
110       int ZR = TM.getRegInfo().getZeroRegNum();
111       MachineInstr *Restore = 
112         BuildMI(V9::RESTORE, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def);
113       
114       MachineCodeForInstruction &termMvec =
115         MachineCodeForInstruction::get(TermInst);
116       
117       // Remove the NOPs in the delay slots of the return instruction
118       unsigned numNOPs = 0;
119       while (termMvec.back()->getOpCode() == V9::NOP)
120       {
121         assert( termMvec.back() == MBB.back());
122         delete MBB.pop_back();
123         termMvec.pop_back();
124         ++numNOPs;
125       }
126       assert(termMvec.back() == MBB.back());
127         
128       // Check that we found the right number of NOPs and have the right
129       // number of instructions to replace them.
130       unsigned ndelays = MII.getNumDelaySlots(termMvec.back()->getOpCode());
131       assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
132       assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
133         
134       // Append the epilog code to the end of the basic block.
135       MBB.push_back(Restore);
136     }
137   }
138 }
139
140 Pass* UltraSparc::getPrologEpilogInsertionPass() {
141   return new InsertPrologEpilogCode();
142 }