mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-08 03:30:22 +00:00
Added missing patterns for subtract instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91995 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e433d5e1f4
commit
7fb0ead091
@ -1561,30 +1561,47 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
|
|||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
// We should have handled larger operands in type legalizer itself.
|
// We should have handled larger operands in type legalizer itself.
|
||||||
assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
|
assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
|
||||||
|
unsigned MemOp = 1;
|
||||||
// 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);
|
|
||||||
|
|
||||||
SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
|
SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
|
||||||
switch (Op.getOpcode()) {
|
|
||||||
default:
|
// Since we don't have an instruction for X - c ,
|
||||||
assert (0 && "Opcode unknown.");
|
// we can change it to X + (-c)
|
||||||
case ISD::SUBE:
|
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
|
||||||
return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1),
|
if (C && (Op.getOpcode() == ISD::SUB))
|
||||||
Op.getOperand(2));
|
{
|
||||||
break;
|
return DAG.getNode(ISD::ADD,
|
||||||
case ISD::SUBC:
|
dl, MVT::i8, Op.getOperand(0),
|
||||||
return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1));
|
DAG.getConstant(0-(C->getZExtValue()), MVT::i8));
|
||||||
break;
|
}
|
||||||
case ISD::SUB:
|
|
||||||
return DAG.getNode(Op.getOpcode(), dl, MVT::i8, NewVal, Op.getOperand(1));
|
if (NeedToConvertToMemOp(Op, MemOp) ||
|
||||||
break;
|
(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) {
|
void PIC16TargetLowering::InitReservedFrameCount(const Function *F) {
|
||||||
|
@ -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.
|
// W = W Op L : Do Op of L with W and place result in W.
|
||||||
let isTwoAddress = 1 in
|
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),
|
LiteralFormat<opcode, (outs GPR:$dst),
|
||||||
(ins GPR:$src, i8imm:$literal),
|
(ins GPR:$src, i8imm:$literal),
|
||||||
!strconcat(OpcStr, " $literal"),
|
!strconcat(OpcStr, " $literal"),
|
||||||
@ -404,33 +404,46 @@ def subwf_cc: SUBWF<0, "subwf", PIC16Subcc>;
|
|||||||
|
|
||||||
// addlw
|
// addlw
|
||||||
let Defs = [STATUS] in {
|
let Defs = [STATUS] in {
|
||||||
def addlw_1 : BinOpLW<0, "addlw", add>;
|
def addlw_1 : BinOpWL<0, "addlw", add>;
|
||||||
def addlw_2 : BinOpLW<0, "addlw", addc>;
|
def addlw_2 : BinOpWL<0, "addlw", addc>;
|
||||||
|
|
||||||
let Uses = [STATUS] in
|
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.
|
// bitwise operations involving a literal and w.
|
||||||
def andlw : BinOpLW<0, "andlw", and>;
|
def andlw : BinOpWL<0, "andlw", and>;
|
||||||
def xorlw : BinOpLW<0, "xorlw", xor>;
|
def xorlw : BinOpWL<0, "xorlw", xor>;
|
||||||
def orlw : BinOpLW<0, "iorlw", or>;
|
def orlw : BinOpWL<0, "iorlw", or>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sublw
|
// sublw
|
||||||
// W = C - W ; sub W from literal. (Without borrow).
|
// W = C - W ; sub W from literal. (Without borrow).
|
||||||
let isTwoAddress = 1 in
|
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),
|
LiteralFormat<opcode, (outs GPR:$dst),
|
||||||
(ins GPR:$src, i8imm:$literal),
|
(ins GPR:$src, i8imm:$literal),
|
||||||
"sublw $literal",
|
!strconcat(OpcStr, " $literal"),
|
||||||
[(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
|
[(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 {
|
let Defs = [STATUS] in {
|
||||||
def sublw_1 : SUBLW<0, sub>;
|
def sublw_1 : SUBLW<0, "sublw", sub>;
|
||||||
def sublw_2 : SUBLW<0, subc>;
|
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
|
let Defs = [STATUS], isTerminator = 1 in
|
||||||
def sublw_cc : SUBLW<0, PIC16Subcc>;
|
def sublw_cc : SUBLW<0, "sublw", PIC16Subcc>;
|
||||||
|
|
||||||
// Call instruction.
|
// Call instruction.
|
||||||
let isCall = 1,
|
let isCall = 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user