Remove attribution from file headers, per discussion on llvmdev.
[oota-llvm.git] / lib / Target / ARM / ARMInstrInfo.cpp
index 1370faba4d7c9e592f4679bb4f9732b602a73f49..92df991931bec5ecaa41137b6a4a2a35076dd89c 100644 (file)
@@ -2,8 +2,7 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
+// This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
@@ -17,6 +16,7 @@
 #include "ARMAddressingModes.h"
 #include "ARMGenInstrInfo.inc"
 #include "ARMMachineFunctionInfo.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
@@ -28,7 +28,7 @@ static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
                                   cl::desc("Enable ARM 2-addr to 3-addr conv"));
 
 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
-  : TargetInstrInfo(ARMInsts, sizeof(ARMInsts)/sizeof(ARMInsts[0])),
+  : TargetInstrInfo(ARMInsts, array_lengthof(ARMInsts)),
     RI(*this, STI) {
 }
 
@@ -67,7 +67,7 @@ unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) co
   default: break;
   case ARM::LDR:
     if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isReg() &&
+        MI->getOperand(2).isRegister() &&
         MI->getOperand(3).isImmediate() && 
         MI->getOperand(2).getReg() == 0 &&
         MI->getOperand(3).getImmedValue() == 0) {
@@ -101,7 +101,7 @@ unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) con
   default: break;
   case ARM::STR:
     if (MI->getOperand(1).isFrameIndex() &&
-        MI->getOperand(2).isReg() &&
+        MI->getOperand(2).isRegister() &&
         MI->getOperand(3).isImmediate() && 
         MI->getOperand(2).getReg() == 0 &&
         MI->getOperand(3).getImmedValue() == 0) {
@@ -214,15 +214,18 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
         // add more than 1 instruction. Abandon!
         return NULL;
       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
-        .addReg(BaseReg).addImm(SOImmVal).addImm(Pred);
+        .addReg(BaseReg).addImm(SOImmVal)
+        .addImm(Pred).addReg(0).addReg(0);
     } else if (Amt != 0) {
       ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
       unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
+        .addImm(Pred).addReg(0).addReg(0);
     } else 
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg)
+        .addImm(Pred).addReg(0).addReg(0);
     break;
   }
   case ARMII::AddrMode3 : {
@@ -231,10 +234,12 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
     if (OffReg == 0)
       // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
-        .addReg(BaseReg).addImm(Amt).addImm(Pred);
+        .addReg(BaseReg).addImm(Amt)
+        .addImm(Pred).addReg(0).addReg(0);
     else
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg)
+        .addImm(Pred).addReg(0).addReg(0);
     break;
   }
   }
@@ -312,8 +317,7 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
   
   // If there is only one terminator instruction, process it.
   unsigned LastOpc = LastInst->getOpcode();
-  if (I == MBB.begin() ||
-      isPredicated(--I) || !isUnpredicatedTerminator(I)) {
+  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
     if (LastOpc == ARM::B || LastOpc == ARM::tB) {
       TBB = LastInst->getOperand(0).getMachineBasicBlock();
       return false;
@@ -322,6 +326,7 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
       // Block ends with fall-through condbranch.
       TBB = LastInst->getOperand(0).getMachineBasicBlock();
       Cond.push_back(LastInst->getOperand(1));
+      Cond.push_back(LastInst->getOperand(2));
       return false;
     }
     return true;  // Can't handle indirect branch.
@@ -331,8 +336,7 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
   MachineInstr *SecondLastInst = I;
   
   // If there are three terminators, we don't know what sort of block this is.
-  if (SecondLastInst && I != MBB.begin() &&
-      !isPredicated(--I) && isUnpredicatedTerminator(I))
+  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
     return true;
   
   // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it.
@@ -341,12 +345,13 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
       (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
     TBB =  SecondLastInst->getOperand(0).getMachineBasicBlock();
     Cond.push_back(SecondLastInst->getOperand(1));
+    Cond.push_back(SecondLastInst->getOperand(2));
     FBB = LastInst->getOperand(0).getMachineBasicBlock();
     return false;
   }
   
-  // If the block ends with two B's or tB's, handle it.  The second one is not
-  // executed, so remove it.
+  // If the block ends with two unconditional branches, handle it.  The second 
+  // one is not executed, so remove it.
   if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) &&
       (LastOpc == ARM::B || LastOpc == ARM::tB)) {
     TBB = SecondLastInst->getOperand(0).getMachineBasicBlock();
@@ -355,6 +360,17 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
     return false;
   }
 
+  // Likewise if it ends with a branch table followed by an unconditional branch.
+  // The branch folder can create these, and we must get rid of them for
+  // correctness of Thumb constant islands.
+  if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
+       SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr) &&
+      (LastOpc == ARM::B || LastOpc == ARM::tB)) {
+    I = LastInst;
+    I->eraseFromParent();
+    return true;
+  } 
+
   // Otherwise, can't handle this.
   return true;
 }
@@ -397,19 +413,21 @@ unsigned ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *T
 
   // Shouldn't be a fall through.
   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
-  assert((Cond.size() == 1 || Cond.size() == 0) &&
+  assert((Cond.size() == 2 || Cond.size() == 0) &&
          "ARM branch conditions have two components!");
   
   if (FBB == 0) {
     if (Cond.empty()) // Unconditional branch?
       BuildMI(&MBB, get(BOpc)).addMBB(TBB);
     else
-      BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
+      BuildMI(&MBB, get(BccOpc)).addMBB(TBB)
+        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
     return 1;
   }
   
   // Two-way conditional branch.
-  BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
+  BuildMI(&MBB, get(BccOpc)).addMBB(TBB)
+    .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
   BuildMI(&MBB, get(BOpc)).addMBB(FBB);
   return 2;
 }
@@ -452,6 +470,7 @@ bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
   if (Opc == ARM::B || Opc == ARM::tB) {
     MI->setInstrDescriptor(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc));
     MI->addImmOperand(Pred[0].getImmedValue());
+    MI->addRegOperand(Pred[1].getReg(), false);
     return true;
   }
 
@@ -459,6 +478,7 @@ bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
   if (PIdx != -1) {
     MachineOperand &PMO = MI->getOperand(PIdx);
     PMO.setImm(Pred[0].getImmedValue());
+    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
     return true;
   }
   return false;
@@ -467,7 +487,7 @@ bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
 bool
 ARMInstrInfo::SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
                                 const std::vector<MachineOperand> &Pred2) const{
-  if (Pred1.size() > 1 || Pred2.size() > 1)
+  if (Pred1.size() > 2 || Pred2.size() > 2)
     return false;
 
   ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImmedValue();
@@ -491,6 +511,25 @@ ARMInstrInfo::SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
   }
 }
 
+bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI,
+                                    std::vector<MachineOperand> &Pred) const {
+  const TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+  if (!TID->ImplicitDefs && (TID->Flags & M_HAS_OPTIONAL_DEF) == 0)
+    return false;
+
+  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) {
+      Pred.push_back(MO);
+      Found = true;
+    }
+  }
+
+  return Found;
+}
+
+
 /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
                                 unsigned JTI) DISABLE_INLINE;