SparcInstrInfo.cpp revision 78e6e009223a38739797629ca2d217acf86dda93
1//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Sparc implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "SparcInstrInfo.h" 15#include "SparcSubtarget.h" 16#include "Sparc.h" 17#include "llvm/ADT/STLExtras.h" 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/CodeGen/MachineInstrBuilder.h" 20#include "llvm/CodeGen/MachineRegisterInfo.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "SparcGenInstrInfo.inc" 23#include "SparcMachineFunctionInfo.h" 24using namespace llvm; 25 26SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 27 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 28 RI(ST, *this), Subtarget(ST) { 29} 30 31/// isLoadFromStackSlot - If the specified machine instruction is a direct 32/// load from a stack slot, return the virtual or physical register number of 33/// the destination along with the FrameIndex of the loaded stack slot. If 34/// not, return 0. This predicate must return 0 if the instruction has 35/// any side effects other than loading from the stack slot. 36unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 37 int &FrameIndex) const { 38 if (MI->getOpcode() == SP::LDri || 39 MI->getOpcode() == SP::LDFri || 40 MI->getOpcode() == SP::LDDFri) { 41 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 42 MI->getOperand(2).getImm() == 0) { 43 FrameIndex = MI->getOperand(1).getIndex(); 44 return MI->getOperand(0).getReg(); 45 } 46 } 47 return 0; 48} 49 50/// isStoreToStackSlot - If the specified machine instruction is a direct 51/// store to a stack slot, return the virtual or physical register number of 52/// the source reg along with the FrameIndex of the loaded stack slot. If 53/// not, return 0. This predicate must return 0 if the instruction has 54/// any side effects other than storing to the stack slot. 55unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 56 int &FrameIndex) const { 57 if (MI->getOpcode() == SP::STri || 58 MI->getOpcode() == SP::STFri || 59 MI->getOpcode() == SP::STDFri) { 60 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && 61 MI->getOperand(1).getImm() == 0) { 62 FrameIndex = MI->getOperand(0).getIndex(); 63 return MI->getOperand(2).getReg(); 64 } 65 } 66 return 0; 67} 68 69unsigned 70SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 71 MachineBasicBlock *FBB, 72 const SmallVectorImpl<MachineOperand> &Cond, 73 DebugLoc DL)const{ 74 // Can only insert uncond branches so far. 75 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 76 BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB); 77 return 1; 78} 79 80void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 81 MachineBasicBlock::iterator I, DebugLoc DL, 82 unsigned DestReg, unsigned SrcReg, 83 bool KillSrc) const { 84 if (SP::IntRegsRegClass.contains(DestReg, SrcReg)) 85 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0) 86 .addReg(SrcReg, getKillRegState(KillSrc)); 87 else if (SP::FPRegsRegClass.contains(DestReg, SrcReg)) 88 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg) 89 .addReg(SrcReg, getKillRegState(KillSrc)); 90 else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) 91 BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg) 92 .addReg(SrcReg, getKillRegState(KillSrc)); 93 else 94 llvm_unreachable("Impossible reg-to-reg copy"); 95} 96 97void SparcInstrInfo:: 98storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 99 unsigned SrcReg, bool isKill, int FI, 100 const TargetRegisterClass *RC, 101 const TargetRegisterInfo *TRI) const { 102 DebugLoc DL; 103 if (I != MBB.end()) DL = I->getDebugLoc(); 104 105 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 106 if (RC == SP::IntRegsRegisterClass) 107 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 108 .addReg(SrcReg, getKillRegState(isKill)); 109 else if (RC == SP::FPRegsRegisterClass) 110 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 111 .addReg(SrcReg, getKillRegState(isKill)); 112 else if (RC == SP::DFPRegsRegisterClass) 113 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 114 .addReg(SrcReg, getKillRegState(isKill)); 115 else 116 llvm_unreachable("Can't store this register to stack slot"); 117} 118 119void SparcInstrInfo:: 120loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 121 unsigned DestReg, int FI, 122 const TargetRegisterClass *RC, 123 const TargetRegisterInfo *TRI) const { 124 DebugLoc DL; 125 if (I != MBB.end()) DL = I->getDebugLoc(); 126 127 if (RC == SP::IntRegsRegisterClass) 128 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 129 else if (RC == SP::FPRegsRegisterClass) 130 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 131 else if (RC == SP::DFPRegsRegisterClass) 132 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 133 else 134 llvm_unreachable("Can't load this register from stack slot"); 135} 136 137unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const 138{ 139 SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>(); 140 unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg(); 141 if (GlobalBaseReg != 0) 142 return GlobalBaseReg; 143 144 // Insert the set of GlobalBaseReg into the first MBB of the function 145 MachineBasicBlock &FirstMBB = MF->front(); 146 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 147 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 148 149 GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 150 151 152 DebugLoc dl; 153 154 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg); 155 SparcFI->setGlobalBaseReg(GlobalBaseReg); 156 return GlobalBaseReg; 157} 158