LLVM API Documentation

ARMInstrInfo.cpp

Go to the documentation of this file.
00001 //===- ARMInstrInfo.cpp - ARM 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 ARM implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "ARMInstrInfo.h"
00015 #include "ARM.h"
00016 #include "ARMAddressingModes.h"
00017 #include "ARMGenInstrInfo.inc"
00018 #include "ARMMachineFunctionInfo.h"
00019 #include "llvm/ADT/STLExtras.h"
00020 #include "llvm/CodeGen/LiveVariables.h"
00021 #include "llvm/CodeGen/MachineFrameInfo.h"
00022 #include "llvm/CodeGen/MachineInstrBuilder.h"
00023 #include "llvm/CodeGen/MachineJumpTableInfo.h"
00024 #include "llvm/Target/TargetAsmInfo.h"
00025 #include "llvm/Support/CommandLine.h"
00026 using namespace llvm;
00027 
00028 static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
00029                                   cl::desc("Enable ARM 2-addr to 3-addr conv"));
00030 
00031 static inline
00032 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
00033   return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
00034 }
00035 
00036 static inline
00037 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
00038   return MIB.addReg(0);
00039 }
00040 
00041 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
00042   : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
00043     RI(*this, STI) {
00044 }
00045 
00046 const TargetRegisterClass *ARMInstrInfo::getPointerRegClass() const {
00047   return &ARM::GPRRegClass;
00048 }
00049 
00050 /// Return true if the instruction is a register to register move and
00051 /// leave the source and dest operands in the passed parameters.
00052 ///
00053 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
00054                                unsigned &SrcReg, unsigned &DstReg) const {
00055   unsigned oc = MI.getOpcode();
00056   switch (oc) {
00057   default:
00058     return false;
00059   case ARM::FCPYS:
00060   case ARM::FCPYD:
00061     SrcReg = MI.getOperand(1).getReg();
00062     DstReg = MI.getOperand(0).getReg();
00063     return true;
00064   case ARM::MOVr:
00065   case ARM::tMOVr:
00066     assert(MI.getDesc().getNumOperands() >= 2 &&
00067            MI.getOperand(0).isReg() &&
00068            MI.getOperand(1).isReg() &&
00069            "Invalid ARM MOV instruction");
00070     SrcReg = MI.getOperand(1).getReg();
00071     DstReg = MI.getOperand(0).getReg();
00072     return true;
00073   }
00074 }
00075 
00076 unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
00077                                            int &FrameIndex) const {
00078   switch (MI->getOpcode()) {
00079   default: break;
00080   case ARM::LDR:
00081     if (MI->getOperand(1).isFI() &&
00082         MI->getOperand(2).isReg() &&
00083         MI->getOperand(3).isImm() &&
00084         MI->getOperand(2).getReg() == 0 &&
00085         MI->getOperand(3).getImm() == 0) {
00086       FrameIndex = MI->getOperand(1).getIndex();
00087       return MI->getOperand(0).getReg();
00088     }
00089     break;
00090   case ARM::FLDD:
00091   case ARM::FLDS:
00092     if (MI->getOperand(1).isFI() &&
00093         MI->getOperand(2).isImm() &&
00094         MI->getOperand(2).getImm() == 0) {
00095       FrameIndex = MI->getOperand(1).getIndex();
00096       return MI->getOperand(0).getReg();
00097     }
00098     break;
00099   case ARM::tRestore:
00100     if (MI->getOperand(1).isFI() &&
00101         MI->getOperand(2).isImm() &&
00102         MI->getOperand(2).getImm() == 0) {
00103       FrameIndex = MI->getOperand(1).getIndex();
00104       return MI->getOperand(0).getReg();
00105     }
00106     break;
00107   }
00108   return 0;
00109 }
00110 
00111 unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
00112                                           int &FrameIndex) const {
00113   switch (MI->getOpcode()) {
00114   default: break;
00115   case ARM::STR:
00116     if (MI->getOperand(1).isFI() &&
00117         MI->getOperand(2).isReg() &&
00118         MI->getOperand(3).isImm() &&
00119         MI->getOperand(2).getReg() == 0 &&
00120         MI->getOperand(3).getImm() == 0) {
00121       FrameIndex = MI->getOperand(1).getIndex();
00122       return MI->getOperand(0).getReg();
00123     }
00124     break;
00125   case ARM::FSTD:
00126   case ARM::FSTS:
00127     if (MI->getOperand(1).isFI() &&
00128         MI->getOperand(2).isImm() &&
00129         MI->getOperand(2).getImm() == 0) {
00130       FrameIndex = MI->getOperand(1).getIndex();
00131       return MI->getOperand(0).getReg();
00132     }
00133     break;
00134   case ARM::tSpill:
00135     if (MI->getOperand(1).isFI() &&
00136         MI->getOperand(2).isImm() &&
00137         MI->getOperand(2).getImm() == 0) {
00138       FrameIndex = MI->getOperand(1).getIndex();
00139       return MI->getOperand(0).getReg();
00140     }
00141     break;
00142   }
00143   return 0;
00144 }
00145 
00146 void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB,
00147                                  MachineBasicBlock::iterator I,
00148                                  unsigned DestReg,
00149                                  const MachineInstr *Orig) const {
00150   if (Orig->getOpcode() == ARM::MOVi2pieces) {
00151     RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(),
00152                          Orig->getOperand(2).getImm(),
00153                          Orig->getOperand(3).getReg(), this, false);
00154     return;
00155   }
00156 
00157   MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
00158   MI->getOperand(0).setReg(DestReg);
00159   MBB.insert(I, MI);
00160 }
00161 
00162 static unsigned getUnindexedOpcode(unsigned Opc) {
00163   switch (Opc) {
00164   default: break;
00165   case ARM::LDR_PRE:
00166   case ARM::LDR_POST:
00167     return ARM::LDR;
00168   case ARM::LDRH_PRE:
00169   case ARM::LDRH_POST:
00170     return ARM::LDRH;
00171   case ARM::LDRB_PRE:
00172   case ARM::LDRB_POST:
00173     return ARM::LDRB;
00174   case ARM::LDRSH_PRE:
00175   case ARM::LDRSH_POST:
00176     return ARM::LDRSH;
00177   case ARM::LDRSB_PRE:
00178   case ARM::LDRSB_POST:
00179     return ARM::LDRSB;
00180   case ARM::STR_PRE:
00181   case ARM::STR_POST:
00182     return ARM::STR;
00183   case ARM::STRH_PRE:
00184   case ARM::STRH_POST:
00185     return ARM::STRH;
00186   case ARM::STRB_PRE:
00187   case ARM::STRB_POST:
00188     return ARM::STRB;
00189   }
00190   return 0;
00191 }
00192 
00193 MachineInstr *
00194 ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
00195                                     MachineBasicBlock::iterator &MBBI,
00196                                     LiveVariables *LV) const {
00197   if (!EnableARM3Addr)
00198     return NULL;
00199 
00200   MachineInstr *MI = MBBI;
00201   MachineFunction &MF = *MI->getParent()->getParent();
00202   unsigned TSFlags = MI->getDesc().TSFlags;
00203   bool isPre = false;
00204   switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
00205   default: return NULL;
00206   case ARMII::IndexModePre:
00207     isPre = true;
00208     break;
00209   case ARMII::IndexModePost:
00210     break;
00211   }
00212 
00213   // Try spliting an indexed load / store to a un-indexed one plus an add/sub
00214   // operation.
00215   unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
00216   if (MemOpc == 0)
00217     return NULL;
00218 
00219   MachineInstr *UpdateMI = NULL;
00220   MachineInstr *MemMI = NULL;
00221   unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
00222   const TargetInstrDesc &TID = MI->getDesc();
00223   unsigned NumOps = TID.getNumOperands();
00224   bool isLoad = !TID.mayStore();
00225   const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
00226   const MachineOperand &Base = MI->getOperand(2);
00227   const MachineOperand &Offset = MI->getOperand(NumOps-3);
00228   unsigned WBReg = WB.getReg();
00229   unsigned BaseReg = Base.getReg();
00230   unsigned OffReg = Offset.getReg();
00231   unsigned OffImm = MI->getOperand(NumOps-2).getImm();
00232   ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
00233   switch (AddrMode) {
00234   default:
00235     assert(false && "Unknown indexed op!");
00236     return NULL;
00237   case ARMII::AddrMode2: {
00238     bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
00239     unsigned Amt = ARM_AM::getAM2Offset(OffImm);
00240     if (OffReg == 0) {
00241       int SOImmVal = ARM_AM::getSOImmVal(Amt);
00242       if (SOImmVal == -1)
00243         // Can't encode it in a so_imm operand. This transformation will
00244         // add more than 1 instruction. Abandon!
00245         return NULL;
00246       UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
00247         .addReg(BaseReg).addImm(SOImmVal)
00248         .addImm(Pred).addReg(0).addReg(0);
00249     } else if (Amt != 0) {
00250       ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
00251       unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
00252       UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
00253         .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
00254         .addImm(Pred).addReg(0).addReg(0);
00255     } else 
00256       UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
00257         .addReg(BaseReg).addReg(OffReg)
00258         .addImm(Pred).addReg(0).addReg(0);
00259     break;
00260   }
00261   case ARMII::AddrMode3 : {
00262     bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
00263     unsigned Amt = ARM_AM::getAM3Offset(OffImm);
00264     if (OffReg == 0)
00265       // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
00266       UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
00267         .addReg(BaseReg).addImm(Amt)
00268         .addImm(Pred).addReg(0).addReg(0);
00269     else
00270       UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
00271         .addReg(BaseReg).addReg(OffReg)
00272         .addImm(Pred).addReg(0).addReg(0);
00273     break;
00274   }
00275   }
00276 
00277   std::vector<MachineInstr*> NewMIs;
00278   if (isPre) {
00279     if (isLoad)
00280       MemMI = BuildMI(MF, get(MemOpc), MI->getOperand(0).getReg())
00281         .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
00282     else
00283       MemMI = BuildMI(MF, get(MemOpc)).addReg(MI->getOperand(1).getReg())
00284         .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
00285     NewMIs.push_back(MemMI);
00286     NewMIs.push_back(UpdateMI);
00287   } else {
00288     if (isLoad)
00289       MemMI = BuildMI(MF, get(MemOpc), MI->getOperand(0).getReg())
00290         .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
00291     else
00292       MemMI = BuildMI(MF, get(MemOpc)).addReg(MI->getOperand(1).getReg())
00293         .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
00294     if (WB.isDead())
00295       UpdateMI->getOperand(0).setIsDead();
00296     NewMIs.push_back(UpdateMI);
00297     NewMIs.push_back(MemMI);
00298   }
00299   
00300   // Transfer LiveVariables states, kill / dead info.
00301   if (LV) {
00302     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
00303       MachineOperand &MO = MI->getOperand(i);
00304       if (MO.isReg() && MO.getReg() &&
00305           TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
00306         unsigned Reg = MO.getReg();
00307       
00308         LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
00309         if (MO.isDef()) {
00310           MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
00311           if (MO.isDead())
00312             LV->addVirtualRegisterDead(Reg, NewMI);
00313         }
00314         if (MO.isUse() && MO.isKill()) {
00315           for (unsigned j = 0; j < 2; ++j) {
00316             // Look at the two new MI's in reverse order.
00317             MachineInstr *NewMI = NewMIs[j];
00318             if (!NewMI->readsRegister(Reg))
00319               continue;
00320             LV->addVirtualRegisterKilled(Reg, NewMI);
00321             if (VI.removeKill(MI))
00322               VI.Kills.push_back(NewMI);
00323             break;
00324           }
00325         }
00326       }
00327     }
00328   }
00329 
00330   MFI->insert(MBBI, NewMIs[1]);
00331   MFI->insert(MBBI, NewMIs[0]);
00332   return NewMIs[0];
00333 }
00334 
00335 // Branch analysis.
00336 bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
00337                                  MachineBasicBlock *&FBB,
00338                                  SmallVectorImpl<MachineOperand> &Cond) const {
00339   // If the block has no terminators, it just falls into the block after it.
00340   MachineBasicBlock::iterator I = MBB.end();
00341   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
00342     return false;
00343   
00344   // Get the last instruction in the block.
00345   MachineInstr *LastInst = I;
00346   
00347   // If there is only one terminator instruction, process it.
00348   unsigned LastOpc = LastInst->getOpcode();
00349   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
00350     if (LastOpc == ARM::B || LastOpc == ARM::tB) {
00351       TBB = LastInst->getOperand(0).getMBB();
00352       return false;
00353     }
00354     if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) {
00355       // Block ends with fall-through condbranch.
00356       TBB = LastInst->getOperand(0).getMBB();
00357       Cond.push_back(LastInst->getOperand(1));
00358       Cond.push_back(LastInst->getOperand(2));
00359       return false;
00360     }
00361     return true;  // Can't handle indirect branch.
00362   }
00363   
00364   // Get the instruction before it if it is a terminator.
00365   MachineInstr *SecondLastInst = I;
00366   
00367   // If there are three terminators, we don't know what sort of block this is.
00368   if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
00369     return true;
00370   
00371   // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it.
00372   unsigned SecondLastOpc = SecondLastInst->getOpcode();
00373   if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
00374       (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
00375     TBB =  SecondLastInst->getOperand(0).getMBB();
00376     Cond.push_back(SecondLastInst->getOperand(1));
00377     Cond.push_back(SecondLastInst->getOperand(2));
00378     FBB = LastInst->getOperand(0).getMBB();
00379     return false;
00380   }
00381   
00382   // If the block ends with two unconditional branches, handle it.  The second 
00383   // one is not executed, so remove it.
00384   if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) &&
00385       (LastOpc == ARM::B || LastOpc == ARM::tB)) {
00386     TBB = SecondLastInst->getOperand(0).getMBB();
00387     I = LastInst;
00388     I->eraseFromParent();
00389     return false;
00390   }
00391 
00392   // Likewise if it ends with a branch table followed by an unconditional branch.
00393   // The branch folder can create these, and we must get rid of them for
00394   // correctness of Thumb constant islands.
00395   if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
00396        SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr) &&
00397       (LastOpc == ARM::B || LastOpc == ARM::tB)) {
00398     I = LastInst;
00399     I->eraseFromParent();
00400     return true;
00401   } 
00402 
00403   // Otherwise, can't handle this.
00404   return true;
00405 }
00406 
00407 
00408 unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
00409   MachineFunction &MF = *MBB.getParent();
00410   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00411   int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
00412   int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
00413 
00414   MachineBasicBlock::iterator I = MBB.end();
00415   if (I == MBB.begin()) return 0;
00416   --I;
00417   if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc)
00418     return 0;
00419   
00420   // Remove the branch.
00421   I->eraseFromParent();
00422   
00423   I = MBB.end();
00424   
00425   if (I == MBB.begin()) return 1;
00426   --I;
00427   if (I->getOpcode() != BccOpc)
00428     return 1;
00429   
00430   // Remove the branch.
00431   I->eraseFromParent();
00432   return 2;
00433 }
00434 
00435 unsigned ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
00436                                 MachineBasicBlock *FBB,
00437                             const SmallVectorImpl<MachineOperand> &Cond) const {
00438   MachineFunction &MF = *MBB.getParent();
00439   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00440   int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
00441   int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
00442 
00443   // Shouldn't be a fall through.
00444   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
00445   assert((Cond.size() == 2 || Cond.size() == 0) &&
00446          "ARM branch conditions have two components!");
00447   
00448   if (FBB == 0) {
00449     if (Cond.empty()) // Unconditional branch?
00450       BuildMI(&MBB, get(BOpc)).addMBB(TBB);
00451     else
00452       BuildMI(&MBB, get(BccOpc)).addMBB(TBB)
00453         .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
00454     return 1;
00455   }
00456   
00457   // Two-way conditional branch.
00458   BuildMI(&MBB, get(BccOpc)).addMBB(TBB)
00459     .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
00460   BuildMI(&MBB, get(BOpc)).addMBB(FBB);
00461   return 2;
00462 }
00463 
00464 bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
00465                                    MachineBasicBlock::iterator I,
00466                                    unsigned DestReg, unsigned SrcReg,
00467                                    const TargetRegisterClass *DestRC,
00468                                    const TargetRegisterClass *SrcRC) const {
00469   if (DestRC != SrcRC) {
00470     // Not yet supported!
00471     return false;
00472   }
00473 
00474   if (DestRC == ARM::GPRRegisterClass) {
00475     MachineFunction &MF = *MBB.getParent();
00476     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00477     if (AFI->isThumbFunction())
00478       BuildMI(MBB, I, get(ARM::tMOVr), DestReg).addReg(SrcReg);
00479     else
00480       AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, get(ARM::MOVr), DestReg)
00481                                   .addReg(SrcReg)));
00482   } else if (DestRC == ARM::SPRRegisterClass)
00483     AddDefaultPred(BuildMI(MBB, I, get(ARM::FCPYS), DestReg)
00484                    .addReg(SrcReg));
00485   else if (DestRC == ARM::DPRRegisterClass)
00486     AddDefaultPred(BuildMI(MBB, I, get(ARM::FCPYD), DestReg)
00487                    .addReg(SrcReg));
00488   else
00489     return false;
00490   
00491   return true;
00492 }
00493 
00494 static const MachineInstrBuilder &ARMInstrAddOperand(MachineInstrBuilder &MIB,
00495                                                      MachineOperand &MO) {
00496   if (MO.isReg())
00497     MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
00498   else if (MO.isImm())
00499     MIB = MIB.addImm(MO.getImm());
00500   else if (MO.isFI())
00501     MIB = MIB.addFrameIndex(MO.getIndex());
00502   else
00503     assert(0 && "Unknown operand for ARMInstrAddOperand!");
00504 
00505   return MIB;
00506 }
00507 
00508 void ARMInstrInfo::
00509 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00510                     unsigned SrcReg, bool isKill, int FI,
00511                     const TargetRegisterClass *RC) const {
00512   if (RC == ARM::GPRRegisterClass) {
00513     MachineFunction &MF = *MBB.getParent();
00514     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00515     if (AFI->isThumbFunction())
00516       BuildMI(MBB, I, get(ARM::tSpill)).addReg(SrcReg, false, false, isKill)
00517         .addFrameIndex(FI).addImm(0);
00518     else
00519       AddDefaultPred(BuildMI(MBB, I, get(ARM::STR))
00520                      .addReg(SrcReg, false, false, isKill)
00521                      .addFrameIndex(FI).addReg(0).addImm(0));
00522   } else if (RC == ARM::DPRRegisterClass) {
00523     AddDefaultPred(BuildMI(MBB, I, get(ARM::FSTD))
00524                    .addReg(SrcReg, false, false, isKill)
00525                    .addFrameIndex(FI).addImm(0));
00526   } else {
00527     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
00528     AddDefaultPred(BuildMI(MBB, I, get(ARM::FSTS))
00529                    .addReg(SrcReg, false, false, isKill)
00530                    .addFrameIndex(FI).addImm(0));
00531   }
00532 }
00533 
00534 void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
00535                                      bool isKill,
00536                                      SmallVectorImpl<MachineOperand> &Addr,
00537                                      const TargetRegisterClass *RC,
00538                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00539   unsigned Opc = 0;
00540   if (RC == ARM::GPRRegisterClass) {
00541     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00542     if (AFI->isThumbFunction()) {
00543       Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
00544       MachineInstrBuilder MIB = 
00545         BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill);
00546       for (unsigned i = 0, e = Addr.size(); i != e; ++i)
00547         MIB = ARMInstrAddOperand(MIB, Addr[i]);
00548       NewMIs.push_back(MIB);
00549       return;
00550     }
00551     Opc = ARM::STR;
00552   } else if (RC == ARM::DPRRegisterClass) {
00553     Opc = ARM::FSTD;
00554   } else {
00555     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
00556     Opc = ARM::FSTS;
00557   }
00558 
00559   MachineInstrBuilder MIB = 
00560     BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill);
00561   for (unsigned i = 0, e = Addr.size(); i != e; ++i)
00562     MIB = ARMInstrAddOperand(MIB, Addr[i]);
00563   AddDefaultPred(MIB);
00564   NewMIs.push_back(MIB);
00565   return;
00566 }
00567 
00568 void ARMInstrInfo::
00569 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00570                      unsigned DestReg, int FI,
00571                      const TargetRegisterClass *RC) const {
00572   if (RC == ARM::GPRRegisterClass) {
00573     MachineFunction &MF = *MBB.getParent();
00574     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00575     if (AFI->isThumbFunction())
00576       BuildMI(MBB, I, get(ARM::tRestore), DestReg)
00577         .addFrameIndex(FI).addImm(0);
00578     else
00579       AddDefaultPred(BuildMI(MBB, I, get(ARM::LDR), DestReg)
00580                      .addFrameIndex(FI).addReg(0).addImm(0));
00581   } else if (RC == ARM::DPRRegisterClass) {
00582     AddDefaultPred(BuildMI(MBB, I, get(ARM::FLDD), DestReg)
00583                    .addFrameIndex(FI).addImm(0));
00584   } else {
00585     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
00586     AddDefaultPred(BuildMI(MBB, I, get(ARM::FLDS), DestReg)
00587                    .addFrameIndex(FI).addImm(0));
00588   }
00589 }
00590 
00591 void ARMInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
00592                                       SmallVectorImpl<MachineOperand> &Addr,
00593                                       const TargetRegisterClass *RC,
00594                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00595   unsigned Opc = 0;
00596   if (RC == ARM::GPRRegisterClass) {
00597     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00598     if (AFI->isThumbFunction()) {
00599       Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
00600       MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg);
00601       for (unsigned i = 0, e = Addr.size(); i != e; ++i)
00602         MIB = ARMInstrAddOperand(MIB, Addr[i]);
00603       NewMIs.push_back(MIB);
00604       return;
00605     }
00606     Opc = ARM::LDR;
00607   } else if (RC == ARM::DPRRegisterClass) {
00608     Opc = ARM::FLDD;
00609   } else {
00610     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
00611     Opc = ARM::FLDS;
00612   }
00613 
00614   MachineInstrBuilder MIB =  BuildMI(MF, get(Opc), DestReg);
00615   for (unsigned i = 0, e = Addr.size(); i != e; ++i)
00616     MIB = ARMInstrAddOperand(MIB, Addr[i]);
00617   AddDefaultPred(MIB);
00618   NewMIs.push_back(MIB);
00619   return;
00620 }
00621 
00622 bool ARMInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
00623                                                 MachineBasicBlock::iterator MI,
00624                                 const std::vector<CalleeSavedInfo> &CSI) const {
00625   MachineFunction &MF = *MBB.getParent();
00626   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00627   if (!AFI->isThumbFunction() || CSI.empty())
00628     return false;
00629 
00630   MachineInstrBuilder MIB = BuildMI(MBB, MI, get(ARM::tPUSH));
00631   for (unsigned i = CSI.size(); i != 0; --i) {
00632     unsigned Reg = CSI[i-1].getReg();
00633     // Add the callee-saved register as live-in. It's killed at the spill.
00634     MBB.addLiveIn(Reg);
00635     MIB.addReg(Reg, false/*isDef*/,false/*isImp*/,true/*isKill*/);
00636   }
00637   return true;
00638 }
00639 
00640 bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
00641                                                  MachineBasicBlock::iterator MI,
00642                                 const std::vector<CalleeSavedInfo> &CSI) const {
00643   MachineFunction &MF = *MBB.getParent();
00644   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00645   if (!AFI->isThumbFunction() || CSI.empty())
00646     return false;
00647 
00648   bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
00649   MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP));
00650   MBB.insert(MI, PopMI);
00651   for (unsigned i = CSI.size(); i != 0; --i) {
00652     unsigned Reg = CSI[i-1].getReg();
00653     if (Reg == ARM::LR) {
00654       // Special epilogue for vararg functions. See emitEpilogue
00655       if (isVarArg)
00656         continue;
00657       Reg = ARM::PC;
00658       PopMI->setDesc(get(ARM::tPOP_RET));
00659       MBB.erase(MI);
00660     }
00661     PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
00662   }
00663   return true;
00664 }
00665 
00666 MachineInstr *ARMInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
00667                                                   MachineInstr *MI,
00668                                         const SmallVectorImpl<unsigned> &Ops,
00669                                                   int FI) const {
00670   if (Ops.size() != 1) return NULL;
00671 
00672   unsigned OpNum = Ops[0];
00673   unsigned Opc = MI->getOpcode();
00674   MachineInstr *NewMI = NULL;
00675   switch (Opc) {
00676   default: break;
00677   case ARM::MOVr: {
00678     if (MI->getOperand(4).getReg() == ARM::CPSR)
00679       // If it is updating CPSR, then it cannot be foled.
00680       break;
00681     unsigned Pred = MI->getOperand(2).getImm();
00682     unsigned PredReg = MI->getOperand(3).getReg();
00683     if (OpNum == 0) { // move -> store
00684       unsigned SrcReg = MI->getOperand(1).getReg();
00685       bool isKill = MI->getOperand(1).isKill();
00686       NewMI = BuildMI(MF, get(ARM::STR)).addReg(SrcReg, false, false, isKill)
00687         .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
00688     } else {          // move -> load
00689       unsigned DstReg = MI->getOperand(0).getReg();
00690       bool isDead = MI->getOperand(0).isDead();
00691       NewMI = BuildMI(MF, get(ARM::LDR)).addReg(DstReg, true, false, false, isDead)
00692         .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
00693     }
00694     break;
00695   }
00696   case ARM::tMOVr: {
00697     if (OpNum == 0) { // move -> store
00698       unsigned SrcReg = MI->getOperand(1).getReg();
00699       bool isKill = MI->getOperand(1).isKill();
00700       if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg))
00701         // tSpill cannot take a high register operand.
00702         break;
00703       NewMI = BuildMI(MF, get(ARM::tSpill)).addReg(SrcReg, false, false, isKill)
00704         .addFrameIndex(FI).addImm(0);
00705     } else {          // move -> load
00706       unsigned DstReg = MI->getOperand(0).getReg();
00707       if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg))
00708         // tRestore cannot target a high register operand.
00709         break;
00710       bool isDead = MI->getOperand(0).isDead();
00711       NewMI = BuildMI(MF, get(ARM::tRestore))
00712         .addReg(DstReg, true, false, false, isDead)
00713         .addFrameIndex(FI).addImm(0);
00714     }
00715     break;
00716   }
00717   case ARM::FCPYS: {
00718     unsigned Pred = MI->getOperand(2).getImm();
00719     unsigned PredReg = MI->getOperand(3).getReg();
00720     if (OpNum == 0) { // move -> store
00721       unsigned SrcReg = MI->getOperand(1).getReg();
00722       NewMI = BuildMI(MF, get(ARM::FSTS)).addReg(SrcReg).addFrameIndex(FI)
00723         .addImm(0).addImm(Pred).addReg(PredReg);
00724     } else {          // move -> load
00725       unsigned DstReg = MI->getOperand(0).getReg();
00726       NewMI = BuildMI(MF, get(ARM::FLDS), DstReg).addFrameIndex(FI)
00727         .addImm(0).addImm(Pred).addReg(PredReg);
00728     }
00729     break;
00730   }
00731   case ARM::FCPYD: {
00732     unsigned Pred = MI->getOperand(2).getImm();
00733     unsigned PredReg = MI->getOperand(3).getReg();
00734     if (OpNum == 0) { // move -> store
00735       unsigned SrcReg = MI->getOperand(1).getReg();
00736       bool isKill = MI->getOperand(1).isKill();
00737       NewMI = BuildMI(MF, get(ARM::FSTD)).addReg(SrcReg, false, false, isKill)
00738         .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
00739     } else {          // move -> load
00740       unsigned DstReg = MI->getOperand(0).getReg();
00741       bool isDead = MI->getOperand(0).isDead();
00742       NewMI = BuildMI(MF, get(ARM::FLDD)).addReg(DstReg, true, false, false, isDead)
00743         .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
00744     }
00745     break;
00746   }
00747   }
00748 
00749   return NewMI;
00750 }
00751 
00752 bool ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
00753                                   const SmallVectorImpl<unsigned> &Ops) const {
00754   if (Ops.size() != 1) return false;
00755 
00756   unsigned OpNum = Ops[0];
00757   unsigned Opc = MI->getOpcode();
00758   switch (Opc) {
00759   default: break;
00760   case ARM::MOVr:
00761     // If it is updating CPSR, then it cannot be foled.
00762     return MI->getOpera