mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
Implement carry for subtract/add for mips16
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166755 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4734fe19f6
commit
a81be80b0e
@ -194,6 +194,10 @@ class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
|
|||||||
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
|
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FRRTR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
|
||||||
|
FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
|
||||||
|
!strconcat(asmstr, "\t$rx, $ry\n\tmove\t$rz, $$t8"), [], itin> ;
|
||||||
|
|
||||||
//
|
//
|
||||||
// maybe refactor but need a $zero as a dummy first parameter
|
// maybe refactor but need a $zero as a dummy first parameter
|
||||||
//
|
//
|
||||||
@ -816,6 +820,9 @@ def SltCCRxRy16: FCCRR16_ins<0b00010, "slt", IIAlu>;
|
|||||||
// Purpose: Set on Less Than Unsigned
|
// Purpose: Set on Less Than Unsigned
|
||||||
// To record the result of an unsigned less-than comparison.
|
// To record the result of an unsigned less-than comparison.
|
||||||
//
|
//
|
||||||
|
def SltuRxRyRz16: FRRTR16_ins<0b00011, "sltu", IIAlu> {
|
||||||
|
let isCodeGenOnly=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def SltuCCRxRy16: FCCRR16_ins<0b00011, "sltu", IIAlu>;
|
def SltuCCRxRy16: FCCRR16_ins<0b00011, "sltu", IIAlu>;
|
||||||
@ -976,6 +983,14 @@ def : Mips16Pat<(i32 imm:$imm),
|
|||||||
(OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16),
|
(OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16),
|
||||||
(LiRxImmX16 (LO16 imm:$imm)))>;
|
(LiRxImmX16 (LO16 imm:$imm)))>;
|
||||||
|
|
||||||
|
// Carry MipsPatterns
|
||||||
|
def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs),
|
||||||
|
(SubuRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
|
||||||
|
def : Mips16Pat<(addc CPU16Regs:$lhs, CPU16Regs:$rhs),
|
||||||
|
(AdduRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
|
||||||
|
def : Mips16Pat<(addc CPU16Regs:$src, immSExt16:$imm),
|
||||||
|
(AddiuRxRxImmX16 CPU16Regs:$src, imm:$imm)>;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Some branch conditional patterns are not generated by llvm at this time.
|
// Some branch conditional patterns are not generated by llvm at this time.
|
||||||
// Some are for seemingly arbitrary reasons not used: i.e. with signed number
|
// Some are for seemingly arbitrary reasons not used: i.e. with signed number
|
||||||
|
@ -413,6 +413,7 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
|||||||
|
|
||||||
case ISD::SUBE:
|
case ISD::SUBE:
|
||||||
case ISD::ADDE: {
|
case ISD::ADDE: {
|
||||||
|
bool inMips16Mode = Subtarget.inMips16Mode();
|
||||||
SDValue InFlag = Node->getOperand(2), CmpLHS;
|
SDValue InFlag = Node->getOperand(2), CmpLHS;
|
||||||
unsigned Opc = InFlag.getOpcode(); (void)Opc;
|
unsigned Opc = InFlag.getOpcode(); (void)Opc;
|
||||||
assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
|
assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
|
||||||
@ -422,10 +423,16 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
|||||||
unsigned MOp;
|
unsigned MOp;
|
||||||
if (Opcode == ISD::ADDE) {
|
if (Opcode == ISD::ADDE) {
|
||||||
CmpLHS = InFlag.getValue(0);
|
CmpLHS = InFlag.getValue(0);
|
||||||
MOp = Mips::ADDu;
|
if (inMips16Mode)
|
||||||
|
MOp = Mips::AdduRxRyRz16;
|
||||||
|
else
|
||||||
|
MOp = Mips::ADDu;
|
||||||
} else {
|
} else {
|
||||||
CmpLHS = InFlag.getOperand(0);
|
CmpLHS = InFlag.getOperand(0);
|
||||||
MOp = Mips::SUBu;
|
if (inMips16Mode)
|
||||||
|
MOp = Mips::SubuRxRyRz16;
|
||||||
|
else
|
||||||
|
MOp = Mips::SUBu;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
|
SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
|
||||||
@ -434,8 +441,11 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
|||||||
SDValue RHS = Node->getOperand(1);
|
SDValue RHS = Node->getOperand(1);
|
||||||
|
|
||||||
EVT VT = LHS.getValueType();
|
EVT VT = LHS.getValueType();
|
||||||
SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2);
|
|
||||||
SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT,
|
unsigned Sltu_op = inMips16Mode? Mips::SltuRxRyRz16: Mips::SLTu;
|
||||||
|
SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);
|
||||||
|
unsigned Addu_op = inMips16Mode? Mips::AdduRxRyRz16 : Mips::ADDu;
|
||||||
|
SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,
|
||||||
SDValue(Carry,0), RHS);
|
SDValue(Carry,0), RHS);
|
||||||
|
|
||||||
return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
|
return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
|
||||||
|
51
test/CodeGen/Mips/llcarry.ll
Normal file
51
test/CodeGen/Mips/llcarry.ll
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
|
||||||
|
|
||||||
|
@i = global i64 4294967295, align 8
|
||||||
|
@j = global i64 15, align 8
|
||||||
|
@ii = global i64 4294967295, align 8
|
||||||
|
@k = common global i64 0, align 8
|
||||||
|
@l = common global i64 0, align 8
|
||||||
|
@m = common global i64 0, align 8
|
||||||
|
|
||||||
|
define void @test1() nounwind {
|
||||||
|
entry:
|
||||||
|
%0 = load i64* @i, align 8
|
||||||
|
%1 = load i64* @j, align 8
|
||||||
|
%add = add nsw i64 %1, %0
|
||||||
|
store i64 %add, i64* @k, align 8
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: sltu ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: move ${{[0-9]+}}, $t8
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test2() nounwind {
|
||||||
|
entry:
|
||||||
|
%0 = load i64* @i, align 8
|
||||||
|
%1 = load i64* @j, align 8
|
||||||
|
%sub = sub nsw i64 %0, %1
|
||||||
|
; 16: subu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: sltu ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: move ${{[0-9]+}}, $t8
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: subu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
store i64 %sub, i64* @l, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test3() nounwind {
|
||||||
|
entry:
|
||||||
|
%0 = load i64* @ii, align 8
|
||||||
|
%add = add nsw i64 %0, 15
|
||||||
|
; 16: addiu ${{[0-9]+}}, 15
|
||||||
|
; 16: sltu ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: move ${{[0-9]+}}, $t8
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
; 16: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}}
|
||||||
|
store i64 %add, i64* @m, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user