Implemented functions for emitting prologues and epilogues;
[oota-llvm.git] / lib / Target / X86 / X86RegisterInfo.cpp
1 //===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===//
2 //
3 // This file contains the X86 implementation of the MRegisterInfo class.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "X86.h"
8 #include "X86RegisterInfo.h"
9 #include "X86InstrBuilder.h"
10 #include "llvm/Constants.h"
11 #include "llvm/Type.h"
12 #include "llvm/CodeGen/MachineInstrBuilder.h"
13
14 // X86Regs - Turn the X86RegisterInfo.def file into a bunch of register
15 // descriptors
16 //
17 static const MRegisterDesc X86Regs[] = {
18 #define R(ENUM, NAME, FLAGS, TSFLAGS) { NAME, FLAGS, TSFLAGS },
19 #include "X86RegisterInfo.def"
20 };
21
22 X86RegisterInfo::X86RegisterInfo()
23   : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0])) {
24 }
25
26
27 MachineBasicBlock::iterator
28 X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock *MBB,
29                                     MachineBasicBlock::iterator MBBI,
30                                     unsigned SrcReg, unsigned DestReg, 
31                                     unsigned ImmOffset, unsigned dataSize)
32   const
33 {
34   MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5),
35                                   DestReg, ImmOffset).addReg(SrcReg);
36   return ++(MBB->insert(MBBI, MI));
37 }
38
39 MachineBasicBlock::iterator
40 X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock *MBB,
41                                    MachineBasicBlock::iterator MBBI,
42                                    unsigned DestReg, unsigned SrcReg,
43                                    unsigned ImmOffset, unsigned dataSize)
44   const
45 {
46   MachineInstr *MI = addRegOffset(BuildMI(X86::MOVmr32, 5).addReg(DestReg),
47                                   SrcReg, ImmOffset);
48   return ++(MBB->insert(MBBI, MI));
49 }
50
51
52 unsigned X86RegisterInfo::getFramePointer() const {
53   return X86::EBP;
54 }
55
56 unsigned X86RegisterInfo::getStackPointer() const {
57   return X86::ESP;
58 }
59
60 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
61   static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX,
62                                              MRegisterInfo::NoRegister };
63   return CalleeSaveRegs;
64 }
65
66
67 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
68   static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX,
69                                              MRegisterInfo::NoRegister };
70   return CallerSaveRegs;
71 }
72
73 MachineBasicBlock::iterator 
74 X86RegisterInfo::emitPrologue(MachineBasicBlock *MBB,
75                               MachineBasicBlock::iterator MBBI,
76                               unsigned numBytes) const
77 {
78   MachineInstr *MI;
79
80   // PUSH ebp
81   MI = BuildMI (X86::PUSHr32, 1).addReg(X86::EBP);
82   MBBI = ++(MBB->insert(MBBI, MI));
83
84   // MOV ebp, esp
85   MI = BuildMI (X86::MOVrr32, 2).addReg(X86::EBP).addReg(X86::ESP);
86   MBBI = ++(MBB->insert(MBBI, MI));  
87
88   // adjust stack pointer
89   MI  = BuildMI(X86::SUBri32, 2).addReg(X86::ESP).addZImm(numBytes);
90   MBBI = ++(MBB->insert(MBBI, MI));
91
92   // PUSH all callee-save registers
93   const unsigned* regs = getCalleeSaveRegs();
94   while (*regs) {
95     MI = BuildMI(X86::PUSHr32, 1).addReg(*regs);
96     MBBI = ++(MBB->insert(MBBI, MI));
97     ++regs;
98   }
99
100   return MBBI;
101 }
102
103 MachineBasicBlock::iterator
104 X86RegisterInfo::emitEpilogue(MachineBasicBlock *MBB,
105                               MachineBasicBlock::iterator MBBI,
106                               unsigned numBytes) const
107 {
108   MachineInstr *MI;
109
110   // POP all callee-save registers in REVERSE ORDER
111   static const unsigned regs[] = { X86::EBX, X86::EDI, X86::ESI,
112                                    MRegisterInfo::NoRegister };
113   unsigned idx = 0;
114   while (regs[idx]) {
115     MI = BuildMI(X86::POPr32, 1).addReg(regs[idx++]);
116     MBBI = ++(MBB->insert(MBBI, MI));
117   }
118   
119   // insert LEAVE
120   MI = BuildMI(X86::LEAVE, 0);
121   MBBI = ++(MBB->insert(MBBI, MI));
122   
123   return MBBI;
124 }