20#include "MipsGenInstrInfo.inc" 21 22using namespace llvm; 23 24MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm) 25 : TargetInstrInfoImpl(MipsInsts, array_lengthof(MipsInsts)), 26 TM(tm), RI(*TM.getSubtargetImpl(), *this) {} 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. 34bool MipsInstrInfo:: 35isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, 36 unsigned &SrcSubIdx, unsigned &DstSubIdx) const 37{ 38 SrcSubIdx = DstSubIdx = 0; // No sub-registers. 39 40 // addu $dst, $src, $zero || addu $dst, $zero, $src 41 // or $dst, $src, $zero || or $dst, $zero, $src 42 if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR)) { 43 if (MI.getOperand(1).getReg() == Mips::ZERO) { 44 DstReg = MI.getOperand(0).getReg(); 45 SrcReg = MI.getOperand(2).getReg(); 46 return true; 47 } else if (MI.getOperand(2).getReg() == Mips::ZERO) { 48 DstReg = MI.getOperand(0).getReg(); 49 SrcReg = MI.getOperand(1).getReg(); 50 return true; 51 } 52 } 53 54 // mov $fpDst, $fpSrc 55 // mfc $gpDst, $fpSrc 56 // mtc $fpDst, $gpSrc 57 if (MI.getOpcode() == Mips::FMOV_S32 || 58 MI.getOpcode() == Mips::FMOV_D32 || 59 MI.getOpcode() == Mips::MFC1 || 60 MI.getOpcode() == Mips::MTC1 || 61 MI.getOpcode() == Mips::MOVCCRToCCR) { 62 DstReg = MI.getOperand(0).getReg(); 63 SrcReg = MI.getOperand(1).getReg(); 64 return true; 65 } 66 67 // addiu $dst, $src, 0 68 if (MI.getOpcode() == Mips::ADDiu) { 69 if ((MI.getOperand(1).isReg()) && (isZeroImm(MI.getOperand(2)))) { 70 DstReg = MI.getOperand(0).getReg(); 71 SrcReg = MI.getOperand(1).getReg(); 72 return true; 73 } 74 } 75 76 return false; 77} 78 79/// isLoadFromStackSlot - If the specified machine instruction is a direct 80/// load from a stack slot, return the virtual or physical register number of 81/// the destination along with the FrameIndex of the loaded stack slot. If 82/// not, return 0. This predicate must return 0 if the instruction has 83/// any side effects other than loading from the stack slot. 84unsigned MipsInstrInfo:: 85isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 86{ 87 if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) || 88 (MI->getOpcode() == Mips::LDC1)) { 89 if ((MI->getOperand(2).isFI()) && // is a stack slot 90 (MI->getOperand(1).isImm()) && // the imm is zero 91 (isZeroImm(MI->getOperand(1)))) { 92 FrameIndex = MI->getOperand(2).getIndex(); 93 return MI->getOperand(0).getReg(); 94 } 95 } 96 97 return 0; 98} 99 100/// isStoreToStackSlot - If the specified machine instruction is a direct 101/// store to a stack slot, return the virtual or physical register number of 102/// the source reg along with the FrameIndex of the loaded stack slot. If 103/// not, return 0. This predicate must return 0 if the instruction has 104/// any side effects other than storing to the stack slot. 105unsigned MipsInstrInfo:: 106isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 107{ 108 if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) || 109 (MI->getOpcode() == Mips::SDC1)) { 110 if ((MI->getOperand(2).isFI()) && // is a stack slot 111 (MI->getOperand(1).isImm()) && // the imm is zero 112 (isZeroImm(MI->getOperand(1)))) { 113 FrameIndex = MI->getOperand(2).getIndex(); 114 return MI->getOperand(0).getReg(); 115 } 116 } 117 return 0; 118} 119 120/// insertNoop - If data hazard condition is found insert the target nop 121/// instruction. 122void MipsInstrInfo:: 123insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const 124{ 125 DebugLoc DL = DebugLoc::getUnknownLoc(); 126 if (MI != MBB.end()) DL = MI->getDebugLoc(); 127 BuildMI(MBB, MI, DL, get(Mips::NOP)); 128} 129 130bool MipsInstrInfo:: 131copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 132 unsigned DestReg, unsigned SrcReg, 133 const TargetRegisterClass *DestRC, 134 const TargetRegisterClass *SrcRC) const { 135 DebugLoc DL = DebugLoc::getUnknownLoc(); 136 if (I != MBB.end()) DL = I->getDebugLoc(); 137 138 if (DestRC != SrcRC) { 139 140 // Copy to/from FCR31 condition register 141 if ((DestRC == Mips::CPURegsRegisterClass) && 142 (SrcRC == Mips::CCRRegisterClass)) 143 BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg).addReg(SrcReg); 144 else if ((DestRC == Mips::CCRRegisterClass) && 145 (SrcRC == Mips::CPURegsRegisterClass)) 146 BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg).addReg(SrcReg); 147 148 // Moves between coprocessors and cpu 149 else if ((DestRC == Mips::CPURegsRegisterClass) && 150 (SrcRC == Mips::FGR32RegisterClass)) 151 BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg).addReg(SrcReg); 152 else if ((DestRC == Mips::FGR32RegisterClass) && 153 (SrcRC == Mips::CPURegsRegisterClass)) 154 BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg); 155 156 // Move from/to Hi/Lo registers 157 else if ((DestRC == Mips::HILORegisterClass) && 158 (SrcRC == Mips::CPURegsRegisterClass)) { 159 unsigned Opc = (DestReg == Mips::HI) ? Mips::MTHI : Mips::MTLO; 160 BuildMI(MBB, I, DL, get(Opc), DestReg); 161 } else if ((SrcRC == Mips::HILORegisterClass) && 162 (DestRC == Mips::CPURegsRegisterClass)) { 163 unsigned Opc = (SrcReg == Mips::HI) ? Mips::MFHI : Mips::MFLO; 164 BuildMI(MBB, I, DL, get(Opc), DestReg); 165 166 // Can't copy this register 167 } else 168 return false; 169 170 return true; 171 } 172 173 if (DestRC == Mips::CPURegsRegisterClass) 174 BuildMI(MBB, I, DL, get(Mips::ADDu), DestReg).addReg(Mips::ZERO) 175 .addReg(SrcReg); 176 else if (DestRC == Mips::FGR32RegisterClass) 177 BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg).addReg(SrcReg); 178 else if (DestRC == Mips::AFGR64RegisterClass) 179 BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg).addReg(SrcReg); 180 else if (DestRC == Mips::CCRRegisterClass) 181 BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg).addReg(SrcReg); 182 else 183 // Can't copy this register 184 return false; 185 186 return true; 187} 188 189void MipsInstrInfo:: 190storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 191 unsigned SrcReg, bool isKill, int FI, 192 const TargetRegisterClass *RC) const { 193 unsigned Opc; 194 195 DebugLoc DL = DebugLoc::getUnknownLoc(); 196 if (I != MBB.end()) DL = I->getDebugLoc(); 197 198 if (RC == Mips::CPURegsRegisterClass) 199 Opc = Mips::SW; 200 else if (RC == Mips::FGR32RegisterClass) 201 Opc = Mips::SWC1; 202 else { 203 assert(RC == Mips::AFGR64RegisterClass); 204 Opc = Mips::SDC1; 205 } 206 207 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 208 .addImm(0).addFrameIndex(FI); 209} 210 211void MipsInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 212 bool isKill, SmallVectorImpl<MachineOperand> &Addr, 213 const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs) const 214{ 215 unsigned Opc; 216 if (RC == Mips::CPURegsRegisterClass) 217 Opc = Mips::SW; 218 else if (RC == Mips::FGR32RegisterClass) 219 Opc = Mips::SWC1; 220 else { 221 assert(RC == Mips::AFGR64RegisterClass); 222 Opc = Mips::SDC1; 223 } 224 225 DebugLoc DL = DebugLoc::getUnknownLoc(); 226 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)) 227 .addReg(SrcReg, getKillRegState(isKill)); 228 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 229 MIB.addOperand(Addr[i]); 230 NewMIs.push_back(MIB); 231 return; 232} 233 234void MipsInstrInfo:: 235loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 236 unsigned DestReg, int FI, 237 const TargetRegisterClass *RC) const 238{ 239 unsigned Opc; 240 if (RC == Mips::CPURegsRegisterClass) 241 Opc = Mips::LW; 242 else if (RC == Mips::FGR32RegisterClass) 243 Opc = Mips::LWC1; 244 else { 245 assert(RC == Mips::AFGR64RegisterClass); 246 Opc = Mips::LDC1; 247 } 248 249 DebugLoc DL = DebugLoc::getUnknownLoc(); 250 if (I != MBB.end()) DL = I->getDebugLoc(); 251 BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0).addFrameIndex(FI); 252} 253 254void MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 255 SmallVectorImpl<MachineOperand> &Addr, 256 const TargetRegisterClass *RC, 257 SmallVectorImpl<MachineInstr*> &NewMIs) const { 258 unsigned Opc; 259 if (RC == Mips::CPURegsRegisterClass) 260 Opc = Mips::LW; 261 else if (RC == Mips::FGR32RegisterClass) 262 Opc = Mips::LWC1; 263 else { 264 assert(RC == Mips::AFGR64RegisterClass); 265 Opc = Mips::LDC1; 266 } 267 268 DebugLoc DL = DebugLoc::getUnknownLoc(); 269 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); 270 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 271 MIB.addOperand(Addr[i]); 272 NewMIs.push_back(MIB); 273 return; 274} 275 276MachineInstr *MipsInstrInfo:: 277foldMemoryOperandImpl(MachineFunction &MF, 278 MachineInstr* MI, 279 const SmallVectorImpl<unsigned> &Ops, int FI) const 280{ 281 if (Ops.size() != 1) return NULL; 282 283 MachineInstr *NewMI = NULL; 284 285 switch (MI->getOpcode()) { 286 case Mips::ADDu: 287 if ((MI->getOperand(0).isReg()) && 288 (MI->getOperand(1).isReg()) && 289 (MI->getOperand(1).getReg() == Mips::ZERO) && 290 (MI->getOperand(2).isReg())) { 291 if (Ops[0] == 0) { // COPY -> STORE 292 unsigned SrcReg = MI->getOperand(2).getReg(); 293 bool isKill = MI->getOperand(2).isKill(); 294 NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::SW)) 295 .addReg(SrcReg, getKillRegState(isKill)) 296 .addImm(0).addFrameIndex(FI); 297 } else { // COPY -> LOAD 298 unsigned DstReg = MI->getOperand(0).getReg(); 299 bool isDead = MI->getOperand(0).isDead(); 300 NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::LW)) 301 .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) 302 .addImm(0).addFrameIndex(FI); 303 } 304 } 305 break; 306 case Mips::FMOV_S32: 307 case Mips::FMOV_D32: 308 if ((MI->getOperand(0).isReg()) && 309 (MI->getOperand(1).isReg())) { 310 const TargetRegisterClass 311 *RC = RI.getRegClass(MI->getOperand(0).getReg()); 312 unsigned StoreOpc, LoadOpc; 313 314 if (RC == Mips::FGR32RegisterClass) { 315 LoadOpc = Mips::LWC1; StoreOpc = Mips::SWC1; 316 } else { 317 assert(RC == Mips::AFGR64RegisterClass); 318 LoadOpc = Mips::LDC1; StoreOpc = Mips::SDC1; 319 } 320 321 if (Ops[0] == 0) { // COPY -> STORE 322 unsigned SrcReg = MI->getOperand(1).getReg(); 323 bool isKill = MI->getOperand(1).isKill(); 324 NewMI = BuildMI(MF, MI->getDebugLoc(), get(StoreOpc)) 325 .addReg(SrcReg, getKillRegState(isKill)) 326 .addImm(0).addFrameIndex(FI) ; 327 } else { // COPY -> LOAD 328 unsigned DstReg = MI->getOperand(0).getReg(); 329 bool isDead = MI->getOperand(0).isDead(); 330 NewMI = BuildMI(MF, MI->getDebugLoc(), get(LoadOpc)) 331 .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) 332 .addImm(0).addFrameIndex(FI); 333 } 334 } 335 break; 336 } 337 338 return NewMI; 339} 340 341//===----------------------------------------------------------------------===// 342// Branch Analysis 343//===----------------------------------------------------------------------===// 344 345/// GetCondFromBranchOpc - Return the Mips CC that matches 346/// the correspondent Branch instruction opcode. 347static Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc) 348{ 349 switch (BrOpc) { 350 default: return Mips::COND_INVALID; 351 case Mips::BEQ : return Mips::COND_E; 352 case Mips::BNE : return Mips::COND_NE; 353 case Mips::BGTZ : return Mips::COND_GZ; 354 case Mips::BGEZ : return Mips::COND_GEZ; 355 case Mips::BLTZ : return Mips::COND_LZ; 356 case Mips::BLEZ : return Mips::COND_LEZ; 357 358 // We dont do fp branch analysis yet! 359 case Mips::BC1T : 360 case Mips::BC1F : return Mips::COND_INVALID; 361 } 362} 363 364/// GetCondBranchFromCond - Return the Branch instruction 365/// opcode that matches the cc. 366unsigned Mips::GetCondBranchFromCond(Mips::CondCode CC) 367{ 368 switch (CC) { 369 default: assert(0 && "Illegal condition code!"); 370 case Mips::COND_E : return Mips::BEQ; 371 case Mips::COND_NE : return Mips::BNE; 372 case Mips::COND_GZ : return Mips::BGTZ; 373 case Mips::COND_GEZ : return Mips::BGEZ; 374 case Mips::COND_LZ : return Mips::BLTZ; 375 case Mips::COND_LEZ : return Mips::BLEZ; 376 377 case Mips::FCOND_F: 378 case Mips::FCOND_UN: 379 case Mips::FCOND_EQ: 380 case Mips::FCOND_UEQ: 381 case Mips::FCOND_OLT: 382 case Mips::FCOND_ULT: 383 case Mips::FCOND_OLE: 384 case Mips::FCOND_ULE: 385 case Mips::FCOND_SF: 386 case Mips::FCOND_NGLE: 387 case Mips::FCOND_SEQ: 388 case Mips::FCOND_NGL: 389 case Mips::FCOND_LT: 390 case Mips::FCOND_NGE: 391 case Mips::FCOND_LE: 392 case Mips::FCOND_NGT: return Mips::BC1T; 393 394 case Mips::FCOND_T: 395 case Mips::FCOND_OR: 396 case Mips::FCOND_NEQ: 397 case Mips::FCOND_OGL: 398 case Mips::FCOND_UGE: 399 case Mips::FCOND_OGE: 400 case Mips::FCOND_UGT: 401 case Mips::FCOND_OGT: 402 case Mips::FCOND_ST: 403 case Mips::FCOND_GLE: 404 case Mips::FCOND_SNE: 405 case Mips::FCOND_GL: 406 case Mips::FCOND_NLT: 407 case Mips::FCOND_GE: 408 case Mips::FCOND_NLE: 409 case Mips::FCOND_GT: return Mips::BC1F; 410 } 411} 412 413/// GetOppositeBranchCondition - Return the inverse of the specified 414/// condition, e.g. turning COND_E to COND_NE. 415Mips::CondCode Mips::GetOppositeBranchCondition(Mips::CondCode CC) 416{ 417 switch (CC) { 418 default: assert(0 && "Illegal condition code!"); 419 case Mips::COND_E : return Mips::COND_NE; 420 case Mips::COND_NE : return Mips::COND_E; 421 case Mips::COND_GZ : return Mips::COND_LEZ; 422 case Mips::COND_GEZ : return Mips::COND_LZ; 423 case Mips::COND_LZ : return Mips::COND_GEZ; 424 case Mips::COND_LEZ : return Mips::COND_GZ; 425 case Mips::FCOND_F : return Mips::FCOND_T; 426 case Mips::FCOND_UN : return Mips::FCOND_OR; 427 case Mips::FCOND_EQ : return Mips::FCOND_NEQ; 428 case Mips::FCOND_UEQ: return Mips::FCOND_OGL; 429 case Mips::FCOND_OLT: return Mips::FCOND_UGE; 430 case Mips::FCOND_ULT: return Mips::FCOND_OGE; 431 case Mips::FCOND_OLE: return Mips::FCOND_UGT; 432 case Mips::FCOND_ULE: return Mips::FCOND_OGT; 433 case Mips::FCOND_SF: return Mips::FCOND_ST; 434 case Mips::FCOND_NGLE:return Mips::FCOND_GLE; 435 case Mips::FCOND_SEQ: return Mips::FCOND_SNE; 436 case Mips::FCOND_NGL: return Mips::FCOND_GL; 437 case Mips::FCOND_LT: return Mips::FCOND_NLT; 438 case Mips::FCOND_NGE: return Mips::FCOND_GE; 439 case Mips::FCOND_LE: return Mips::FCOND_NLE; 440 case Mips::FCOND_NGT: return Mips::FCOND_GT; 441 } 442} 443 444bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 445 MachineBasicBlock *&TBB, 446 MachineBasicBlock *&FBB, 447 SmallVectorImpl<MachineOperand> &Cond, 448 bool AllowModify) const 449{ 450 // If the block has no terminators, it just falls into the block after it. 451 MachineBasicBlock::iterator I = MBB.end(); 452 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 453 return false; 454 455 // Get the last instruction in the block. 456 MachineInstr *LastInst = I; 457 458 // If there is only one terminator instruction, process it. 459 unsigned LastOpc = LastInst->getOpcode(); 460 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 461 if (!LastInst->getDesc().isBranch()) 462 return true; 463 464 // Unconditional branch 465 if (LastOpc == Mips::J) { 466 TBB = LastInst->getOperand(0).getMBB(); 467 return false; 468 } 469 470 Mips::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 471 if (BranchCode == Mips::COND_INVALID) 472 return true; // Can't handle indirect branch. 473 474 // Conditional branch 475 // Block ends with fall-through condbranch. 476 if (LastOpc != Mips::COND_INVALID) { 477 int LastNumOp = LastInst->getNumOperands(); 478 479 TBB = LastInst->getOperand(LastNumOp-1).getMBB(); 480 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 481 482 for (int i=0; i<LastNumOp-1; i++) { 483 Cond.push_back(LastInst->getOperand(i)); 484 } 485 486 return false; 487 } 488 } 489 490 // Get the instruction before it if it is a terminator. 491 MachineInstr *SecondLastInst = I; 492 493 // If there are three terminators, we don't know what sort of block this is. 494 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 495 return true; 496 497 // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it. 498 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 499 Mips::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 500 501 if (BranchCode != Mips::COND_INVALID && LastOpc == Mips::J) { 502 int SecondNumOp = SecondLastInst->getNumOperands(); 503 504 TBB = SecondLastInst->getOperand(SecondNumOp-1).getMBB(); 505 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 506 507 for (int i=0; i<SecondNumOp-1; i++) { 508 Cond.push_back(SecondLastInst->getOperand(i)); 509 } 510 511 FBB = LastInst->getOperand(0).getMBB(); 512 return false; 513 } 514 515 // If the block ends with two unconditional branches, handle it. The last 516 // one is not executed, so remove it. 517 if ((SecondLastOpc == Mips::J) && (LastOpc == Mips::J)) { 518 TBB = SecondLastInst->getOperand(0).getMBB(); 519 I = LastInst; 520 if (AllowModify) 521 I->eraseFromParent(); 522 return false; 523 } 524 525 // Otherwise, can't handle this. 526 return true; 527} 528 529unsigned MipsInstrInfo:: 530InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 531 MachineBasicBlock *FBB, 532 const SmallVectorImpl<MachineOperand> &Cond) const { 533 // FIXME this should probably have a DebugLoc argument 534 DebugLoc dl = DebugLoc::getUnknownLoc(); 535 // Shouldn't be a fall through. 536 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 537 assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) && 538 "Mips branch conditions can have two|three components!"); 539 540 if (FBB == 0) { // One way branch. 541 if (Cond.empty()) { 542 // Unconditional branch? 543 BuildMI(&MBB, dl, get(Mips::J)).addMBB(TBB); 544 } else { 545 // Conditional branch. 546 unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); 547 const TargetInstrDesc &TID = get(Opc); 548 549 if (TID.getNumOperands() == 3) 550 BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()) 551 .addReg(Cond[2].getReg()) 552 .addMBB(TBB); 553 else 554 BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()) 555 .addMBB(TBB); 556 557 } 558 return 1; 559 } 560 561 // Two-way Conditional branch. 562 unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); 563 const TargetInstrDesc &TID = get(Opc); 564 565 if (TID.getNumOperands() == 3) 566 BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addReg(Cond[2].getReg()) 567 .addMBB(TBB); 568 else 569 BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addMBB(TBB); 570 571 BuildMI(&MBB, dl, get(Mips::J)).addMBB(FBB); 572 return 2; 573} 574 575unsigned MipsInstrInfo:: 576RemoveBranch(MachineBasicBlock &MBB) const 577{ 578 MachineBasicBlock::iterator I = MBB.end(); 579 if (I == MBB.begin()) return 0; 580 --I; 581 if (I->getOpcode() != Mips::J && 582 GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) 583 return 0; 584 585 // Remove the branch. 586 I->eraseFromParent(); 587 588 I = MBB.end(); 589 590 if (I == MBB.begin()) return 1; 591 --I; 592 if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) 593 return 1; 594 595 // Remove the branch. 596 I->eraseFromParent(); 597 return 2; 598} 599 600/// BlockHasNoFallThrough - Analyze if MachineBasicBlock does not 601/// fall-through into its successor block. 602bool MipsInstrInfo:: 603BlockHasNoFallThrough(const MachineBasicBlock &MBB) const 604{ 605 if (MBB.empty()) return false; 606 607 switch (MBB.back().getOpcode()) { 608 case Mips::RET: // Return. 609 case Mips::JR: // Indirect branch. 610 case Mips::J: // Uncond branch. 611 return true; 612 default: return false; 613 } 614} 615 616/// ReverseBranchCondition - Return the inverse opcode of the 617/// specified Branch instruction. 618bool MipsInstrInfo:: 619ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const 620{ 621 assert( (Cond.size() == 3 || Cond.size() == 2) && 622 "Invalid Mips branch condition!"); 623 Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm())); 624 return false; 625}
|