SparcInstrInfo.cpp revision 21b5541814d57d0a31f353948e4e933dbb1af6a4
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 "SparcGenInstrInfo.inc" 21using namespace llvm; 22 23SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 24 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 25 RI(ST, *this), Subtarget(ST) { 26} 27 28static bool isZeroImm(const MachineOperand &op) { 29 return op.isImm() && op.getImm() == 0; 30} 31 32/// Return true if the instruction is a register to register move and 33/// leave the source and dest operands in the passed parameters. 34/// 35bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 36 unsigned &SrcReg, unsigned &DstReg, 37 unsigned &SrcSR, unsigned &DstSR) const { 38 SrcSR = DstSR = 0; // No sub-registers. 39 40 // We look for 3 kinds of patterns here: 41 // or with G0 or 0 42 // add with G0 or 0 43 // fmovs or FpMOVD (pseudo double move). 44 if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 45 if (MI.getOperand(1).getReg() == SP::G0) { 46 DstReg = MI.getOperand(0).getReg(); 47 SrcReg = MI.getOperand(2).getReg(); 48 return true; 49 } else if (MI.getOperand(2).getReg() == SP::G0) { 50 DstReg = MI.getOperand(0).getReg(); 51 SrcReg = MI.getOperand(1).getReg(); 52 return true; 53 } 54 } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 55 isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) { 56 DstReg = MI.getOperand(0).getReg(); 57 SrcReg = MI.getOperand(1).getReg(); 58 return true; 59 } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 60 MI.getOpcode() == SP::FMOVD) { 61 SrcReg = MI.getOperand(1).getReg(); 62 DstReg = MI.getOperand(0).getReg(); 63 return true; 64 } 65 return false; 66} 67 68/// isLoadFromStackSlot - If the specified machine instruction is a direct 69/// load from a stack slot, return the virtual or physical register number of 70/// the destination along with the FrameIndex of the loaded stack slot. If 71/// not, return 0. This predicate must return 0 if the instruction has 72/// any side effects other than loading from the stack slot. 73unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 74 int &FrameIndex) const { 75 if (MI->getOpcode() == SP::LDri || 76 MI->getOpcode() == SP::LDFri || 77 MI->getOpcode() == SP::LDDFri) { 78 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 79 MI->getOperand(2).getImm() == 0) { 80 FrameIndex = MI->getOperand(1).getIndex(); 81 return MI->getOperand(0).getReg(); 82 } 83 } 84 return 0; 85} 86 87/// isStoreToStackSlot - If the specified machine instruction is a direct 88/// store to a stack slot, return the virtual or physical register number of 89/// the source reg along with the FrameIndex of the loaded stack slot. If 90/// not, return 0. This predicate must return 0 if the instruction has 91/// any side effects other than storing to the stack slot. 92unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 93 int &FrameIndex) const { 94 if (MI->getOpcode() == SP::STri || 95 MI->getOpcode() == SP::STFri || 96 MI->getOpcode() == SP::STDFri) { 97 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && 98 MI->getOperand(1).getImm() == 0) { 99 FrameIndex = MI->getOperand(0).getIndex(); 100 return MI->getOperand(2).getReg(); 101 } 102 } 103 return 0; 104} 105 106unsigned 107SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 108 MachineBasicBlock *FBB, 109 const SmallVectorImpl<MachineOperand> &Cond)const{ 110 // Can only insert uncond branches so far. 111 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 112 BuildMI(&MBB, get(SP::BA)).addMBB(TBB); 113 return 1; 114} 115 116bool SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 117 MachineBasicBlock::iterator I, 118 unsigned DestReg, unsigned SrcReg, 119 const TargetRegisterClass *DestRC, 120 const TargetRegisterClass *SrcRC) const { 121 if (DestRC != SrcRC) { 122 // Not yet supported! 123 return false; 124 } 125 126 DebugLoc DL = DebugLoc::getUnknownLoc(); 127 if (I != MBB.end()) DL = I->getDebugLoc(); 128 129 if (DestRC == SP::IntRegsRegisterClass) 130 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 131 else if (DestRC == SP::FPRegsRegisterClass) 132 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg).addReg(SrcReg); 133 else if (DestRC == SP::DFPRegsRegisterClass) 134 BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 135 .addReg(SrcReg); 136 else 137 // Can't copy this register 138 return false; 139 140 return true; 141} 142 143void SparcInstrInfo:: 144storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 145 unsigned SrcReg, bool isKill, int FI, 146 const TargetRegisterClass *RC) const { 147 DebugLoc DL = DebugLoc::getUnknownLoc(); 148 if (I != MBB.end()) DL = I->getDebugLoc(); 149 150 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 151 if (RC == SP::IntRegsRegisterClass) 152 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 153 .addReg(SrcReg, false, false, isKill); 154 else if (RC == SP::FPRegsRegisterClass) 155 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 156 .addReg(SrcReg, false, false, isKill); 157 else if (RC == SP::DFPRegsRegisterClass) 158 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 159 .addReg(SrcReg, false, false, isKill); 160 else 161 assert(0 && "Can't store this register to stack slot"); 162} 163 164void SparcInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 165 bool isKill, 166 SmallVectorImpl<MachineOperand> &Addr, 167 const TargetRegisterClass *RC, 168 SmallVectorImpl<MachineInstr*> &NewMIs) const { 169 unsigned Opc = 0; 170 DebugLoc DL = DebugLoc::getUnknownLoc(); 171 if (RC == SP::IntRegsRegisterClass) 172 Opc = SP::STri; 173 else if (RC == SP::FPRegsRegisterClass) 174 Opc = SP::STFri; 175 else if (RC == SP::DFPRegsRegisterClass) 176 Opc = SP::STDFri; 177 else 178 assert(0 && "Can't load this register"); 179 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)); 180 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 181 MachineOperand &MO = Addr[i]; 182 if (MO.isReg()) 183 MIB.addReg(MO.getReg()); 184 else if (MO.isImm()) 185 MIB.addImm(MO.getImm()); 186 else { 187 assert(MO.isFI()); 188 MIB.addFrameIndex(MO.getIndex()); 189 } 190 } 191 MIB.addReg(SrcReg, false, false, isKill); 192 NewMIs.push_back(MIB); 193 return; 194} 195 196void SparcInstrInfo:: 197loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 198 unsigned DestReg, int FI, 199 const TargetRegisterClass *RC) const { 200 DebugLoc DL = DebugLoc::getUnknownLoc(); 201 if (I != MBB.end()) DL = I->getDebugLoc(); 202 203 if (RC == SP::IntRegsRegisterClass) 204 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 205 else if (RC == SP::FPRegsRegisterClass) 206 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 207 else if (RC == SP::DFPRegsRegisterClass) 208 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 209 else 210 assert(0 && "Can't load this register from stack slot"); 211} 212 213void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 214 SmallVectorImpl<MachineOperand> &Addr, 215 const TargetRegisterClass *RC, 216 SmallVectorImpl<MachineInstr*> &NewMIs) const { 217 unsigned Opc = 0; 218 if (RC == SP::IntRegsRegisterClass) 219 Opc = SP::LDri; 220 else if (RC == SP::FPRegsRegisterClass) 221 Opc = SP::LDFri; 222 else if (RC == SP::DFPRegsRegisterClass) 223 Opc = SP::LDDFri; 224 else 225 assert(0 && "Can't load this register"); 226 DebugLoc DL = DebugLoc::getUnknownLoc(); 227 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); 228 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 229 MachineOperand &MO = Addr[i]; 230 if (MO.isReg()) 231 MIB.addReg(MO.getReg()); 232 else if (MO.isImm()) 233 MIB.addImm(MO.getImm()); 234 else { 235 assert(MO.isFI()); 236 MIB.addFrameIndex(MO.getIndex()); 237 } 238 } 239 NewMIs.push_back(MIB); 240 return; 241} 242 243MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 244 MachineInstr* MI, 245 const SmallVectorImpl<unsigned> &Ops, 246 int FI) const { 247 if (Ops.size() != 1) return NULL; 248 249 unsigned OpNum = Ops[0]; 250 bool isFloat = false; 251 MachineInstr *NewMI = NULL; 252 switch (MI->getOpcode()) { 253 case SP::ORrr: 254 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 255 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 256 if (OpNum == 0) // COPY -> STORE 257 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::STri)) 258 .addFrameIndex(FI) 259 .addImm(0) 260 .addReg(MI->getOperand(2).getReg()); 261 else // COPY -> LOAD 262 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::LDri), 263 MI->getOperand(0).getReg()) 264 .addFrameIndex(FI) 265 .addImm(0); 266 } 267 break; 268 case SP::FMOVS: 269 isFloat = true; 270 // FALLTHROUGH 271 case SP::FMOVD: 272 if (OpNum == 0) { // COPY -> STORE 273 unsigned SrcReg = MI->getOperand(1).getReg(); 274 bool isKill = MI->getOperand(1).isKill(); 275 NewMI = BuildMI(MF, MI->getDebugLoc(), 276 get(isFloat ? SP::STFri : SP::STDFri)) 277 .addFrameIndex(FI) 278 .addImm(0) 279 .addReg(SrcReg, false, false, isKill); 280 } else { // COPY -> LOAD 281 unsigned DstReg = MI->getOperand(0).getReg(); 282 bool isDead = MI->getOperand(0).isDead(); 283 NewMI = BuildMI(MF, MI->getDebugLoc(), 284 get(isFloat ? SP::LDFri : SP::LDDFri)) 285 .addReg(DstReg, true, false, false, isDead) 286 .addFrameIndex(FI) 287 .addImm(0); 288 } 289 break; 290 } 291 292 return NewMI; 293} 294