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