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" 21 using namespace llvm; 22 23 SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 24 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 25 RI(ST, *this), Subtarget(ST) { 26 } 27 28 static 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 /// 35 bool 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. 73 unsigned 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. 92 unsigned 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 106 unsigned 107 SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 108 MachineBasicBlock *FBB, 109 const SmallVectorImpl<MachineOperand> &Cond)const{ 110 // FIXME this should probably take a DebugLoc argument 111 DebugLoc dl = DebugLoc::getUnknownLoc(); 112 // Can only insert uncond branches so far. 113 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 114 BuildMI(&MBB, dl, get(SP::BA)).addMBB(TBB); 115 return 1; 116 } 117 118 bool SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 119 MachineBasicBlock::iterator I, 120 unsigned DestReg, unsigned SrcReg, 121 const TargetRegisterClass *DestRC, 122 const TargetRegisterClass *SrcRC) const { 123 if (DestRC != SrcRC) { 124 // Not yet supported! 125 return false; 126 } 127 128 DebugLoc DL = DebugLoc::getUnknownLoc(); 129 if (I != MBB.end()) DL = I->getDebugLoc(); 130 131 if (DestRC == SP::IntRegsRegisterClass) 132 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 133 else if (DestRC == SP::FPRegsRegisterClass) 134 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg).addReg(SrcReg); 135 else if (DestRC == SP::DFPRegsRegisterClass) 136 BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 137 .addReg(SrcReg); 138 else 139 // Can't copy this register 140 return false; 141 142 return true; 143 } 144 145 void SparcInstrInfo:: 146 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 147 unsigned SrcReg, bool isKill, int FI, 148 const TargetRegisterClass *RC) const { 149 DebugLoc DL = DebugLoc::getUnknownLoc(); 150 if (I != MBB.end()) DL = I->getDebugLoc(); 151 152 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 153 if (RC == SP::IntRegsRegisterClass) 154 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 155 .addReg(SrcReg, getKillRegState(isKill)); 156 else if (RC == SP::FPRegsRegisterClass) 157 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 158 .addReg(SrcReg, getKillRegState(isKill)); 159 else if (RC == SP::DFPRegsRegisterClass) 160 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 161 .addReg(SrcReg, getKillRegState(isKill)); 162 else 163 assert(0 && "Can't store this register to stack slot"); 164 } 165 166 void SparcInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 167 bool isKill, 168 SmallVectorImpl<MachineOperand> &Addr, 169 const TargetRegisterClass *RC, 170 SmallVectorImpl<MachineInstr*> &NewMIs) const { 171 unsigned Opc = 0; 172 DebugLoc DL = DebugLoc::getUnknownLoc(); 173 if (RC == SP::IntRegsRegisterClass) 174 Opc = SP::STri; 175 else if (RC == SP::FPRegsRegisterClass) 176 Opc = SP::STFri; 177 else if (RC == SP::DFPRegsRegisterClass) 178 Opc = SP::STDFri; 179 else 180 assert(0 && "Can't load this register"); 181 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)); 182 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 183 MIB.addOperand(Addr[i]); 184 MIB.addReg(SrcReg, getKillRegState(isKill)); 185 NewMIs.push_back(MIB); 186 return; 187 } 188 189 void SparcInstrInfo:: 190 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 191 unsigned DestReg, int FI, 192 const TargetRegisterClass *RC) const { 193 DebugLoc DL = DebugLoc::getUnknownLoc(); 194 if (I != MBB.end()) DL = I->getDebugLoc(); 195 196 if (RC == SP::IntRegsRegisterClass) 197 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 198 else if (RC == SP::FPRegsRegisterClass) 199 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 200 else if (RC == SP::DFPRegsRegisterClass) 201 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 202 else 203 assert(0 && "Can't load this register from stack slot"); 204 } 205 206 void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 207 SmallVectorImpl<MachineOperand> &Addr, 208 const TargetRegisterClass *RC, 209 SmallVectorImpl<MachineInstr*> &NewMIs) const { 210 unsigned Opc = 0; 211 if (RC == SP::IntRegsRegisterClass) 212 Opc = SP::LDri; 213 else if (RC == SP::FPRegsRegisterClass) 214 Opc = SP::LDFri; 215 else if (RC == SP::DFPRegsRegisterClass) 216 Opc = SP::LDDFri; 217 else 218 assert(0 && "Can't load this register"); 219 DebugLoc DL = DebugLoc::getUnknownLoc(); 220 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); 221 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 222 MIB.addOperand(Addr[i]); 223 NewMIs.push_back(MIB); 224 return; 225 } 226 227 MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 228 MachineInstr* MI, 229 const SmallVectorImpl<unsigned> &Ops, 230 int FI) const { 231 if (Ops.size() != 1) return NULL; 232 233 unsigned OpNum = Ops[0]; 234 bool isFloat = false; 235 MachineInstr *NewMI = NULL; 236 switch (MI->getOpcode()) { 237 case SP::ORrr: 238 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 239 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 240 if (OpNum == 0) // COPY -> STORE 241 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::STri)) 242 .addFrameIndex(FI) 243 .addImm(0) 244 .addReg(MI->getOperand(2).getReg()); 245 else // COPY -> LOAD 246 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::LDri), 247 MI->getOperand(0).getReg()) 248 .addFrameIndex(FI) 249 .addImm(0); 250 } 251 break; 252 case SP::FMOVS: 253 isFloat = true; 254 // FALLTHROUGH 255 case SP::FMOVD: 256 if (OpNum == 0) { // COPY -> STORE 257 unsigned SrcReg = MI->getOperand(1).getReg(); 258 bool isKill = MI->getOperand(1).isKill(); 259 bool isUndef = MI->getOperand(1).isUndef(); 260 NewMI = BuildMI(MF, MI->getDebugLoc(), 261 get(isFloat ? SP::STFri : SP::STDFri)) 262 .addFrameIndex(FI) 263 .addImm(0) 264 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)); 265 } else { // COPY -> LOAD 266 unsigned DstReg = MI->getOperand(0).getReg(); 267 bool isDead = MI->getOperand(0).isDead(); 268 bool isUndef = MI->getOperand(0).isUndef(); 269 NewMI = BuildMI(MF, MI->getDebugLoc(), 270 get(isFloat ? SP::LDFri : SP::LDDFri)) 271 .addReg(DstReg, RegState::Define | 272 getDeadRegState(isDead) | getUndefRegState(isUndef)) 273 .addFrameIndex(FI) 274 .addImm(0); 275 } 276 break; 277 } 278 279 return NewMI; 280 } 281