X86RegisterInfo.cpp revision 8e581790489cedd2a734e833973415b79d9e791a
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
15static 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
25void 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
37void 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
49void 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
59void 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
71unsigned X86RegisterInfo::getFramePointer() const {
72  return X86::EBP;
73}
74
75unsigned X86RegisterInfo::getStackPointer() const {
76  return X86::ESP;
77}
78
79const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
80  static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, 0 };
81  return CalleeSaveRegs;
82}
83
84
85const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
86  static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX, 0 };
87  return CallerSaveRegs;
88}
89
90void 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
111void 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}
121