1 //===- BlackfinInstrInfo.cpp - Blackfin 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 Blackfin implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "BlackfinInstrInfo.h" 15 #include "BlackfinSubtarget.h" 16 #include "Blackfin.h" 17 #include "llvm/CodeGen/MachineRegisterInfo.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 #define GET_INSTRINFO_CTOR 25 #include "BlackfinGenInstrInfo.inc" 26 27 using namespace llvm; 28 29 BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget &ST) 30 : BlackfinGenInstrInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP), 31 RI(ST, *this), 32 Subtarget(ST) {} 33 34 /// isLoadFromStackSlot - If the specified machine instruction is a direct 35 /// load from a stack slot, return the virtual or physical register number of 36 /// the destination along with the FrameIndex of the loaded stack slot. If 37 /// not, return 0. This predicate must return 0 if the instruction has 38 /// any side effects other than loading from the stack slot. 39 unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 40 int &FrameIndex) const { 41 switch (MI->getOpcode()) { 42 default: break; 43 case BF::LOAD32fi: 44 case BF::LOAD16fi: 45 if (MI->getOperand(1).isFI() && 46 MI->getOperand(2).isImm() && 47 MI->getOperand(2).getImm() == 0) { 48 FrameIndex = MI->getOperand(1).getIndex(); 49 return MI->getOperand(0).getReg(); 50 } 51 break; 52 } 53 return 0; 54 } 55 56 /// isStoreToStackSlot - If the specified machine instruction is a direct 57 /// store to a stack slot, return the virtual or physical register number of 58 /// the source reg along with the FrameIndex of the loaded stack slot. If 59 /// not, return 0. This predicate must return 0 if the instruction has 60 /// any side effects other than storing to the stack slot. 61 unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 62 int &FrameIndex) const { 63 switch (MI->getOpcode()) { 64 default: break; 65 case BF::STORE32fi: 66 case BF::STORE16fi: 67 if (MI->getOperand(1).isFI() && 68 MI->getOperand(2).isImm() && 69 MI->getOperand(2).getImm() == 0) { 70 FrameIndex = MI->getOperand(1).getIndex(); 71 return MI->getOperand(0).getReg(); 72 } 73 break; 74 } 75 return 0; 76 } 77 78 unsigned BlackfinInstrInfo:: 79 InsertBranch(MachineBasicBlock &MBB, 80 MachineBasicBlock *TBB, 81 MachineBasicBlock *FBB, 82 const SmallVectorImpl<MachineOperand> &Cond, 83 DebugLoc DL) const { 84 // Shouldn't be a fall through. 85 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 86 assert((Cond.size() == 1 || Cond.size() == 0) && 87 "Branch conditions have one component!"); 88 89 if (Cond.empty()) { 90 // Unconditional branch? 91 assert(!FBB && "Unconditional branch with multiple successors!"); 92 BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB); 93 return 1; 94 } 95 96 // Conditional branch. 97 llvm_unreachable("Implement conditional branches!"); 98 } 99 100 void BlackfinInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 101 MachineBasicBlock::iterator I, DebugLoc DL, 102 unsigned DestReg, unsigned SrcReg, 103 bool KillSrc) const { 104 if (BF::ALLRegClass.contains(DestReg, SrcReg)) { 105 BuildMI(MBB, I, DL, get(BF::MOVE), DestReg) 106 .addReg(SrcReg, getKillRegState(KillSrc)); 107 return; 108 } 109 110 if (BF::D16RegClass.contains(DestReg, SrcReg)) { 111 BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg) 112 .addReg(SrcReg, getKillRegState(KillSrc)) 113 .addImm(0); 114 return; 115 } 116 117 if (BF::DRegClass.contains(DestReg)) { 118 if (SrcReg == BF::NCC) { 119 BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg) 120 .addReg(SrcReg, getKillRegState(KillSrc)); 121 BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0); 122 return; 123 } 124 if (SrcReg == BF::CC) { 125 BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg) 126 .addReg(SrcReg, getKillRegState(KillSrc)); 127 return; 128 } 129 } 130 131 if (BF::DRegClass.contains(SrcReg)) { 132 if (DestReg == BF::NCC) { 133 BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg) 134 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(0); 135 return; 136 } 137 if (DestReg == BF::CC) { 138 BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg) 139 .addReg(SrcReg, getKillRegState(KillSrc)); 140 return; 141 } 142 } 143 144 145 if (DestReg == BF::NCC && SrcReg == BF::CC) { 146 BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg) 147 .addReg(SrcReg, getKillRegState(KillSrc)); 148 return; 149 } 150 151 if (DestReg == BF::CC && SrcReg == BF::NCC) { 152 BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg) 153 .addReg(SrcReg, getKillRegState(KillSrc)); 154 return; 155 } 156 157 llvm_unreachable("Bad reg-to-reg copy"); 158 } 159 160 static bool inClass(const TargetRegisterClass &Test, 161 unsigned Reg, 162 const TargetRegisterClass *RC) { 163 if (TargetRegisterInfo::isPhysicalRegister(Reg)) 164 return Test.contains(Reg); 165 else 166 return Test.hasSubClassEq(RC); 167 } 168 169 void 170 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 171 MachineBasicBlock::iterator I, 172 unsigned SrcReg, 173 bool isKill, 174 int FI, 175 const TargetRegisterClass *RC, 176 const TargetRegisterInfo *TRI) const { 177 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 178 179 if (inClass(BF::DPRegClass, SrcReg, RC)) { 180 BuildMI(MBB, I, DL, get(BF::STORE32fi)) 181 .addReg(SrcReg, getKillRegState(isKill)) 182 .addFrameIndex(FI) 183 .addImm(0); 184 return; 185 } 186 187 if (inClass(BF::D16RegClass, SrcReg, RC)) { 188 BuildMI(MBB, I, DL, get(BF::STORE16fi)) 189 .addReg(SrcReg, getKillRegState(isKill)) 190 .addFrameIndex(FI) 191 .addImm(0); 192 return; 193 } 194 195 if (inClass(BF::AnyCCRegClass, SrcReg, RC)) { 196 BuildMI(MBB, I, DL, get(BF::STORE8fi)) 197 .addReg(SrcReg, getKillRegState(isKill)) 198 .addFrameIndex(FI) 199 .addImm(0); 200 return; 201 } 202 203 llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+ 204 RC->getName()).c_str()); 205 } 206 207 void BlackfinInstrInfo:: 208 storeRegToAddr(MachineFunction &MF, 209 unsigned SrcReg, 210 bool isKill, 211 SmallVectorImpl<MachineOperand> &Addr, 212 const TargetRegisterClass *RC, 213 SmallVectorImpl<MachineInstr*> &NewMIs) const { 214 llvm_unreachable("storeRegToAddr not implemented"); 215 } 216 217 void 218 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 219 MachineBasicBlock::iterator I, 220 unsigned DestReg, 221 int FI, 222 const TargetRegisterClass *RC, 223 const TargetRegisterInfo *TRI) const { 224 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 225 if (inClass(BF::DPRegClass, DestReg, RC)) { 226 BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg) 227 .addFrameIndex(FI) 228 .addImm(0); 229 return; 230 } 231 232 if (inClass(BF::D16RegClass, DestReg, RC)) { 233 BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg) 234 .addFrameIndex(FI) 235 .addImm(0); 236 return; 237 } 238 239 if (inClass(BF::AnyCCRegClass, DestReg, RC)) { 240 BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg) 241 .addFrameIndex(FI) 242 .addImm(0); 243 return; 244 } 245 246 llvm_unreachable("Cannot load regclass from stack slot"); 247 } 248 249 void BlackfinInstrInfo:: 250 loadRegFromAddr(MachineFunction &MF, 251 unsigned DestReg, 252 SmallVectorImpl<MachineOperand> &Addr, 253 const TargetRegisterClass *RC, 254 SmallVectorImpl<MachineInstr*> &NewMIs) const { 255 llvm_unreachable("loadRegFromAddr not implemented"); 256 } 257