LLVM API Documentation

AlphaInstrInfo.cpp

Go to the documentation of this file.
00001 //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===//
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 Alpha implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "Alpha.h"
00015 #include "AlphaInstrInfo.h"
00016 #include "AlphaGenInstrInfo.inc"
00017 #include "llvm/ADT/STLExtras.h"
00018 #include "llvm/CodeGen/MachineInstrBuilder.h"
00019 using namespace llvm;
00020 
00021 AlphaInstrInfo::AlphaInstrInfo()
00022   : TargetInstrInfoImpl(AlphaInsts, array_lengthof(AlphaInsts)),
00023     RI(*this) { }
00024 
00025 
00026 bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI,
00027                                  unsigned& sourceReg,
00028                                  unsigned& destReg) const {
00029   unsigned oc = MI.getOpcode();
00030   if (oc == Alpha::BISr   || 
00031       oc == Alpha::CPYSS  || 
00032       oc == Alpha::CPYST  ||
00033       oc == Alpha::CPYSSt || 
00034       oc == Alpha::CPYSTs) {
00035     // or r1, r2, r2 
00036     // cpys(s|t) r1 r2 r2
00037     assert(MI.getNumOperands() >= 3 &&
00038            MI.getOperand(0).isReg() &&
00039            MI.getOperand(1).isReg() &&
00040            MI.getOperand(2).isReg() &&
00041            "invalid Alpha BIS instruction!");
00042     if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
00043       sourceReg = MI.getOperand(1).getReg();
00044       destReg = MI.getOperand(0).getReg();
00045       return true;
00046     }
00047   }
00048   return false;
00049 }
00050 
00051 unsigned 
00052 AlphaInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const {
00053   switch (MI->getOpcode()) {
00054   case Alpha::LDL:
00055   case Alpha::LDQ:
00056   case Alpha::LDBU:
00057   case Alpha::LDWU:
00058   case Alpha::LDS:
00059   case Alpha::LDT:
00060     if (MI->getOperand(1).isFI()) {
00061       FrameIndex = MI->getOperand(1).getIndex();
00062       return MI->getOperand(0).getReg();
00063     }
00064     break;
00065   }
00066   return 0;
00067 }
00068 
00069 unsigned 
00070 AlphaInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
00071   switch (MI->getOpcode()) {
00072   case Alpha::STL:
00073   case Alpha::STQ:
00074   case Alpha::STB:
00075   case Alpha::STW:
00076   case Alpha::STS:
00077   case Alpha::STT:
00078     if (MI->getOperand(1).isFI()) {
00079       FrameIndex = MI->getOperand(1).getIndex();
00080       return MI->getOperand(0).getReg();
00081     }
00082     break;
00083   }
00084   return 0;
00085 }
00086 
00087 static bool isAlphaIntCondCode(unsigned Opcode) {
00088   switch (Opcode) {
00089   case Alpha::BEQ: 
00090   case Alpha::BNE: 
00091   case Alpha::BGE: 
00092   case Alpha::BGT: 
00093   case Alpha::BLE: 
00094   case Alpha::BLT: 
00095   case Alpha::BLBC: 
00096   case Alpha::BLBS:
00097     return true;
00098   default:
00099     return false;
00100   }
00101 }
00102 
00103 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,
00104                             MachineBasicBlock *TBB,
00105                             MachineBasicBlock *FBB,
00106                             const SmallVectorImpl<MachineOperand> &Cond) const {
00107   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
00108   assert((Cond.size() == 2 || Cond.size() == 0) && 
00109          "Alpha branch conditions have two components!");
00110 
00111   // One-way branch.
00112   if (FBB == 0) {
00113     if (Cond.empty())   // Unconditional branch
00114       BuildMI(&MBB, get(Alpha::BR)).addMBB(TBB);
00115     else                // Conditional branch
00116       if (isAlphaIntCondCode(Cond[0].getImm()))
00117         BuildMI(&MBB, get(Alpha::COND_BRANCH_I))
00118           .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
00119       else
00120         BuildMI(&MBB, get(Alpha::COND_BRANCH_F))
00121           .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
00122     return 1;
00123   }
00124   
00125   // Two-way Conditional Branch.
00126   if (isAlphaIntCondCode(Cond[0].getImm()))
00127     BuildMI(&MBB, get(Alpha::COND_BRANCH_I))
00128       .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
00129   else
00130     BuildMI(&MBB, get(Alpha::COND_BRANCH_F))
00131       .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
00132   BuildMI(&MBB, get(Alpha::BR)).addMBB(FBB);
00133   return 2;
00134 }
00135 
00136 bool AlphaInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
00137                                      MachineBasicBlock::iterator MI,
00138                                      unsigned DestReg, unsigned SrcReg,
00139                                      const TargetRegisterClass *DestRC,
00140                                      const TargetRegisterClass *SrcRC) const {
00141   //cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n";
00142   if (DestRC != SrcRC) {
00143     // Not yet supported!
00144     return false;
00145   }
00146 
00147   if (DestRC == Alpha::GPRCRegisterClass) {
00148     BuildMI(MBB, MI, get(Alpha::BISr), DestReg).addReg(SrcReg).addReg(SrcReg);
00149   } else if (DestRC == Alpha::F4RCRegisterClass) {
00150     BuildMI(MBB, MI, get(Alpha::CPYSS), DestReg).addReg(SrcReg).addReg(SrcReg);
00151   } else if (DestRC == Alpha::F8RCRegisterClass) {
00152     BuildMI(MBB, MI, get(Alpha::CPYST), DestReg).addReg(SrcReg).addReg(SrcReg);
00153   } else {
00154     // Attempt to copy register that is not GPR or FPR
00155     return false;
00156   }
00157   
00158   return true;
00159 }
00160 
00161 void
00162 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
00163                                        MachineBasicBlock::iterator MI,
00164                                      unsigned SrcReg, bool isKill, int FrameIdx,
00165                                      const TargetRegisterClass *RC) const {
00166   //cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
00167   //     << FrameIdx << "\n";
00168   //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
00169   if (RC == Alpha::F4RCRegisterClass)
00170     BuildMI(MBB, MI, get(Alpha::STS))
00171       .addReg(SrcReg, false, false, isKill)
00172       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00173   else if (RC == Alpha::F8RCRegisterClass)
00174     BuildMI(MBB, MI, get(Alpha::STT))
00175       .addReg(SrcReg, false, false, isKill)
00176       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00177   else if (RC == Alpha::GPRCRegisterClass)
00178     BuildMI(MBB, MI, get(Alpha::STQ))
00179       .addReg(SrcReg, false, false, isKill)
00180       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00181   else
00182     abort();
00183 }
00184 
00185 void AlphaInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
00186                                        bool isKill,
00187                                        SmallVectorImpl<MachineOperand> &Addr,
00188                                        const TargetRegisterClass *RC,
00189                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00190   unsigned Opc = 0;
00191   if (RC == Alpha::F4RCRegisterClass)
00192     Opc = Alpha::STS;
00193   else if (RC == Alpha::F8RCRegisterClass)
00194     Opc = Alpha::STT;
00195   else if (RC == Alpha::GPRCRegisterClass)
00196     Opc = Alpha::STQ;
00197   else
00198     abort();
00199   MachineInstrBuilder MIB = 
00200     BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill);
00201   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00202     MachineOperand &MO = Addr[i];
00203     if (MO.isReg())
00204       MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
00205     else
00206       MIB.addImm(MO.getImm());
00207   }
00208   NewMIs.push_back(MIB);
00209 }
00210 
00211 void
00212 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
00213                                         MachineBasicBlock::iterator MI,
00214                                         unsigned DestReg, int FrameIdx,
00215                                         const TargetRegisterClass *RC) const {
00216   //cerr << "Trying to load " << getPrettyName(DestReg) << " to "
00217   //     << FrameIdx << "\n";
00218   if (RC == Alpha::F4RCRegisterClass)
00219     BuildMI(MBB, MI, get(Alpha::LDS), DestReg)
00220       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00221   else if (RC == Alpha::F8RCRegisterClass)
00222     BuildMI(MBB, MI, get(Alpha::LDT), DestReg)
00223       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00224   else if (RC == Alpha::GPRCRegisterClass)
00225     BuildMI(MBB, MI, get(Alpha::LDQ), DestReg)
00226       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
00227   else
00228     abort();
00229 }
00230 
00231 void AlphaInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
00232                                         SmallVectorImpl<MachineOperand> &Addr,
00233                                         const TargetRegisterClass *RC,
00234                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00235   unsigned Opc = 0;
00236   if (RC == Alpha::F4RCRegisterClass)
00237     Opc = Alpha::LDS;
00238   else if (RC == Alpha::F8RCRegisterClass)
00239     Opc = Alpha::LDT;
00240   else if (RC == Alpha::GPRCRegisterClass)
00241     Opc = Alpha::LDQ;
00242   else
00243     abort();
00244   MachineInstrBuilder MIB = 
00245     BuildMI(MF, get(Opc), DestReg);
00246   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00247     MachineOperand &MO = Addr[i];
00248     if (MO.isReg())
00249       MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
00250     else
00251       MIB.addImm(MO.getImm());
00252   }
00253   NewMIs.push_back(MIB);
00254 }
00255 
00256 MachineInstr *AlphaInstrInfo::foldMemoryOperand(MachineFunction &MF,
00257                                                 MachineInstr *MI,
00258                                                 SmallVectorImpl<unsigned> &Ops,
00259                                                 int FrameIndex) const {
00260    if (Ops.size() != 1) return NULL;
00261 
00262    // Make sure this is a reg-reg copy.
00263    unsigned Opc = MI->getOpcode();
00264 
00265    MachineInstr *NewMI = NULL;
00266    switch(Opc) {
00267    default:
00268      break;
00269    case Alpha::BISr:
00270    case Alpha::CPYSS:
00271    case Alpha::CPYST:
00272      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
00273        if (Ops[0] == 0) {  // move -> store
00274          unsigned InReg = MI->getOperand(1).getReg();
00275          bool isKill = MI->getOperand(1).isKill();
00276          Opc = (Opc == Alpha::BISr) ? Alpha::STQ : 
00277            ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT);
00278          NewMI = BuildMI(MF, get(Opc)).addReg(InReg, false, false, isKill)
00279            .addFrameIndex(FrameIndex)
00280            .addReg(Alpha::F31);
00281        } else {           // load -> move
00282          unsigned OutReg = MI->getOperand(0).getReg();
00283          bool isDead = MI->getOperand(0).isDead();
00284          Opc = (Opc == Alpha::BISr) ? Alpha::LDQ : 
00285            ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT);
00286          NewMI = BuildMI(MF, get(Opc)).addReg(OutReg, true, false, false, isDead)
00287            .addFrameIndex(FrameIndex)
00288            .addReg(Alpha::F31);
00289        }
00290      }
00291      break;
00292    }
00293   return NewMI;
00294 }
00295 
00296 static unsigned AlphaRevCondCode(unsigned Opcode) {
00297   switch (Opcode) {
00298   case Alpha::BEQ: return Alpha::BNE;
00299   case Alpha::BNE: return Alpha::BEQ;
00300   case Alpha::BGE: return Alpha::BLT;
00301   case Alpha::BGT: return Alpha::BLE;
00302   case Alpha::BLE: return Alpha::BGT;
00303   case Alpha::BLT: return Alpha::BGE;
00304   case Alpha::BLBC: return Alpha::BLBS;
00305   case Alpha::BLBS: return Alpha::BLBC;
00306   case Alpha::FBEQ: return Alpha::FBNE;
00307   case Alpha::FBNE: return Alpha::FBEQ;
00308   case Alpha::FBGE: return Alpha::FBLT;
00309   case Alpha::FBGT: return Alpha::FBLE;
00310   case Alpha::FBLE: return Alpha::FBGT;
00311   case Alpha::FBLT: return Alpha::FBGE;
00312   default:
00313     assert(0 && "Unknown opcode");
00314   }
00315   return 0; // Not reached
00316 }
00317 
00318 // Branch analysis.
00319 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
00320                                  MachineBasicBlock *&FBB,
00321                                  SmallVectorImpl<MachineOperand> &Cond) const {
00322   // If the block has no terminators, it just falls into the block after it.
00323   MachineBasicBlock::iterator I = MBB.end();
00324   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
00325     return false;
00326 
00327   // Get the last instruction in the block.
00328   MachineInstr *LastInst = I;
00329   
00330   // If there is only one terminator instruction, process it.
00331   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
00332     if (LastInst->getOpcode() == Alpha::BR) {
00333       TBB = LastInst->getOperand(0).getMBB();
00334       return false;
00335     } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
00336                LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
00337       // Block ends with fall-through condbranch.
00338       TBB = LastInst->getOperand(2).getMBB();
00339       Cond.push_back(LastInst->getOperand(0));
00340       Cond.push_back(LastInst->getOperand(1));
00341       return false;
00342     }
00343     // Otherwise, don't know what this is.
00344     return true;
00345   }
00346   
00347   // Get the instruction before it if it's a terminator.
00348   MachineInstr *SecondLastInst = I;
00349 
00350   // If there are three terminators, we don't know what sort of block this is.
00351   if (SecondLastInst && I != MBB.begin() &&
00352       isUnpredicatedTerminator(--I))
00353     return true;
00354   
00355   // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
00356   if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
00357       SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) && 
00358       LastInst->getOpcode() == Alpha::BR) {
00359     TBB =  SecondLastInst->getOperand(2).getMBB();
00360     Cond.push_back(SecondLastInst->getOperand(0));
00361     Cond.push_back(SecondLastInst->getOperand(1));
00362     FBB = LastInst->getOperand(0).getMBB();
00363     return false;
00364   }
00365   
00366   // If the block ends with two Alpha::BRs, handle it.  The second one is not
00367   // executed, so remove it.
00368   if (SecondLastInst->getOpcode() == Alpha::BR && 
00369       LastInst->getOpcode() == Alpha::BR) {
00370     TBB = SecondLastInst->getOperand(0).getMBB();
00371     I = LastInst;
00372     I->eraseFromParent();
00373     return false;
00374   }
00375 
00376   // Otherwise, can't handle this.
00377   return true;
00378 }
00379 
00380 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
00381   MachineBasicBlock::iterator I = MBB.end();
00382   if (I == MBB.begin()) return 0;
00383   --I;
00384   if (I->getOpcode() != Alpha::BR && 
00385       I->getOpcode() != Alpha::COND_BRANCH_I &&
00386       I->getOpcode() != Alpha::COND_BRANCH_F)
00387     return 0;
00388   
00389   // Remove the branch.
00390   I->eraseFromParent();
00391   
00392   I = MBB.end();
00393 
00394   if (I == MBB.begin()) return 1;
00395   --I;
00396   if (I->getOpcode() != Alpha::COND_BRANCH_I && 
00397       I->getOpcode() != Alpha::COND_BRANCH_F)
00398     return 1;
00399   
00400   // Remove the branch.
00401   I->eraseFromParent();
00402   return 2;
00403 }
00404 
00405 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB, 
00406                                 MachineBasicBlock::iterator MI) const {
00407   BuildMI(MBB, MI, get(Alpha::BISr), Alpha::R31).addReg(Alpha::R31)
00408     .addReg(Alpha::R31);
00409 }
00410 
00411 bool AlphaInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
00412   if (MBB.empty()) return false;
00413   
00414   switch (MBB.back().getOpcode()) {
00415   case Alpha::RETDAG: // Return.
00416   case Alpha::RETDAGp:
00417   case Alpha::BR:     // Uncond branch.
00418   case Alpha::JMP:  // Indirect branch.
00419     return true;
00420   default: return false;
00421   }
00422 }
00423 bool AlphaInstrInfo::
00424 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
00425   assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
00426   Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));
00427   return false;
00428 }
00429 



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.