LLVM API Documentation

XCoreInstrInfo.cpp
Go to the documentation of this file.
00001 //===-- XCoreInstrInfo.cpp - XCore 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 XCore implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "XCoreInstrInfo.h"
00015 #include "XCore.h"
00016 #include "XCoreMachineFunctionInfo.h"
00017 #include "llvm/ADT/STLExtras.h"
00018 #include "llvm/CodeGen/MachineConstantPool.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/CodeGen/MachineMemOperand.h"
00022 #include "llvm/IR/Constants.h"
00023 #include "llvm/IR/Function.h"
00024 #include "llvm/MC/MCContext.h"
00025 #include "llvm/Support/Debug.h"
00026 #include "llvm/Support/ErrorHandling.h"
00027 #include "llvm/Support/TargetRegistry.h"
00028 
00029 using namespace llvm;
00030 
00031 #define GET_INSTRINFO_CTOR_DTOR
00032 #include "XCoreGenInstrInfo.inc"
00033 
00034 namespace llvm {
00035 namespace XCore {
00036 
00037   // XCore Condition Codes
00038   enum CondCode {
00039     COND_TRUE,
00040     COND_FALSE,
00041     COND_INVALID
00042   };
00043 }
00044 }
00045 
00046 // Pin the vtable to this file.
00047 void XCoreInstrInfo::anchor() {}
00048 
00049 XCoreInstrInfo::XCoreInstrInfo()
00050   : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP),
00051     RI() {
00052 }
00053 
00054 static bool isZeroImm(const MachineOperand &op) {
00055   return op.isImm() && op.getImm() == 0;
00056 }
00057 
00058 /// isLoadFromStackSlot - If the specified machine instruction is a direct
00059 /// load from a stack slot, return the virtual or physical register number of
00060 /// the destination along with the FrameIndex of the loaded stack slot.  If
00061 /// not, return 0.  This predicate must return 0 if the instruction has
00062 /// any side effects other than loading from the stack slot.
00063 unsigned
00064 XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{
00065   int Opcode = MI->getOpcode();
00066   if (Opcode == XCore::LDWFI) 
00067   {
00068     if ((MI->getOperand(1).isFI()) && // is a stack slot
00069         (MI->getOperand(2).isImm()) &&  // the imm is zero
00070         (isZeroImm(MI->getOperand(2)))) 
00071     {
00072       FrameIndex = MI->getOperand(1).getIndex();
00073       return MI->getOperand(0).getReg();
00074     }
00075   }
00076   return 0;
00077 }
00078   
00079   /// isStoreToStackSlot - If the specified machine instruction is a direct
00080   /// store to a stack slot, return the virtual or physical register number of
00081   /// the source reg along with the FrameIndex of the loaded stack slot.  If
00082   /// not, return 0.  This predicate must return 0 if the instruction has
00083   /// any side effects other than storing to the stack slot.
00084 unsigned
00085 XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
00086                                    int &FrameIndex) const {
00087   int Opcode = MI->getOpcode();
00088   if (Opcode == XCore::STWFI)
00089   {
00090     if ((MI->getOperand(1).isFI()) && // is a stack slot
00091         (MI->getOperand(2).isImm()) &&  // the imm is zero
00092         (isZeroImm(MI->getOperand(2))))
00093     {
00094       FrameIndex = MI->getOperand(1).getIndex();
00095       return MI->getOperand(0).getReg();
00096     }
00097   }
00098   return 0;
00099 }
00100 
00101 //===----------------------------------------------------------------------===//
00102 // Branch Analysis
00103 //===----------------------------------------------------------------------===//
00104 
00105 static inline bool IsBRU(unsigned BrOpc) {
00106   return BrOpc == XCore::BRFU_u6
00107       || BrOpc == XCore::BRFU_lu6
00108       || BrOpc == XCore::BRBU_u6
00109       || BrOpc == XCore::BRBU_lu6;
00110 }
00111 
00112 static inline bool IsBRT(unsigned BrOpc) {
00113   return BrOpc == XCore::BRFT_ru6
00114       || BrOpc == XCore::BRFT_lru6
00115       || BrOpc == XCore::BRBT_ru6
00116       || BrOpc == XCore::BRBT_lru6;
00117 }
00118 
00119 static inline bool IsBRF(unsigned BrOpc) {
00120   return BrOpc == XCore::BRFF_ru6
00121       || BrOpc == XCore::BRFF_lru6
00122       || BrOpc == XCore::BRBF_ru6
00123       || BrOpc == XCore::BRBF_lru6;
00124 }
00125 
00126 static inline bool IsCondBranch(unsigned BrOpc) {
00127   return IsBRF(BrOpc) || IsBRT(BrOpc);
00128 }
00129 
00130 static inline bool IsBR_JT(unsigned BrOpc) {
00131   return BrOpc == XCore::BR_JT
00132       || BrOpc == XCore::BR_JT32;
00133 }
00134 
00135 /// GetCondFromBranchOpc - Return the XCore CC that matches 
00136 /// the correspondent Branch instruction opcode.
00137 static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) 
00138 {
00139   if (IsBRT(BrOpc)) {
00140     return XCore::COND_TRUE;
00141   } else if (IsBRF(BrOpc)) {
00142     return XCore::COND_FALSE;
00143   } else {
00144     return XCore::COND_INVALID;
00145   }
00146 }
00147 
00148 /// GetCondBranchFromCond - Return the Branch instruction
00149 /// opcode that matches the cc.
00150 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) 
00151 {
00152   switch (CC) {
00153   default: llvm_unreachable("Illegal condition code!");
00154   case XCore::COND_TRUE   : return XCore::BRFT_lru6;
00155   case XCore::COND_FALSE  : return XCore::BRFF_lru6;
00156   }
00157 }
00158 
00159 /// GetOppositeBranchCondition - Return the inverse of the specified 
00160 /// condition, e.g. turning COND_E to COND_NE.
00161 static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC)
00162 {
00163   switch (CC) {
00164   default: llvm_unreachable("Illegal condition code!");
00165   case XCore::COND_TRUE   : return XCore::COND_FALSE;
00166   case XCore::COND_FALSE  : return XCore::COND_TRUE;
00167   }
00168 }
00169 
00170 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
00171 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
00172 /// implemented for a target).  Upon success, this returns false and returns
00173 /// with the following information in various cases:
00174 ///
00175 /// 1. If this block ends with no branches (it just falls through to its succ)
00176 ///    just return false, leaving TBB/FBB null.
00177 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
00178 ///    the destination block.
00179 /// 3. If this block ends with an conditional branch and it falls through to
00180 ///    an successor block, it sets TBB to be the branch destination block and a
00181 ///    list of operands that evaluate the condition. These
00182 ///    operands can be passed to other TargetInstrInfo methods to create new
00183 ///    branches.
00184 /// 4. If this block ends with an conditional branch and an unconditional
00185 ///    block, it returns the 'true' destination in TBB, the 'false' destination
00186 ///    in FBB, and a list of operands that evaluate the condition. These
00187 ///    operands can be passed to other TargetInstrInfo methods to create new
00188 ///    branches.
00189 ///
00190 /// Note that RemoveBranch and InsertBranch must be implemented to support
00191 /// cases where this method returns success.
00192 ///
00193 bool
00194 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
00195                               MachineBasicBlock *&FBB,
00196                               SmallVectorImpl<MachineOperand> &Cond,
00197                               bool AllowModify) const {
00198   // If the block has no terminators, it just falls into the block after it.
00199   MachineBasicBlock::iterator I = MBB.end();
00200   if (I == MBB.begin())
00201     return false;
00202   --I;
00203   while (I->isDebugValue()) {
00204     if (I == MBB.begin())
00205       return false;
00206     --I;
00207   }
00208   if (!isUnpredicatedTerminator(I))
00209     return false;
00210 
00211   // Get the last instruction in the block.
00212   MachineInstr *LastInst = I;
00213   
00214   // If there is only one terminator instruction, process it.
00215   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
00216     if (IsBRU(LastInst->getOpcode())) {
00217       TBB = LastInst->getOperand(0).getMBB();
00218       return false;
00219     }
00220     
00221     XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode());
00222     if (BranchCode == XCore::COND_INVALID)
00223       return true;  // Can't handle indirect branch.
00224     
00225     // Conditional branch
00226     // Block ends with fall-through condbranch.
00227 
00228     TBB = LastInst->getOperand(1).getMBB();
00229     Cond.push_back(MachineOperand::CreateImm(BranchCode));
00230     Cond.push_back(LastInst->getOperand(0));
00231     return false;
00232   }
00233   
00234   // Get the instruction before it if it's a terminator.
00235   MachineInstr *SecondLastInst = I;
00236 
00237   // If there are three terminators, we don't know what sort of block this is.
00238   if (SecondLastInst && I != MBB.begin() &&
00239       isUnpredicatedTerminator(--I))
00240     return true;
00241   
00242   unsigned SecondLastOpc    = SecondLastInst->getOpcode();
00243   XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc);
00244   
00245   // If the block ends with conditional branch followed by unconditional,
00246   // handle it.
00247   if (BranchCode != XCore::COND_INVALID
00248     && IsBRU(LastInst->getOpcode())) {
00249 
00250     TBB = SecondLastInst->getOperand(1).getMBB();
00251     Cond.push_back(MachineOperand::CreateImm(BranchCode));
00252     Cond.push_back(SecondLastInst->getOperand(0));
00253 
00254     FBB = LastInst->getOperand(0).getMBB();
00255     return false;
00256   }
00257   
00258   // If the block ends with two unconditional branches, handle it.  The second
00259   // one is not executed, so remove it.
00260   if (IsBRU(SecondLastInst->getOpcode()) && 
00261       IsBRU(LastInst->getOpcode())) {
00262     TBB = SecondLastInst->getOperand(0).getMBB();
00263     I = LastInst;
00264     if (AllowModify)
00265       I->eraseFromParent();
00266     return false;
00267   }
00268 
00269   // Likewise if it ends with a branch table followed by an unconditional branch.
00270   if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) {
00271     I = LastInst;
00272     if (AllowModify)
00273       I->eraseFromParent();
00274     return true;
00275   }
00276 
00277   // Otherwise, can't handle this.
00278   return true;
00279 }
00280 
00281 unsigned
00282 XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
00283                              MachineBasicBlock *FBB,
00284                              const SmallVectorImpl<MachineOperand> &Cond,
00285                              DebugLoc DL)const{
00286   // Shouldn't be a fall through.
00287   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
00288   assert((Cond.size() == 2 || Cond.size() == 0) &&
00289          "Unexpected number of components!");
00290   
00291   if (!FBB) { // One way branch.
00292     if (Cond.empty()) {
00293       // Unconditional branch
00294       BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB);
00295     } else {
00296       // Conditional branch.
00297       unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
00298       BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
00299                              .addMBB(TBB);
00300     }
00301     return 1;
00302   }
00303   
00304   // Two-way Conditional branch.
00305   assert(Cond.size() == 2 && "Unexpected number of components!");
00306   unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
00307   BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
00308                          .addMBB(TBB);
00309   BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB);
00310   return 2;
00311 }
00312 
00313 unsigned
00314 XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
00315   MachineBasicBlock::iterator I = MBB.end();
00316   if (I == MBB.begin()) return 0;
00317   --I;
00318   while (I->isDebugValue()) {
00319     if (I == MBB.begin())
00320       return 0;
00321     --I;
00322   }
00323   if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode()))
00324     return 0;
00325   
00326   // Remove the branch.
00327   I->eraseFromParent();
00328   
00329   I = MBB.end();
00330 
00331   if (I == MBB.begin()) return 1;
00332   --I;
00333   if (!IsCondBranch(I->getOpcode()))
00334     return 1;
00335   
00336   // Remove the branch.
00337   I->eraseFromParent();
00338   return 2;
00339 }
00340 
00341 void XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
00342                                  MachineBasicBlock::iterator I, DebugLoc DL,
00343                                  unsigned DestReg, unsigned SrcReg,
00344                                  bool KillSrc) const {
00345   bool GRDest = XCore::GRRegsRegClass.contains(DestReg);
00346   bool GRSrc  = XCore::GRRegsRegClass.contains(SrcReg);
00347 
00348   if (GRDest && GRSrc) {
00349     BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg)
00350       .addReg(SrcReg, getKillRegState(KillSrc))
00351       .addImm(0);
00352     return;
00353   }
00354   
00355   if (GRDest && SrcReg == XCore::SP) {
00356     BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0);
00357     return;
00358   }
00359 
00360   if (DestReg == XCore::SP && GRSrc) {
00361     BuildMI(MBB, I, DL, get(XCore::SETSP_1r))
00362       .addReg(SrcReg, getKillRegState(KillSrc));
00363     return;
00364   }
00365   llvm_unreachable("Impossible reg-to-reg copy");
00366 }
00367 
00368 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
00369                                          MachineBasicBlock::iterator I,
00370                                          unsigned SrcReg, bool isKill,
00371                                          int FrameIndex,
00372                                          const TargetRegisterClass *RC,
00373                                          const TargetRegisterInfo *TRI) const
00374 {
00375   DebugLoc DL;
00376   if (I != MBB.end() && !I->isDebugValue())
00377     DL = I->getDebugLoc();
00378   MachineFunction *MF = MBB.getParent();
00379   const MachineFrameInfo &MFI = *MF->getFrameInfo();
00380   MachineMemOperand *MMO =
00381     MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex),
00382                              MachineMemOperand::MOStore,
00383                              MFI.getObjectSize(FrameIndex),
00384                              MFI.getObjectAlignment(FrameIndex));
00385   BuildMI(MBB, I, DL, get(XCore::STWFI))
00386     .addReg(SrcReg, getKillRegState(isKill))
00387     .addFrameIndex(FrameIndex)
00388     .addImm(0)
00389     .addMemOperand(MMO);
00390 }
00391 
00392 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
00393                                           MachineBasicBlock::iterator I,
00394                                           unsigned DestReg, int FrameIndex,
00395                                           const TargetRegisterClass *RC,
00396                                           const TargetRegisterInfo *TRI) const
00397 {
00398   DebugLoc DL;
00399   if (I != MBB.end() && !I->isDebugValue())
00400     DL = I->getDebugLoc();
00401   MachineFunction *MF = MBB.getParent();
00402   const MachineFrameInfo &MFI = *MF->getFrameInfo();
00403   MachineMemOperand *MMO =
00404     MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex),
00405                              MachineMemOperand::MOLoad,
00406                              MFI.getObjectSize(FrameIndex),
00407                              MFI.getObjectAlignment(FrameIndex));
00408   BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg)
00409     .addFrameIndex(FrameIndex)
00410     .addImm(0)
00411     .addMemOperand(MMO);
00412 }
00413 
00414 /// ReverseBranchCondition - Return the inverse opcode of the 
00415 /// specified Branch instruction.
00416 bool XCoreInstrInfo::
00417 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
00418   assert((Cond.size() == 2) && 
00419           "Invalid XCore branch condition!");
00420   Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm()));
00421   return false;
00422 }
00423 
00424 static inline bool isImmU6(unsigned val) {
00425   return val < (1 << 6);
00426 }
00427 
00428 static inline bool isImmU16(unsigned val) {
00429   return val < (1 << 16);
00430 }
00431 
00432 static bool isImmMskBitp(unsigned val) {
00433   if (!isMask_32(val)) {
00434     return false;
00435   }
00436   int N = Log2_32(val) + 1;
00437   return (N >= 1 && N <= 8) || N == 16 || N == 24 || N == 32;
00438 }
00439 
00440 MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate(
00441                                               MachineBasicBlock &MBB,
00442                                               MachineBasicBlock::iterator MI,
00443                                               unsigned Reg, uint64_t Value) const {
00444   DebugLoc dl;
00445   if (MI != MBB.end() && !MI->isDebugValue())
00446     dl = MI->getDebugLoc();
00447   if (isImmMskBitp(Value)) {
00448     int N = Log2_32(Value) + 1;
00449     return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg).addImm(N);
00450   }
00451   if (isImmU16(Value)) {
00452     int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
00453     return BuildMI(MBB, MI, dl, get(Opcode), Reg).addImm(Value);
00454   }
00455   MachineConstantPool *ConstantPool = MBB.getParent()->getConstantPool();
00456   const Constant *C = ConstantInt::get(
00457         Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Value);
00458   unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
00459   return BuildMI(MBB, MI, dl, get(XCore::LDWCP_lru6), Reg)
00460             .addConstantPoolIndex(Idx);
00461 }