X86RegisterInfo.cpp revision 01d0efba3982e98e2dc7bc534406fbf9fd1af137
130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===// 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// The LLVM Compiler Infrastructure 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// This file was developed by the LLVM research group and is distributed under 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// the University of Illinois Open Source License. See LICENSE.TXT for details. 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//===----------------------------------------------------------------------===// 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// This file contains the X86 implementation of the MRegisterInfo class. This 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// file is responsible for the frame pointer elimination optimization on X86. 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//===----------------------------------------------------------------------===// 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "X86.h" 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "X86RegisterInfo.h" 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "X86InstrBuilder.h" 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/Constants.h" 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/Type.h" 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/CodeGen/ValueTypes.h" 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/CodeGen/MachineInstrBuilder.h" 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/CodeGen/MachineFunction.h" 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/CodeGen/MachineFrameInfo.h" 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/Target/TargetFrameInfo.h" 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/Target/TargetMachine.h" 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "llvm/Target/TargetOptions.h" 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "Support/CommandLine.h" 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "Support/STLExtras.h" 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <iostream> 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunusing namespace llvm; 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace { 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cl::opt<bool> 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun NoFusing("disable-spill-fusing", 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cl::desc("Disable fusing of spill code into instructions")); 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cl::opt<bool> 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PrintFailedFusing("print-failed-fuse-candidates", 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cl::desc("Print instructions that the allocator wants to" 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun " fuse, but the X86 backend currently can't"), 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun cl::Hidden); 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunX86RegisterInfo::X86RegisterInfo() 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) {} 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic unsigned getIdx(const TargetRegisterClass *RC) { 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun switch (RC->getSize()) { 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun default: assert(0 && "Invalid data size!"); 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case 1: return 0; 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case 2: return 1; 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case 4: return 2; 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case 10: return 3; 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineBasicBlock::iterator MI, 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun unsigned SrcReg, int FrameIdx) const { 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static const unsigned Opcode[] = 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FSTP80m }; 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const TargetRegisterClass *RC = getRegClass(SrcReg); 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *I = addFrameReference(BuildMI(Opcode[getIdx(RC)], 5), 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FrameIdx).addReg(SrcReg); 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MBB.insert(MI, I); 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineBasicBlock::iterator MI, 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun unsigned DestReg, int FrameIdx)const{ 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static const unsigned Opcode[] = 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { X86::MOV8rm, X86::MOV16rm, X86::MOV32rm, X86::FLD80m }; 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const TargetRegisterClass *RC = getRegClass(DestReg); 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun unsigned OC = Opcode[getIdx(RC)]; 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MBB.insert(MI, addFrameReference(BuildMI(OC, 4, DestReg), FrameIdx)); 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineBasicBlock::iterator MI, 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun unsigned DestReg, unsigned SrcReg, 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const TargetRegisterClass *RC) const { 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static const unsigned Opcode[] = 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { X86::MOV8rr, X86::MOV16rr, X86::MOV32rr, X86::FpMOV }; 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MBB.insert(MI, BuildMI(Opcode[getIdx(RC)],1,DestReg).addReg(SrcReg)); 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeMInst(unsigned Opcode, unsigned FrameIndex, 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 4), FrameIndex); 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeMRInst(unsigned Opcode, unsigned FrameIndex, 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun .addReg(MI->getOperand(1).getReg()); 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeMRIInst(unsigned Opcode, unsigned FrameIndex, 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 6), FrameIndex) 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun .addReg(MI->getOperand(1).getReg()) 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun .addZImm(MI->getOperand(2).getImmedValue()); 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeMIInst(unsigned Opcode, unsigned FrameIndex, 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (MI->getOperand(1).isImmediate()) 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun .addZImm(MI->getOperand(1).getImmedValue()); 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun else if (MI->getOperand(1).isGlobalAddress()) 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 5), FrameIndex) 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun .addGlobalAddress(MI->getOperand(1).getGlobal()); 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(0 && "Unknown operand for MakeMI!"); 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeRMInst(unsigned Opcode, unsigned FrameIndex, 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const MachineOperand& op = MI->getOperand(0); 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 5, op.getReg(), op.getUseType()), 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FrameIndex); 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic MachineInstr *MakeRMIInst(unsigned Opcode, unsigned FrameIndex, 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineInstr *MI) { 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const MachineOperand& op = MI->getOperand(0); 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return addFrameReference(BuildMI(Opcode, 6, op.getReg(), op.getUseType()), 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FrameIndex).addZImm(MI->getOperand(2).getImmedValue()); 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunMachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr* MI, 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun unsigned i, 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int FrameIndex) const { 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (NoFusing) return NULL; 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun /// FIXME: This should obviously be autogenerated by tablegen when patterns 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun /// are available! 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun MachineBasicBlock& MBB = *MI->getParent(); 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (i == 0) { 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun switch(MI->getOpcode()) { 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XCHG8rr: return MakeMRInst(X86::XCHG8mr ,FrameIndex, MI); 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XCHG16rr: return MakeMRInst(X86::XCHG16mr,FrameIndex, MI); 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XCHG32rr: return MakeMRInst(X86::XCHG32mr,FrameIndex, MI); 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV8rr: return MakeMRInst(X86::MOV8mr , FrameIndex, MI); 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV16rr: return MakeMRInst(X86::MOV16mr, FrameIndex, MI); 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV32rr: return MakeMRInst(X86::MOV32mr, FrameIndex, MI); 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV8ri: return MakeMIInst(X86::MOV8mi , FrameIndex, MI); 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV16ri: return MakeMIInst(X86::MOV16mi, FrameIndex, MI); 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MOV32ri: return MakeMIInst(X86::MOV32mi, FrameIndex, MI); 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MUL8r: return MakeMInst( X86::MUL8m , FrameIndex, MI); 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MUL16r: return MakeMInst( X86::MUL16m, FrameIndex, MI); 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::MUL32r: return MakeMInst( X86::MUL32m, FrameIndex, MI); 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DIV8r: return MakeMInst( X86::DIV8m , FrameIndex, MI); 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DIV16r: return MakeMInst( X86::DIV16m, FrameIndex, MI); 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DIV32r: return MakeMInst( X86::DIV32m, FrameIndex, MI); 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::IDIV8r: return MakeMInst( X86::IDIV8m , FrameIndex, MI); 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::IDIV16r: return MakeMInst( X86::IDIV16m, FrameIndex, MI); 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::IDIV32r: return MakeMInst( X86::IDIV32m, FrameIndex, MI); 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NEG8r: return MakeMInst( X86::NEG8m , FrameIndex, MI); 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NEG16r: return MakeMInst( X86::NEG16m, FrameIndex, MI); 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NEG32r: return MakeMInst( X86::NEG32m, FrameIndex, MI); 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NOT8r: return MakeMInst( X86::NOT8m , FrameIndex, MI); 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NOT16r: return MakeMInst( X86::NOT16m, FrameIndex, MI); 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::NOT32r: return MakeMInst( X86::NOT32m, FrameIndex, MI); 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::INC8r: return MakeMInst( X86::INC8m , FrameIndex, MI); 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::INC16r: return MakeMInst( X86::INC16m, FrameIndex, MI); 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::INC32r: return MakeMInst( X86::INC32m, FrameIndex, MI); 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DEC8r: return MakeMInst( X86::DEC8m , FrameIndex, MI); 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DEC16r: return MakeMInst( X86::DEC16m, FrameIndex, MI); 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::DEC32r: return MakeMInst( X86::DEC32m, FrameIndex, MI); 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD8rr: return MakeMRInst(X86::ADD8mr , FrameIndex, MI); 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD16rr: return MakeMRInst(X86::ADD16mr, FrameIndex, MI); 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD32rr: return MakeMRInst(X86::ADD32mr, FrameIndex, MI); 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADC32rr: return MakeMRInst(X86::ADC32mr, FrameIndex, MI); 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADC32ri: return MakeMIInst(X86::ADC32mi, FrameIndex, MI); 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD8ri: return MakeMIInst(X86::ADD8mi , FrameIndex, MI); 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD16ri: return MakeMIInst(X86::ADD16mi, FrameIndex, MI); 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::ADD32ri: return MakeMIInst(X86::ADD32mi, FrameIndex, MI); 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB8rr: return MakeMRInst(X86::SUB8mr , FrameIndex, MI); 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB16rr: return MakeMRInst(X86::SUB16mr, FrameIndex, MI); 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB32rr: return MakeMRInst(X86::SUB32mr, FrameIndex, MI); 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SBB32rr: return MakeMRInst(X86::SBB32mr, FrameIndex, MI); 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SBB32ri: return MakeMIInst(X86::SBB32mi, FrameIndex, MI); 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB8ri: return MakeMIInst(X86::SUB8mi , FrameIndex, MI); 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB16ri: return MakeMIInst(X86::SUB16mi, FrameIndex, MI); 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SUB32ri: return MakeMIInst(X86::SUB32mi, FrameIndex, MI); 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND8rr: return MakeMRInst(X86::AND8mr , FrameIndex, MI); 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND16rr: return MakeMRInst(X86::AND16mr, FrameIndex, MI); 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND32rr: return MakeMRInst(X86::AND32mr, FrameIndex, MI); 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND8ri: return MakeMIInst(X86::AND8mi , FrameIndex, MI); 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND16ri: return MakeMIInst(X86::AND16mi, FrameIndex, MI); 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::AND32ri: return MakeMIInst(X86::AND32mi, FrameIndex, MI); 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR8rr: return MakeMRInst(X86::OR8mr , FrameIndex, MI); 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR16rr: return MakeMRInst(X86::OR16mr, FrameIndex, MI); 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR32rr: return MakeMRInst(X86::OR32mr, FrameIndex, MI); 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR8ri: return MakeMIInst(X86::OR8mi , FrameIndex, MI); 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR16ri: return MakeMIInst(X86::OR16mi, FrameIndex, MI); 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::OR32ri: return MakeMIInst(X86::OR32mi, FrameIndex, MI); 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR8rr: return MakeMRInst(X86::XOR8mr , FrameIndex, MI); 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR16rr: return MakeMRInst(X86::XOR16mr, FrameIndex, MI); 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR32rr: return MakeMRInst(X86::XOR32mr, FrameIndex, MI); 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR8ri: return MakeMIInst(X86::XOR8mi , FrameIndex, MI); 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR16ri: return MakeMIInst(X86::XOR16mi, FrameIndex, MI); 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::XOR32ri: return MakeMIInst(X86::XOR32mi, FrameIndex, MI); 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL8rCL: return MakeMInst( X86::SHL8mCL ,FrameIndex, MI); 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL16rCL: return MakeMInst( X86::SHL16mCL,FrameIndex, MI); 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL32rCL: return MakeMInst( X86::SHL32mCL,FrameIndex, MI); 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL8ri: return MakeMIInst(X86::SHL8mi , FrameIndex, MI); 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL16ri: return MakeMIInst(X86::SHL16mi, FrameIndex, MI); 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHL32ri: return MakeMIInst(X86::SHL32mi, FrameIndex, MI); 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR8rCL: return MakeMInst( X86::SHR8mCL ,FrameIndex, MI); 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR16rCL: return MakeMInst( X86::SHR16mCL,FrameIndex, MI); 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR32rCL: return MakeMInst( X86::SHR32mCL,FrameIndex, MI); 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR8ri: return MakeMIInst(X86::SHR8mi , FrameIndex, MI); 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR16ri: return MakeMIInst(X86::SHR16mi, FrameIndex, MI); 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHR32ri: return MakeMIInst(X86::SHR32mi, FrameIndex, MI); 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR8rCL: return MakeMInst( X86::SAR8mCL ,FrameIndex, MI); 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR16rCL: return MakeMInst( X86::SAR16mCL,FrameIndex, MI); 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR32rCL: return MakeMInst( X86::SAR32mCL,FrameIndex, MI); 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR8ri: return MakeMIInst(X86::SAR8mi , FrameIndex, MI); 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR16ri: return MakeMIInst(X86::SAR16mi, FrameIndex, MI); 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SAR32ri: return MakeMIInst(X86::SAR32mi, FrameIndex, MI); 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHLD32rrCL:return MakeMRInst( X86::SHLD32mrCL,FrameIndex, MI); 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHLD32rri8:return MakeMRIInst(X86::SHLD32mri8,FrameIndex, MI); 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHRD32rrCL:return MakeMRInst( X86::SHRD32mrCL,FrameIndex, MI); 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SHRD32rri8:return MakeMRIInst(X86::SHRD32mri8,FrameIndex, MI); 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETBr: return MakeMInst( X86::SETBm, FrameIndex, MI); 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETAEr: return MakeMInst( X86::SETAEm, FrameIndex, MI); 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETEr: return MakeMInst( X86::SETEm, FrameIndex, MI); 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETNEr: return MakeMInst( X86::SETNEm, FrameIndex, MI); 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETBEr: return MakeMInst( X86::SETBEm, FrameIndex, MI); 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETAr: return MakeMInst( X86::SETAm, FrameIndex, MI); 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETSr: return MakeMInst( X86::SETSm, FrameIndex, MI); 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETNSr: return MakeMInst( X86::SETNSm, FrameIndex, MI); 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETPr: return MakeMInst( X86::SETPm, FrameIndex, MI); 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETLr: return MakeMInst( X86::SETLm, FrameIndex, MI); 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETGEr: return MakeMInst( X86::SETGEm, FrameIndex, MI); 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETLEr: return MakeMInst( X86::SETLEm, FrameIndex, MI); 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::SETGr: return MakeMInst( X86::SETGm, FrameIndex, MI); 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::TEST8rr: return MakeMRInst(X86::TEST8mr ,FrameIndex, MI); 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::TEST16rr: return MakeMRInst(X86::TEST16mr,FrameIndex, MI); 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::TEST32rr: return MakeMRInst(X86::TEST32mr,FrameIndex, MI); 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun case X86::TEST8ri: return MakeMIInst(X86::TEST8mi ,FrameIndex, MI); 245 case X86::TEST16ri: return MakeMIInst(X86::TEST16mi,FrameIndex, MI); 246 case X86::TEST32ri: return MakeMIInst(X86::TEST32mi,FrameIndex, MI); 247 case X86::CMP8rr: return MakeMRInst(X86::CMP8mr , FrameIndex, MI); 248 case X86::CMP16rr: return MakeMRInst(X86::CMP16mr, FrameIndex, MI); 249 case X86::CMP32rr: return MakeMRInst(X86::CMP32mr, FrameIndex, MI); 250 case X86::CMP8ri: return MakeMIInst(X86::CMP8mi , FrameIndex, MI); 251 case X86::CMP16ri: return MakeMIInst(X86::CMP16mi, FrameIndex, MI); 252 case X86::CMP32ri: return MakeMIInst(X86::CMP32mi, FrameIndex, MI); 253 } 254 } else if (i == 1) { 255 switch(MI->getOpcode()) { 256 case X86::XCHG8rr: return MakeRMInst(X86::XCHG8rm ,FrameIndex, MI); 257 case X86::XCHG16rr: return MakeRMInst(X86::XCHG16rm,FrameIndex, MI); 258 case X86::XCHG32rr: return MakeRMInst(X86::XCHG32rm,FrameIndex, MI); 259 case X86::MOV8rr: return MakeRMInst(X86::MOV8rm , FrameIndex, MI); 260 case X86::MOV16rr: return MakeRMInst(X86::MOV16rm, FrameIndex, MI); 261 case X86::MOV32rr: return MakeRMInst(X86::MOV32rm, FrameIndex, MI); 262 case X86::CMOVB16rr: return MakeRMInst(X86::CMOVB16rm , FrameIndex, MI); 263 case X86::CMOVB32rr: return MakeRMInst(X86::CMOVB32rm , FrameIndex, MI); 264 case X86::CMOVAE16rr: return MakeRMInst(X86::CMOVAE16rm , FrameIndex, MI); 265 case X86::CMOVAE32rr: return MakeRMInst(X86::CMOVAE32rm , FrameIndex, MI); 266 case X86::CMOVE16rr: return MakeRMInst(X86::CMOVE16rm , FrameIndex, MI); 267 case X86::CMOVE32rr: return MakeRMInst(X86::CMOVE32rm , FrameIndex, MI); 268 case X86::CMOVNE16rr:return MakeRMInst(X86::CMOVNE16rm, FrameIndex, MI); 269 case X86::CMOVNE32rr:return MakeRMInst(X86::CMOVNE32rm, FrameIndex, MI); 270 case X86::CMOVBE16rr:return MakeRMInst(X86::CMOVBE16rm, FrameIndex, MI); 271 case X86::CMOVBE32rr:return MakeRMInst(X86::CMOVBE32rm, FrameIndex, MI); 272 case X86::CMOVA16rr:return MakeRMInst(X86::CMOVA16rm, FrameIndex, MI); 273 case X86::CMOVA32rr:return MakeRMInst(X86::CMOVA32rm, FrameIndex, MI); 274 case X86::CMOVS16rr: return MakeRMInst(X86::CMOVS16rm , FrameIndex, MI); 275 case X86::CMOVS32rr: return MakeRMInst(X86::CMOVS32rm , FrameIndex, MI); 276 case X86::CMOVNS16rr: return MakeRMInst(X86::CMOVNS16rm , FrameIndex, MI); 277 case X86::CMOVNS32rr: return MakeRMInst(X86::CMOVNS32rm , FrameIndex, MI); 278 case X86::CMOVL16rr: return MakeRMInst(X86::CMOVL16rm , FrameIndex, MI); 279 case X86::CMOVL32rr: return MakeRMInst(X86::CMOVL32rm , FrameIndex, MI); 280 case X86::CMOVGE16rr: return MakeRMInst(X86::CMOVGE16rm , FrameIndex, MI); 281 case X86::CMOVGE32rr: return MakeRMInst(X86::CMOVGE32rm , FrameIndex, MI); 282 case X86::CMOVLE16rr: return MakeRMInst(X86::CMOVLE16rm , FrameIndex, MI); 283 case X86::CMOVLE32rr: return MakeRMInst(X86::CMOVLE32rm , FrameIndex, MI); 284 case X86::CMOVG16rr: return MakeRMInst(X86::CMOVG16rm , FrameIndex, MI); 285 case X86::CMOVG32rr: return MakeRMInst(X86::CMOVG32rm , FrameIndex, MI); 286 case X86::ADD8rr: return MakeRMInst(X86::ADD8rm , FrameIndex, MI); 287 case X86::ADD16rr: return MakeRMInst(X86::ADD16rm, FrameIndex, MI); 288 case X86::ADD32rr: return MakeRMInst(X86::ADD32rm, FrameIndex, MI); 289 case X86::ADC32rr: return MakeRMInst(X86::ADC32rm, FrameIndex, MI); 290 case X86::SUB8rr: return MakeRMInst(X86::SUB8rm , FrameIndex, MI); 291 case X86::SUB16rr: return MakeRMInst(X86::SUB16rm, FrameIndex, MI); 292 case X86::SUB32rr: return MakeRMInst(X86::SUB32rm, FrameIndex, MI); 293 case X86::SBB32rr: return MakeRMInst(X86::SBB32rm, FrameIndex, MI); 294 case X86::AND8rr: return MakeRMInst(X86::AND8rm , FrameIndex, MI); 295 case X86::AND16rr: return MakeRMInst(X86::AND16rm, FrameIndex, MI); 296 case X86::AND32rr: return MakeRMInst(X86::AND32rm, FrameIndex, MI); 297 case X86::OR8rr: return MakeRMInst(X86::OR8rm , FrameIndex, MI); 298 case X86::OR16rr: return MakeRMInst(X86::OR16rm, FrameIndex, MI); 299 case X86::OR32rr: return MakeRMInst(X86::OR32rm, FrameIndex, MI); 300 case X86::XOR8rr: return MakeRMInst(X86::XOR8rm , FrameIndex, MI); 301 case X86::XOR16rr: return MakeRMInst(X86::XOR16rm, FrameIndex, MI); 302 case X86::XOR32rr: return MakeRMInst(X86::XOR32rm, FrameIndex, MI); 303 case X86::TEST8rr: return MakeRMInst(X86::TEST8rm ,FrameIndex, MI); 304 case X86::TEST16rr: return MakeRMInst(X86::TEST16rm,FrameIndex, MI); 305 case X86::TEST32rr: return MakeRMInst(X86::TEST32rm,FrameIndex, MI); 306 case X86::IMUL16rr: return MakeRMInst(X86::IMUL16rm,FrameIndex, MI); 307 case X86::IMUL32rr: return MakeRMInst(X86::IMUL32rm,FrameIndex, MI); 308 case X86::IMUL16rri: return MakeRMIInst(X86::IMUL16rmi, FrameIndex, MI); 309 case X86::IMUL32rri: return MakeRMIInst(X86::IMUL32rmi, FrameIndex, MI); 310 case X86::CMP8rr: return MakeRMInst(X86::CMP8rm , FrameIndex, MI); 311 case X86::CMP16rr: return MakeRMInst(X86::CMP16rm, FrameIndex, MI); 312 case X86::CMP32rr: return MakeRMInst(X86::CMP32rm, FrameIndex, MI); 313 case X86::MOVSX16rr8:return MakeRMInst(X86::MOVSX16rm8 , FrameIndex, MI); 314 case X86::MOVSX32rr8:return MakeRMInst(X86::MOVSX32rm8, FrameIndex, MI); 315 case X86::MOVSX32rr16:return MakeRMInst(X86::MOVSX32rm16, FrameIndex, MI); 316 case X86::MOVZX16rr8:return MakeRMInst(X86::MOVZX16rm8 , FrameIndex, MI); 317 case X86::MOVZX32rr8: return MakeRMInst(X86::MOVZX32rm8, FrameIndex, MI); 318 case X86::MOVZX32rr16:return MakeRMInst(X86::MOVZX32rm16, FrameIndex, MI); 319 } 320 } 321 if (PrintFailedFusing) 322 std::cerr << "We failed to fuse: " << *MI; 323 return NULL; 324} 325 326//===----------------------------------------------------------------------===// 327// Stack Frame Processing methods 328//===----------------------------------------------------------------------===// 329 330// hasFP - Return true if the specified function should have a dedicated frame 331// pointer register. This is true if the function has variable sized allocas or 332// if frame pointer elimination is disabled. 333// 334static bool hasFP(MachineFunction &MF) { 335 return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); 336} 337 338void X86RegisterInfo:: 339eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 340 MachineBasicBlock::iterator I) const { 341 if (hasFP(MF)) { 342 // If we have a frame pointer, turn the adjcallstackup instruction into a 343 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, 344 // <amt>' 345 MachineInstr *Old = I; 346 unsigned Amount = Old->getOperand(0).getImmedValue(); 347 if (Amount != 0) { 348 // We need to keep the stack aligned properly. To do this, we round the 349 // amount of space needed for the outgoing arguments up to the next 350 // alignment boundary. 351 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 352 Amount = (Amount+Align-1)/Align*Align; 353 354 MachineInstr *New; 355 if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) { 356 New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) 357 .addZImm(Amount); 358 } else { 359 assert(Old->getOpcode() == X86::ADJCALLSTACKUP); 360 New=BuildMI(X86::ADD32ri, 1, X86::ESP, MachineOperand::UseAndDef) 361 .addZImm(Amount); 362 } 363 364 // Replace the pseudo instruction with a new instruction... 365 MBB.insert(I, New); 366 } 367 } 368 369 MBB.erase(I); 370} 371 372void X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{ 373 unsigned i = 0; 374 MachineInstr &MI = *II; 375 MachineFunction &MF = *MI.getParent()->getParent(); 376 while (!MI.getOperand(i).isFrameIndex()) { 377 ++i; 378 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 379 } 380 381 int FrameIndex = MI.getOperand(i).getFrameIndex(); 382 383 // This must be part of a four operand memory reference. Replace the 384 // FrameIndex with base register with EBP. Add add an offset to the offset. 385 MI.SetMachineOperandReg(i, hasFP(MF) ? X86::EBP : X86::ESP); 386 387 // Now add the frame object offset to the offset from EBP. 388 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 389 MI.getOperand(i+3).getImmedValue()+4; 390 391 if (!hasFP(MF)) 392 Offset += MF.getFrameInfo()->getStackSize(); 393 else 394 Offset += 4; // Skip the saved EBP 395 396 MI.SetMachineOperandConst(i+3, MachineOperand::MO_SignExtendedImmed, Offset); 397} 398 399void 400X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{ 401 if (hasFP(MF)) { 402 // Create a frame entry for the EBP register that must be saved. 403 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, -8); 404 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 405 "Slot for EBP register must be last in order to be found!"); 406 } 407} 408 409void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { 410 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 411 MachineBasicBlock::iterator MBBI = MBB.begin(); 412 MachineFrameInfo *MFI = MF.getFrameInfo(); 413 MachineInstr *MI; 414 415 // Get the number of bytes to allocate from the FrameInfo 416 unsigned NumBytes = MFI->getStackSize(); 417 if (hasFP(MF)) { 418 // Get the offset of the stack slot for the EBP register... which is 419 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 420 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexBegin())+4; 421 422 if (NumBytes) { // adjust stack pointer: ESP -= numbytes 423 MI= BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) 424 .addZImm(NumBytes); 425 MBB.insert(MBBI, MI); 426 } 427 428 // Save EBP into the appropriate stack slot... 429 MI = addRegOffset(BuildMI(X86::MOV32mr, 5), // mov [ESP-<offset>], EBP 430 X86::ESP, EBPOffset+NumBytes).addReg(X86::EBP); 431 MBB.insert(MBBI, MI); 432 433 // Update EBP with the new base value... 434 if (NumBytes == 4) // mov EBP, ESP 435 MI = BuildMI(X86::MOV32rr, 2, X86::EBP).addReg(X86::ESP); 436 else // lea EBP, [ESP+StackSize] 437 MI = addRegOffset(BuildMI(X86::LEA32r, 5, X86::EBP), X86::ESP,NumBytes-4); 438 439 MBB.insert(MBBI, MI); 440 441 } else { 442 if (MFI->hasCalls()) { 443 // When we have no frame pointer, we reserve argument space for call sites 444 // in the function immediately on entry to the current function. This 445 // eliminates the need for add/sub ESP brackets around call sites. 446 // 447 NumBytes += MFI->getMaxCallFrameSize(); 448 449 // Round the size to a multiple of the alignment (don't forget the 4 byte 450 // offset though). 451 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 452 NumBytes = ((NumBytes+4)+Align-1)/Align*Align - 4; 453 } 454 455 // Update frame info to pretend that this is part of the stack... 456 MFI->setStackSize(NumBytes); 457 458 if (NumBytes) { 459 // adjust stack pointer: ESP -= numbytes 460 MI= BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) 461 .addZImm(NumBytes); 462 MBB.insert(MBBI, MI); 463 } 464 } 465} 466 467void X86RegisterInfo::emitEpilogue(MachineFunction &MF, 468 MachineBasicBlock &MBB) const { 469 const MachineFrameInfo *MFI = MF.getFrameInfo(); 470 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 471 MachineInstr *MI; 472 assert(MBBI->getOpcode() == X86::RET && 473 "Can only insert epilog into returning blocks"); 474 475 if (hasFP(MF)) { 476 // Get the offset of the stack slot for the EBP register... which is 477 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 478 int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4; 479 480 // mov ESP, EBP 481 MI = BuildMI(X86::MOV32rr, 1,X86::ESP).addReg(X86::EBP); 482 MBB.insert(MBBI, MI); 483 484 // pop EBP 485 MI = BuildMI(X86::POP32r, 0, X86::EBP); 486 MBB.insert(MBBI, MI); 487 } else { 488 // Get the number of bytes allocated from the FrameInfo... 489 unsigned NumBytes = MFI->getStackSize(); 490 491 if (NumBytes) { // adjust stack pointer back: ESP += numbytes 492 MI =BuildMI(X86::ADD32ri, 1, X86::ESP, MachineOperand::UseAndDef) 493 .addZImm(NumBytes); 494 MBB.insert(MBBI, MI); 495 } 496 } 497} 498 499#include "X86GenRegisterInfo.inc" 500 501const TargetRegisterClass* 502X86RegisterInfo::getRegClassForType(const Type* Ty) const { 503 switch (Ty->getTypeID()) { 504 case Type::LongTyID: 505 case Type::ULongTyID: assert(0 && "Long values can't fit in registers!"); 506 default: assert(0 && "Invalid type to getClass!"); 507 case Type::BoolTyID: 508 case Type::SByteTyID: 509 case Type::UByteTyID: return &R8Instance; 510 case Type::ShortTyID: 511 case Type::UShortTyID: return &R16Instance; 512 case Type::IntTyID: 513 case Type::UIntTyID: 514 case Type::PointerTyID: return &R32Instance; 515 516 case Type::FloatTyID: 517 case Type::DoubleTyID: return &RFPInstance; 518 } 519} 520