Added missing patterns for subtract instruction.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91995 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 4d2096e..c4f45fe 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -1561,30 +1561,47 @@
   DebugLoc dl = Op.getDebugLoc();
   // We should have handled larger operands in type legalizer itself.
   assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
-
-  // Nothing to do if the first operand is already a direct load and it has
-  // only one use.
-  if (isDirectLoad(Op.getOperand(0)) && Op.getOperand(0).hasOneUse())
-    return Op;
-
-  // Put first operand on stack.
-  SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG, dl);
-
+  unsigned MemOp = 1;
   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
-  switch (Op.getOpcode()) {
-    default:
-      assert (0 && "Opcode unknown."); 
-    case ISD::SUBE:
-      return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1),
-                         Op.getOperand(2));
-      break;
-    case ISD::SUBC:
-      return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1));
-      break;
-    case ISD::SUB:
-      return DAG.getNode(Op.getOpcode(), dl, MVT::i8, NewVal, Op.getOperand(1));
-      break;
-  }
+
+  // Since we don't have an instruction for X - c , 
+  // we can change it to X + (-c)
+  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+  if (C && (Op.getOpcode() == ISD::SUB))
+    {
+      return DAG.getNode(ISD::ADD, 
+                         dl, MVT::i8, Op.getOperand(0), 
+                         DAG.getConstant(0-(C->getZExtValue()), MVT::i8));
+    }
+
+  if (NeedToConvertToMemOp(Op, MemOp) ||
+      (isDirectLoad(Op.getOperand(1)) && 
+       (!isDirectLoad(Op.getOperand(0))) &&
+       (Op.getOperand(0).getOpcode() != ISD::Constant)))
+    {
+      // Put first operand on stack.
+      SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG, dl);
+      
+      switch (Op.getOpcode()) {
+      default:
+        assert (0 && "Opcode unknown."); 
+      case ISD::SUBE:
+        return DAG.getNode(Op.getOpcode(), 
+                           dl, Tys, NewVal, Op.getOperand(1),
+                           Op.getOperand(2));
+        break;
+      case ISD::SUBC:
+        return DAG.getNode(Op.getOpcode(), 
+                           dl, Tys, NewVal, Op.getOperand(1));
+        break;
+      case ISD::SUB:
+        return DAG.getNode(Op.getOpcode(), 
+                           dl, MVT::i8, NewVal, Op.getOperand(1));
+        break;
+      }
+    }
+  else 
+    return Op;
 }
 
 void PIC16TargetLowering::InitReservedFrameCount(const Function *F) {