1 //===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===//
3 // This file contains the X86 implementation of the MRegisterInfo class.
5 //===----------------------------------------------------------------------===//
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"
15 static unsigned getIdx(const TargetRegisterClass *RC) {
16 switch (RC->getDataSize()) {
17 default: assert(0 && "Invalid data size!");
25 void X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock &MBB,
26 MachineBasicBlock::iterator &MBBI,
27 unsigned SrcReg, unsigned DestReg,
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;
37 void X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock &MBB,
38 MachineBasicBlock::iterator &MBBI,
39 unsigned DestReg, unsigned SrcReg,
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),
46 MBBI = MBB.insert(MBBI, MI)+1;
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;
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;
71 unsigned X86RegisterInfo::getFramePointer() const {
75 unsigned X86RegisterInfo::getStackPointer() const {
79 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
80 static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, 0 };
81 return CalleeSaveRegs;
85 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
86 static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX, 0 };
87 return CallerSaveRegs;
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();
95 // Round stack allocation up to a nice alignment to keep the stack aligned
96 NumBytes = (NumBytes + 3) & ~3;
99 MachineInstr *MI = BuildMI(X86::PUSHr32, 1).addReg(X86::EBP);
100 MBBI = MBB.insert(MBBI, MI)+1;
103 MI = BuildMI(X86::MOVrr32, 1, X86::EBP).addReg(X86::ESP);
104 MBBI = MBB.insert(MBBI, MI)+1;
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);
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");
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));