Fix prolog/epilog in the presence of alloca
[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 #include "llvm/CodeGen/MachineFunction.h"
14
15 // Create static lists to contain register alias sets...
16 #define ALIASLIST(NAME, ...) \
17   static const unsigned NAME[] = { __VA_ARGS__ };
18 #include "X86RegisterInfo.def"
19
20
21 // X86Regs - Turn the X86RegisterInfo.def file into a bunch of register
22 // descriptors
23 //
24 static const MRegisterDesc X86Regs[] = {
25 #define R(ENUM, NAME, FLAGS, TSFLAGS, ALIAS_SET) \
26          { NAME, ALIAS_SET, FLAGS, TSFLAGS },
27 #include "X86RegisterInfo.def"
28 };
29
30 X86RegisterInfo::X86RegisterInfo()
31   : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0])) {
32 }
33
34 unsigned getIdx(unsigned dataSize) {
35   switch (dataSize) {
36   case 1: return 0;
37   case 2: return 1;
38   case 4: return 2;
39     // FIXME: longs handled as ints
40   case 8: return 2;
41   default: assert(0 && "Invalid data size!");
42   }
43 }
44
45 MachineBasicBlock::iterator
46 X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock &MBB,
47                                     MachineBasicBlock::iterator MBBI,
48                                     unsigned SrcReg, unsigned DestReg, 
49                                     unsigned ImmOffset, unsigned dataSize)
50   const
51 {
52   static const unsigned Opcode[] = { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32 };
53   MachineInstr *MI = addRegOffset(BuildMI(Opcode[getIdx(dataSize)], 5),
54                                   DestReg, ImmOffset).addReg(SrcReg);
55   return ++MBB.insert(MBBI, MI);
56 }
57
58 MachineBasicBlock::iterator
59 X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock &MBB,
60                                    MachineBasicBlock::iterator MBBI,
61                                    unsigned DestReg, unsigned SrcReg,
62                                    unsigned ImmOffset, unsigned dataSize)
63   const
64 {
65   static const unsigned Opcode[] = { X86::MOVmr8, X86::MOVmr16, X86::MOVmr32 };
66   MachineInstr *MI = addRegOffset(BuildMI(Opcode[getIdx(dataSize)], 4, DestReg),
67                                   SrcReg, ImmOffset);
68   return ++MBB.insert(MBBI, MI);
69 }
70
71 MachineBasicBlock::iterator
72 X86RegisterInfo::moveReg2Reg(MachineBasicBlock &MBB,
73                              MachineBasicBlock::iterator MBBI,
74                              unsigned DestReg, unsigned SrcReg,
75                              unsigned dataSize) const
76 {
77   static const unsigned Opcode[] = { X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
78   MachineInstr *MI = BuildMI(Opcode[getIdx(dataSize)],1,DestReg).addReg(SrcReg);
79   return ++MBB.insert(MBBI, MI);
80 }
81
82 MachineBasicBlock::iterator
83 X86RegisterInfo::moveImm2Reg(MachineBasicBlock &MBB,
84                              MachineBasicBlock::iterator MBBI,
85                              unsigned DestReg, unsigned Imm, unsigned dataSize)
86   const
87 {
88   static const unsigned Opcode[] = { X86::MOVir8, X86::MOVir16, X86::MOVir32 };
89   MachineInstr *MI = BuildMI(Opcode[getIdx(dataSize)], 1, DestReg).addReg(Imm);
90   return ++MBB.insert(MBBI, MI);
91 }
92
93
94 unsigned X86RegisterInfo::getFramePointer() const {
95   return X86::EBP;
96 }
97
98 unsigned X86RegisterInfo::getStackPointer() const {
99   return X86::ESP;
100 }
101
102 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
103   static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX,
104                                              MRegisterInfo::NoRegister };
105   return CalleeSaveRegs;
106 }
107
108
109 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
110   static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX,
111                                              MRegisterInfo::NoRegister };
112   return CallerSaveRegs;
113 }
114
115 void X86RegisterInfo::emitPrologue(MachineFunction &MF,
116                                    unsigned numBytes) const {
117   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
118   MachineBasicBlock::iterator MBBI = MBB.begin();
119
120   // PUSH all callee-save registers
121   const unsigned* regs = getCalleeSaveRegs();
122   while (*regs) {
123     MachineInstr *MI = BuildMI(X86::PUSHr32, 1).addReg(*regs);
124     MBBI = ++MBB.insert(MBBI, MI);
125     ++regs;
126   }
127
128   // PUSH ebp
129   MachineInstr *MI = BuildMI(X86::PUSHr32, 1).addReg(X86::EBP);
130   MBBI = ++MBB.insert(MBBI, MI);
131
132   // MOV ebp, esp
133   MI = BuildMI(X86::MOVrr32, 1, X86::EBP).addReg(X86::ESP);
134   MBBI = ++MBB.insert(MBBI, MI);
135
136   // adjust stack pointer: ESP -= numbytes
137   MI  = BuildMI(X86::SUBri32, 2, X86::ESP).addReg(X86::ESP).addZImm(numBytes);
138   MBBI = ++MBB.insert(MBBI, MI);
139 }
140
141 void X86RegisterInfo::emitEpilogue(MachineBasicBlock &MBB,
142                                    unsigned numBytes) const {
143   MachineBasicBlock::iterator MBBI = --MBB.end();
144   assert((*MBBI)->getOpcode() == X86::RET &&
145          "Can only insert epilog into returning blocks");
146
147   // insert LEAVE
148   MBBI = ++MBB.insert(MBBI, BuildMI(X86::LEAVE, 0));
149
150   // POP all callee-save registers in REVERSE ORDER
151   static const unsigned regs[] = { X86::EBX, X86::EDI, X86::ESI,
152                                    MRegisterInfo::NoRegister };
153   unsigned idx = 0;
154   while (regs[idx]) {
155     MachineInstr *MI = BuildMI(X86::POPr32, 0, regs[idx++]);
156     MBBI = ++(MBB.insert(MBBI, MI));
157   }
158 }