Simple branch instruction support.
authorEric Christopher <echristo@apple.com>
Fri, 3 Sep 2010 00:35:47 +0000 (00:35 +0000)
committerEric Christopher <echristo@apple.com>
Fri, 3 Sep 2010 00:35:47 +0000 (00:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112923 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMFastISel.cpp

index 81a514077198aa7ba20c1b033abecf4b576ac18f..4892eae95833b2e0340d84983a4403bc29a644ea 100644 (file)
@@ -112,6 +112,7 @@ class ARMFastISel : public FastISel {
     // Instruction selection routines.
     virtual bool ARMSelectLoad(const Instruction *I);
     virtual bool ARMSelectStore(const Instruction *I);
+    virtual bool ARMSelectBranch(const Instruction *I);
 
     // Utility routines.
   private:
@@ -619,6 +620,26 @@ bool ARMFastISel::ARMSelectLoad(const Instruction *I) {
   return true;
 }
 
+bool ARMFastISel::ARMSelectBranch(const Instruction *I) {
+  const BranchInst *BI = cast<BranchInst>(I);
+  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
+  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
+  
+  // Simple branch support.
+  unsigned CondReg = getRegForValue(BI->getCondition());
+  if (CondReg == 0) return false;
+  
+  unsigned CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
+  unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
+  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
+                  .addReg(CondReg).addReg(CondReg));
+  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
+                  .addMBB(TBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
+  FastEmitBranch(FBB, DL);
+  FuncInfo.MBB->addSuccessor(TBB);
+  return true;
+}
+
 // TODO: SoftFP support.
 bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
   // No Thumb-1 for now.
@@ -629,6 +650,8 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
       return ARMSelectLoad(I);
     case Instruction::Store:
       return ARMSelectStore(I);
+    case Instruction::Br:
+      return ARMSelectBranch(I);
     default: break;
   }
   return false;