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