mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 14:40:25 +00:00
Add support for 64-bit divide instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141024 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0e6a24d92a
commit
dda4a07cd8
@ -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">;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>]>;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user