Implement select handling for ARM fast-isel.
authorEric Christopher <echristo@apple.com>
Mon, 11 Oct 2010 08:27:59 +0000 (08:27 +0000)
committerEric Christopher <echristo@apple.com>
Mon, 11 Oct 2010 08:27:59 +0000 (08:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116194 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMFastISel.cpp

index 7eb9decce6b69f2686f2585f2175d4d50221e31d..e1f2759fae8f784cdabaaa38fe60769038f96ba3 100644 (file)
@@ -128,6 +128,7 @@ class ARMFastISel : public FastISel {
     virtual bool SelectFPToSI(const Instruction *I);
     virtual bool SelectSDiv(const Instruction *I);
     virtual bool SelectCall(const Instruction *I);
+    virtual bool SelectSelect(const Instruction *I);
 
     // Utility routines.
   private:
@@ -1063,6 +1064,34 @@ bool ARMFastISel::SelectFPToSI(const Instruction *I) {
   return true;
 }
 
+bool ARMFastISel::SelectSelect(const Instruction *I) {
+  EVT VT = TLI.getValueType(I->getType(), /*HandleUnknown=*/true);
+  if (VT == MVT::Other || !isTypeLegal(I->getType(), VT))
+    return false;
+
+  // Things need to be register sized for register moves.
+  if (VT.getSimpleVT().SimpleTy != MVT::i32) return false;
+  const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
+
+  unsigned CondReg = getRegForValue(I->getOperand(0));
+  if (CondReg == 0) return false;
+  unsigned Op1Reg = getRegForValue(I->getOperand(1));
+  if (Op1Reg == 0) return false;
+  unsigned Op2Reg = getRegForValue(I->getOperand(2));
+  if (Op2Reg == 0) return false;
+
+  unsigned CmpOpc = isThumb ? ARM::t2TSTri : ARM::TSTri;
+  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
+                  .addReg(CondReg).addImm(1));
+  unsigned ResultReg = createResultReg(RC);
+  unsigned MovCCOpc = isThumb ? ARM::t2MOVCCr : ARM::MOVCCr;
+  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
+    .addReg(Op1Reg).addReg(Op2Reg)
+    .addImm(ARMCC::EQ).addReg(ARM::CPSR);
+  UpdateValueMap(I, ResultReg);
+  return true;
+}
+
 bool ARMFastISel::SelectSDiv(const Instruction *I) {
   EVT VT;
   const Type *Ty = I->getType();
@@ -1490,6 +1519,8 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
       return SelectSDiv(I);
     case Instruction::Call:
       return SelectCall(I);
+    case Instruction::Select:
+      return SelectSelect(I);
     default: break;
   }
   return false;