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