Added moveReg2Reg() and moveImm2Reg() to accomodate moving data around due to
[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 MachineBasicBlock::iterator
67 X86RegisterInfo::moveReg2Reg(MachineBasicBlock *MBB,
68                              MachineBasicBlock::iterator MBBI,
69                              unsigned DestReg, unsigned SrcReg,
70                              unsigned dataSize) const
71 {
72   unsigned opcode;
73   switch (dataSize) {
74   case 1: opcode = X86::MOVrr8; break;
75   case 2: opcode = X86::MOVrr16; break;
76   case 4: opcode = X86::MOVrr32; break;
77   default: assert(0 && "Invalid data size!");
78   }
79   
80   MachineInstr *MI = BuildMI(opcode, 2).addReg(DestReg).addReg(SrcReg);
81   return ++(MBB->insert(MBBI, MI));
82 }
83
84 MachineBasicBlock::iterator
85 X86RegisterInfo::moveImm2Reg(MachineBasicBlock *MBB,
86                              MachineBasicBlock::iterator MBBI,
87                              unsigned DestReg, unsigned Imm, unsigned dataSize)
88   const
89 {
90   unsigned opcode;
91   switch (dataSize) {
92   case 1: opcode = X86::MOVir8; break;
93   case 2: opcode = X86::MOVir16; break;
94   case 4: opcode = X86::MOVir32; break;
95   default: assert(0 && "Invalid data size!");
96   }
97   
98   MachineInstr *MI = BuildMI(opcode, 2).addReg(DestReg).addReg(Imm);
99   return ++(MBB->insert(MBBI, MI));
100 }
101
102
103 unsigned X86RegisterInfo::getFramePointer() const {
104   return X86::EBP;
105 }
106
107 unsigned X86RegisterInfo::getStackPointer() const {
108   return X86::ESP;
109 }
110
111 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
112   static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX,
113                                              MRegisterInfo::NoRegister };
114   return CalleeSaveRegs;
115 }
116
117
118 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
119   static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX,
120                                              MRegisterInfo::NoRegister };
121   return CallerSaveRegs;
122 }
123
124 MachineBasicBlock::iterator 
125 X86RegisterInfo::emitPrologue(MachineBasicBlock *MBB,
126                               MachineBasicBlock::iterator MBBI,
127                               unsigned numBytes) const
128 {
129   MachineInstr *MI;
130
131   // PUSH ebp
132   MI = BuildMI (X86::PUSHr32, 1).addReg(X86::EBP);
133   MBBI = ++(MBB->insert(MBBI, MI));
134
135   // MOV ebp, esp
136   MI = BuildMI (X86::MOVrr32, 2).addReg(X86::EBP).addReg(X86::ESP);
137   MBBI = ++(MBB->insert(MBBI, MI));  
138
139   // adjust stack pointer
140   MI  = BuildMI(X86::SUBri32, 2).addReg(X86::ESP).addZImm(numBytes);
141   MBBI = ++(MBB->insert(MBBI, MI));
142
143   // PUSH all callee-save registers
144   const unsigned* regs = getCalleeSaveRegs();
145   while (*regs) {
146     MI = BuildMI(X86::PUSHr32, 1).addReg(*regs);
147     MBBI = ++(MBB->insert(MBBI, MI));
148     ++regs;
149   }
150
151   return MBBI;
152 }
153
154 MachineBasicBlock::iterator
155 X86RegisterInfo::emitEpilogue(MachineBasicBlock *MBB,
156                               MachineBasicBlock::iterator MBBI,
157                               unsigned numBytes) const
158 {
159   MachineInstr *MI;
160
161   // POP all callee-save registers in REVERSE ORDER
162   static const unsigned regs[] = { X86::EBX, X86::EDI, X86::ESI,
163                                    MRegisterInfo::NoRegister };
164   unsigned idx = 0;
165   while (regs[idx]) {
166     MI = BuildMI(X86::POPr32, 1).addReg(regs[idx++]);
167     MBBI = ++(MBB->insert(MBBI, MI));
168   }
169   
170   // insert LEAVE
171   MI = BuildMI(X86::LEAVE, 0);
172   MBBI = ++(MBB->insert(MBBI, MI));
173   
174   return MBBI;
175 }