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