LLVM API Documentation

SPUInstrInfo.cpp

Go to the documentation of this file.
00001 //===- SPUInstrInfo.cpp - Cell SPU Instruction Information ----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the Cell SPU implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "SPURegisterNames.h"
00015 #include "SPUInstrInfo.h"
00016 #include "SPUInstrBuilder.h"
00017 #include "SPUTargetMachine.h"
00018 #include "SPUGenInstrInfo.inc"
00019 #include "llvm/CodeGen/MachineInstrBuilder.h"
00020 #include "llvm/Support/Streams.h"
00021 #include "llvm/Support/Debug.h"
00022 
00023 using namespace llvm;
00024 
00025 namespace {
00026   //! Predicate for an unconditional branch instruction
00027   inline bool isUncondBranch(const MachineInstr *I) {
00028     unsigned opc = I->getOpcode();
00029 
00030     return (opc == SPU::BR
00031             || opc == SPU::BRA
00032             || opc == SPU::BI);
00033   }
00034 
00035   //! Predicate for a conditional branch instruction
00036   inline bool isCondBranch(const MachineInstr *I) {
00037     unsigned opc = I->getOpcode();
00038 
00039     return (opc == SPU::BRNZr32
00040             || opc == SPU::BRNZv4i32
00041             || opc == SPU::BRZr32
00042             || opc == SPU::BRZv4i32
00043             || opc == SPU::BRHNZr16
00044             || opc == SPU::BRHNZv8i16
00045             || opc == SPU::BRHZr16
00046             || opc == SPU::BRHZv8i16);
00047   }
00048 }
00049 
00050 SPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm)
00051   : TargetInstrInfoImpl(SPUInsts, sizeof(SPUInsts)/sizeof(SPUInsts[0])),
00052     TM(tm),
00053     RI(*TM.getSubtargetImpl(), *this)
00054 { /* NOP */ }
00055 
00056 /// getPointerRegClass - Return the register class to use to hold pointers.
00057 /// This is used for addressing modes.
00058 const TargetRegisterClass *
00059 SPUInstrInfo::getPointerRegClass() const
00060 {
00061   return &SPU::R32CRegClass;
00062 }
00063 
00064 bool
00065 SPUInstrInfo::isMoveInstr(const MachineInstr& MI,
00066                           unsigned& sourceReg,
00067                           unsigned& destReg,
00068                           unsigned& SrcSR, unsigned& DstSR) const {
00069   SrcSR = DstSR = 0;  // No sub-registers.
00070 
00071   // Primarily, ORI and OR are generated by copyRegToReg. But, there are other
00072   // cases where we can safely say that what's being done is really a move
00073   // (see how PowerPC does this -- it's the model for this code too.)
00074   switch (MI.getOpcode()) {
00075   default:
00076     break;
00077   case SPU::ORIv4i32:
00078   case SPU::ORIr32:
00079   case SPU::ORHIv8i16:
00080   case SPU::ORHIr16:
00081   case SPU::ORHIi8i16:
00082   case SPU::ORBIv16i8:
00083   case SPU::ORBIr8:
00084   case SPU::ORIi16i32:
00085   case SPU::ORIi8i32:
00086   case SPU::AHIvec:
00087   case SPU::AHIr16:
00088   case SPU::AIv4i32:
00089     assert(MI.getNumOperands() == 3 &&
00090            MI.getOperand(0).isReg() &&
00091            MI.getOperand(1).isReg() &&
00092            MI.getOperand(2).isImm() &&
00093            "invalid SPU ORI/ORHI/ORBI/AHI/AI/SFI/SFHI instruction!");
00094     if (MI.getOperand(2).getImm() == 0) {
00095       sourceReg = MI.getOperand(1).getReg();
00096       destReg = MI.getOperand(0).getReg();
00097       return true;
00098     }
00099     break;
00100   case SPU::AIr32:
00101     assert(MI.getNumOperands() == 3 &&
00102            "wrong number of operands to AIr32");
00103     if (MI.getOperand(0).isReg() &&
00104         MI.getOperand(1).isReg() &&
00105         (MI.getOperand(2).isImm() &&
00106          MI.getOperand(2).getImm() == 0)) {
00107       sourceReg = MI.getOperand(1).getReg();
00108       destReg = MI.getOperand(0).getReg();
00109       return true;
00110     }
00111     break;
00112   case SPU::LRr8:
00113   case SPU::LRr16:
00114   case SPU::LRr32:
00115   case SPU::LRf32:
00116   case SPU::LRr64:
00117   case SPU::LRf64:
00118   case SPU::LRr128:
00119   case SPU::LRv16i8:
00120   case SPU::LRv8i16:
00121   case SPU::LRv4i32:
00122   case SPU::LRv4f32:
00123   case SPU::LRv2i64:
00124   case SPU::LRv2f64:
00125   case SPU::ORv16i8_i8:
00126   case SPU::ORv8i16_i16:
00127   case SPU::ORv4i32_i32:
00128   case SPU::ORv2i64_i64:
00129   case SPU::ORv4f32_f32:
00130   case SPU::ORv2f64_f64:
00131   case SPU::ORi8_v16i8:
00132   case SPU::ORi16_v8i16:
00133   case SPU::ORi32_v4i32:
00134   case SPU::ORi64_v2i64:
00135   case SPU::ORf32_v4f32:
00136   case SPU::ORf64_v2f64:
00137 /*
00138   case SPU::ORi128_r64:
00139   case SPU::ORi128_f64:
00140   case SPU::ORi128_r32:
00141   case SPU::ORi128_f32:
00142   case SPU::ORi128_r16:
00143   case SPU::ORi128_r8:
00144   case SPU::ORi128_vec:
00145   case SPU::ORr64_i128:
00146   case SPU::ORf64_i128:
00147   case SPU::ORr32_i128:
00148   case SPU::ORf32_i128:
00149   case SPU::ORr16_i128:
00150   case SPU::ORr8_i128:
00151   case SPU::ORvec_i128:
00152 */
00153 /*
00154   case SPU::ORr16_r32:
00155   case SPU::ORr8_r32:
00156   case SPU::ORr32_r16:
00157   case SPU::ORr32_r8:
00158   case SPU::ORr16_r64:
00159   case SPU::ORr8_r64:
00160   case SPU::ORr64_r16:
00161   case SPU::ORr64_r8:
00162 */
00163   case SPU::ORr64_r32:
00164   case SPU::ORr32_r64:
00165   case SPU::ORf32_r32:
00166   case SPU::ORr32_f32:
00167   case SPU::ORf64_r64:
00168   case SPU::ORr64_f64: {
00169     assert(MI.getNumOperands() == 2 &&
00170            MI.getOperand(0).isReg() &&
00171            MI.getOperand(1).isReg() &&
00172            "invalid SPU OR<type>_<vec> or LR instruction!");
00173     if (MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) {
00174       sourceReg = MI.getOperand(0).getReg();
00175       destReg = MI.getOperand(0).getReg();
00176       return true;
00177     }
00178     break;
00179   }
00180   case SPU::ORv16i8:
00181   case SPU::ORv8i16:
00182   case SPU::ORv4i32:
00183   case SPU::ORv2i64:
00184   case SPU::ORr8:
00185   case SPU::ORr16:
00186   case SPU::ORr32:
00187   case SPU::ORr64:
00188   case SPU::ORf32:
00189   case SPU::ORf64:
00190     assert(MI.getNumOperands() == 3 &&
00191            MI.getOperand(0).isReg() &&
00192            MI.getOperand(1).isReg() &&
00193            MI.getOperand(2).isReg() &&
00194            "invalid SPU OR(vec|r32|r64|gprc) instruction!");
00195     if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
00196       sourceReg = MI.getOperand(1).getReg();
00197       destReg = MI.getOperand(0).getReg();
00198       return true;
00199     }
00200     break;
00201   }
00202 
00203   return false;
00204 }
00205 
00206 unsigned
00207 SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
00208                                   int &FrameIndex) const {
00209   switch (MI->getOpcode()) {
00210   default: break;
00211   case SPU::LQDv16i8:
00212   case SPU::LQDv8i16:
00213   case SPU::LQDv4i32:
00214   case SPU::LQDv4f32:
00215   case SPU::LQDv2f64:
00216   case SPU::LQDr128:
00217   case SPU::LQDr64:
00218   case SPU::LQDr32:
00219   case SPU::LQDr16: {
00220     const MachineOperand MOp1 = MI->getOperand(1);
00221     const MachineOperand MOp2 = MI->getOperand(2);
00222     if (MOp1.isImm() && MOp2.isFI()) {
00223       FrameIndex = MOp2.getIndex();
00224       return MI->getOperand(0).getReg();
00225     }
00226     break;
00227   }
00228   }
00229   return 0;
00230 }
00231 
00232 unsigned
00233 SPUInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
00234                                  int &FrameIndex) const {
00235   switch (MI->getOpcode()) {
00236   default: break;
00237   case SPU::STQDv16i8:
00238   case SPU::STQDv8i16:
00239   case SPU::STQDv4i32:
00240   case SPU::STQDv4f32:
00241   case SPU::STQDv2f64:
00242   case SPU::STQDr128:
00243   case SPU::STQDr64:
00244   case SPU::STQDr32:
00245   case SPU::STQDr16:
00246   case SPU::STQDr8: {
00247     const MachineOperand MOp1 = MI->getOperand(1);
00248     const MachineOperand MOp2 = MI->getOperand(2);
00249     if (MOp1.isImm() && MOp2.isFI()) {
00250       FrameIndex = MOp2.getIndex();
00251       return MI->getOperand(0).getReg();
00252     }
00253     break;
00254   }
00255   }
00256   return 0;
00257 }
00258 
00259 bool SPUInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
00260                                    MachineBasicBlock::iterator MI,
00261                                    unsigned DestReg, unsigned SrcReg,
00262                                    const TargetRegisterClass *DestRC,
00263                                    const TargetRegisterClass *SrcRC) const
00264 {
00265   // We support cross register class moves for our aliases, such as R3 in any
00266   // reg class to any other reg class containing R3.  This is required because
00267   // we instruction select bitconvert i64 -> f64 as a noop for example, so our
00268   // types have no specific meaning.
00269 
00270   if (DestRC == SPU::R8CRegisterClass) {
00271     BuildMI(MBB, MI, get(SPU::LRr8), DestReg).addReg(SrcReg);
00272   } else if (DestRC == SPU::R16CRegisterClass) {
00273     BuildMI(MBB, MI, get(SPU::LRr16), DestReg).addReg(SrcReg);
00274   } else if (DestRC == SPU::R32CRegisterClass) {
00275     BuildMI(MBB, MI, get(SPU::LRr32), DestReg).addReg(SrcReg);
00276   } else if (DestRC == SPU::R32FPRegisterClass) {
00277     BuildMI(MBB, MI, get(SPU::LRf32), DestReg).addReg(SrcReg);
00278   } else if (DestRC == SPU::R64CRegisterClass) {
00279     BuildMI(MBB, MI, get(SPU::LRr64), DestReg).addReg(SrcReg);
00280   } else if (DestRC == SPU::R64FPRegisterClass) {
00281     BuildMI(MBB, MI, get(SPU::LRf64), DestReg).addReg(SrcReg);
00282   } else if (DestRC == SPU::GPRCRegisterClass) {
00283     BuildMI(MBB, MI, get(SPU::LRr128), DestReg).addReg(SrcReg);
00284   } else if (DestRC == SPU::VECREGRegisterClass) {
00285     BuildMI(MBB, MI, get(SPU::LRv16i8), DestReg).addReg(SrcReg);
00286   } else {
00287     // Attempt to copy unknown/unsupported register class!
00288     return false;
00289   }
00290 
00291   return true;
00292 }
00293 
00294 void
00295 SPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
00296                                      MachineBasicBlock::iterator MI,
00297                                      unsigned SrcReg, bool isKill, int FrameIdx,
00298                                      const TargetRegisterClass *RC) const
00299 {
00300   unsigned opc;
00301   bool isValidFrameIdx = (FrameIdx < SPUFrameInfo::maxFrameOffset());
00302   if (RC == SPU::GPRCRegisterClass) {
00303     opc = (isValidFrameIdx ? SPU::STQDr128 : SPU::STQXr128);
00304   } else if (RC == SPU::R64CRegisterClass) {
00305     opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64);
00306   } else if (RC == SPU::R64FPRegisterClass) {
00307     opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64);
00308   } else if (RC == SPU::R32CRegisterClass) {
00309     opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32);
00310   } else if (RC == SPU::R32FPRegisterClass) {
00311     opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32);
00312   } else if (RC == SPU::R16CRegisterClass) {
00313     opc = (isValidFrameIdx ? SPU::STQDr16 : SPU::STQXr16);
00314   } else if (RC == SPU::R8CRegisterClass) {
00315     opc = (isValidFrameIdx ? SPU::STQDr8 : SPU::STQXr8);
00316   } else if (RC == SPU::VECREGRegisterClass) {
00317     opc = (isValidFrameIdx) ? SPU::STQDv16i8 : SPU::STQXv16i8;
00318   } else {
00319     assert(0 && "Unknown regclass!");
00320     abort();
00321   }
00322 
00323   addFrameReference(BuildMI(MBB, MI, get(opc))
00324                     .addReg(SrcReg, false, false, isKill), FrameIdx);
00325 }
00326 
00327 void SPUInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
00328                                      bool isKill,
00329                                      SmallVectorImpl<MachineOperand> &Addr,
00330                                      const TargetRegisterClass *RC,
00331                                      SmallVectorImpl<MachineInstr*> &NewMIs) const {
00332   cerr << "storeRegToAddr() invoked!\n";
00333   abort();
00334 
00335   if (Addr[0].isFI()) {
00336     /* do what storeRegToStackSlot does here */
00337   } else {
00338     unsigned Opc = 0;
00339     if (RC == SPU::GPRCRegisterClass) {
00340       /* Opc = PPC::STW; */
00341     } else if (RC == SPU::R16CRegisterClass) {
00342       /* Opc = PPC::STD; */
00343     } else if (RC == SPU::R32CRegisterClass) {
00344       /* Opc = PPC::STFD; */
00345     } else if (RC == SPU::R32FPRegisterClass) {
00346       /* Opc = PPC::STFD; */
00347     } else if (RC == SPU::R64FPRegisterClass) {
00348       /* Opc = PPC::STFS; */
00349     } else if (RC == SPU::VECREGRegisterClass) {
00350       /* Opc = PPC::STVX; */
00351     } else {
00352       assert(0 && "Unknown regclass!");
00353       abort();
00354     }
00355     MachineInstrBuilder MIB = BuildMI(MF, get(Opc))
00356       .addReg(SrcReg, false, false, isKill);
00357     for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00358       MachineOperand &MO = Addr[i];
00359       if (MO.isReg())
00360         MIB.addReg(MO.getReg());
00361       else if (MO.isImm())
00362         MIB.addImm(MO.getImm());
00363       else
00364         MIB.addFrameIndex(MO.getIndex());
00365     }
00366     NewMIs.push_back(MIB);
00367   }
00368 }
00369 
00370 void
00371 SPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
00372                                         MachineBasicBlock::iterator MI,
00373                                         unsigned DestReg, int FrameIdx,
00374                                         const TargetRegisterClass *RC) const
00375 {
00376   unsigned opc;
00377   bool isValidFrameIdx = (FrameIdx < SPUFrameInfo::maxFrameOffset());
00378   if (RC == SPU::GPRCRegisterClass) {
00379     opc = (isValidFrameIdx ? SPU::LQDr128 : SPU::LQXr128);
00380   } else if (RC == SPU::R64CRegisterClass) {
00381     opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64);
00382   } else if (RC == SPU::R64FPRegisterClass) {
00383     opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64);
00384   } else if (RC == SPU::R32CRegisterClass) {
00385     opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32);
00386   } else if (RC == SPU::R32FPRegisterClass) {
00387     opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32);
00388   } else if (RC == SPU::R16CRegisterClass) {
00389     opc = (isValidFrameIdx ? SPU::LQDr16 : SPU::LQXr16);
00390   } else if (RC == SPU::R8CRegisterClass) {
00391     opc = (isValidFrameIdx ? SPU::LQDr8 : SPU::LQXr8);
00392   } else if (RC == SPU::VECREGRegisterClass) {
00393     opc = (isValidFrameIdx) ? SPU::LQDv16i8 : SPU::LQXv16i8;
00394   } else {
00395     assert(0 && "Unknown regclass in loadRegFromStackSlot!");
00396     abort();
00397   }
00398 
00399   addFrameReference(BuildMI(MBB, MI, get(opc)).addReg(DestReg), FrameIdx);
00400 }
00401 
00402 /*!
00403   \note We are really pessimistic here about what kind of a load we're doing.
00404  */
00405 void SPUInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
00406                                    SmallVectorImpl<MachineOperand> &Addr,
00407                                    const TargetRegisterClass *RC,
00408                                    SmallVectorImpl<MachineInstr*> &NewMIs)
00409     const {
00410   cerr << "loadRegToAddr() invoked!\n";
00411   abort();
00412 
00413   if (Addr[0].isFI()) {
00414     /* do what loadRegFromStackSlot does here... */
00415   } else {
00416     unsigned Opc = 0;
00417     if (RC == SPU::R8CRegisterClass) {
00418       /* do brilliance here */
00419     } else if (RC == SPU::R16CRegisterClass) {
00420       /* Opc = PPC::LWZ; */
00421     } else if (RC == SPU::R32CRegisterClass) {
00422       /* Opc = PPC::LD; */
00423     } else if (RC == SPU::R32FPRegisterClass) {
00424       /* Opc = PPC::LFD; */
00425     } else if (RC == SPU::R64FPRegisterClass) {
00426       /* Opc = PPC::LFS; */
00427     } else if (RC == SPU::VECREGRegisterClass) {
00428       /* Opc = PPC::LVX; */
00429     } else if (RC == SPU::GPRCRegisterClass) {
00430       /* Opc = something else! */
00431     } else {
00432       assert(0 && "Unknown regclass!");
00433       abort();
00434     }
00435     MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg);
00436     for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00437       MachineOperand &MO = Addr[i];
00438       if (MO.isReg())
00439         MIB.addReg(MO.getReg());
00440       else if (MO.isImm())
00441         MIB.addImm(MO.getImm());
00442       else
00443         MIB.addFrameIndex(MO.getIndex());
00444     }
00445     NewMIs.push_back(MIB);
00446   }
00447 }
00448 
00449 //! Return true if the specified load or store can be folded
00450 bool
00451 SPUInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
00452                                    const SmallVectorImpl<unsigned> &Ops) const {
00453   if (Ops.size() != 1) return false;
00454 
00455   // Make sure this is a reg-reg copy.
00456   unsigned Opc = MI->getOpcode();
00457 
00458   switch (Opc) {
00459   case SPU::ORv16i8:
00460   case SPU::ORv8i16:
00461   case SPU::ORv4i32:
00462   case SPU::ORv2i64:
00463   case SPU::ORr8:
00464   case SPU::ORr16:
00465   case SPU::ORr32:
00466   case SPU::ORr64:
00467   case SPU::ORf32:
00468   case SPU::ORf64:
00469     if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())
00470       return true;
00471     break;
00472   }
00473 
00474   return false;
00475 }
00476 
00477 /// foldMemoryOperand - SPU, like PPC, can only fold spills into
00478 /// copy instructions, turning them into load/store instructions.
00479 MachineInstr *
00480 SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
00481                                     MachineInstr *MI,
00482                                     const SmallVectorImpl<unsigned> &Ops,
00483                                     int FrameIndex) const
00484 {
00485   if (Ops.size() != 1) return 0;
00486 
00487   unsigned OpNum = Ops[0];
00488   unsigned Opc = MI->getOpcode();
00489   MachineInstr *NewMI = 0;
00490 
00491   switch (Opc) {
00492   case SPU::ORv16i8:
00493   case SPU::ORv8i16:
00494   case SPU::ORv4i32:
00495   case SPU::ORv2i64:
00496   case SPU::ORr8:
00497   case SPU::ORr16:
00498   case SPU::ORr32:
00499   case SPU::ORr64:
00500   case SPU::ORf32:
00501   case SPU::ORf64:
00502     if (OpNum == 0) {  // move -> store
00503       unsigned InReg = MI->getOperand(1).getReg();
00504       bool isKill = MI->getOperand(1).isKill();
00505       if (FrameIndex < SPUFrameInfo::maxFrameOffset()) {
00506         MachineInstrBuilder MIB = BuildMI(MF, get(SPU::STQDr32));
00507 
00508         MIB.addReg(InReg, false, false, isKill);
00509         NewMI = addFrameReference(MIB, FrameIndex);
00510       }
00511     } else {           // move -> load
00512       unsigned OutReg = MI->getOperand(0).getReg();
00513       bool isDead = MI->getOperand(0).isDead();
00514       MachineInstrBuilder MIB = BuildMI(MF, get(Opc));
00515 
00516       MIB.addReg(OutReg, true, false, false, isDead);
00517       Opc = (FrameIndex < SPUFrameInfo::maxFrameOffset())
00518         ? SPU::STQDr32 : SPU::STQXr32;
00519       NewMI = addFrameReference(MIB, FrameIndex);
00520     break;
00521   }
00522   }
00523 
00524   return NewMI;
00525 }
00526 
00527 //! Branch analysis
00528 /*!
00529   \note This code was kiped from PPC. There may be more branch analysis for
00530   CellSPU than what's currently done here.
00531  */
00532 bool
00533 SPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
00534                             MachineBasicBlock *&FBB,
00535                             SmallVectorImpl<MachineOperand> &Cond,
00536                             bool AllowModify) const {
00537   // If the block has no terminators, it just falls into the block after it.
00538   MachineBasicBlock::iterator I = MBB.end();
00539   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
00540     return false;
00541 
00542   // Get the last instruction in the block.
00543   MachineInstr *LastInst = I;
00544 
00545   // If there is only one terminator instruction, process it.
00546   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
00547     if (isUncondBranch(LastInst)) {
00548       TBB = LastInst->getOperand(0).getMBB();
00549       return false;
00550     } else if (isCondBranch(LastInst)) {
00551       // Block ends with fall-through condbranch.
00552       TBB = LastInst->getOperand(1).getMBB();
00553       DEBUG(cerr << "Pushing LastInst:               ");
00554       DEBUG(LastInst->dump());
00555       Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
00556       Cond.push_back(LastInst->getOperand(0));
00557       return false;
00558     }
00559     // Otherwise, don't know what this is.
00560     return true;
00561   }
00562 
00563   // Get the instruction before it if it's a terminator.
00564   MachineInstr *SecondLastInst = I;
00565 
00566   // If there are three terminators, we don't know what sort of block this is.
00567   if (SecondLastInst && I != MBB.begin() &&
00568       isUnpredicatedTerminator(--I))
00569     return true;
00570 
00571   // If the block ends with a conditional and unconditional branch, handle it.
00572   if (isCondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
00573     TBB =  SecondLastInst->getOperand(1).getMBB();
00574     DEBUG(cerr << "Pushing SecondLastInst:         ");
00575     DEBUG(SecondLastInst->dump());
00576     Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
00577     Cond.push_back(SecondLastInst->getOperand(0));
00578     FBB = LastInst->getOperand(0).getMBB();
00579     return false;
00580   }
00581 
00582   // If the block ends with two unconditional branches, handle it.  The second
00583   // one is not executed, so remove it.
00584   if (isUncondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
00585     TBB = SecondLastInst->getOperand(0).getMBB();
00586     I = LastInst;
00587     if (AllowModify)
00588       I->eraseFromParent();
00589     return false;
00590   }
00591 
00592   // Otherwise, can't handle this.
00593   return true;
00594 }
00595 
00596 unsigned
00597 SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
00598   MachineBasicBlock::iterator I = MBB.end();
00599   if (I == MBB.begin())
00600     return 0;
00601   --I;
00602   if (!isCondBranch(I) && !isUncondBranch(I))
00603     return 0;
00604 
00605   // Remove the first branch.
00606   DEBUG(cerr << "Removing branch:                ");
00607   DEBUG(I->dump());
00608   I->eraseFromParent();
00609   I = MBB.end();
00610   if (I == MBB.begin())
00611     return 1;
00612 
00613   --I;
00614   if (!(isCondBranch(I) || isUncondBranch(I)))
00615     return 1;
00616 
00617   // Remove the second branch.
00618   DEBUG(cerr << "Removing second branch:         ");
00619   DEBUG(I->dump());
00620   I->eraseFromParent();
00621   return 2;
00622 }
00623 
00624 unsigned
00625 SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
00626                            MachineBasicBlock *FBB,
00627                            const SmallVectorImpl<MachineOperand> &Cond) const {
00628   // Shouldn't be a fall through.
00629   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
00630   assert((Cond.size() == 2 || Cond.size() == 0) &&
00631          "SPU branch conditions have two components!");
00632 
00633   // One-way branch.
00634   if (FBB == 0) {
00635     if (Cond.empty()) {
00636       // Unconditional branch
00637       MachineInstrBuilder MIB = BuildMI(&MBB, get(SPU::BR));
00638       MIB.addMBB(TBB);
00639 
00640       DEBUG(cerr << "Inserted one-way uncond branch: ");
00641       DEBUG((*MIB).dump());
00642     } else {
00643       // Conditional branch
00644       MachineInstrBuilder  MIB = BuildMI(&MBB, get(Cond[0].getImm()));
00645       MIB.addReg(Cond[1].getReg()).addMBB(TBB);
00646 
00647       DEBUG(cerr << "Inserted one-way cond branch:   ");
00648       DEBUG((*MIB).dump());
00649     }
00650     return 1;
00651   } else {
00652     MachineInstrBuilder MIB = BuildMI(&MBB, get(Cond[0].getImm()));
00653     MachineInstrBuilder MIB2 = BuildMI(&MBB, get(SPU::BR));
00654 
00655     // Two-way Conditional Branch.
00656     MIB.addReg(Cond[1].getReg()).addMBB(TBB);
00657     MIB2.addMBB(FBB);
00658 
00659     DEBUG(cerr << "Inserted conditional branch:    ");
00660     DEBUG((*MIB).dump());
00661     DEBUG(cerr << "part 2: ");
00662     DEBUG((*MIB2).dump());
00663    return 2;
00664   }
00665 }
00666 
00667 bool
00668 SPUInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
00669   return (!MBB.empty() && isUncondBranch(&MBB.back()));
00670 }
00671 //! Reverses a branch's condition, returning false on success.
00672 bool
00673 SPUInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
00674   const {
00675   // Pretty brainless way of inverting the condition, but it works, considering
00676   // there are only two conditions...
00677   static struct {
00678     unsigned Opc;               //! The incoming opcode
00679     unsigned RevCondOpc;        //! The reversed condition opcode
00680   } revconds[] = {
00681     { SPU::BRNZr32, SPU::BRZr32 },
00682     { SPU::BRNZv4i32, SPU::BRZv4i32 },
00683     { SPU::BRZr32, SPU::BRNZr32 },
00684     { SPU::BRZv4i32, SPU::BRNZv4i32 },
00685     { SPU::BRHNZr16, SPU::BRHZr16 },
00686     { SPU::BRHNZv8i16, SPU::BRHZv8i16 },
00687     { SPU::BRHZr16, SPU::BRHNZr16 },
00688     { SPU::BRHZv8i16, SPU::BRHNZv8i16 }
00689   };
00690 
00691   unsigned Opc = unsigned(Cond[0].getImm());
00692   // Pretty dull mapping between the two conditions that SPU can generate:
00693   for (int i = sizeof(revconds)/sizeof(revconds[0]) - 1; i >= 0; --i) {
00694     if (revconds[i].Opc == Opc) {
00695       Cond[0].setImm(revconds[i].RevCondOpc);
00696       return false;
00697     }
00698   }
00699 
00700   return true;
00701 }