|  | //===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file contains the Sparc implementation of the TargetInstrInfo class. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "SparcInstrInfo.h" | 
|  | #include "SparcSubtarget.h" | 
|  | #include "Sparc.h" | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/ADT/SmallVector.h" | 
|  | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
|  | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
|  | #include "llvm/Support/ErrorHandling.h" | 
|  | #include "SparcGenInstrInfo.inc" | 
|  | #include "SparcMachineFunctionInfo.h" | 
|  | using namespace llvm; | 
|  |  | 
|  | SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) | 
|  | : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), | 
|  | RI(ST, *this), Subtarget(ST) { | 
|  | } | 
|  |  | 
|  | /// isLoadFromStackSlot - If the specified machine instruction is a direct | 
|  | /// load from a stack slot, return the virtual or physical register number of | 
|  | /// the destination along with the FrameIndex of the loaded stack slot.  If | 
|  | /// not, return 0.  This predicate must return 0 if the instruction has | 
|  | /// any side effects other than loading from the stack slot. | 
|  | unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, | 
|  | int &FrameIndex) const { | 
|  | if (MI->getOpcode() == SP::LDri || | 
|  | MI->getOpcode() == SP::LDFri || | 
|  | MI->getOpcode() == SP::LDDFri) { | 
|  | if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && | 
|  | MI->getOperand(2).getImm() == 0) { | 
|  | FrameIndex = MI->getOperand(1).getIndex(); | 
|  | return MI->getOperand(0).getReg(); | 
|  | } | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /// isStoreToStackSlot - If the specified machine instruction is a direct | 
|  | /// store to a stack slot, return the virtual or physical register number of | 
|  | /// the source reg along with the FrameIndex of the loaded stack slot.  If | 
|  | /// not, return 0.  This predicate must return 0 if the instruction has | 
|  | /// any side effects other than storing to the stack slot. | 
|  | unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, | 
|  | int &FrameIndex) const { | 
|  | if (MI->getOpcode() == SP::STri || | 
|  | MI->getOpcode() == SP::STFri || | 
|  | MI->getOpcode() == SP::STDFri) { | 
|  | if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && | 
|  | MI->getOperand(1).getImm() == 0) { | 
|  | FrameIndex = MI->getOperand(0).getIndex(); | 
|  | return MI->getOperand(2).getReg(); | 
|  | } | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | unsigned | 
|  | SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, | 
|  | MachineBasicBlock *FBB, | 
|  | const SmallVectorImpl<MachineOperand> &Cond, | 
|  | DebugLoc DL)const{ | 
|  | // Can only insert uncond branches so far. | 
|  | assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); | 
|  | BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, | 
|  | MachineBasicBlock::iterator I, DebugLoc DL, | 
|  | unsigned DestReg, unsigned SrcReg, | 
|  | bool KillSrc) const { | 
|  | if (SP::IntRegsRegClass.contains(DestReg, SrcReg)) | 
|  | BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0) | 
|  | .addReg(SrcReg, getKillRegState(KillSrc)); | 
|  | else if (SP::FPRegsRegClass.contains(DestReg, SrcReg)) | 
|  | BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg) | 
|  | .addReg(SrcReg, getKillRegState(KillSrc)); | 
|  | else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) | 
|  | BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg) | 
|  | .addReg(SrcReg, getKillRegState(KillSrc)); | 
|  | else | 
|  | llvm_unreachable("Impossible reg-to-reg copy"); | 
|  | } | 
|  |  | 
|  | void SparcInstrInfo:: | 
|  | storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, | 
|  | unsigned SrcReg, bool isKill, int FI, | 
|  | const TargetRegisterClass *RC, | 
|  | const TargetRegisterInfo *TRI) const { | 
|  | DebugLoc DL; | 
|  | if (I != MBB.end()) DL = I->getDebugLoc(); | 
|  |  | 
|  | // On the order of operands here: think "[FrameIdx + 0] = SrcReg". | 
|  | if (RC == SP::IntRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) | 
|  | .addReg(SrcReg, getKillRegState(isKill)); | 
|  | else if (RC == SP::FPRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) | 
|  | .addReg(SrcReg,  getKillRegState(isKill)); | 
|  | else if (RC == SP::DFPRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) | 
|  | .addReg(SrcReg,  getKillRegState(isKill)); | 
|  | else | 
|  | llvm_unreachable("Can't store this register to stack slot"); | 
|  | } | 
|  |  | 
|  | void SparcInstrInfo:: | 
|  | loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, | 
|  | unsigned DestReg, int FI, | 
|  | const TargetRegisterClass *RC, | 
|  | const TargetRegisterInfo *TRI) const { | 
|  | DebugLoc DL; | 
|  | if (I != MBB.end()) DL = I->getDebugLoc(); | 
|  |  | 
|  | if (RC == SP::IntRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); | 
|  | else if (RC == SP::FPRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); | 
|  | else if (RC == SP::DFPRegsRegisterClass) | 
|  | BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); | 
|  | else | 
|  | llvm_unreachable("Can't load this register from stack slot"); | 
|  | } | 
|  |  | 
|  | unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const | 
|  | { | 
|  | SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>(); | 
|  | unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg(); | 
|  | if (GlobalBaseReg != 0) | 
|  | return GlobalBaseReg; | 
|  |  | 
|  | // Insert the set of GlobalBaseReg into the first MBB of the function | 
|  | MachineBasicBlock &FirstMBB = MF->front(); | 
|  | MachineBasicBlock::iterator MBBI = FirstMBB.begin(); | 
|  | MachineRegisterInfo &RegInfo = MF->getRegInfo(); | 
|  |  | 
|  | GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); | 
|  |  | 
|  |  | 
|  | DebugLoc dl; | 
|  |  | 
|  | BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg); | 
|  | SparcFI->setGlobalBaseReg(GlobalBaseReg); | 
|  | return GlobalBaseReg; | 
|  | } |