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