diff options
author | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-12-23 10:56:02 +0000 |
---|---|---|
committer | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-12-23 10:56:02 +0000 |
commit | 8a7ed9ef7f162e01acfb0759c82ca6cfff25972a (patch) | |
tree | 419d723a4fdfd7172d0cf6e1ec8e0f5a383904a9 | |
parent | 5bab1aac1172486e13c29be0302047cfd80984f1 (diff) | |
download | external_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.cpp | 61 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16InstrInfo.td | 37 |
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, |