From dda4a07cd818fdfe2b49412e32e0e12d9e566e31 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 3 Oct 2011 21:06:13 +0000 Subject: [PATCH] Add support for 64-bit divide instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141024 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips64InstrInfo.td | 7 ++++++ lib/Target/Mips/MipsISelLowering.cpp | 11 ++++++++-- lib/Target/Mips/MipsInstrInfo.td | 2 +- test/CodeGen/Mips/mips64instrs.ll | 33 ++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 2fdc2ff007e..60fc40ca617 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -96,6 +96,11 @@ let Defs = [HI64, LO64] in { class Mul64 func, string instr_asm, InstrItinClass itin>: FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b), !strconcat(instr_asm, "\t$a, $b"), [], itin>; + + class Div64 func, string instr_asm, InstrItinClass itin>: + FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b), + !strconcat(instr_asm, "\t$$zero, $a, $b"), + [(op CPU64Regs:$a, CPU64Regs:$b)], itin>; } // Move from Hi/Lo @@ -150,6 +155,8 @@ let Predicates = [HasMips64r2] in { /// Multiply and Divide Instructions. def DMULT : Mul64<0x1c, "dmult", IIImul>; def DMULTu : Mul64<0x1d, "dmultu", IIImul>; +def DSDIV : Div64; +def DUDIV : Div64; let Defs = [HI64] in def MTHI64 : MoveToLOHI64<0x11, "mthi">; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 45f00aeb5bb..ea017c64df6 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -138,6 +138,10 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UDIV, MVT::i32, Expand); setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SDIV, MVT::i64, Expand); + setOperationAction(ISD::SREM, MVT::i64, Expand); + setOperationAction(ISD::UDIV, MVT::i64, Expand); + setOperationAction(ISD::UREM, MVT::i64, Expand); // Operations not directly supported by Mips. setOperationAction(ISD::BR_JT, MVT::Other, Expand); @@ -413,6 +417,9 @@ static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG, if (DCI.isBeforeLegalizeOps()) return SDValue(); + EVT Ty = N->getValueType(0); + unsigned LO = (Ty == MVT::i32) ? Mips::LO : Mips::LO64; + unsigned HI = (Ty == MVT::i32) ? Mips::HI : Mips::HI64; unsigned opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem : MipsISD::DivRemU; DebugLoc dl = N->getDebugLoc(); @@ -424,7 +431,7 @@ static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG, // insert MFLO if (N->hasAnyUseOfValue(0)) { - SDValue CopyFromLo = DAG.getCopyFromReg(InChain, dl, Mips::LO, MVT::i32, + SDValue CopyFromLo = DAG.getCopyFromReg(InChain, dl, LO, Ty, InGlue); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo); InChain = CopyFromLo.getValue(1); @@ -434,7 +441,7 @@ static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG, // insert MFHI if (N->hasAnyUseOfValue(1)) { SDValue CopyFromHi = DAG.getCopyFromReg(InChain, dl, - Mips::HI, MVT::i32, InGlue); + HI, Ty, InGlue); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi); } diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index cac64e5987d..75e6b04bed7 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -34,7 +34,7 @@ def SDT_MipsMAddMSub : SDTypeProfile<0, 4, SDTCisSameAs<1, 2>, SDTCisSameAs<2, 3>]>; def SDT_MipsDivRem : SDTypeProfile<0, 2, - [SDTCisVT<0, i32>, + [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; diff --git a/test/CodeGen/Mips/mips64instrs.ll b/test/CodeGen/Mips/mips64instrs.ll index 98aff526de2..b2aa3ecc02d 100644 --- a/test/CodeGen/Mips/mips64instrs.ll +++ b/test/CodeGen/Mips/mips64instrs.ll @@ -83,3 +83,36 @@ entry: %mul = mul i64 %b, %a ret i64 %mul } + +define i64 @f14(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: ddiv $zero +; CHECK: mflo + %div = sdiv i64 %a, %b + ret i64 %div +} + +define i64 @f15(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: ddivu $zero +; CHECK: mflo + %div = udiv i64 %a, %b + ret i64 %div +} + +define i64 @f16(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: ddiv $zero +; CHECK: mfhi + %rem = srem i64 %a, %b + ret i64 %rem +} + +define i64 @f17(i64 %a, i64 %b) nounwind readnone { +entry: +; CHECK: ddivu $zero +; CHECK: mfhi + %rem = urem i64 %a, %b + ret i64 %rem +} + -- 2.34.1