SparcInstrInfo.cpp revision c54baa2d43730f1804acfb4f4e738fba72f966bd
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 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 24 RI(ST, *this), Subtarget(ST) { 25} 26 27static bool isZeroImm(const MachineOperand &op) { 28 return op.isImm() && 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).isReg()) { 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(const 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).isFI() && MI->getOperand(2).isImm() && 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(const 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).isFI() && MI->getOperand(1).isImm() && 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 SmallVectorImpl<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 112bool 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 // Not yet supported! 119 return false; 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 // Can't copy this register 131 return false; 132 133 return true; 134} 135 136void SparcInstrInfo:: 137storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 138 unsigned SrcReg, bool isKill, int FI, 139 const TargetRegisterClass *RC) const { 140 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 141 if (RC == SP::IntRegsRegisterClass) 142 BuildMI(MBB, I, get(SP::STri)).addFrameIndex(FI).addImm(0) 143 .addReg(SrcReg, false, false, isKill); 144 else if (RC == SP::FPRegsRegisterClass) 145 BuildMI(MBB, I, get(SP::STFri)).addFrameIndex(FI).addImm(0) 146 .addReg(SrcReg, false, false, isKill); 147 else if (RC == SP::DFPRegsRegisterClass) 148 BuildMI(MBB, I, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 149 .addReg(SrcReg, false, false, isKill); 150 else 151 assert(0 && "Can't store this register to stack slot"); 152} 153 154void SparcInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 155 bool isKill, 156 SmallVectorImpl<MachineOperand> &Addr, 157 const TargetRegisterClass *RC, 158 SmallVectorImpl<MachineInstr*> &NewMIs) const { 159 unsigned Opc = 0; 160 if (RC == SP::IntRegsRegisterClass) 161 Opc = SP::STri; 162 else if (RC == SP::FPRegsRegisterClass) 163 Opc = SP::STFri; 164 else if (RC == SP::DFPRegsRegisterClass) 165 Opc = SP::STDFri; 166 else 167 assert(0 && "Can't load this register"); 168 MachineInstrBuilder MIB = BuildMI(MF, get(Opc)); 169 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 170 MachineOperand &MO = Addr[i]; 171 if (MO.isReg()) 172 MIB.addReg(MO.getReg()); 173 else if (MO.isImm()) 174 MIB.addImm(MO.getImm()); 175 else { 176 assert(MO.isFI()); 177 MIB.addFrameIndex(MO.getIndex()); 178 } 179 } 180 MIB.addReg(SrcReg, false, false, isKill); 181 NewMIs.push_back(MIB); 182 return; 183} 184 185void SparcInstrInfo:: 186loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 187 unsigned DestReg, int FI, 188 const TargetRegisterClass *RC) const { 189 if (RC == SP::IntRegsRegisterClass) 190 BuildMI(MBB, I, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 191 else if (RC == SP::FPRegsRegisterClass) 192 BuildMI(MBB, I, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 193 else if (RC == SP::DFPRegsRegisterClass) 194 BuildMI(MBB, I, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 195 else 196 assert(0 && "Can't load this register from stack slot"); 197} 198 199void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 200 SmallVectorImpl<MachineOperand> &Addr, 201 const TargetRegisterClass *RC, 202 SmallVectorImpl<MachineInstr*> &NewMIs) const { 203 unsigned Opc = 0; 204 if (RC == SP::IntRegsRegisterClass) 205 Opc = SP::LDri; 206 else if (RC == SP::FPRegsRegisterClass) 207 Opc = SP::LDFri; 208 else if (RC == SP::DFPRegsRegisterClass) 209 Opc = SP::LDDFri; 210 else 211 assert(0 && "Can't load this register"); 212 MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg); 213 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 214 MachineOperand &MO = Addr[i]; 215 if (MO.isReg()) 216 MIB.addReg(MO.getReg()); 217 else if (MO.isImm()) 218 MIB.addImm(MO.getImm()); 219 else { 220 assert(MO.isFI()); 221 MIB.addFrameIndex(MO.getIndex()); 222 } 223 } 224 NewMIs.push_back(MIB); 225 return; 226} 227 228MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 229 MachineInstr* MI, 230 const SmallVectorImpl<unsigned> &Ops, 231 int FI) const { 232 if (Ops.size() != 1) return NULL; 233 234 unsigned OpNum = Ops[0]; 235 bool isFloat = false; 236 MachineInstr *NewMI = NULL; 237 switch (MI->getOpcode()) { 238 case SP::ORrr: 239 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 240 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 241 if (OpNum == 0) // COPY -> STORE 242 NewMI = BuildMI(MF, get(SP::STri)).addFrameIndex(FI).addImm(0) 243 .addReg(MI->getOperand(2).getReg()); 244 else // COPY -> LOAD 245 NewMI = BuildMI(MF, get(SP::LDri), MI->getOperand(0).getReg()) 246 .addFrameIndex(FI).addImm(0); 247 } 248 break; 249 case SP::FMOVS: 250 isFloat = true; 251 // FALLTHROUGH 252 case SP::FMOVD: 253 if (OpNum == 0) { // COPY -> STORE 254 unsigned SrcReg = MI->getOperand(1).getReg(); 255 bool isKill = MI->getOperand(1).isKill(); 256 NewMI = BuildMI(MF, get(isFloat ? SP::STFri : SP::STDFri)) 257 .addFrameIndex(FI).addImm(0).addReg(SrcReg, false, false, isKill); 258 } else { // COPY -> LOAD 259 unsigned DstReg = MI->getOperand(0).getReg(); 260 bool isDead = MI->getOperand(0).isDead(); 261 NewMI = BuildMI(MF, get(isFloat ? SP::LDFri : SP::LDDFri)) 262 .addReg(DstReg, true, false, false, isDead).addFrameIndex(FI).addImm(0); 263 } 264 break; 265 } 266 267 return NewMI; 268} 269