1 //===- MBlazeInstrInfo.cpp - MBlaze 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 MBlaze implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MBlazeInstrInfo.h" 15 #include "MBlazeTargetMachine.h" 16 #include "MBlazeMachineFunction.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" 20 #include "llvm/Support/CommandLine.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include "llvm/Support/TargetRegistry.h" 23 #include "llvm/ADT/STLExtras.h" 24 25 #define GET_INSTRINFO_CTOR 26 #include "MBlazeGenInstrInfo.inc" 27 28 using namespace llvm; 29 30 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm) 31 : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP), 32 TM(tm), RI(*TM.getSubtargetImpl(), *this) {} 33 34 static bool isZeroImm(const MachineOperand &op) { 35 return op.isImm() && op.getImm() == 0; 36 } 37 38 /// isLoadFromStackSlot - If the specified machine instruction is a direct 39 /// load from a stack slot, return the virtual or physical register number of 40 /// the destination along with the FrameIndex of the loaded stack slot. If 41 /// not, return 0. This predicate must return 0 if the instruction has 42 /// any side effects other than loading from the stack slot. 43 unsigned MBlazeInstrInfo:: 44 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { 45 if (MI->getOpcode() == MBlaze::LWI) { 46 if ((MI->getOperand(1).isFI()) && // is a stack slot 47 (MI->getOperand(2).isImm()) && // the imm is zero 48 (isZeroImm(MI->getOperand(2)))) { 49 FrameIndex = MI->getOperand(1).getIndex(); 50 return MI->getOperand(0).getReg(); 51 } 52 } 53 54 return 0; 55 } 56 57 /// isStoreToStackSlot - If the specified machine instruction is a direct 58 /// store to a stack slot, return the virtual or physical register number of 59 /// the source reg along with the FrameIndex of the loaded stack slot. If 60 /// not, return 0. This predicate must return 0 if the instruction has 61 /// any side effects other than storing to the stack slot. 62 unsigned MBlazeInstrInfo:: 63 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { 64 if (MI->getOpcode() == MBlaze::SWI) { 65 if ((MI->getOperand(1).isFI()) && // is a stack slot 66 (MI->getOperand(2).isImm()) && // the imm is zero 67 (isZeroImm(MI->getOperand(2)))) { 68 FrameIndex = MI->getOperand(1).getIndex(); 69 return MI->getOperand(0).getReg(); 70 } 71 } 72 return 0; 73 } 74 75 /// insertNoop - If data hazard condition is found insert the target nop 76 /// instruction. 77 void MBlazeInstrInfo:: 78 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { 79 DebugLoc DL; 80 BuildMI(MBB, MI, DL, get(MBlaze::NOP)); 81 } 82 83 void MBlazeInstrInfo:: 84 copyPhysReg(MachineBasicBlock &MBB, 85 MachineBasicBlock::iterator I, DebugLoc DL, 86 unsigned DestReg, unsigned SrcReg, 87 bool KillSrc) const { 88 llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg) 89 .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0); 90 } 91 92 void MBlazeInstrInfo:: 93 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 94 unsigned SrcReg, bool isKill, int FI, 95 const TargetRegisterClass *RC, 96 const TargetRegisterInfo *TRI) const { 97 DebugLoc DL; 98 BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill)) 99 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 100 } 101 102 void MBlazeInstrInfo:: 103 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 104 unsigned DestReg, int FI, 105 const TargetRegisterClass *RC, 106 const TargetRegisterInfo *TRI) const { 107 DebugLoc DL; 108 BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg) 109 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 110 } 111 112 //===----------------------------------------------------------------------===// 113 // Branch Analysis 114 //===----------------------------------------------------------------------===// 115 bool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 116 MachineBasicBlock *&TBB, 117 MachineBasicBlock *&FBB, 118 SmallVectorImpl<MachineOperand> &Cond, 119 bool AllowModify) const { 120 // If the block has no terminators, it just falls into the block after it. 121 MachineBasicBlock::iterator I = MBB.end(); 122 if (I == MBB.begin()) 123 return false; 124 --I; 125 while (I->isDebugValue()) { 126 if (I == MBB.begin()) 127 return false; 128 --I; 129 } 130 if (!isUnpredicatedTerminator(I)) 131 return false; 132 133 // Get the last instruction in the block. 134 MachineInstr *LastInst = I; 135 136 // If there is only one terminator instruction, process it. 137 unsigned LastOpc = LastInst->getOpcode(); 138 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 139 if (MBlaze::isUncondBranchOpcode(LastOpc)) { 140 TBB = LastInst->getOperand(0).getMBB(); 141 return false; 142 } 143 if (MBlaze::isCondBranchOpcode(LastOpc)) { 144 // Block ends with fall-through condbranch. 145 TBB = LastInst->getOperand(1).getMBB(); 146 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 147 Cond.push_back(LastInst->getOperand(0)); 148 return false; 149 } 150 // Otherwise, don't know what this is. 151 return true; 152 } 153 154 // Get the instruction before it if it's a terminator. 155 MachineInstr *SecondLastInst = I; 156 157 // If there are three terminators, we don't know what sort of block this is. 158 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 159 return true; 160 161 // If the block ends with something like BEQID then BRID, handle it. 162 if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) && 163 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 164 TBB = SecondLastInst->getOperand(1).getMBB(); 165 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode())); 166 Cond.push_back(SecondLastInst->getOperand(0)); 167 FBB = LastInst->getOperand(0).getMBB(); 168 return false; 169 } 170 171 // If the block ends with two unconditional branches, handle it. 172 // The second one is not executed, so remove it. 173 if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) && 174 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 175 TBB = SecondLastInst->getOperand(0).getMBB(); 176 I = LastInst; 177 if (AllowModify) 178 I->eraseFromParent(); 179 return false; 180 } 181 182 // Otherwise, can't handle this. 183 return true; 184 } 185 186 unsigned MBlazeInstrInfo:: 187 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 188 MachineBasicBlock *FBB, 189 const SmallVectorImpl<MachineOperand> &Cond, 190 DebugLoc DL) const { 191 // Shouldn't be a fall through. 192 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 193 assert((Cond.size() == 2 || Cond.size() == 0) && 194 "MBlaze branch conditions have two components!"); 195 196 unsigned Opc = MBlaze::BRID; 197 if (!Cond.empty()) 198 Opc = (unsigned)Cond[0].getImm(); 199 200 if (FBB == 0) { 201 if (Cond.empty()) // Unconditional branch 202 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB); 203 else // Conditional branch 204 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 205 return 1; 206 } 207 208 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 209 BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB); 210 return 2; 211 } 212 213 unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 214 MachineBasicBlock::iterator I = MBB.end(); 215 if (I == MBB.begin()) return 0; 216 --I; 217 while (I->isDebugValue()) { 218 if (I == MBB.begin()) 219 return 0; 220 --I; 221 } 222 223 if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) && 224 !MBlaze::isCondBranchOpcode(I->getOpcode())) 225 return 0; 226 227 // Remove the branch. 228 I->eraseFromParent(); 229 230 I = MBB.end(); 231 232 if (I == MBB.begin()) return 1; 233 --I; 234 if (!MBlaze::isCondBranchOpcode(I->getOpcode())) 235 return 1; 236 237 // Remove the branch. 238 I->eraseFromParent(); 239 return 2; 240 } 241 242 bool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> 243 &Cond) const { 244 assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!"); 245 switch (Cond[0].getImm()) { 246 default: return true; 247 case MBlaze::BEQ: Cond[0].setImm(MBlaze::BNE); return false; 248 case MBlaze::BNE: Cond[0].setImm(MBlaze::BEQ); return false; 249 case MBlaze::BGT: Cond[0].setImm(MBlaze::BLE); return false; 250 case MBlaze::BGE: Cond[0].setImm(MBlaze::BLT); return false; 251 case MBlaze::BLT: Cond[0].setImm(MBlaze::BGE); return false; 252 case MBlaze::BLE: Cond[0].setImm(MBlaze::BGT); return false; 253 case MBlaze::BEQI: Cond[0].setImm(MBlaze::BNEI); return false; 254 case MBlaze::BNEI: Cond[0].setImm(MBlaze::BEQI); return false; 255 case MBlaze::BGTI: Cond[0].setImm(MBlaze::BLEI); return false; 256 case MBlaze::BGEI: Cond[0].setImm(MBlaze::BLTI); return false; 257 case MBlaze::BLTI: Cond[0].setImm(MBlaze::BGEI); return false; 258 case MBlaze::BLEI: Cond[0].setImm(MBlaze::BGTI); return false; 259 case MBlaze::BEQD: Cond[0].setImm(MBlaze::BNED); return false; 260 case MBlaze::BNED: Cond[0].setImm(MBlaze::BEQD); return false; 261 case MBlaze::BGTD: Cond[0].setImm(MBlaze::BLED); return false; 262 case MBlaze::BGED: Cond[0].setImm(MBlaze::BLTD); return false; 263 case MBlaze::BLTD: Cond[0].setImm(MBlaze::BGED); return false; 264 case MBlaze::BLED: Cond[0].setImm(MBlaze::BGTD); return false; 265 case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false; 266 case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false; 267 case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false; 268 case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false; 269 case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false; 270 case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false; 271 } 272 } 273 274 /// getGlobalBaseReg - Return a virtual register initialized with the 275 /// the global base register value. Output instructions required to 276 /// initialize the register in the function entry block, if necessary. 277 /// 278 unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 279 MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>(); 280 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg(); 281 if (GlobalBaseReg != 0) 282 return GlobalBaseReg; 283 284 // Insert the set of GlobalBaseReg into the first MBB of the function 285 MachineBasicBlock &FirstMBB = MF->front(); 286 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 287 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 288 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 289 290 GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::GPRRegisterClass); 291 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), 292 GlobalBaseReg).addReg(MBlaze::R20); 293 RegInfo.addLiveIn(MBlaze::R20); 294 295 MBlazeFI->setGlobalBaseReg(GlobalBaseReg); 296 return GlobalBaseReg; 297 } 298