cd22d88efbd6acdab4f33e94cbcd8409cb985838
[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 MachineBasicBlock::iterator
27 X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock *MBB,
28                                     MachineBasicBlock::iterator MBBI,
29                                     unsigned SrcReg, unsigned DestReg, 
30                                     unsigned ImmOffset, unsigned dataSize)
31   const
32 {
33   unsigned opcode;
34   switch (dataSize) {
35   case 1: opcode = X86::MOVrm8; break;
36   case 2: opcode = X86::MOVrm16; break;
37   case 4: opcode = X86::MOVrm32; break;
38   default: assert(0 && "Invalid data size!");
39   }
40
41   MachineInstr *MI = addRegOffset(BuildMI(opcode, 5),
42                                   DestReg, ImmOffset).addReg(SrcReg);
43   return ++(MBB->insert(MBBI, MI));
44 }
45
46 MachineBasicBlock::iterator
47 X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock *MBB,
48                                    MachineBasicBlock::iterator MBBI,
49                                    unsigned DestReg, unsigned SrcReg,
50                                    unsigned ImmOffset, unsigned dataSize)
51   const
52 {
53   unsigned opcode;
54   switch (dataSize) {
55   case 1: opcode = X86::MOVmr8; break;
56   case 2: opcode = X86::MOVmr16; break;
57   case 4: opcode = X86::MOVmr32; break;
58   default: assert(0 && "Invalid data size!");
59   }
60
61   MachineInstr *MI = addRegOffset(BuildMI(opcode, 5).addReg(DestReg),
62                                   SrcReg, ImmOffset);
63   return ++(MBB->insert(MBBI, MI));
64 }
65
66
67 unsigned X86RegisterInfo::getFramePointer() const {
68   return X86::EBP;
69 }
70
71 unsigned X86RegisterInfo::getStackPointer() const {
72   return X86::ESP;
73 }
74
75 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
76   static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX,
77                                              MRegisterInfo::NoRegister };
78   return CalleeSaveRegs;
79 }
80
81
82 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
83   static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX,
84                                              MRegisterInfo::NoRegister };
85   return CallerSaveRegs;
86 }
87
88 MachineBasicBlock::iterator 
89 X86RegisterInfo::emitPrologue(MachineBasicBlock *MBB,
90                               MachineBasicBlock::iterator MBBI,
91                               unsigned numBytes) const
92 {
93   MachineInstr *MI;
94
95   // PUSH ebp
96   MI = BuildMI (X86::PUSHr32, 1).addReg(X86::EBP);
97   MBBI = ++(MBB->insert(MBBI, MI));
98
99   // MOV ebp, esp
100   MI = BuildMI (X86::MOVrr32, 2).addReg(X86::EBP).addReg(X86::ESP);
101   MBBI = ++(MBB->insert(MBBI, MI));  
102
103   // adjust stack pointer
104   MI  = BuildMI(X86::SUBri32, 2).addReg(X86::ESP).addZImm(numBytes);
105   MBBI = ++(MBB->insert(MBBI, MI));
106
107   // PUSH all callee-save registers
108   const unsigned* regs = getCalleeSaveRegs();
109   while (*regs) {
110     MI = BuildMI(X86::PUSHr32, 1).addReg(*regs);
111     MBBI = ++(MBB->insert(MBBI, MI));
112     ++regs;
113   }
114
115   return MBBI;
116 }
117
118 MachineBasicBlock::iterator
119 X86RegisterInfo::emitEpilogue(MachineBasicBlock *MBB,
120                               MachineBasicBlock::iterator MBBI,
121                               unsigned numBytes) const
122 {
123   MachineInstr *MI;
124
125   // POP all callee-save registers in REVERSE ORDER
126   static const unsigned regs[] = { X86::EBX, X86::EDI, X86::ESI,
127                                    MRegisterInfo::NoRegister };
128   unsigned idx = 0;
129   while (regs[idx]) {
130     MI = BuildMI(X86::POPr32, 1).addReg(regs[idx++]);
131     MBBI = ++(MBB->insert(MBBI, MI));
132   }
133   
134   // insert LEAVE
135   MI = BuildMI(X86::LEAVE, 0);
136   MBBI = ++(MBB->insert(MBBI, MI));
137   
138   return MBBI;
139 }