New simpler spill interface
[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 static unsigned getIdx(const TargetRegisterClass *RC) {
16   switch (RC->getDataSize()) {
17   default: assert(0 && "Invalid data size!");
18   case 1:  return 0;
19   case 2:  return 1;
20   case 4:  return 2;
21   case 10: return 3;
22   }
23 }
24
25 void X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock &MBB,
26                                          MachineBasicBlock::iterator &MBBI,
27                                          unsigned SrcReg, unsigned DestReg, 
28                                          unsigned ImmOffset,
29                                          const TargetRegisterClass *RC) const {
30   static const unsigned Opcode[] =
31     { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32, X86::FSTPr80 };
32   MachineInstr *MI = addRegOffset(BuildMI(Opcode[getIdx(RC)], 5),
33                                   DestReg, ImmOffset).addReg(SrcReg);
34   MBBI = MBB.insert(MBBI, MI)+1;
35 }
36
37 void X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock &MBB,
38                                         MachineBasicBlock::iterator &MBBI,
39                                         unsigned DestReg, unsigned SrcReg,
40                                         unsigned ImmOffset,
41                                         const TargetRegisterClass *RC) const {
42   static const unsigned Opcode[] =
43     { X86::MOVmr8, X86::MOVmr16, X86::MOVmr32, X86::FLDr80 };
44   MachineInstr *MI = addRegOffset(BuildMI(Opcode[getIdx(RC)], 4, DestReg),
45                                   SrcReg, ImmOffset);
46   MBBI = MBB.insert(MBBI, MI)+1;
47 }
48
49 void X86RegisterInfo::moveReg2Reg(MachineBasicBlock &MBB,
50                                   MachineBasicBlock::iterator &MBBI,
51                                   unsigned DestReg, unsigned SrcReg,
52                                   const TargetRegisterClass *RC) const {
53   static const unsigned Opcode[] =
54     { X86::MOVrr8, X86::MOVrr16, X86::MOVrr32, X86::FpMOV };
55   MachineInstr *MI = BuildMI(Opcode[getIdx(RC)],1,DestReg).addReg(SrcReg);
56   MBBI = MBB.insert(MBBI, MI)+1;
57 }
58
59 void X86RegisterInfo::moveImm2Reg(MachineBasicBlock &MBB,
60                                   MachineBasicBlock::iterator &MBBI,
61                                   unsigned DestReg, unsigned Imm,
62                                   const TargetRegisterClass *RC) const {
63   static const unsigned Opcode[] =
64     { X86::MOVir8, X86::MOVir16, X86::MOVir32, 0 };
65   MachineInstr *MI = BuildMI(Opcode[getIdx(RC)], 1, DestReg).addReg(Imm);
66   assert(MI->getOpcode() != 0 && "Cannot move FP imm to reg yet!");
67   MBBI = MBB.insert(MBBI, MI)+1;
68 }
69
70
71 unsigned X86RegisterInfo::getFramePointer() const {
72   return X86::EBP;
73 }
74
75 unsigned X86RegisterInfo::getStackPointer() const {
76   return X86::ESP;
77 }
78
79 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
80   static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, 0 };
81   return CalleeSaveRegs;
82 }
83
84
85 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
86   static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX, 0 };
87   return CallerSaveRegs;
88 }
89
90 void X86RegisterInfo::emitPrologue(MachineFunction &MF,
91                                    unsigned NumBytes) const {
92   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
93   MachineBasicBlock::iterator MBBI = MBB.begin();
94
95   // Round stack allocation up to a nice alignment to keep the stack aligned
96   NumBytes = (NumBytes + 3) & ~3;
97
98   // PUSH ebp
99   MachineInstr *MI = BuildMI(X86::PUSHr32, 1).addReg(X86::EBP);
100   MBBI = MBB.insert(MBBI, MI)+1;
101
102   // MOV ebp, esp
103   MI = BuildMI(X86::MOVrr32, 1, X86::EBP).addReg(X86::ESP);
104   MBBI = MBB.insert(MBBI, MI)+1;
105
106   // adjust stack pointer: ESP -= numbytes
107   MI  = BuildMI(X86::SUBri32, 2, X86::ESP).addReg(X86::ESP).addZImm(NumBytes);
108   MBBI = 1+MBB.insert(MBBI, MI);
109 }
110
111 void X86RegisterInfo::emitEpilogue(MachineBasicBlock &MBB,
112                                    unsigned numBytes) const {
113   MachineBasicBlock::iterator MBBI = MBB.end()-1;
114   assert((*MBBI)->getOpcode() == X86::RET &&
115          "Can only insert epilog into returning blocks");
116
117   // insert LEAVE: mov ESP, EBP; pop EBP
118   MBBI = 1+MBB.insert(MBBI, BuildMI(X86::MOVrr32, 1,X86::ESP).addReg(X86::EBP));
119   MBBI = 1+MBB.insert(MBBI, BuildMI(X86::POPr32, 1).addReg(X86::EBP));
120 }