aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjiv Gupta <sanjiv.gupta@microchip.com>2009-12-23 10:56:02 +0000
committerSanjiv Gupta <sanjiv.gupta@microchip.com>2009-12-23 10:56:02 +0000
commit8a7ed9ef7f162e01acfb0759c82ca6cfff25972a (patch)
tree419d723a4fdfd7172d0cf6e1ec8e0f5a383904a9
parent5bab1aac1172486e13c29be0302047cfd80984f1 (diff)
downloadexternal_llvm-8a7ed9ef7f162e01acfb0759c82ca6cfff25972a.zip
external_llvm-8a7ed9ef7f162e01acfb0759c82ca6cfff25972a.tar.gz
external_llvm-8a7ed9ef7f162e01acfb0759c82ca6cfff25972a.tar.bz2
Added missing patterns for subtract instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91995 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp61
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.td37
2 files changed, 64 insertions, 34 deletions
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 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
DebugLoc dl = Op.getDebugLoc();
// We should have handled larger operands in type legalizer itself.
assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
+ unsigned MemOp = 1;
+ SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
- // 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);
+ // 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));
+ }
- 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;
- }
+ 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) {
diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td
index bf4baf3..24df251 100644
--- a/lib/Target/PIC16/PIC16InstrInfo.td
+++ b/lib/Target/PIC16/PIC16InstrInfo.td
@@ -161,7 +161,7 @@ class BinOpWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
// W = W Op L : Do Op of L with W and place result in W.
let isTwoAddress = 1 in
-class BinOpLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
+class BinOpWL<bits<6> opcode, string OpcStr, SDNode OpNode> :
LiteralFormat<opcode, (outs GPR:$dst),
(ins GPR:$src, i8imm:$literal),
!strconcat(OpcStr, " $literal"),
@@ -404,33 +404,46 @@ def subwf_cc: SUBWF<0, "subwf", PIC16Subcc>;
// addlw
let Defs = [STATUS] in {
-def addlw_1 : BinOpLW<0, "addlw", add>;
-def addlw_2 : BinOpLW<0, "addlw", addc>;
+def addlw_1 : BinOpWL<0, "addlw", add>;
+def addlw_2 : BinOpWL<0, "addlw", addc>;
let Uses = [STATUS] in
-def addlwc : BinOpLW<0, "addlwc", adde>; // With Carry. (Assembler macro).
+def addlwc : BinOpWL<0, "addlwc", adde>; // With Carry. (Assembler macro).
// bitwise operations involving a literal and w.
-def andlw : BinOpLW<0, "andlw", and>;
-def xorlw : BinOpLW<0, "xorlw", xor>;
-def orlw : BinOpLW<0, "iorlw", or>;
+def andlw : BinOpWL<0, "andlw", and>;
+def xorlw : BinOpWL<0, "xorlw", xor>;
+def orlw : BinOpWL<0, "iorlw", or>;
}
// sublw
// W = C - W ; sub W from literal. (Without borrow).
let isTwoAddress = 1 in
-class SUBLW<bits<6> opcode, SDNode OpNode> :
+class SUBLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
LiteralFormat<opcode, (outs GPR:$dst),
(ins GPR:$src, i8imm:$literal),
- "sublw $literal",
+ !strconcat(OpcStr, " $literal"),
[(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
+// subwl
+// W = W - C ; sub literal from W (Without borrow).
+let isTwoAddress = 1 in
+class SUBWL<bits<6> opcode, string OpcStr, SDNode OpNode> :
+ LiteralFormat<opcode, (outs GPR:$dst),
+ (ins GPR:$src, i8imm:$literal),
+ !strconcat(OpcStr, " $literal"),
+ [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>;
let Defs = [STATUS] in {
-def sublw_1 : SUBLW<0, sub>;
-def sublw_2 : SUBLW<0, subc>;
+def sublw_1 : SUBLW<0, "sublw", sub>;
+def sublw_2 : SUBLW<0, "sublw", subc>;
+def sublw_3 : SUBLW<0, "sublwb", sube>; // With borrow (Assembler macro).
+
+def sublw_4 : SUBWL<0, "subwl", sub>; // Assembler macro replace with addlw
+def sublw_5 : SUBWL<0, "subwl", subc>; // Assembler macro replace with addlw
+def sublw_6 : SUBWL<0, "subwlb", sube>; // With borrow (Assembler macro).
}
let Defs = [STATUS], isTerminator = 1 in
-def sublw_cc : SUBLW<0, PIC16Subcc>;
+def sublw_cc : SUBLW<0, "sublw", PIC16Subcc>;
// Call instruction.
let isCall = 1,