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 // Create static lists to contain register alias sets...
16 #define ALIASLIST(NAME, ...) \
17 static const unsigned NAME[] = { __VA_ARGS__ };
18 #include "X86RegisterInfo.def"
21 // X86Regs - Turn the X86RegisterInfo.def file into a bunch of register
24 static const MRegisterDesc X86Regs[] = {
25 #define R(ENUM, NAME, FLAGS, TSFLAGS, ALIAS_SET) \
26 { NAME, ALIAS_SET, FLAGS, TSFLAGS },
27 #include "X86RegisterInfo.def"
30 X86RegisterInfo::X86RegisterInfo()
31 : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0])) {
34 unsigned getIdx(unsigned dataSize) {
39 // FIXME: longs handled as ints
41 default: assert(0 && "Invalid data size!");
45 MachineBasicBlock::iterator
46 X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator MBBI,
48 unsigned SrcReg, unsigned DestReg,
49 unsigned ImmOffset, unsigned dataSize)
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);
58 MachineBasicBlock::iterator
59 X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock &MBB,
60 MachineBasicBlock::iterator MBBI,
61 unsigned DestReg, unsigned SrcReg,
62 unsigned ImmOffset, unsigned dataSize)
65 static const unsigned Opcode[] = { X86::MOVmr8, X86::MOVmr16, X86::MOVmr32 };
66 MachineInstr *MI = addRegOffset(BuildMI(Opcode[getIdx(dataSize)], 4, DestReg),
68 return ++MBB.insert(MBBI, MI);
71 MachineBasicBlock::iterator
72 X86RegisterInfo::moveReg2Reg(MachineBasicBlock &MBB,
73 MachineBasicBlock::iterator MBBI,
74 unsigned DestReg, unsigned SrcReg,
75 unsigned dataSize) const
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);
82 MachineBasicBlock::iterator
83 X86RegisterInfo::moveImm2Reg(MachineBasicBlock &MBB,
84 MachineBasicBlock::iterator MBBI,
85 unsigned DestReg, unsigned Imm, unsigned dataSize)
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);
94 unsigned X86RegisterInfo::getFramePointer() const {
98 unsigned X86RegisterInfo::getStackPointer() const {
102 const unsigned* X86RegisterInfo::getCalleeSaveRegs() const {
103 static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX,
104 MRegisterInfo::NoRegister };
105 return CalleeSaveRegs;
109 const unsigned* X86RegisterInfo::getCallerSaveRegs() const {
110 static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX,
111 MRegisterInfo::NoRegister };
112 return CallerSaveRegs;
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();
120 // Round stack allocation up to a nice alignment to keep the stack aligned
121 NumBytes = (NumBytes + 3) & ~3;
124 MachineInstr *MI = BuildMI(X86::PUSHr32, 1).addReg(X86::EBP);
125 MBBI = ++MBB.insert(MBBI, MI);
128 MI = BuildMI(X86::MOVrr32, 1, X86::EBP).addReg(X86::ESP);
129 MBBI = ++MBB.insert(MBBI, MI);
131 // adjust stack pointer: ESP -= numbytes
132 MI = BuildMI(X86::SUBri32, 2, X86::ESP).addReg(X86::ESP).addZImm(NumBytes);
133 MBBI = ++MBB.insert(MBBI, MI);
136 void X86RegisterInfo::emitEpilogue(MachineBasicBlock &MBB,
137 unsigned numBytes) const {
138 MachineBasicBlock::iterator MBBI = --MBB.end();
139 assert((*MBBI)->getOpcode() == X86::RET &&
140 "Can only insert epilog into returning blocks");
142 // insert LEAVE: mov ESP, EBP; pop EBP
143 MBBI = ++MBB.insert(MBBI, BuildMI(X86::MOVrr32, 1,X86::ESP).addReg(X86::EBP));
144 MBBI = ++MBB.insert(MBBI, BuildMI(X86::POPr32, 1).addReg(X86::EBP));