use MVN to handle small negative constants


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32459 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 08864a7..48d918c 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -781,6 +781,8 @@
   virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
   bool SelectAddrMode1(SDOperand Op, SDOperand N, SDOperand &Arg,
                        SDOperand &Shift, SDOperand &ShiftType);
+  bool SelectAddrMode1a(SDOperand Op, SDOperand N, SDOperand &Arg,
+			SDOperand &Shift, SDOperand &ShiftType);
   bool SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Arg,
                        SDOperand &Offset);
   bool SelectAddrMode5(SDOperand Op, SDOperand N, SDOperand &Arg,
@@ -883,6 +885,25 @@
   return true;
 }
 
+bool ARMDAGToDAGISel::SelectAddrMode1a(SDOperand Op,
+				       SDOperand N,
+				       SDOperand &Arg,
+				       SDOperand &Shift,
+				       SDOperand &ShiftType) {
+  if (N.getOpcode() != ISD::Constant)
+    return false;
+
+  uint32_t val = ~cast<ConstantSDNode>(N)->getValue();
+  if(!isRotInt8Immediate(val))
+    return false;
+
+  Arg       = CurDAG->getTargetConstant(val,    MVT::i32);
+  Shift     = CurDAG->getTargetConstant(0,             MVT::i32);
+  ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
+
+  return true;
+}
+
 bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N,
                                       SDOperand &Arg, SDOperand &Offset) {
   //TODO: complete and cleanup!