diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2011-10-03 21:06:13 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2011-10-03 21:06:13 +0000 |
commit | dda4a07cd818fdfe2b49412e32e0e12d9e566e31 (patch) | |
tree | 59d9f1b80a2e26173247c054871f5de39415e573 | |
parent | 0e6a24d92ab4661bb39f838ac390ccb17f649cb5 (diff) |
Add support for 64-bit divide instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141024 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 7 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 11 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 2 | ||||
-rw-r--r-- | 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 2fdc2ff007..60fc40ca61 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -96,6 +96,11 @@ let Defs = [HI64, LO64] in { class Mul64<bits<6> func, string instr_asm, InstrItinClass itin>: FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b), !strconcat(instr_asm, "\t$a, $b"), [], itin>; + + class Div64<SDNode op, bits<6> 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<MipsDivRem, 0x1e, "ddiv", IIIdiv>; +def DUDIV : Div64<MipsDivRemU, 0x1f, "ddivu", IIIdiv>; let Defs = [HI64] in def MTHI64 : MoveToLOHI64<0x11, "mthi">; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 45f00aeb5b..ea017c64df 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 cac64e5987..75e6b04bed 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 98aff526de..b2aa3ecc02 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 +} + |