MipsInstrInfo.cpp revision 193323
1193323Sed//===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file contains the Mips implementation of the TargetInstrInfo class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "MipsInstrInfo.h" 15193323Sed#include "MipsTargetMachine.h" 16193323Sed#include "llvm/ADT/STLExtras.h" 17193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 18193323Sed#include "MipsGenInstrInfo.inc" 19193323Sed 20193323Sedusing namespace llvm; 21193323Sed 22193323SedMipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm) 23193323Sed : TargetInstrInfoImpl(MipsInsts, array_lengthof(MipsInsts)), 24193323Sed TM(tm), RI(*TM.getSubtargetImpl(), *this) {} 25193323Sed 26193323Sedstatic bool isZeroImm(const MachineOperand &op) { 27193323Sed return op.isImm() && op.getImm() == 0; 28193323Sed} 29193323Sed 30193323Sed/// Return true if the instruction is a register to register move and 31193323Sed/// leave the source and dest operands in the passed parameters. 32193323Sedbool MipsInstrInfo:: 33193323SedisMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, 34193323Sed unsigned &SrcSubIdx, unsigned &DstSubIdx) const 35193323Sed{ 36193323Sed SrcSubIdx = DstSubIdx = 0; // No sub-registers. 37193323Sed 38193323Sed // addu $dst, $src, $zero || addu $dst, $zero, $src 39193323Sed // or $dst, $src, $zero || or $dst, $zero, $src 40193323Sed if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR)) { 41193323Sed if (MI.getOperand(1).getReg() == Mips::ZERO) { 42193323Sed DstReg = MI.getOperand(0).getReg(); 43193323Sed SrcReg = MI.getOperand(2).getReg(); 44193323Sed return true; 45193323Sed } else if (MI.getOperand(2).getReg() == Mips::ZERO) { 46193323Sed DstReg = MI.getOperand(0).getReg(); 47193323Sed SrcReg = MI.getOperand(1).getReg(); 48193323Sed return true; 49193323Sed } 50193323Sed } 51193323Sed 52193323Sed // mov $fpDst, $fpSrc 53193323Sed // mfc $gpDst, $fpSrc 54193323Sed // mtc $fpDst, $gpSrc 55193323Sed if (MI.getOpcode() == Mips::FMOV_S32 || 56193323Sed MI.getOpcode() == Mips::FMOV_D32 || 57193323Sed MI.getOpcode() == Mips::MFC1 || 58193323Sed MI.getOpcode() == Mips::MTC1 || 59193323Sed MI.getOpcode() == Mips::MOVCCRToCCR) { 60193323Sed DstReg = MI.getOperand(0).getReg(); 61193323Sed SrcReg = MI.getOperand(1).getReg(); 62193323Sed return true; 63193323Sed } 64193323Sed 65193323Sed // addiu $dst, $src, 0 66193323Sed if (MI.getOpcode() == Mips::ADDiu) { 67193323Sed if ((MI.getOperand(1).isReg()) && (isZeroImm(MI.getOperand(2)))) { 68193323Sed DstReg = MI.getOperand(0).getReg(); 69193323Sed SrcReg = MI.getOperand(1).getReg(); 70193323Sed return true; 71193323Sed } 72193323Sed } 73193323Sed 74193323Sed return false; 75193323Sed} 76193323Sed 77193323Sed/// isLoadFromStackSlot - If the specified machine instruction is a direct 78193323Sed/// load from a stack slot, return the virtual or physical register number of 79193323Sed/// the destination along with the FrameIndex of the loaded stack slot. If 80193323Sed/// not, return 0. This predicate must return 0 if the instruction has 81193323Sed/// any side effects other than loading from the stack slot. 82193323Sedunsigned MipsInstrInfo:: 83193323SedisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 84193323Sed{ 85193323Sed if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) || 86193323Sed (MI->getOpcode() == Mips::LDC1)) { 87193323Sed if ((MI->getOperand(2).isFI()) && // is a stack slot 88193323Sed (MI->getOperand(1).isImm()) && // the imm is zero 89193323Sed (isZeroImm(MI->getOperand(1)))) { 90193323Sed FrameIndex = MI->getOperand(2).getIndex(); 91193323Sed return MI->getOperand(0).getReg(); 92193323Sed } 93193323Sed } 94193323Sed 95193323Sed return 0; 96193323Sed} 97193323Sed 98193323Sed/// isStoreToStackSlot - If the specified machine instruction is a direct 99193323Sed/// store to a stack slot, return the virtual or physical register number of 100193323Sed/// the source reg along with the FrameIndex of the loaded stack slot. If 101193323Sed/// not, return 0. This predicate must return 0 if the instruction has 102193323Sed/// any side effects other than storing to the stack slot. 103193323Sedunsigned MipsInstrInfo:: 104193323SedisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 105193323Sed{ 106193323Sed if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) || 107193323Sed (MI->getOpcode() == Mips::SDC1)) { 108193323Sed if ((MI->getOperand(2).isFI()) && // is a stack slot 109193323Sed (MI->getOperand(1).isImm()) && // the imm is zero 110193323Sed (isZeroImm(MI->getOperand(1)))) { 111193323Sed FrameIndex = MI->getOperand(2).getIndex(); 112193323Sed return MI->getOperand(0).getReg(); 113193323Sed } 114193323Sed } 115193323Sed return 0; 116193323Sed} 117193323Sed 118193323Sed/// insertNoop - If data hazard condition is found insert the target nop 119193323Sed/// instruction. 120193323Sedvoid MipsInstrInfo:: 121193323SedinsertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const 122193323Sed{ 123193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 124193323Sed if (MI != MBB.end()) DL = MI->getDebugLoc(); 125193323Sed BuildMI(MBB, MI, DL, get(Mips::NOP)); 126193323Sed} 127193323Sed 128193323Sedbool MipsInstrInfo:: 129193323SedcopyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 130193323Sed unsigned DestReg, unsigned SrcReg, 131193323Sed const TargetRegisterClass *DestRC, 132193323Sed const TargetRegisterClass *SrcRC) const { 133193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 134193323Sed if (I != MBB.end()) DL = I->getDebugLoc(); 135193323Sed 136193323Sed if (DestRC != SrcRC) { 137193323Sed 138193323Sed // Copy to/from FCR31 condition register 139193323Sed if ((DestRC == Mips::CPURegsRegisterClass) && 140193323Sed (SrcRC == Mips::CCRRegisterClass)) 141193323Sed BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg).addReg(SrcReg); 142193323Sed else if ((DestRC == Mips::CCRRegisterClass) && 143193323Sed (SrcRC == Mips::CPURegsRegisterClass)) 144193323Sed BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg).addReg(SrcReg); 145193323Sed 146193323Sed // Moves between coprocessors and cpu 147193323Sed else if ((DestRC == Mips::CPURegsRegisterClass) && 148193323Sed (SrcRC == Mips::FGR32RegisterClass)) 149193323Sed BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg).addReg(SrcReg); 150193323Sed else if ((DestRC == Mips::FGR32RegisterClass) && 151193323Sed (SrcRC == Mips::CPURegsRegisterClass)) 152193323Sed BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg); 153193323Sed 154193323Sed // Move from/to Hi/Lo registers 155193323Sed else if ((DestRC == Mips::HILORegisterClass) && 156193323Sed (SrcRC == Mips::CPURegsRegisterClass)) { 157193323Sed unsigned Opc = (DestReg == Mips::HI) ? Mips::MTHI : Mips::MTLO; 158193323Sed BuildMI(MBB, I, DL, get(Opc), DestReg); 159193323Sed } else if ((SrcRC == Mips::HILORegisterClass) && 160193323Sed (DestRC == Mips::CPURegsRegisterClass)) { 161193323Sed unsigned Opc = (SrcReg == Mips::HI) ? Mips::MFHI : Mips::MFLO; 162193323Sed BuildMI(MBB, I, DL, get(Opc), DestReg); 163193323Sed 164193323Sed // Can't copy this register 165193323Sed } else 166193323Sed return false; 167193323Sed 168193323Sed return true; 169193323Sed } 170193323Sed 171193323Sed if (DestRC == Mips::CPURegsRegisterClass) 172193323Sed BuildMI(MBB, I, DL, get(Mips::ADDu), DestReg).addReg(Mips::ZERO) 173193323Sed .addReg(SrcReg); 174193323Sed else if (DestRC == Mips::FGR32RegisterClass) 175193323Sed BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg).addReg(SrcReg); 176193323Sed else if (DestRC == Mips::AFGR64RegisterClass) 177193323Sed BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg).addReg(SrcReg); 178193323Sed else if (DestRC == Mips::CCRRegisterClass) 179193323Sed BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg).addReg(SrcReg); 180193323Sed else 181193323Sed // Can't copy this register 182193323Sed return false; 183193323Sed 184193323Sed return true; 185193323Sed} 186193323Sed 187193323Sedvoid MipsInstrInfo:: 188193323SedstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 189193323Sed unsigned SrcReg, bool isKill, int FI, 190193323Sed const TargetRegisterClass *RC) const { 191193323Sed unsigned Opc; 192193323Sed 193193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 194193323Sed if (I != MBB.end()) DL = I->getDebugLoc(); 195193323Sed 196193323Sed if (RC == Mips::CPURegsRegisterClass) 197193323Sed Opc = Mips::SW; 198193323Sed else if (RC == Mips::FGR32RegisterClass) 199193323Sed Opc = Mips::SWC1; 200193323Sed else { 201193323Sed assert(RC == Mips::AFGR64RegisterClass); 202193323Sed Opc = Mips::SDC1; 203193323Sed } 204193323Sed 205193323Sed BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 206193323Sed .addImm(0).addFrameIndex(FI); 207193323Sed} 208193323Sed 209193323Sedvoid MipsInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 210193323Sed bool isKill, SmallVectorImpl<MachineOperand> &Addr, 211193323Sed const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs) const 212193323Sed{ 213193323Sed unsigned Opc; 214193323Sed if (RC == Mips::CPURegsRegisterClass) 215193323Sed Opc = Mips::SW; 216193323Sed else if (RC == Mips::FGR32RegisterClass) 217193323Sed Opc = Mips::SWC1; 218193323Sed else { 219193323Sed assert(RC == Mips::AFGR64RegisterClass); 220193323Sed Opc = Mips::SDC1; 221193323Sed } 222193323Sed 223193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 224193323Sed MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)) 225193323Sed .addReg(SrcReg, getKillRegState(isKill)); 226193323Sed for (unsigned i = 0, e = Addr.size(); i != e; ++i) 227193323Sed MIB.addOperand(Addr[i]); 228193323Sed NewMIs.push_back(MIB); 229193323Sed return; 230193323Sed} 231193323Sed 232193323Sedvoid MipsInstrInfo:: 233193323SedloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 234193323Sed unsigned DestReg, int FI, 235193323Sed const TargetRegisterClass *RC) const 236193323Sed{ 237193323Sed unsigned Opc; 238193323Sed if (RC == Mips::CPURegsRegisterClass) 239193323Sed Opc = Mips::LW; 240193323Sed else if (RC == Mips::FGR32RegisterClass) 241193323Sed Opc = Mips::LWC1; 242193323Sed else { 243193323Sed assert(RC == Mips::AFGR64RegisterClass); 244193323Sed Opc = Mips::LDC1; 245193323Sed } 246193323Sed 247193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 248193323Sed if (I != MBB.end()) DL = I->getDebugLoc(); 249193323Sed BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0).addFrameIndex(FI); 250193323Sed} 251193323Sed 252193323Sedvoid MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 253193323Sed SmallVectorImpl<MachineOperand> &Addr, 254193323Sed const TargetRegisterClass *RC, 255193323Sed SmallVectorImpl<MachineInstr*> &NewMIs) const { 256193323Sed unsigned Opc; 257193323Sed if (RC == Mips::CPURegsRegisterClass) 258193323Sed Opc = Mips::LW; 259193323Sed else if (RC == Mips::FGR32RegisterClass) 260193323Sed Opc = Mips::LWC1; 261193323Sed else { 262193323Sed assert(RC == Mips::AFGR64RegisterClass); 263193323Sed Opc = Mips::LDC1; 264193323Sed } 265193323Sed 266193323Sed DebugLoc DL = DebugLoc::getUnknownLoc(); 267193323Sed MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); 268193323Sed for (unsigned i = 0, e = Addr.size(); i != e; ++i) 269193323Sed MIB.addOperand(Addr[i]); 270193323Sed NewMIs.push_back(MIB); 271193323Sed return; 272193323Sed} 273193323Sed 274193323SedMachineInstr *MipsInstrInfo:: 275193323SedfoldMemoryOperandImpl(MachineFunction &MF, 276193323Sed MachineInstr* MI, 277193323Sed const SmallVectorImpl<unsigned> &Ops, int FI) const 278193323Sed{ 279193323Sed if (Ops.size() != 1) return NULL; 280193323Sed 281193323Sed MachineInstr *NewMI = NULL; 282193323Sed 283193323Sed switch (MI->getOpcode()) { 284193323Sed case Mips::ADDu: 285193323Sed if ((MI->getOperand(0).isReg()) && 286193323Sed (MI->getOperand(1).isReg()) && 287193323Sed (MI->getOperand(1).getReg() == Mips::ZERO) && 288193323Sed (MI->getOperand(2).isReg())) { 289193323Sed if (Ops[0] == 0) { // COPY -> STORE 290193323Sed unsigned SrcReg = MI->getOperand(2).getReg(); 291193323Sed bool isKill = MI->getOperand(2).isKill(); 292193323Sed NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::SW)) 293193323Sed .addReg(SrcReg, getKillRegState(isKill)) 294193323Sed .addImm(0).addFrameIndex(FI); 295193323Sed } else { // COPY -> LOAD 296193323Sed unsigned DstReg = MI->getOperand(0).getReg(); 297193323Sed bool isDead = MI->getOperand(0).isDead(); 298193323Sed NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::LW)) 299193323Sed .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) 300193323Sed .addImm(0).addFrameIndex(FI); 301193323Sed } 302193323Sed } 303193323Sed break; 304193323Sed case Mips::FMOV_S32: 305193323Sed case Mips::FMOV_D32: 306193323Sed if ((MI->getOperand(0).isReg()) && 307193323Sed (MI->getOperand(1).isReg())) { 308193323Sed const TargetRegisterClass 309193323Sed *RC = RI.getRegClass(MI->getOperand(0).getReg()); 310193323Sed unsigned StoreOpc, LoadOpc; 311193323Sed 312193323Sed if (RC == Mips::FGR32RegisterClass) { 313193323Sed LoadOpc = Mips::LWC1; StoreOpc = Mips::SWC1; 314193323Sed } else { 315193323Sed assert(RC == Mips::AFGR64RegisterClass); 316193323Sed LoadOpc = Mips::LDC1; StoreOpc = Mips::SDC1; 317193323Sed } 318193323Sed 319193323Sed if (Ops[0] == 0) { // COPY -> STORE 320193323Sed unsigned SrcReg = MI->getOperand(1).getReg(); 321193323Sed bool isKill = MI->getOperand(1).isKill(); 322193323Sed NewMI = BuildMI(MF, MI->getDebugLoc(), get(StoreOpc)) 323193323Sed .addReg(SrcReg, getKillRegState(isKill)) 324193323Sed .addImm(0).addFrameIndex(FI) ; 325193323Sed } else { // COPY -> LOAD 326193323Sed unsigned DstReg = MI->getOperand(0).getReg(); 327193323Sed bool isDead = MI->getOperand(0).isDead(); 328193323Sed NewMI = BuildMI(MF, MI->getDebugLoc(), get(LoadOpc)) 329193323Sed .addReg(DstReg, RegState::Define | getDeadRegState(isDead)) 330193323Sed .addImm(0).addFrameIndex(FI); 331193323Sed } 332193323Sed } 333193323Sed break; 334193323Sed } 335193323Sed 336193323Sed return NewMI; 337193323Sed} 338193323Sed 339193323Sed//===----------------------------------------------------------------------===// 340193323Sed// Branch Analysis 341193323Sed//===----------------------------------------------------------------------===// 342193323Sed 343193323Sed/// GetCondFromBranchOpc - Return the Mips CC that matches 344193323Sed/// the correspondent Branch instruction opcode. 345193323Sedstatic Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc) 346193323Sed{ 347193323Sed switch (BrOpc) { 348193323Sed default: return Mips::COND_INVALID; 349193323Sed case Mips::BEQ : return Mips::COND_E; 350193323Sed case Mips::BNE : return Mips::COND_NE; 351193323Sed case Mips::BGTZ : return Mips::COND_GZ; 352193323Sed case Mips::BGEZ : return Mips::COND_GEZ; 353193323Sed case Mips::BLTZ : return Mips::COND_LZ; 354193323Sed case Mips::BLEZ : return Mips::COND_LEZ; 355193323Sed 356193323Sed // We dont do fp branch analysis yet! 357193323Sed case Mips::BC1T : 358193323Sed case Mips::BC1F : return Mips::COND_INVALID; 359193323Sed } 360193323Sed} 361193323Sed 362193323Sed/// GetCondBranchFromCond - Return the Branch instruction 363193323Sed/// opcode that matches the cc. 364193323Sedunsigned Mips::GetCondBranchFromCond(Mips::CondCode CC) 365193323Sed{ 366193323Sed switch (CC) { 367193323Sed default: assert(0 && "Illegal condition code!"); 368193323Sed case Mips::COND_E : return Mips::BEQ; 369193323Sed case Mips::COND_NE : return Mips::BNE; 370193323Sed case Mips::COND_GZ : return Mips::BGTZ; 371193323Sed case Mips::COND_GEZ : return Mips::BGEZ; 372193323Sed case Mips::COND_LZ : return Mips::BLTZ; 373193323Sed case Mips::COND_LEZ : return Mips::BLEZ; 374193323Sed 375193323Sed case Mips::FCOND_F: 376193323Sed case Mips::FCOND_UN: 377193323Sed case Mips::FCOND_EQ: 378193323Sed case Mips::FCOND_UEQ: 379193323Sed case Mips::FCOND_OLT: 380193323Sed case Mips::FCOND_ULT: 381193323Sed case Mips::FCOND_OLE: 382193323Sed case Mips::FCOND_ULE: 383193323Sed case Mips::FCOND_SF: 384193323Sed case Mips::FCOND_NGLE: 385193323Sed case Mips::FCOND_SEQ: 386193323Sed case Mips::FCOND_NGL: 387193323Sed case Mips::FCOND_LT: 388193323Sed case Mips::FCOND_NGE: 389193323Sed case Mips::FCOND_LE: 390193323Sed case Mips::FCOND_NGT: return Mips::BC1T; 391193323Sed 392193323Sed case Mips::FCOND_T: 393193323Sed case Mips::FCOND_OR: 394193323Sed case Mips::FCOND_NEQ: 395193323Sed case Mips::FCOND_OGL: 396193323Sed case Mips::FCOND_UGE: 397193323Sed case Mips::FCOND_OGE: 398193323Sed case Mips::FCOND_UGT: 399193323Sed case Mips::FCOND_OGT: 400193323Sed case Mips::FCOND_ST: 401193323Sed case Mips::FCOND_GLE: 402193323Sed case Mips::FCOND_SNE: 403193323Sed case Mips::FCOND_GL: 404193323Sed case Mips::FCOND_NLT: 405193323Sed case Mips::FCOND_GE: 406193323Sed case Mips::FCOND_NLE: 407193323Sed case Mips::FCOND_GT: return Mips::BC1F; 408193323Sed } 409193323Sed} 410193323Sed 411193323Sed/// GetOppositeBranchCondition - Return the inverse of the specified 412193323Sed/// condition, e.g. turning COND_E to COND_NE. 413193323SedMips::CondCode Mips::GetOppositeBranchCondition(Mips::CondCode CC) 414193323Sed{ 415193323Sed switch (CC) { 416193323Sed default: assert(0 && "Illegal condition code!"); 417193323Sed case Mips::COND_E : return Mips::COND_NE; 418193323Sed case Mips::COND_NE : return Mips::COND_E; 419193323Sed case Mips::COND_GZ : return Mips::COND_LEZ; 420193323Sed case Mips::COND_GEZ : return Mips::COND_LZ; 421193323Sed case Mips::COND_LZ : return Mips::COND_GEZ; 422193323Sed case Mips::COND_LEZ : return Mips::COND_GZ; 423193323Sed case Mips::FCOND_F : return Mips::FCOND_T; 424193323Sed case Mips::FCOND_UN : return Mips::FCOND_OR; 425193323Sed case Mips::FCOND_EQ : return Mips::FCOND_NEQ; 426193323Sed case Mips::FCOND_UEQ: return Mips::FCOND_OGL; 427193323Sed case Mips::FCOND_OLT: return Mips::FCOND_UGE; 428193323Sed case Mips::FCOND_ULT: return Mips::FCOND_OGE; 429193323Sed case Mips::FCOND_OLE: return Mips::FCOND_UGT; 430193323Sed case Mips::FCOND_ULE: return Mips::FCOND_OGT; 431193323Sed case Mips::FCOND_SF: return Mips::FCOND_ST; 432193323Sed case Mips::FCOND_NGLE:return Mips::FCOND_GLE; 433193323Sed case Mips::FCOND_SEQ: return Mips::FCOND_SNE; 434193323Sed case Mips::FCOND_NGL: return Mips::FCOND_GL; 435193323Sed case Mips::FCOND_LT: return Mips::FCOND_NLT; 436193323Sed case Mips::FCOND_NGE: return Mips::FCOND_GE; 437193323Sed case Mips::FCOND_LE: return Mips::FCOND_NLE; 438193323Sed case Mips::FCOND_NGT: return Mips::FCOND_GT; 439193323Sed } 440193323Sed} 441193323Sed 442193323Sedbool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 443193323Sed MachineBasicBlock *&TBB, 444193323Sed MachineBasicBlock *&FBB, 445193323Sed SmallVectorImpl<MachineOperand> &Cond, 446193323Sed bool AllowModify) const 447193323Sed{ 448193323Sed // If the block has no terminators, it just falls into the block after it. 449193323Sed MachineBasicBlock::iterator I = MBB.end(); 450193323Sed if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 451193323Sed return false; 452193323Sed 453193323Sed // Get the last instruction in the block. 454193323Sed MachineInstr *LastInst = I; 455193323Sed 456193323Sed // If there is only one terminator instruction, process it. 457193323Sed unsigned LastOpc = LastInst->getOpcode(); 458193323Sed if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 459193323Sed if (!LastInst->getDesc().isBranch()) 460193323Sed return true; 461193323Sed 462193323Sed // Unconditional branch 463193323Sed if (LastOpc == Mips::J) { 464193323Sed TBB = LastInst->getOperand(0).getMBB(); 465193323Sed return false; 466193323Sed } 467193323Sed 468193323Sed Mips::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 469193323Sed if (BranchCode == Mips::COND_INVALID) 470193323Sed return true; // Can't handle indirect branch. 471193323Sed 472193323Sed // Conditional branch 473193323Sed // Block ends with fall-through condbranch. 474193323Sed if (LastOpc != Mips::COND_INVALID) { 475193323Sed int LastNumOp = LastInst->getNumOperands(); 476193323Sed 477193323Sed TBB = LastInst->getOperand(LastNumOp-1).getMBB(); 478193323Sed Cond.push_back(MachineOperand::CreateImm(BranchCode)); 479193323Sed 480193323Sed for (int i=0; i<LastNumOp-1; i++) { 481193323Sed Cond.push_back(LastInst->getOperand(i)); 482193323Sed } 483193323Sed 484193323Sed return false; 485193323Sed } 486193323Sed } 487193323Sed 488193323Sed // Get the instruction before it if it is a terminator. 489193323Sed MachineInstr *SecondLastInst = I; 490193323Sed 491193323Sed // If there are three terminators, we don't know what sort of block this is. 492193323Sed if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 493193323Sed return true; 494193323Sed 495193323Sed // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it. 496193323Sed unsigned SecondLastOpc = SecondLastInst->getOpcode(); 497193323Sed Mips::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 498193323Sed 499193323Sed if (BranchCode != Mips::COND_INVALID && LastOpc == Mips::J) { 500193323Sed int SecondNumOp = SecondLastInst->getNumOperands(); 501193323Sed 502193323Sed TBB = SecondLastInst->getOperand(SecondNumOp-1).getMBB(); 503193323Sed Cond.push_back(MachineOperand::CreateImm(BranchCode)); 504193323Sed 505193323Sed for (int i=0; i<SecondNumOp-1; i++) { 506193323Sed Cond.push_back(SecondLastInst->getOperand(i)); 507193323Sed } 508193323Sed 509193323Sed FBB = LastInst->getOperand(0).getMBB(); 510193323Sed return false; 511193323Sed } 512193323Sed 513193323Sed // If the block ends with two unconditional branches, handle it. The last 514193323Sed // one is not executed, so remove it. 515193323Sed if ((SecondLastOpc == Mips::J) && (LastOpc == Mips::J)) { 516193323Sed TBB = SecondLastInst->getOperand(0).getMBB(); 517193323Sed I = LastInst; 518193323Sed if (AllowModify) 519193323Sed I->eraseFromParent(); 520193323Sed return false; 521193323Sed } 522193323Sed 523193323Sed // Otherwise, can't handle this. 524193323Sed return true; 525193323Sed} 526193323Sed 527193323Sedunsigned MipsInstrInfo:: 528193323SedInsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 529193323Sed MachineBasicBlock *FBB, 530193323Sed const SmallVectorImpl<MachineOperand> &Cond) const { 531193323Sed // FIXME this should probably have a DebugLoc argument 532193323Sed DebugLoc dl = DebugLoc::getUnknownLoc(); 533193323Sed // Shouldn't be a fall through. 534193323Sed assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 535193323Sed assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) && 536193323Sed "Mips branch conditions can have two|three components!"); 537193323Sed 538193323Sed if (FBB == 0) { // One way branch. 539193323Sed if (Cond.empty()) { 540193323Sed // Unconditional branch? 541193323Sed BuildMI(&MBB, dl, get(Mips::J)).addMBB(TBB); 542193323Sed } else { 543193323Sed // Conditional branch. 544193323Sed unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); 545193323Sed const TargetInstrDesc &TID = get(Opc); 546193323Sed 547193323Sed if (TID.getNumOperands() == 3) 548193323Sed BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()) 549193323Sed .addReg(Cond[2].getReg()) 550193323Sed .addMBB(TBB); 551193323Sed else 552193323Sed BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()) 553193323Sed .addMBB(TBB); 554193323Sed 555193323Sed } 556193323Sed return 1; 557193323Sed } 558193323Sed 559193323Sed // Two-way Conditional branch. 560193323Sed unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); 561193323Sed const TargetInstrDesc &TID = get(Opc); 562193323Sed 563193323Sed if (TID.getNumOperands() == 3) 564193323Sed BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addReg(Cond[2].getReg()) 565193323Sed .addMBB(TBB); 566193323Sed else 567193323Sed BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addMBB(TBB); 568193323Sed 569193323Sed BuildMI(&MBB, dl, get(Mips::J)).addMBB(FBB); 570193323Sed return 2; 571193323Sed} 572193323Sed 573193323Sedunsigned MipsInstrInfo:: 574193323SedRemoveBranch(MachineBasicBlock &MBB) const 575193323Sed{ 576193323Sed MachineBasicBlock::iterator I = MBB.end(); 577193323Sed if (I == MBB.begin()) return 0; 578193323Sed --I; 579193323Sed if (I->getOpcode() != Mips::J && 580193323Sed GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) 581193323Sed return 0; 582193323Sed 583193323Sed // Remove the branch. 584193323Sed I->eraseFromParent(); 585193323Sed 586193323Sed I = MBB.end(); 587193323Sed 588193323Sed if (I == MBB.begin()) return 1; 589193323Sed --I; 590193323Sed if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) 591193323Sed return 1; 592193323Sed 593193323Sed // Remove the branch. 594193323Sed I->eraseFromParent(); 595193323Sed return 2; 596193323Sed} 597193323Sed 598193323Sed/// BlockHasNoFallThrough - Analyze if MachineBasicBlock does not 599193323Sed/// fall-through into its successor block. 600193323Sedbool MipsInstrInfo:: 601193323SedBlockHasNoFallThrough(const MachineBasicBlock &MBB) const 602193323Sed{ 603193323Sed if (MBB.empty()) return false; 604193323Sed 605193323Sed switch (MBB.back().getOpcode()) { 606193323Sed case Mips::RET: // Return. 607193323Sed case Mips::JR: // Indirect branch. 608193323Sed case Mips::J: // Uncond branch. 609193323Sed return true; 610193323Sed default: return false; 611193323Sed } 612193323Sed} 613193323Sed 614193323Sed/// ReverseBranchCondition - Return the inverse opcode of the 615193323Sed/// specified Branch instruction. 616193323Sedbool MipsInstrInfo:: 617193323SedReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const 618193323Sed{ 619193323Sed assert( (Cond.size() == 3 || Cond.size() == 2) && 620193323Sed "Invalid Mips branch condition!"); 621193323Sed Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm())); 622193323Sed return false; 623193323Sed} 624