SparcInstrInfo.cpp revision d10fd9791c20fd8368fa0ce94b626b769c6c8ba0
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/CodeGen/MachineInstrBuilder.h" 19#include "SparcGenInstrInfo.inc" 20using namespace llvm; 21 22SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 23 : TargetInstrInfo(SparcInsts, array_lengthof(SparcInsts)), 24 RI(ST, *this), Subtarget(ST) { 25} 26 27static bool isZeroImm(const MachineOperand &op) { 28 return op.isImmediate() && op.getImm() == 0; 29} 30 31/// Return true if the instruction is a register to register move and 32/// leave the source and dest operands in the passed parameters. 33/// 34bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 35 unsigned &SrcReg, unsigned &DstReg) const { 36 // We look for 3 kinds of patterns here: 37 // or with G0 or 0 38 // add with G0 or 0 39 // fmovs or FpMOVD (pseudo double move). 40 if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 41 if (MI.getOperand(1).getReg() == SP::G0) { 42 DstReg = MI.getOperand(0).getReg(); 43 SrcReg = MI.getOperand(2).getReg(); 44 return true; 45 } else if (MI.getOperand(2).getReg() == SP::G0) { 46 DstReg = MI.getOperand(0).getReg(); 47 SrcReg = MI.getOperand(1).getReg(); 48 return true; 49 } 50 } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 51 isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { 52 DstReg = MI.getOperand(0).getReg(); 53 SrcReg = MI.getOperand(1).getReg(); 54 return true; 55 } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 56 MI.getOpcode() == SP::FMOVD) { 57 SrcReg = MI.getOperand(1).getReg(); 58 DstReg = MI.getOperand(0).getReg(); 59 return true; 60 } 61 return false; 62} 63 64/// isLoadFromStackSlot - If the specified machine instruction is a direct 65/// load from a stack slot, return the virtual or physical register number of 66/// the destination along with the FrameIndex of the loaded stack slot. If 67/// not, return 0. This predicate must return 0 if the instruction has 68/// any side effects other than loading from the stack slot. 69unsigned SparcInstrInfo::isLoadFromStackSlot(MachineInstr *MI, 70 int &FrameIndex) const { 71 if (MI->getOpcode() == SP::LDri || 72 MI->getOpcode() == SP::LDFri || 73 MI->getOpcode() == SP::LDDFri) { 74 if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && 75 MI->getOperand(2).getImm() == 0) { 76 FrameIndex = MI->getOperand(1).getIndex(); 77 return MI->getOperand(0).getReg(); 78 } 79 } 80 return 0; 81} 82 83/// isStoreToStackSlot - If the specified machine instruction is a direct 84/// store to a stack slot, return the virtual or physical register number of 85/// the source reg along with the FrameIndex of the loaded stack slot. If 86/// not, return 0. This predicate must return 0 if the instruction has 87/// any side effects other than storing to the stack slot. 88unsigned SparcInstrInfo::isStoreToStackSlot(MachineInstr *MI, 89 int &FrameIndex) const { 90 if (MI->getOpcode() == SP::STri || 91 MI->getOpcode() == SP::STFri || 92 MI->getOpcode() == SP::STDFri) { 93 if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && 94 MI->getOperand(1).getImm() == 0) { 95 FrameIndex = MI->getOperand(0).getIndex(); 96 return MI->getOperand(2).getReg(); 97 } 98 } 99 return 0; 100} 101 102unsigned 103SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 104 MachineBasicBlock *FBB, 105 const std::vector<MachineOperand> &Cond)const{ 106 // Can only insert uncond branches so far. 107 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 108 BuildMI(&MBB, get(SP::BA)).addMBB(TBB); 109 return 1; 110} 111 112void SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 113 MachineBasicBlock::iterator I, 114 unsigned DestReg, unsigned SrcReg, 115 const TargetRegisterClass *DestRC, 116 const TargetRegisterClass *SrcRC) const { 117 if (DestRC != SrcRC) { 118 cerr << "Not yet supported!"; 119 abort(); 120 } 121 122 if (DestRC == SP::IntRegsRegisterClass) 123 BuildMI(MBB, I, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 124 else if (DestRC == SP::FPRegsRegisterClass) 125 BuildMI(MBB, I, get(SP::FMOVS), DestReg).addReg(SrcReg); 126 else if (DestRC == SP::DFPRegsRegisterClass) 127 BuildMI(MBB, I, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 128 .addReg(SrcReg); 129 else 130 assert (0 && "Can't copy this register"); 131} 132