Use doxygen comment syntax.
[oota-llvm.git] / lib / Target / ARM / ARMInstrInfo.cpp
index 9a8d7da6117e33f92cf5f65e81a0bbc2097de6a8..0c55f938b2fa88d36f0df715a776125d28827a40 100644 (file)
@@ -43,15 +43,15 @@ ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
     RI(*this, STI) {
 }
 
-const TargetRegisterClass *ARMInstrInfo::getPointerRegClass() const {
-  return &ARM::GPRRegClass;
-}
 
 /// Return true if the instruction is a register to register move and
 /// leave the source and dest operands in the passed parameters.
 ///
 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
-                               unsigned &SrcReg, unsigned &DstReg) const {
+                               unsigned &SrcReg, unsigned &DstReg,
+                               unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
+  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
+
   unsigned oc = MI.getOpcode();
   switch (oc) {
   default:
@@ -64,8 +64,8 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
   case ARM::MOVr:
   case ARM::tMOVr:
     assert(MI.getDesc().getNumOperands() >= 2 &&
-           MI.getOperand(0).isRegister() &&
-           MI.getOperand(1).isRegister() &&
+           MI.getOperand(0).isReg() &&
+           MI.getOperand(1).isReg() &&
            "Invalid ARM MOV instruction");
     SrcReg = MI.getOperand(1).getReg();
     DstReg = MI.getOperand(0).getReg();
@@ -73,13 +73,14 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
   }
 }
 
-unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
+                                           int &FrameIndex) const {
   switch (MI->getOpcode()) {
   default: break;
   case ARM::LDR:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isRegister() &&
-        MI->getOperand(3).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isReg() &&
+        MI->getOperand(3).isImm() &&
         MI->getOperand(2).getReg() == 0 &&
         MI->getOperand(3).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
@@ -88,16 +89,16 @@ unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) co
     break;
   case ARM::FLDD:
   case ARM::FLDS:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isImm() &&
         MI->getOperand(2).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
       return MI->getOperand(0).getReg();
     }
     break;
   case ARM::tRestore:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isImm() &&
         MI->getOperand(2).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
       return MI->getOperand(0).getReg();
@@ -107,13 +108,14 @@ unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) co
   return 0;
 }
 
-unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
+                                          int &FrameIndex) const {
   switch (MI->getOpcode()) {
   default: break;
   case ARM::STR:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isRegister() &&
-        MI->getOperand(3).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isReg() &&
+        MI->getOperand(3).isImm() &&
         MI->getOperand(2).getReg() == 0 &&
         MI->getOperand(3).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
@@ -122,16 +124,16 @@ unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) con
     break;
   case ARM::FSTD:
   case ARM::FSTS:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isImm() &&
         MI->getOperand(2).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
       return MI->getOperand(0).getReg();
     }
     break;
   case ARM::tSpill:
-    if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isImmediate() && 
+    if (MI->getOperand(1).isFI() &&
+        MI->getOperand(2).isImm() &&
         MI->getOperand(2).getImm() == 0) {
       FrameIndex = MI->getOperand(1).getIndex();
       return MI->getOperand(0).getReg();
@@ -296,13 +298,13 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
   }
   
   // Transfer LiveVariables states, kill / dead info.
-  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
-    MachineOperand &MO = MI->getOperand(i);
-    if (MO.isRegister() && MO.getReg() &&
-        TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
-      unsigned Reg = MO.getReg();
+  if (LV) {
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = MI->getOperand(i);
+      if (MO.isReg() && MO.getReg() &&
+          TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
+        unsigned Reg = MO.getReg();
       
-      if (LV) {
         LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
         if (MO.isDef()) {
           MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
@@ -333,7 +335,8 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
 // Branch analysis.
 bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
                                  MachineBasicBlock *&FBB,
-                                 std::vector<MachineOperand> &Cond) const {
+                                 SmallVectorImpl<MachineOperand> &Cond,
+                                 bool AllowModify) const {
   // If the block has no terminators, it just falls into the block after it.
   MachineBasicBlock::iterator I = MBB.end();
   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
@@ -383,7 +386,8 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
       (LastOpc == ARM::B || LastOpc == ARM::tB)) {
     TBB = SecondLastInst->getOperand(0).getMBB();
     I = LastInst;
-    I->eraseFromParent();
+    if (AllowModify)
+      I->eraseFromParent();
     return false;
   }
 
@@ -394,7 +398,8 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
        SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr) &&
       (LastOpc == ARM::B || LastOpc == ARM::tB)) {
     I = LastInst;
-    I->eraseFromParent();
+    if (AllowModify)
+      I->eraseFromParent();
     return true;
   } 
 
@@ -432,7 +437,7 @@ unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
 
 unsigned ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                                 MachineBasicBlock *FBB,
-                                const std::vector<MachineOperand> &Cond) const {
+                            const SmallVectorImpl<MachineOperand> &Cond) const {
   MachineFunction &MF = *MBB.getParent();
   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
   int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
@@ -459,14 +464,14 @@ unsigned ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *T
   return 2;
 }
 
-void ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
+bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator I,
                                    unsigned DestReg, unsigned SrcReg,
                                    const TargetRegisterClass *DestRC,
                                    const TargetRegisterClass *SrcRC) const {
   if (DestRC != SrcRC) {
-    cerr << "Not yet supported!";
-    abort();
+    // Not yet supported!
+    return false;
   }
 
   if (DestRC == ARM::GPRRegisterClass) {
@@ -484,16 +489,18 @@ void ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
     AddDefaultPred(BuildMI(MBB, I, get(ARM::FCPYD), DestReg)
                    .addReg(SrcReg));
   else
-    abort();
+    return false;
+  
+  return true;
 }
 
 static const MachineInstrBuilder &ARMInstrAddOperand(MachineInstrBuilder &MIB,
                                                      MachineOperand &MO) {
-  if (MO.isRegister())
+  if (MO.isReg())
     MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
-  else if (MO.isImmediate())
+  else if (MO.isImm())
     MIB = MIB.addImm(MO.getImm());
-  else if (MO.isFrameIndex())
+  else if (MO.isFI())
     MIB = MIB.addFrameIndex(MO.getIndex());
   else
     assert(0 && "Unknown operand for ARMInstrAddOperand!");
@@ -536,7 +543,7 @@ void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
   if (RC == ARM::GPRRegisterClass) {
     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
     if (AFI->isThumbFunction()) {
-      Opc = Addr[0].isFrameIndex() ? ARM::tSpill : ARM::tSTR;
+      Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
       MachineInstrBuilder MIB = 
         BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill);
       for (unsigned i = 0, e = Addr.size(); i != e; ++i)
@@ -592,7 +599,7 @@ void ARMInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
   if (RC == ARM::GPRRegisterClass) {
     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
     if (AFI->isThumbFunction()) {
-      Opc = Addr[0].isFrameIndex() ? ARM::tRestore : ARM::tLDR;
+      Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
       MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg);
       for (unsigned i = 0, e = Addr.size(); i != e; ++i)
         MIB = ARMInstrAddOperand(MIB, Addr[i]);
@@ -642,7 +649,7 @@ bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
     return false;
 
   bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
-  MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP));
+  MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
   MBB.insert(MI, PopMI);
   for (unsigned i = CSI.size(); i != 0; --i) {
     unsigned Reg = CSI[i-1].getReg();
@@ -659,10 +666,10 @@ bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
   return true;
 }
 
-MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineFunction &MF,
-                                              MachineInstr *MI,
-                                              SmallVectorImpl<unsigned> &Ops,
-                                              int FI) const {
+MachineInstr *ARMInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
+                                                  MachineInstr *MI,
+                                        const SmallVectorImpl<unsigned> &Ops,
+                                                  int FI) const {
   if (Ops.size() != 1) return NULL;
 
   unsigned OpNum = Ops[0];
@@ -745,8 +752,8 @@ MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineFunction &MF,
   return NewMI;
 }
 
-bool ARMInstrInfo::canFoldMemoryOperand(MachineInstr *MI,
-                                        SmallVectorImpl<unsigned> &Ops) const {
+bool ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
+                                  const SmallVectorImpl<unsigned> &Ops) const {
   if (Ops.size() != 1) return false;
 
   unsigned OpNum = Ops[0];
@@ -778,7 +785,7 @@ bool ARMInstrInfo::canFoldMemoryOperand(MachineInstr *MI,
   return false;
 }
 
-bool ARMInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+bool ARMInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
   if (MBB.empty()) return false;
   
   switch (MBB.back().getOpcode()) {
@@ -799,7 +806,7 @@ bool ARMInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
 }
 
 bool ARMInstrInfo::
-ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
   ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
   Cond[0].setImm(ARMCC::getOppositeCondition(CC));
   return false;
@@ -811,7 +818,7 @@ bool ARMInstrInfo::isPredicated(const MachineInstr *MI) const {
 }
 
 bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
-                                const std::vector<MachineOperand> &Pred) const {
+                            const SmallVectorImpl<MachineOperand> &Pred) const {
   unsigned Opc = MI->getOpcode();
   if (Opc == ARM::B || Opc == ARM::tB) {
     MI->setDesc(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc));
@@ -831,8 +838,8 @@ bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
 }
 
 bool
-ARMInstrInfo::SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
-                                const std::vector<MachineOperand> &Pred2) const{
+ARMInstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
+                            const SmallVectorImpl<MachineOperand> &Pred2) const{
   if (Pred1.size() > 2 || Pred2.size() > 2)
     return false;
 
@@ -866,7 +873,7 @@ bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI,
   bool Found = false;
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = MI->getOperand(i);
-    if (MO.isRegister() && MO.getReg() == ARM::CPSR) {
+    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
       Pred.push_back(MO);
       Found = true;
     }
@@ -896,16 +903,24 @@ unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
   unsigned TSFlags = TID.TSFlags;
   
   switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
-  default:
+  default: {
     // If this machine instr is an inline asm, measure it.
     if (MI->getOpcode() == ARM::INLINEASM)
       return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName());
     if (MI->isLabel())
       return 0;
-    if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+    switch (MI->getOpcode()) {
+    default:
+      assert(0 && "Unknown or unset size field for instr!");
+      break;
+    case TargetInstrInfo::IMPLICIT_DEF:
+    case TargetInstrInfo::DECLARE:
+    case TargetInstrInfo::DBG_LABEL:
+    case TargetInstrInfo::EH_LABEL:
       return 0;
-    assert(0 && "Unknown or unset size field for instr!");
+    }
     break;
+  }
   case ARMII::Size8Bytes: return 8;          // Arm instruction x 2.
   case ARMII::Size4Bytes: return 4;          // Arm instruction.
   case ARMII::Size2Bytes: return 2;          // Thumb instruction.