From 58d6a959be057126f2063431d4eb9542de07aab9 Mon Sep 17 00:00:00 2001 From: Zlatko Buljan Date: Wed, 13 Apr 2016 08:02:26 +0000 Subject: [PATCH] [mips][microMIPS] Add CodeGen support for DIV, MOD, DIVU, MODU, DDIV, DMOD, DDIVU and DMODU instructions Differential Revision: http://reviews.llvm.org/D17137 This patch was reverted after the revertion of dependant patch http://reviews.llvm.org/D17068. There was the problem with test-suite failure. The problem is hopefully solved with dependant patch so this patch is commited again. llvm-svn: 266179 --- .../lib/Target/Mips/MicroMips32r6InstrInfo.td | 25 +- .../Target/Mips/MicroMips64r6InstrFormats.td | 8 +- .../lib/Target/Mips/MicroMips64r6InstrInfo.td | 8 +- llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 9 +- llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 12 +- llvm/lib/Target/Mips/Mips64InstrInfo.td | 10 +- llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 10 +- llvm/lib/Target/Mips/MipsISelLowering.cpp | 24 +- llvm/lib/Target/Mips/MipsInstrInfo.td | 25 +- llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll | 231 +++++++++++++++++- llvm/test/CodeGen/Mips/llvm-ir/srem.ll | 224 ++++++++++++++++- llvm/test/CodeGen/Mips/llvm-ir/udiv.ll | 43 ++++ llvm/test/CodeGen/Mips/llvm-ir/urem.ll | 69 +++++- .../Disassembler/Mips/micromips64r6/valid.txt | 8 +- llvm/test/MC/Mips/micromips64r6/valid.s | 8 +- 15 files changed, 655 insertions(+), 59 deletions(-) diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index b8a40ad6e969..e8aff4597b8f 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -513,10 +513,27 @@ class RDHWR_MMR6_DESC : MMR6Arch<"rdhwr">, MipsR6Inst { class WAIT_MMR6_DESC : WaitMM<"wait">; class SSNOP_MMR6_DESC : Barrier<"ssnop">; class SLL_MMR6_DESC : shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>; -class DIV_MMR6_DESC : ArithLogicR<"div", GPR32Opnd>; -class DIVU_MMR6_DESC : ArithLogicR<"divu", GPR32Opnd>; -class MOD_MMR6_DESC : ArithLogicR<"mod", GPR32Opnd>; -class MODU_MMR6_DESC : ArithLogicR<"modu", GPR32Opnd>; + +class DIVMOD_MMR6_DESC_BASE + : MipsR6Inst { + dag OutOperandList = (outs GPROpnd:$rd); + dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt); + string AsmString = !strconcat(opstr, "\t$rd, $rs, $rt"); + list Pattern = [(set GPROpnd:$rd, (OpNode GPROpnd:$rs, GPROpnd:$rt))]; + string BaseOpcode = opstr; + Format f = FrmR; + let isCommutable = 0; + let isReMaterializable = 1; + + // This instruction doesn't trap division by zero itself. We must insert + // teq instructions as well. + bit usesCustomInserter = 1; +} +class DIV_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"div", GPR32Opnd, sdiv>; +class DIVU_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"divu", GPR32Opnd, udiv>; +class MOD_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"mod", GPR32Opnd, srem>; +class MODU_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"modu", GPR32Opnd, urem>; class AND_MMR6_DESC : ArithLogicR<"and", GPR32Opnd>; class ANDI_MMR6_DESC : ArithLogicI<"andi", uimm16, GPR32Opnd>; class NOR_MMR6_DESC : ArithLogicR<"nor", GPR32Opnd>; diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td index 9ce767910901..45fc9e35447a 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -71,16 +71,16 @@ class POOL32S_DALIGN_FM_MMR6 { class POOL32A_DIVMOD_FM_MMR6 funct> : MMR6Arch { - bits<5> rd; - bits<5> rs; bits<5> rt; + bits<5> rs; + bits<5> rd; bits<32> Inst; let Inst{31-26} = 0b010110; - let Inst{25-21} = rd; + let Inst{25-21} = rt; let Inst{20-16} = rs; - let Inst{15-11} = rt; + let Inst{15-11} = rd; let Inst{10-9} = 0b00; let Inst{8-0} = funct; } diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td index fa7aa444ed1e..563a97c07147 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -97,10 +97,10 @@ class DALIGN_DESC_BASE; -class DDIV_MM64R6_DESC : ArithLogicR<"ddiv", GPR32Opnd>; -class DMOD_MM64R6_DESC : ArithLogicR<"dmod", GPR32Opnd>; -class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>; -class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>; +class DDIV_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddiv", GPR64Opnd, sdiv>; +class DMOD_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmod", GPR64Opnd, srem>; +class DDIVU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddivu", GPR64Opnd, udiv>; +class DMODU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmodu", GPR64Opnd, urem>; class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1, MipsIns>; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 01feebf6961c..7fb07a54d0bb 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -696,9 +696,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def MULTu_MM : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM_MM<0x26c>; def SDIV_MM : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ac>; + MULT_FM_MM<0x2ac>, ISA_MIPS1_NOT_32R6_64R6; def UDIV_MM : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ec>; + MULT_FM_MM<0x2ec>, ISA_MIPS1_NOT_32R6_64R6; /// Arithmetic Instructions with PC and Immediate def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM; @@ -998,6 +998,11 @@ class UncondBranchMMPseudo : def B_MM_Pseudo : UncondBranchMMPseudo<"b">, ISA_MICROMIPS; +def SDIV_MM_Pseudo : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; +def UDIV_MM_Pseudo : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; + def : MipsInstAlias<"wait", (WAIT_MM 0x0), 1>; def : MipsInstAlias<"nop", (SLL_MM ZERO, ZERO, 0), 1>; def : MipsInstAlias<"nop", (MOVE16_MM ZERO, ZERO), 1>; diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 3e2c8293c26c..0a5d887e4f9c 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -748,8 +748,10 @@ def CLO_R6 : R6MMR6Rel, CLO_R6_ENC, CLO_R6_DESC, ISA_MIPS32R6; def CLZ_R6 : R6MMR6Rel, CLZ_R6_ENC, CLZ_R6_DESC, ISA_MIPS32R6; defm S : CMP_CC_M; defm D : CMP_CC_M; -def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; -def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; + def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; +} def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6; def JIC : R6MMR6Rel, JIC_ENC, JIC_DESC, ISA_MIPS32R6; def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6; @@ -771,8 +773,10 @@ let AdditionalPredicates = [NotInMicroMips] in { def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT; def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT; } -def MOD : R6MMR6Rel, MOD_ENC, MOD_DESC, ISA_MIPS32R6; -def MODU : R6MMR6Rel, MODU_ENC, MODU_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def MOD : R6MMR6Rel, MOD_ENC, MOD_DESC, ISA_MIPS32R6; + def MODU : R6MMR6Rel, MODU_ENC, MODU_DESC, ISA_MIPS32R6; +} let AdditionalPredicates = [NotInMicroMips] in { def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT; def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT; diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 0f9e18af261b..12ff9f32892a 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -224,10 +224,12 @@ def PseudoDMULT : MultDivPseudo, ISA_MIPS3_NOT_32R6_64R6; def PseudoDMULTu : MultDivPseudo, ISA_MIPS3_NOT_32R6_64R6; -def DSDIV : Div<"ddiv", II_DDIV, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1e>, ISA_MIPS3_NOT_32R6_64R6; -def DUDIV : Div<"ddivu", II_DDIVU, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1f>, ISA_MIPS3_NOT_32R6_64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DSDIV : Div<"ddiv", II_DDIV, GPR64Opnd, [HI0_64, LO0_64]>, + MULT_FM<0, 0x1e>, ISA_MIPS3_NOT_32R6_64R6; + def DUDIV : Div<"ddivu", II_DDIVU, GPR64Opnd, [HI0_64, LO0_64]>, + MULT_FM<0, 0x1f>, ISA_MIPS3_NOT_32R6_64R6; +} def PseudoDSDIV : MultDivPseudo, ISA_MIPS3_NOT_32R6_64R6; def PseudoDUDIV : MultDivPseudogetOperand(2); - MIB = BuildMI(MBB, std::next(I), MI->getDebugLoc(), TII.get(Mips::TEQ)) + MIB = BuildMI(MBB, std::next(I), MI->getDebugLoc(), + TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ)) .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill())) .addReg(Mips::ZERO).addImm(7); @@ -1016,14 +1017,29 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case Mips::DIVU: case Mips::MOD: case Mips::MODU: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false); + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, + false); + case Mips::SDIV_MM_Pseudo: + case Mips::UDIV_MM_Pseudo: + case Mips::SDIV_MM: + case Mips::UDIV_MM: + case Mips::DIV_MMR6: + case Mips::DIVU_MMR6: + case Mips::MOD_MMR6: + case Mips::MODU_MMR6: + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, true); case Mips::PseudoDSDIV: case Mips::PseudoDUDIV: case Mips::DDIV: case Mips::DDIVU: case Mips::DMOD: case Mips::DMODU: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true); + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false); + case Mips::DDIV_MM64R6: + case Mips::DDIVU_MM64R6: + case Mips::DMOD_MM64R6: + case Mips::DMODU_MM64R6: + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, true); case Mips::SEL_D: return emitSEL_D(MI, BB); diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index e9d7f8d43c5f..db6d3f37be92 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1927,11 +1927,12 @@ def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6; def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6; -def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; -def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; - +let AdditionalPredicates = [NotInMicroMips] in { + def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; + def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; +} def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>, ISA_MIPS1_NOT_32R6_64R6; def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>, @@ -1999,12 +2000,12 @@ def PseudoMSUBU : MAddSubPseudo, ISA_MIPS32_NOT_32R6_64R6; } -def PseudoSDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; -def PseudoUDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; let AdditionalPredicates = [NotInMicroMips] in { -def RDHWR : MMRel, ReadHardware, RDHWR_FM; + def PseudoSDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; + def PseudoUDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; + def RDHWR : MMRel, ReadHardware, RDHWR_FM; } // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5, @@ -2359,10 +2360,10 @@ def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6; -def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), +def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt), "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; -def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), +def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt), "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), diff --git a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll index 4d81da03267f..301642c76ce0 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll @@ -24,6 +24,12 @@ ; RUN: -check-prefix=NOT-R6 -check-prefix=R2-R5 -check-prefix=GP64-NOT-R6 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ ; RUN: -check-prefix=R6 -check-prefix=64R6 +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR3 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM64 define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) { entry: @@ -42,6 +48,17 @@ entry: ; R6: sll $[[T1:[0-9]+]], $[[T0]], 31 ; R6: sra $2, $[[T1]], 31 + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $[[T0:[0-9]+]] + ; MMR3: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; MMR3: sra $2, $[[T1]], 31 + + ; MMR6: div $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; MMR6: sra $2, $[[T1]], 31 + %r = sdiv i1 %a, %b ret i1 %r } @@ -68,6 +85,15 @@ entry: ; FIXME: This instruction is redundant. ; R6: seb $2, $[[T0]] + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $[[T0:[0-9]+]] + ; MMR3: seb $2, $[[T0]] + + ; MMR6: div $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: seb $2, $[[T0]] + %r = sdiv i8 %a, %b ret i8 %r } @@ -94,6 +120,15 @@ entry: ; FIXME: This is instruction is redundant since div is signed. ; R6: seh $2, $[[T0]] + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $[[T0:[0-9]+]] + ; MMR3: seh $2, $[[T0]] + + ; MMR6: div $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: seh $2, $[[T0]] + %r = sdiv i16 %a, %b ret i16 %r } @@ -109,6 +144,13 @@ entry: ; R6: div $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: div $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = sdiv i32 %a, %b ret i32 %r } @@ -126,6 +168,11 @@ entry: ; 64R6: ddiv $2, $4, $5 ; 64R6: teq $5, $zero, 7 + ; MM32: lw $25, %call16(__divdi3)($2) + + ; MM64: ddiv $2, $4, $5 + ; MM64: teq $5, $zero, 7 + %r = sdiv i64 %a, %b ret i64 %r } @@ -134,11 +181,185 @@ define signext i128 @sdiv_i128(i128 signext %a, i128 signext %b) { entry: ; ALL-LABEL: sdiv_i128: - ; GP32: lw $25, %call16(__divti3)($gp) + ; GP32: lw $25, %call16(__divti3)($gp) - ; GP64-NOT-R6: ld $25, %call16(__divti3)($gp) - ; 64R6: ld $25, %call16(__divti3)($gp) + ; GP64-NOT-R6: ld $25, %call16(__divti3)($gp) + ; 64R6: ld $25, %call16(__divti3)($gp) - %r = sdiv i128 %a, %b - ret i128 %r + ; MM32: lw $25, %call16(__divti3)($2) + + ; MM64: ld $25, %call16(__divti3)($2) + + %r = sdiv i128 %a, %b + ret i128 %r +} + +define signext i1 @sdiv_0_i1(i1 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i8: + + ; NOT-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R6: div $zero, $4, $[[T0]] + ; NOT-R6: teq $[[T0]], $zero, 7 + ; NOT-R6: mflo $[[T1:[0-9]+]] + ; NOT-R6: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; NOT-R6: sra $2, $[[T2]], 31 + + ; R6: div $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; R6: sra $2, $[[T1]], 31 + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mflo $[[T1:[0-9]+]] + ; MMR3: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; MMR3: sra $2, $[[T2]], 31 + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: div $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; MMR6: sra $2, $[[T2]], 31 + + %r = sdiv i1 %a, 0 + ret i1 %r +} + +define signext i8 @sdiv_0_i8(i8 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i8: + + ; NOT-R2-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R2-R6: div $zero, $4, $[[T0]] + ; NOT-R2-R6: teq $[[T0]], $zero, 7 + ; NOT-R2-R6: mflo $[[T1:[0-9]+]] + ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 24 + ; NOT-R2-R6: sra $2, $[[T2]], 24 + + ; R2-R5: addiu $[[T0:[0-9]+]], $zero, 0 + ; R2-R5: div $zero, $4, $[[T0]] + ; R2-R5: teq $[[T0]], $zero, 7 + ; R2-R5: mflo $[[T1:[0-9]+]] + ; R2-R5: seb $2, $[[T1]] + + ; R6: div $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: seb $2, $[[T0]] + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mflo $[[T1:[0-9]+]] + ; MMR3: seb $2, $[[T1]] + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: div $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seb $2, $[[T1]] + + %r = sdiv i8 %a, 0 + ret i8 %r +} + +define signext i16 @sdiv_0_i16(i16 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i16: + + ; NOT-R2-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R2-R6: div $zero, $4, $[[T0]] + ; NOT-R2-R6: teq $[[T0]], $zero, 7 + ; NOT-R2-R6: mflo $[[T1:[0-9]+]] + ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 16 + ; NOT-R2-R6: sra $2, $[[T2]], 16 + + ; R2-R5: addiu $[[T0:[0-9]+]], $zero, 0 + ; R2-R5: div $zero, $4, $[[T0]] + ; R2-R5: teq $[[T0]], $zero, 7 + ; R2-R5: mflo $[[T1:[0-9]+]] + ; R2-R5: seh $2, $[[T1]] + + ; R6: div $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: seh $2, $[[T0]] + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mflo $[[T1:[0-9]+]] + ; MMR3: seh $2, $[[T1]] + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: div $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seh $2, $[[T1]] + + %r = sdiv i16 %a, 0 + ret i16 %r +} + +define signext i32 @sdiv_0_i32(i32 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i32: + + ; NOT-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R6: div $zero, $4, $[[T0]] + ; NOT-R6: teq $[[T0]], $zero, 7 + ; NOT-R6: mflo $2 + + ; R6: div $2, $4, $zero + ; R6: teq $zero, $zero, 7 + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: div $2, $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + + %r = sdiv i32 %a, 0 + ret i32 %r +} + +define signext i64 @sdiv_0_i64(i64 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i64: + + ; GP32: lw $25, %call16(__divdi3)($gp) + + ; GP64-NOT-R6: daddiu $[[T0:[0-9]+]], $zero, 0 + ; GP64-NOT-R6: ddiv $zero, $4, $[[T0]] + ; GP64-NOT-R6: teq $[[T0]], $zero, 7 + ; GP64-NOT-R6: mflo $2 + + ; 64R6: ddiv $2, $4, $zero + ; 64R6: teq $zero, $zero, 7 + + ; MM32: lw $25, %call16(__divdi3)($2) + + ; MM64: ddiv $2, $4, $zero + ; MM64: teq $zero, $zero, 7 + + %r = sdiv i64 %a, 0 + ret i64 %r +} + +define signext i128 @sdiv_0_i128(i128 signext %a) { +entry: +; ALL-LABEL: sdiv_0_i128: + + ; GP32: lw $25, %call16(__divti3)($gp) + + ; GP64-NOT-R6: ld $25, %call16(__divti3)($gp) + ; 64R6: ld $25, %call16(__divti3)($gp) + + ; MM32: lw $25, %call16(__divti3)($2) + + ; MM64: ld $25, %call16(__divti3)($2) + + %r = sdiv i128 %a, 0 + ret i128 %r } diff --git a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll index 1ebf9c667e72..c979944c4238 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll @@ -27,6 +27,12 @@ ; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ ; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6 +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR3 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM64 define signext i1 @srem_i1(i1 signext %a, i1 signext %b) { entry: @@ -43,6 +49,17 @@ entry: ; R6: sll $[[T3:[0-9]+]], $[[T0]], 31 ; R6: sra $2, $[[T3]], 31 + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mfhi $[[T0:[0-9]+]] + ; MMR3: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; MMR3: sra $2, $[[T1]], 31 + + ; MMR6: mod $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; MMR6: sra $2, $[[T1]], 31 + %r = srem i1 %a, %b ret i1 %r } @@ -66,6 +83,15 @@ entry: ; R6: teq $5, $zero, 7 ; R6: seb $2, $[[T0]] + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mfhi $[[T0:[0-9]+]] + ; MMR3: seb $2, $[[T0]] + + ; MMR6: mod $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: seb $2, $[[T0]] + %r = srem i8 %a, %b ret i8 %r } @@ -83,12 +109,21 @@ entry: ; R2-R5: div $zero, $4, $5 ; R2-R5: teq $5, $zero, 7 ; R2-R5: mfhi $[[T0:[0-9]+]] - ; R2-R5: seh $2, $[[T1]] + ; R2-R5: seh $2, $[[T0]] ; R6: mod $[[T0:[0-9]+]], $4, $5 ; R6: teq $5, $zero, 7 ; R6: seh $2, $[[T0]] + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mfhi $[[T0:[0-9]+]] + ; MMR3: seh $2, $[[T0]] + + ; MMR6: mod $[[T0:[0-9]+]], $4, $5 + ; MMR6: teq $5, $zero, 7 + ; MMR6: seh $2, $[[T0]] + %r = srem i16 %a, %b ret i16 %r } @@ -104,6 +139,13 @@ entry: ; R6: mod $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: div $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mfhi $2 + + ; MMR6: mod $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = srem i32 %a, %b ret i32 %r } @@ -121,6 +163,11 @@ entry: ; 64R6: dmod $2, $4, $5 ; 64R6: teq $5, $zero, 7 + ; MM32: lw $25, %call16(__moddi3)($2) + + ; MM64: dmod $2, $4, $5 + ; MM64: teq $5, $zero, 7 + %r = srem i64 %a, %b ret i64 %r } @@ -134,6 +181,181 @@ entry: ; GP64-NOT-R6: ld $25, %call16(__modti3)($gp) ; 64-R6: ld $25, %call16(__modti3)($gp) + ; MM32: lw $25, %call16(__modti3)($2) + + ; MM64: ld $25, %call16(__modti3)($2) + %r = srem i128 %a, %b ret i128 %r } + +define signext i1 @srem_0_i1(i1 signext %a) { +entry: +; ALL-LABEL: srem_0_i1: + + ; NOT-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R6: div $zero, $4, $[[T0]] + ; NOT-R6: teq $[[T0]], $zero, 7 + ; NOT-R6: mfhi $[[T1:[0-9]+]] + ; NOT-R6: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; NOT-R6: sra $2, $[[T2]], 31 + + ; R6: mod $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: sll $[[T1:[0-9]+]], $[[T0]], 31 + ; R6: sra $2, $[[T1]], 31 + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T1:[0-9]+]] + ; MMR3: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; MMR3: sra $2, $[[T2]], 31 + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: mod $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: sll $[[T2:[0-9]+]], $[[T1]], 31 + ; MMR6: sra $2, $[[T2]], 31 + + %r = srem i1 %a, 0 + ret i1 %r +} + +define signext i8 @srem_0_i8(i8 signext %a) { +entry: +; ALL-LABEL: srem_0_i8: + + ; NOT-R2-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R2-R6: div $zero, $4, $[[T0]] + ; NOT-R2-R6: teq $[[T0]], $zero, 7 + ; NOT-R2-R6: mfhi $[[T1:[0-9]+]] + ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 24 + ; NOT-R2-R6: sra $2, $[[T2]], 24 + + ; R2-R5: addiu $[[T0:[0-9]+]], $zero, 0 + ; R2-R5: div $zero, $4, $[[T0]] + ; R2-R5: teq $[[T0]], $zero, 7 + ; R2-R5: mfhi $[[T1:[0-9]+]] + ; R2-R5: seb $2, $[[T1]] + + ; R6: mod $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: seb $2, $[[T0]] + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T1:[0-9]+]] + ; MMR3: seb $2, $[[T1]] + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: mod $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seb $2, $[[T1]] + + %r = srem i8 %a, 0 + ret i8 %r +} + +define signext i16 @srem_0_i16(i16 signext %a) { +entry: +; ALL-LABEL: srem_0_i16: + + ; NOT-R2-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R2-R6: div $zero, $4, $[[T0]] + ; NOT-R2-R6: teq $[[T0]], $zero, 7 + ; NOT-R2-R6: mfhi $[[T1:[0-9]+]] + ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 16 + ; NOT-R2-R6: sra $2, $[[T2]], 16 + + ; R2-R5: addiu $[[T0:[0-9]+]], $zero, 0 + ; R2-R5: div $zero, $4, $[[T0]] + ; R2-R5: teq $[[T0]], $zero, 7 + ; R2-R5: mfhi $[[T1:[0-9]+]] + ; R2-R5: seh $2, $[[T1]] + + ; R6: mod $[[T0:[0-9]+]], $4, $zero + ; R6: teq $zero, $zero, 7 + ; R6: seh $2, $[[T0]] + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T1:[0-9]+]] + ; MMR3: seh $2, $[[T1]] + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: mod $[[T1:[0-9]+]], $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seh $2, $[[T1]] + + %r = srem i16 %a, 0 + ret i16 %r +} + + +define signext i32 @srem_0_i32(i32 signext %a) { +entry: +; ALL-LABEL: srem_0_i32: + + ; NOT-R6: addiu $[[T0:[0-9]+]], $zero, 0 + ; NOT-R6: div $zero, $4, $[[T0]] + ; NOT-R6: teq $[[T0]], $zero, 7 + ; NOT-R6: mfhi $2 + + ; R6: mod $2, $4, $zero + ; R6: teq $zero, $zero, 7 + + ; MMR3: lui $[[T0:[0-9]+]], 0 + ; MMR3: div $zero, $4, $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $2 + + ; MMR6: lui $[[T0:[0-9]+]], 0 + ; MMR6: mod $2, $4, $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + + %r = srem i32 %a, 0 + ret i32 %r +} + +define signext i64 @srem_0_i64(i64 signext %a) { +entry: +; ALL-LABEL: srem_0_i64: + + ; GP32: lw $25, %call16(__moddi3)($gp) + + ; GP64-NOT-R6: daddiu $[[T0:[0-9]+]], $zero, 0 + ; GP64-NOT-R6: ddiv $zero, $4, $[[T0]] + ; GP64-NOT-R6: teq $[[T0]], $zero, 7 + ; GP64-NOT-R6: mfhi $2 + + ; 64R6: dmod $2, $4, $zero + ; 64R6: teq $zero, $zero, 7 + + ; MM32: lw $25, %call16(__moddi3)($2) + + ; MM64: dmod $2, $4, $zero + ; MM64: teq $zero, $zero, 7 + + %r = srem i64 %a, 0 + ret i64 %r +} + +define signext i128 @srem_0_i128(i128 signext %a) { +entry: +; ALL-LABEL: srem_0_i128: + + ; GP32: lw $25, %call16(__modti3)($gp) + + ; GP64-NOT-R6: ld $25, %call16(__modti3)($gp) + ; 64R6: ld $25, %call16(__modti3)($gp) + + ; MM32: lw $25, %call16(__modti3)($2) + + ; MM64: ld $25, %call16(__modti3)($2) + + %r = srem i128 %a, 0 + ret i128 %r +} diff --git a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll index 8ee4deb41b5f..69083f612c39 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll @@ -24,6 +24,12 @@ ; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ ; RUN: -check-prefix=R6 -check-prefix=64R6 +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR3 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM64 define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) { entry: @@ -36,6 +42,13 @@ entry: ; R6: divu $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: divu $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: divu $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = udiv i1 %a, %b ret i1 %r } @@ -51,6 +64,13 @@ entry: ; R6: divu $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: divu $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: divu $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = udiv i8 %a, %b ret i8 %r } @@ -66,6 +86,13 @@ entry: ; R6: divu $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: divu $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: divu $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = udiv i16 %a, %b ret i16 %r } @@ -81,6 +108,13 @@ entry: ; R6: divu $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: divu $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mflo $2 + + ; MMR6: divu $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = udiv i32 %a, %b ret i32 %r } @@ -98,6 +132,11 @@ entry: ; 64R6: ddivu $2, $4, $5 ; 64R6: teq $5, $zero, 7 + ; MM32: lw $25, %call16(__udivdi3)($2) + + ; MM64: ddivu $2, $4, $5 + ; MM64: teq $5, $zero, 7 + %r = udiv i64 %a, %b ret i64 %r } @@ -111,6 +150,10 @@ entry: ; GP64-NOT-R6: ld $25, %call16(__udivti3)($gp) ; 64-R6: ld $25, %call16(__udivti3)($gp) + ; MM32: lw $25, %call16(__udivti3)($2) + + ; MM64: ld $25, %call16(__udivti3)($2) + %r = udiv i128 %a, %b ret i128 %r } diff --git a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll index 9815ade1bab8..37d9bc769d30 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll @@ -27,6 +27,12 @@ ; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ ; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6 +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR3 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM32 +; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \ +; RUN: -check-prefix=MM -check-prefix=MMR6 -check-prefix=MM64 define signext i1 @urem_i1(i1 signext %a, i1 signext %b) { entry: @@ -47,6 +53,21 @@ entry: ; R6: sll $[[T3:[0-9]+]], $[[T2]], 31 ; R6: sra $2, $[[T3]], 31 + ; MMR3: andi16 $[[T0:[0-9]+]], $5, 1 + ; MMR3: andi16 $[[T1:[0-9]+]], $4, 1 + ; MMR3: divu $zero, $[[T1]], $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T2:[0-9]+]] + ; MMR3: sll $[[T3:[0-9]+]], $[[T2]], 31 + ; MMR3: sra $2, $[[T3]], 31 + + ; MMR6: andi16 $[[T0:[0-9]+]], $5, 1 + ; MMR6: andi16 $[[T1:[0-9]+]], $4, 1 + ; MMR6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: sll $[[T3:[0-9]+]], $[[T2]], 31 + ; MMR6: sra $2, $[[T3]], 31 + %r = urem i1 %a, %b ret i1 %r } @@ -76,6 +97,19 @@ entry: ; R6: teq $[[T0]], $zero, 7 ; R6: seb $2, $[[T2]] + ; MMR3: andi16 $[[T0:[0-9]+]], $5, 255 + ; MMR3: andi16 $[[T1:[0-9]+]], $4, 255 + ; MMR3: divu $zero, $[[T1]], $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T2:[0-9]+]] + ; MMR3: seb $2, $[[T2]] + + ; MMR6: andi16 $[[T0:[0-9]+]], $5, 255 + ; MMR6: andi16 $[[T1:[0-9]+]], $4, 255 + ; MMR6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seb $2, $[[T2]] + %r = urem i8 %a, %b ret i8 %r } @@ -105,6 +139,19 @@ entry: ; R6: teq $[[T0]], $zero, 7 ; R6: seh $2, $[[T2]] + ; MMR3: andi16 $[[T0:[0-9]+]], $5, 65535 + ; MMR3: andi16 $[[T1:[0-9]+]], $4, 65535 + ; MMR3: divu $zero, $[[T1]], $[[T0]] + ; MMR3: teq $[[T0]], $zero, 7 + ; MMR3: mfhi $[[T2:[0-9]+]] + ; MMR3: seh $2, $[[T2]] + + ; MMR6: andi16 $[[T0:[0-9]+]], $5, 65535 + ; MMR6: andi16 $[[T1:[0-9]+]], $4, 65535 + ; MMR6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] + ; MMR6: teq $[[T0]], $zero, 7 + ; MMR6: seh $2, $[[T2]] + %r = urem i16 %a, %b ret i16 %r } @@ -120,6 +167,13 @@ entry: ; R6: modu $2, $4, $5 ; R6: teq $5, $zero, 7 + ; MMR3: divu $zero, $4, $5 + ; MMR3: teq $5, $zero, 7 + ; MMR3: mfhi $2 + + ; MMR6: modu $2, $4, $5 + ; MMR6: teq $5, $zero, 7 + %r = urem i32 %a, %b ret i32 %r } @@ -137,6 +191,11 @@ entry: ; 64R6: dmodu $2, $4, $5 ; 64R6: teq $5, $zero, 7 + ; MM32: lw $25, %call16(__umoddi3)($2) + + ; MM64: dmodu $2, $4, $5 + ; MM64: teq $5, $zero, 7 + %r = urem i64 %a, %b ret i64 %r } @@ -145,10 +204,14 @@ define signext i128 @urem_i128(i128 signext %a, i128 signext %b) { entry: ; ALL-LABEL: urem_i128: - ; GP32: lw $25, %call16(__umodti3)($gp) + ; GP32: lw $25, %call16(__umodti3)($gp) - ; GP64-NOT-R6: ld $25, %call16(__umodti3)($gp) - ; 64-R6: ld $25, %call16(__umodti3)($gp) + ; GP64-NOT-R6: ld $25, %call16(__umodti3)($gp) + ; 64-R6: ld $25, %call16(__umodti3)($gp) + + ; MM32: lw $25, %call16(__umodti3)($2) + + ; MM64: ld $25, %call16(__umodti3)($2) %r = urem i128 %a, %b ret i128 %r diff --git a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt index 9eff5178bd38..4d7402ad4f50 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -28,10 +28,10 @@ 0x59 0x26 0x30 0xe4 # CHECK: dextm $9, $6, 3, 39 0x59 0x26 0x30 0xd4 # CHECK: dextu $9, $6, 35, 7 0x58 0x43 0x25 0x1c # CHECK: dalign $4, $2, $3, 5 -0x58 0x64 0x29 0x18 # CHECK: ddiv $3, $4, $5 -0x58 0x64 0x29 0x58 # CHECK: dmod $3, $4, $5 -0x58 0x64 0x29 0x98 # CHECK: ddivu $3, $4, $5 -0x58 0x64 0x29 0xd8 # CHECK: dmodu $3, $4, $5 +0x58 0xa4 0x19 0x18 # CHECK: ddiv $3, $4, $5 +0x58 0xa4 0x19 0x58 # CHECK: dmod $3, $4, $5 +0x58 0xa4 0x19 0x98 # CHECK: ddivu $3, $4, $5 +0x58 0xa4 0x19 0xd8 # CHECK: dmodu $3, $4, $5 0x54 0xa4 0x18 0x30 # CHECK: add.s $f3, $f4, $f5 0x54 0xc4 0x11 0x30 # CHECK: add.d $f2, $f4, $f6 0x54 0xa4 0x18 0x70 # CHECK: sub.s $f3, $f4, $f5 diff --git a/llvm/test/MC/Mips/micromips64r6/valid.s b/llvm/test/MC/Mips/micromips64r6/valid.s index 3e64314c1b79..32113e34ed09 100644 --- a/llvm/test/MC/Mips/micromips64r6/valid.s +++ b/llvm/test/MC/Mips/micromips64r6/valid.s @@ -27,10 +27,10 @@ a: lhu16 $3, 4($16) # CHECK: lhu16 $3, 4($16) # encoding: [0x29,0x82] lbu16 $3, 4($17) # CHECK: lbu16 $3, 4($17) # encoding: [0x09,0x94] lbu16 $3, -1($17) # CHECK: lbu16 $3, -1($17) # encoding: [0x09,0x9f] - ddiv $3, $4, $5 # CHECK: ddiv $3, $4, $5 # encoding: [0x58,0x64,0x29,0x18] - dmod $3, $4, $5 # CHECK: dmod $3, $4, $5 # encoding: [0x58,0x64,0x29,0x58] - ddivu $3, $4, $5 # CHECK: ddivu $3, $4, $5 # encoding: [0x58,0x64,0x29,0x98] - dmodu $3, $4, $5 # CHECK: dmodu $3, $4, $5 # encoding: [0x58,0x64,0x29,0xd8] + ddiv $3, $4, $5 # CHECK: ddiv $3, $4, $5 # encoding: [0x58,0xa4,0x19,0x18] + dmod $3, $4, $5 # CHECK: dmod $3, $4, $5 # encoding: [0x58,0xa4,0x19,0x58] + ddivu $3, $4, $5 # CHECK: ddivu $3, $4, $5 # encoding: [0x58,0xa4,0x19,0x98] + dmodu $3, $4, $5 # CHECK: dmodu $3, $4, $5 # encoding: [0x58,0xa4,0x19,0xd8] add.s $f3, $f4, $f5 # CHECK: add.s $f3, $f4, $f5 # encoding: [0x54,0xa4,0x18,0x30] add.d $f2, $f4, $f6 # CHECK: add.d $f2, $f4, $f6 # encoding: [0x54,0xc4,0x11,0x30] sub.s $f3, $f4, $f5 # CHECK: sub.s $f3, $f4, $f5 # encoding: [0x54,0xa4,0x18,0x70]