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) {