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