LLVM API Documentation

MBlazeInstrInfo.cpp
Go to the documentation of this file.
00001 //===-- MBlazeInstrInfo.cpp - MBlaze 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 MBlaze implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "MBlazeInstrInfo.h"
00015 #include "MBlazeMachineFunction.h"
00016 #include "MBlazeTargetMachine.h"
00017 #include "llvm/ADT/STLExtras.h"
00018 #include "llvm/CodeGen/MachineInstrBuilder.h"
00019 #include "llvm/CodeGen/MachineRegisterInfo.h"
00020 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Support/ErrorHandling.h"
00023 #include "llvm/Support/TargetRegistry.h"
00024 
00025 #define GET_INSTRINFO_CTOR
00026 #include "MBlazeGenInstrInfo.inc"
00027 
00028 using namespace llvm;
00029 
00030 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
00031   : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
00032     TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
00033 
00034 static bool isZeroImm(const MachineOperand &op) {
00035   return op.isImm() && op.getImm() == 0;
00036 }
00037 
00038 /// isLoadFromStackSlot - If the specified machine instruction is a direct
00039 /// load from a stack slot, return the virtual or physical register number of
00040 /// the destination along with the FrameIndex of the loaded stack slot.  If
00041 /// not, return 0.  This predicate must return 0 if the instruction has
00042 /// any side effects other than loading from the stack slot.
00043 unsigned MBlazeInstrInfo::
00044 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
00045   if (MI->getOpcode() == MBlaze::LWI) {
00046     if ((MI->getOperand(1).isFI()) && // is a stack slot
00047         (MI->getOperand(2).isImm()) &&  // the imm is zero
00048         (isZeroImm(MI->getOperand(2)))) {
00049       FrameIndex = MI->getOperand(1).getIndex();
00050       return MI->getOperand(0).getReg();
00051     }
00052   }
00053 
00054   return 0;
00055 }
00056 
00057 /// isStoreToStackSlot - If the specified machine instruction is a direct
00058 /// store to a stack slot, return the virtual or physical register number of
00059 /// the source reg along with the FrameIndex of the loaded stack slot.  If
00060 /// not, return 0.  This predicate must return 0 if the instruction has
00061 /// any side effects other than storing to the stack slot.
00062 unsigned MBlazeInstrInfo::
00063 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
00064   if (MI->getOpcode() == MBlaze::SWI) {
00065     if ((MI->getOperand(1).isFI()) && // is a stack slot
00066         (MI->getOperand(2).isImm()) &&  // the imm is zero
00067         (isZeroImm(MI->getOperand(2)))) {
00068       FrameIndex = MI->getOperand(1).getIndex();
00069       return MI->getOperand(0).getReg();
00070     }
00071   }
00072   return 0;
00073 }
00074 
00075 /// insertNoop - If data hazard condition is found insert the target nop
00076 /// instruction.
00077 void MBlazeInstrInfo::
00078 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
00079   DebugLoc DL;
00080   BuildMI(MBB, MI, DL, get(MBlaze::NOP));
00081 }
00082 
00083 void MBlazeInstrInfo::
00084 copyPhysReg(MachineBasicBlock &MBB,
00085             MachineBasicBlock::iterator I, DebugLoc DL,
00086             unsigned DestReg, unsigned SrcReg,
00087             bool KillSrc) const {
00088   llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg)
00089     .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
00090 }
00091 
00092 void MBlazeInstrInfo::
00093 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00094                     unsigned SrcReg, bool isKill, int FI,
00095                     const TargetRegisterClass *RC,
00096                     const TargetRegisterInfo *TRI) const {
00097   DebugLoc DL;
00098   BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
00099     .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
00100 }
00101 
00102 void MBlazeInstrInfo::
00103 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00104                      unsigned DestReg, int FI,
00105                      const TargetRegisterClass *RC,
00106                      const TargetRegisterInfo *TRI) const {
00107   DebugLoc DL;
00108   BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
00109       .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
00110 }
00111 
00112 //===----------------------------------------------------------------------===//
00113 // Branch Analysis
00114 //===----------------------------------------------------------------------===//
00115 bool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
00116                                     MachineBasicBlock *&TBB,
00117                                     MachineBasicBlock *&FBB,
00118                                     SmallVectorImpl<MachineOperand> &Cond,
00119                                     bool AllowModify) const {
00120   // If the block has no terminators, it just falls into the block after it.
00121   MachineBasicBlock::iterator I = MBB.end();
00122   if (I == MBB.begin())
00123     return false;
00124   --I;
00125   while (I->isDebugValue()) {
00126     if (I == MBB.begin())
00127       return false;
00128     --I;
00129   }
00130   if (!isUnpredicatedTerminator(I))
00131     return false;
00132 
00133   // Get the last instruction in the block.
00134   MachineInstr *LastInst = I;
00135 
00136   // If there is only one terminator instruction, process it.
00137   unsigned LastOpc = LastInst->getOpcode();
00138   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
00139     if (MBlaze::isUncondBranchOpcode(LastOpc)) {
00140       TBB = LastInst->getOperand(0).getMBB();
00141       return false;
00142     }
00143     if (MBlaze::isCondBranchOpcode(LastOpc)) {
00144       // Block ends with fall-through condbranch.
00145       TBB = LastInst->getOperand(1).getMBB();
00146       Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
00147       Cond.push_back(LastInst->getOperand(0));
00148       return false;
00149     }
00150     // Otherwise, don't know what this is.
00151     return true;
00152   }
00153 
00154   // Get the instruction before it if it's a terminator.
00155   MachineInstr *SecondLastInst = I;
00156 
00157   // If there are three terminators, we don't know what sort of block this is.
00158   if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
00159     return true;
00160 
00161   // If the block ends with something like BEQID then BRID, handle it.
00162   if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) &&
00163       MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
00164     TBB = SecondLastInst->getOperand(1).getMBB();
00165     Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
00166     Cond.push_back(SecondLastInst->getOperand(0));
00167     FBB = LastInst->getOperand(0).getMBB();
00168     return false;
00169   }
00170 
00171   // If the block ends with two unconditional branches, handle it.
00172   // The second one is not executed, so remove it.
00173   if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) &&
00174       MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
00175     TBB = SecondLastInst->getOperand(0).getMBB();
00176     I = LastInst;
00177     if (AllowModify)
00178       I->eraseFromParent();
00179     return false;
00180   }
00181 
00182   // Otherwise, can't handle this.
00183   return true;
00184 }
00185 
00186 unsigned MBlazeInstrInfo::
00187 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
00188              MachineBasicBlock *FBB,
00189              const SmallVectorImpl<MachineOperand> &Cond,
00190              DebugLoc DL) const {
00191   // Shouldn't be a fall through.
00192   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
00193   assert((Cond.size() == 2 || Cond.size() == 0) &&
00194          "MBlaze branch conditions have two components!");
00195 
00196   unsigned Opc = MBlaze::BRID;
00197   if (!Cond.empty())
00198     Opc = (unsigned)Cond[0].getImm();
00199 
00200   if (FBB == 0) {
00201     if (Cond.empty()) // Unconditional branch
00202       BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
00203     else              // Conditional branch
00204       BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
00205     return 1;
00206   }
00207 
00208   BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
00209   BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB);
00210   return 2;
00211 }
00212 
00213 unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
00214   MachineBasicBlock::iterator I = MBB.end();
00215   if (I == MBB.begin()) return 0;
00216   --I;
00217   while (I->isDebugValue()) {
00218     if (I == MBB.begin())
00219       return 0;
00220     --I;
00221   }
00222 
00223   if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) &&
00224       !MBlaze::isCondBranchOpcode(I->getOpcode()))
00225     return 0;
00226 
00227   // Remove the branch.
00228   I->eraseFromParent();
00229 
00230   I = MBB.end();
00231 
00232   if (I == MBB.begin()) return 1;
00233   --I;
00234   if (!MBlaze::isCondBranchOpcode(I->getOpcode()))
00235     return 1;
00236 
00237   // Remove the branch.
00238   I->eraseFromParent();
00239   return 2;
00240 }
00241 
00242 bool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand>
00243                                                &Cond) const {
00244   assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!");
00245   switch (Cond[0].getImm()) {
00246   default:            return true;
00247   case MBlaze::BEQ:   Cond[0].setImm(MBlaze::BNE); return false;
00248   case MBlaze::BNE:   Cond[0].setImm(MBlaze::BEQ); return false;
00249   case MBlaze::BGT:   Cond[0].setImm(MBlaze::BLE); return false;
00250   case MBlaze::BGE:   Cond[0].setImm(MBlaze::BLT); return false;
00251   case MBlaze::BLT:   Cond[0].setImm(MBlaze::BGE); return false;
00252   case MBlaze::BLE:   Cond[0].setImm(MBlaze::BGT); return false;
00253   case MBlaze::BEQI:  Cond[0].setImm(MBlaze::BNEI); return false;
00254   case MBlaze::BNEI:  Cond[0].setImm(MBlaze::BEQI); return false;
00255   case MBlaze::BGTI:  Cond[0].setImm(MBlaze::BLEI); return false;
00256   case MBlaze::BGEI:  Cond[0].setImm(MBlaze::BLTI); return false;
00257   case MBlaze::BLTI:  Cond[0].setImm(MBlaze::BGEI); return false;
00258   case MBlaze::BLEI:  Cond[0].setImm(MBlaze::BGTI); return false;
00259   case MBlaze::BEQD:  Cond[0].setImm(MBlaze::BNED); return false;
00260   case MBlaze::BNED:  Cond[0].setImm(MBlaze::BEQD); return false;
00261   case MBlaze::BGTD:  Cond[0].setImm(MBlaze::BLED); return false;
00262   case MBlaze::BGED:  Cond[0].setImm(MBlaze::BLTD); return false;
00263   case MBlaze::BLTD:  Cond[0].setImm(MBlaze::BGED); return false;
00264   case MBlaze::BLED:  Cond[0].setImm(MBlaze::BGTD); return false;
00265   case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false;
00266   case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false;
00267   case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false;
00268   case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false;
00269   case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false;
00270   case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false;
00271   }
00272 }
00273 
00274 /// getGlobalBaseReg - Return a virtual register initialized with the
00275 /// the global base register value. Output instructions required to
00276 /// initialize the register in the function entry block, if necessary.
00277 ///
00278 unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
00279   MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
00280   unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
00281   if (GlobalBaseReg != 0)
00282     return GlobalBaseReg;
00283 
00284   // Insert the set of GlobalBaseReg into the first MBB of the function
00285   MachineBasicBlock &FirstMBB = MF->front();
00286   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
00287   MachineRegisterInfo &RegInfo = MF->getRegInfo();
00288   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
00289 
00290   GlobalBaseReg = RegInfo.createVirtualRegister(&MBlaze::GPRRegClass);
00291   BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
00292           GlobalBaseReg).addReg(MBlaze::R20);
00293   RegInfo.addLiveIn(MBlaze::R20);
00294 
00295   MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
00296   return GlobalBaseReg;
00297 }