Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -31,17 +31,15 @@ // Removed: bgezal // Removed: bltzal // Removed: c.cond.fmt, bc1[ft] -// Removed: div, divu // Removed: jalx // Removed: ldxc1 // Removed: luxc1 // Removed: lwxc1 // Removed: madd.[ds], nmadd.[ds], nmsub.[ds], sub.[ds] -// Removed: mfhi, mflo, mthi, mtlo, madd, maddu, msub, msubu, mul +// Removed: madd, maddu, msub, msubu // Removed: movf, movt // Removed: movf.fmt, movt.fmt, movn.fmt, movz.fmt // Removed: movn, movz -// Removed: mult, multu // Removed: prefx // Removed: sdxc1 // Removed: suxc1 @@ -389,17 +387,22 @@ class BITSWAP_DESC : BITSWAP_DESC_BASE<"bitswap", GPR32Opnd>; -class DIVMOD_DESC_BASE { +class DIVMOD_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rd); dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt); string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt"); - list Pattern = []; + list Pattern = [(set GPROpnd:$rd, (Op GPROpnd:$rs, GPROpnd:$rt))]; + + // This instruction doesn't trap division by zero itself. We must insert + // teq instructions as well. + bit usesCustomInserter = 1; } -class DIV_DESC : DIVMOD_DESC_BASE<"div", GPR32Opnd>; -class DIVU_DESC : DIVMOD_DESC_BASE<"divu", GPR32Opnd>; -class MOD_DESC : DIVMOD_DESC_BASE<"mod", GPR32Opnd>; -class MODU_DESC : DIVMOD_DESC_BASE<"modu", GPR32Opnd>; +class DIV_DESC : DIVMOD_DESC_BASE<"div", GPR32Opnd, sdiv>; +class DIVU_DESC : DIVMOD_DESC_BASE<"divu", GPR32Opnd, udiv>; +class MOD_DESC : DIVMOD_DESC_BASE<"mod", GPR32Opnd, srem>; +class MODU_DESC : DIVMOD_DESC_BASE<"modu", GPR32Opnd, urem>; class BEQZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"beqzalc", brtarget, GPR32Opnd> { list Defs = [RA]; @@ -424,16 +427,18 @@ class BNEZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bnezalc", brtarget, GPR32Opnd> { list Defs = [RA]; } -class MUL_R6_DESC_BASE { + +class MUL_R6_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rd); dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt); string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt"); - list Pattern = []; + list Pattern = [(set GPROpnd:$rd, (Op GPROpnd:$rs, GPROpnd:$rt))]; } -class MUH_DESC : MUL_R6_DESC_BASE<"muh", GPR32Opnd>; -class MUHU_DESC : MUL_R6_DESC_BASE<"muhu", GPR32Opnd>; -class MUL_R6_DESC : MUL_R6_DESC_BASE<"mul", GPR32Opnd>; +class MUH_DESC : MUL_R6_DESC_BASE<"muh", GPR32Opnd, mulhs>; +class MUHU_DESC : MUL_R6_DESC_BASE<"muhu", GPR32Opnd, mulhu>; +class MUL_R6_DESC : MUL_R6_DESC_BASE<"mul", GPR32Opnd, mul>; class MULU_DESC : MUL_R6_DESC_BASE<"mulu", GPR32Opnd>; class COP1_4R_DESC_BASE { Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -183,30 +183,30 @@ /// Multiply and Divide Instructions. def DMULT : Mult<"dmult", II_DMULT, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1c>, ISA_MIPS3; + MULT_FM<0, 0x1c>, ISA_MIPS3_NOT_32R6_64R6; def DMULTu : Mult<"dmultu", II_DMULTU, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1d>, ISA_MIPS3; + MULT_FM<0, 0x1d>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDMULT : MultDivPseudo; + II_DMULT>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDMULTu : MultDivPseudo; + II_DMULTU>, ISA_MIPS3_NOT_32R6_64R6; def DSDIV : Div<"ddiv", II_DDIV, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1e>, ISA_MIPS3; + 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; + MULT_FM<0, 0x1f>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDSDIV : MultDivPseudo; + II_DDIV, 0, 1, 1>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDUDIV : MultDivPseudo; + II_DDIVU, 0, 1, 1>, ISA_MIPS3_NOT_32R6_64R6; let isCodeGenOnly = 1 in { -def MTHI64 : MoveToLOHI<"mthi", GPR64Opnd, [HI0_64]>, MTLO_FM<0x11>; -def MTLO64 : MoveToLOHI<"mtlo", GPR64Opnd, [LO0_64]>, MTLO_FM<0x13>; -def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, AC0_64>, MFLO_FM<0x10>; -def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, AC0_64>, MFLO_FM<0x12>; -def PseudoMFHI64 : PseudoMFLOHI; -def PseudoMFLO64 : PseudoMFLOHI; -def PseudoMTLOHI64 : PseudoMTLOHI; +def MTHI64 : MoveToLOHI<"mthi", GPR64Opnd, [HI0_64]>, MTLO_FM<0x11>, ISA_MIPS3_NOT_32R6_64R6; +def MTLO64 : MoveToLOHI<"mtlo", GPR64Opnd, [LO0_64]>, MTLO_FM<0x13>, ISA_MIPS3_NOT_32R6_64R6; +def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, AC0_64>, MFLO_FM<0x10>, ISA_MIPS3_NOT_32R6_64R6; +def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, AC0_64>, MFLO_FM<0x12>, ISA_MIPS3_NOT_32R6_64R6; +def PseudoMFHI64 : PseudoMFLOHI, ISA_MIPS3_NOT_32R6_64R6; +def PseudoMFLO64 : PseudoMFLOHI, ISA_MIPS3_NOT_32R6_64R6; +def PseudoMTLOHI64 : PseudoMTLOHI, ISA_MIPS3_NOT_32R6_64R6; /// Sign Ext In Register Instructions. def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd, II_SEB>, SEB_FM<0x10, 0x20>, Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -15,8 +15,6 @@ // Reencoded: dclo, dclz // Reencoded: lld, scd // Removed: daddi -// Removed: ddiv, ddivu, dmult, dmultu -// Removed: div, divu //===----------------------------------------------------------------------===// // @@ -56,13 +54,13 @@ class DATI_DESC : AHI_ATI_DESC_BASE<"dati", GPR64Opnd>; class DAUI_DESC : AUI_DESC_BASE<"daui", GPR64Opnd>; class DBITSWAP_DESC : BITSWAP_DESC_BASE<"dbitswap", GPR64Opnd>; -class DDIV_DESC : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd>; -class DDIVU_DESC : DIVMOD_DESC_BASE<"ddivu", GPR64Opnd>; -class DMOD_DESC : DIVMOD_DESC_BASE<"dmod", GPR64Opnd>; -class DMODU_DESC : DIVMOD_DESC_BASE<"dmodu", GPR64Opnd>; -class DMUH_DESC : MUL_R6_DESC_BASE<"dmuh", GPR64Opnd>; -class DMUHU_DESC : MUL_R6_DESC_BASE<"dmuhu", GPR64Opnd>; -class DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd>; +class DDIV_DESC : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd, sdiv>; +class DDIVU_DESC : DIVMOD_DESC_BASE<"ddivu", GPR64Opnd, udiv>; +class DMOD_DESC : DIVMOD_DESC_BASE<"dmod", GPR64Opnd, srem>; +class DMODU_DESC : DIVMOD_DESC_BASE<"dmodu", GPR64Opnd, urem>; +class DMUH_DESC : MUL_R6_DESC_BASE<"dmuh", GPR64Opnd, mulhs>; +class DMUHU_DESC : MUL_R6_DESC_BASE<"dmuhu", GPR64Opnd, mulhu>; +class DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd, mul>; class DMULU_DESC : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd>; //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsDelaySlotFiller.cpp =================================================================== --- lib/Target/Mips/MipsDelaySlotFiller.cpp +++ lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetInstrInfo.h" @@ -177,6 +178,13 @@ for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) Changed |= runOnMachineBasicBlock(*FI); + + // This pass invalidates liveness information when it reorders + // instructions to fill delay slot. Without this, -verify-machineinstrs + // will fail. + if (Changed) + F.getRegInfo().invalidateLiveness(); + return Changed; } Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -815,10 +815,10 @@ return VReg; } -static MachineBasicBlock *expandPseudoDIV(MachineInstr *MI, - MachineBasicBlock &MBB, - const TargetInstrInfo &TII, - bool Is64Bit) { +static MachineBasicBlock *insertDivByZeroTrap(MachineInstr *MI, + MachineBasicBlock &MBB, + const TargetInstrInfo &TII, + bool Is64Bit) { if (NoZeroDivCheck) return &MBB; @@ -836,6 +836,10 @@ // Clear Divisor's kill flag. Divisor.setIsKill(false); + + // We would normally delete the original instruction here but in this case + // we only needed to inject an additional instruction rather than replace it. + return &MBB; } @@ -918,10 +922,20 @@ return emitAtomicCmpSwap(MI, BB, 8); case Mips::PseudoSDIV: case Mips::PseudoUDIV: - return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), false); + case Mips::DIV: + case Mips::DIVU: + case Mips::MOD: + case Mips::MODU: + return insertDivByZeroTrap(MI, *BB, *getTargetMachine().getInstrInfo(), + false); case Mips::PseudoDSDIV: case Mips::PseudoDUDIV: - return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), true); + case Mips::DDIV: + case Mips::DDIVU: + case Mips::DMOD: + case Mips::DMODU: + return insertDivByZeroTrap(MI, *BB, *getTargetMachine().getInstrInfo(), + true); } } Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -232,6 +232,9 @@ list InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6]; } class ISA_MIPS32 { list InsnPredicates = [HasMips32]; } +class ISA_MIPS32_NOT_32R6_64R6 { + list InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6]; +} class ISA_MIPS32R2 { list InsnPredicates = [HasMips32r2]; } class ISA_MIPS64 { list InsnPredicates = [HasMips64]; } class ISA_MIPS64R2 { list InsnPredicates = [HasMips64r2]; } @@ -1042,7 +1045,7 @@ ADD_FM<0, 0x23>; let Defs = [HI0, LO0] in def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>, - ADD_FM<0x1c, 2>, ISA_MIPS32; + ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6; def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>; def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; @@ -1196,20 +1199,24 @@ /// Multiply and Divide Instructions. def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x18>; + MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6; def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x19>; + MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6; def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1a>; + MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1b>; + MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; -def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>; -def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>; +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>, + ISA_MIPS1_NOT_32R6_64R6; let EncodingPredicates = [], // FIXME: Lack of HasStdEnc is probably a bug AdditionalPredicates = [NotInMicroMips] in { -def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>; -def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>; +def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>, + ISA_MIPS1_NOT_32R6_64R6; +def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>, + ISA_MIPS1_NOT_32R6_64R6; } /// Sign Ext In Register Instructions. @@ -1241,11 +1248,13 @@ def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>, ISA_MIPS32; let AdditionalPredicates = [NotDSP] in { -def PseudoMULT : MultDivPseudo; -def PseudoMULTu : MultDivPseudo; -def PseudoMFHI : PseudoMFLOHI; -def PseudoMFLO : PseudoMFLOHI; -def PseudoMTLOHI : PseudoMTLOHI; +def PseudoMULT : MultDivPseudo, + ISA_MIPS1_NOT_32R6_64R6; +def PseudoMULTu : MultDivPseudo, + ISA_MIPS1_NOT_32R6_64R6; +def PseudoMFHI : PseudoMFLOHI, ISA_MIPS1_NOT_32R6_64R6; +def PseudoMFLO : PseudoMFLOHI, ISA_MIPS1_NOT_32R6_64R6; +def PseudoMTLOHI : PseudoMTLOHI, ISA_MIPS1_NOT_32R6_64R6; def PseudoMADD : MAddSubPseudo; def PseudoMADDU : MAddSubPseudo; def PseudoMSUB : MAddSubPseudo; @@ -1253,9 +1262,9 @@ } def PseudoSDIV : MultDivPseudo; + 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; def PseudoUDIV : MultDivPseudo; + 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; def RDHWR : ReadHardware, RDHWR_FM; Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -152,6 +152,40 @@ setOperationAction(ISD::STORE, MVT::f64, Custom); } + if (Subtarget->hasMips32r6()) { + // MIPS32r6 replaces the accumulator-based multiplies with a three register + // instruction + setOperationAction(ISD::MUL, MVT::i32, Legal); + setOperationAction(ISD::MULHS, MVT::i32, Legal); + setOperationAction(ISD::MULHU, MVT::i32, Legal); + + // MIPS32r6 replaces the accumulator-based division/remainder with separate + // three register division and remainder instructions. + setOperationAction(ISD::SDIVREM, MVT::i32, Expand); + setOperationAction(ISD::UDIVREM, MVT::i32, Expand); + setOperationAction(ISD::SDIV, MVT::i32, Legal); + setOperationAction(ISD::UDIV, MVT::i32, Legal); + setOperationAction(ISD::SREM, MVT::i32, Legal); + setOperationAction(ISD::UREM, MVT::i32, Legal); + } + + if (Subtarget->hasMips64r6()) { + // MIPS64r6 replaces the accumulator-based multiplies with a three register + // instruction + setOperationAction(ISD::MUL, MVT::i64, Legal); + setOperationAction(ISD::MULHS, MVT::i64, Legal); + setOperationAction(ISD::MULHU, MVT::i64, Legal); + + // MIPS32r6 replaces the accumulator-based division/remainder with separate + // three register division and remainder instructions. + setOperationAction(ISD::SDIVREM, MVT::i64, Expand); + setOperationAction(ISD::UDIVREM, MVT::i64, Expand); + setOperationAction(ISD::SDIV, MVT::i64, Legal); + setOperationAction(ISD::UDIV, MVT::i64, Legal); + setOperationAction(ISD::SREM, MVT::i64, Legal); + setOperationAction(ISD::UREM, MVT::i64, Legal); + } + computeRegisterProperties(); } @@ -1178,6 +1212,9 @@ SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi, SelectionDAG &DAG) const { + // MIPS32r6/MIPS64r6 removed accumulator based multiplies. + assert(!Subtarget->hasMips32r6()); + EVT Ty = Op.getOperand(0).getValueType(); SDLoc DL(Op); SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, Index: test/CodeGen/Mips/divrem.ll =================================================================== --- test/CodeGen/Mips/divrem.ll +++ test/CodeGen/Mips/divrem.ll @@ -1,10 +1,27 @@ -; RUN: llc -march=mips -mcpu=mips32 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC -check-prefix=TRAP -; RUN: llc -march=mips -mcpu=mips32 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP +; RUN: llc -march=mips -mcpu=mips32r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP +; RUN: llc -march=mips -mcpu=mips32r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=GPR32-TRAP +; RUN: llc -march=mips64 -mcpu=mips64 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP +; RUN: llc -march=mips64 -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP +; RUN: llc -march=mips64 -mcpu=mips64r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=GPR64-TRAP + +; RUN: llc -march=mips -mcpu=mips32 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=NOCHECK ; FileCheck Prefixes: ; ALL - All targets -; ACC - Accumulator based multiply/divide. I.e. All ISA's before MIPS32r6 -; TRAP - Division must be explicitly checked for divide by zero +; ACC32 - Accumulator based multiply/divide on 32-bit targets +; ACC64 - Same as ACC32 but only for 64-bit targets +; GPR32 - GPR based multiply/divide on 32-bit targets +; GPR64 - Same as GPR32 but only for 64-bit targets +; ACC32-TRAP - Same as TRAP and ACC32 combined +; ACC64-TRAP - Same as TRAP and ACC64 combined +; GPR32-TRAP - Same as TRAP and GPR32 combined +; GPR64-TRAP - Same as TRAP and GPR64 combined ; NOCHECK - Division by zero will not be detected @g0 = common global i32 0, align 4 @@ -14,12 +31,22 @@ entry: ; ALL-LABEL: sdiv1: -; ACC: div $zero, $4, $5 +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: div $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: div $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 -; TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mflo $2 +; ACC32: mflo $2 +; ACC64: mflo $2 ; ALL: .end sdiv1 @@ -31,12 +58,22 @@ entry: ; ALL-LABEL: srem1: -; ACC: div $zero, $4, $5 +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: mod $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: mod $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 -; TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mfhi $2 +; ACC32: mfhi $2 +; ACC64: mfhi $2 ; ALL: .end srem1 @@ -48,12 +85,22 @@ entry: ; ALL-LABEL: udiv1: -; ACC: divu $zero, $4, $5 +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: divu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: divu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 -; TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mflo $2 +; ACC32: mflo $2 +; ACC64: mflo $2 ; ALL: .end udiv1 %div = udiv i32 %a0, %a1 @@ -64,12 +111,22 @@ entry: ; ALL-LABEL: urem1: -; ACC: divu $zero, $4, $5 +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: modu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: modu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 -; TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mfhi $2 +; ACC32: mfhi $2 +; ACC64: mfhi $2 ; ALL: .end urem1 @@ -81,12 +138,34 @@ entry: ; ALL-LABEL: sdivrem1: -; ACC: div $zero, $4, $5 -; TRAP: teq $5, $zero, 7 +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC32: mflo $2 +; ACC32: mfhi $[[R0:[0-9]+]] +; ACC32: sw $[[R0]], 0(${{[0-9]+}}) + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sw $[[R0]], 0(${{[0-9]+}}) + +; GPR32: mod $[[R0:[0-9]+]], $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR32: sw $[[R0]], 0(${{[0-9]+}}) +; GPR32-DAG: div $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: mod $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sw $[[R0]], 0(${{[0-9]+}}) +; GPR64-DAG: div $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mflo $2 -; ACC: mfhi $[[R0:[0-9]+]] -; ACC: sw $[[R0]], 0(${{[0-9]+}}) ; ALL: .end sdivrem1 @@ -100,12 +179,35 @@ entry: ; ALL-LABEL: udivrem1: -; ACC: divu $zero, $4, $5 -; TRAP: teq $5, $zero, 7 +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC32: mflo $2 +; ACC32: mfhi $[[R0:[0-9]+]] +; ACC32: sw $[[R0]], 0(${{[0-9]+}}) + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sw $[[R0]], 0(${{[0-9]+}}) + +; GPR32: modu $[[R0:[0-9]+]], $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR32: sw $[[R0]], 0(${{[0-9]+}}) +; GPR32-DAG: divu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; GPR64: modu $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sw $[[R0]], 0(${{[0-9]+}}) +; GPR64-DAG: divu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 ; NOCHECK-NOT: teq -; ACC: mflo $2 -; ACC: mfhi $[[R0:[0-9]+]] -; ACC: sw $[[R0]], 0(${{[0-9]+}}) ; ALL: .end udivrem1 @@ -123,3 +225,164 @@ %div = sdiv i32 %0, %1 ret i32 %div } + +define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: sdiv2: + +; ACC32: lw $25, %call16(__divdi3)( +; ACC32: jalr $25 + +; ACC64: ddiv $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: ddiv $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mflo $2 + +; ALL: .end sdiv2 + + %div = sdiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: srem2: + +; ACC32: lw $25, %call16(__moddi3)( +; ACC32: jalr $25 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: dmod $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mfhi $2 + +; ALL: .end srem2 + + %rem = srem i64 %a0, %a1 + ret i64 %rem +} + +define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: udiv2: + +; ACC32: lw $25, %call16(__udivdi3)( +; ACC32: jalr $25 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: ddivu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mflo $2 + +; ALL: .end udiv2 + %div = udiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: urem2: + +; ACC32: lw $25, %call16(__umoddi3)( +; ACC32: jalr $25 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: dmodu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mfhi $2 + +; ALL: .end urem2 + + %rem = urem i64 %a0, %a1 + ret i64 %rem +} + +define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { +entry: +; ALL-LABEL: sdivrem2: + +; sdivrem2 is too complex to effectively check. We can at least check for the +; calls though. +; ACC32: lw $25, %call16(__moddi3)( +; ACC32: jalr $25 +; ACC32: lw $25, %call16(__divdi3)( +; ACC32: jalr $25 + +; ACC64: ddiv $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64: dmod $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64-DAG: ddiv $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end sdivrem2 + + %rem = srem i64 %a0, %a1 + store i64 %rem, i64* %r, align 8 + %div = sdiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { +entry: +; ALL-LABEL: udivrem2: + +; udivrem2 is too complex to effectively check. We can at least check for the +; calls though. +; ACC32: lw $25, %call16(__umoddi3)( +; ACC32: jalr $25 +; ACC32: lw $25, %call16(__udivdi3)( +; ACC32: jalr $25 + +; ACC64: ddivu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64: dmodu $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64-DAG: ddivu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end udivrem2 + + %rem = urem i64 %a0, %a1 + store i64 %rem, i64* %r, align 8 + %div = udiv i64 %a0, %a1 + ret i64 %div +} Index: test/CodeGen/Mips/mips64muldiv.ll =================================================================== --- test/CodeGen/Mips/mips64muldiv.ll +++ test/CodeGen/Mips/mips64muldiv.ll @@ -1,11 +1,19 @@ -; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL +; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR + +; FileCheck prefixes: +; ALL - All targets +; ACC - Targets with accumulator based mul/div (i.e. pre-MIPS32r6) +; GPR - Targets with register based mul/div (i.e. MIPS32r6) define i64 @m0(i64 %a0, i64 %a1) nounwind readnone { entry: ; ALL-LABEL: m0: -; ALL: dmult ${{[45]}}, ${{[45]}} -; ALL: mflo $2 +; ACC: dmult ${{[45]}}, ${{[45]}} +; ACC: mflo $2 +; GPR: dmul $2, ${{[45]}}, ${{[45]}} %mul = mul i64 %a1, %a0 ret i64 %mul } @@ -19,8 +27,11 @@ ; ALL: addiu $[[T0]], $[[T0]], 21845 ; ALL: dsll $[[T0]], $[[T0]], 16 ; ALL: addiu $[[T0]], $[[T0]], 21846 -; ALL: dmult ${{[45]}}, $[[T0]] -; ALL: mfhi $[[T1:[0-9]+]] + +; ACC: dmult $4, $[[T0]] +; ACC: mfhi $[[T1:[0-9]+]] +; GPR: dmuh $[[T1:[0-9]+]], $4, $[[T0]] + ; ALL: dsrl $2, $[[T1]], 63 ; ALL: daddu $2, $[[T1]], $2 %div = sdiv i64 %a, 3 @@ -30,8 +41,9 @@ define i64 @d0(i64 %a0, i64 %a1) nounwind readnone { entry: ; ALL-LABEL: d0: -; ALL: ddivu $zero, $4, $5 -; ALL: mflo $2 +; ACC: ddivu $zero, $4, $5 +; ACC: mflo $2 +; GPR: ddivu $2, $4, $5 %div = udiv i64 %a0, %a1 ret i64 %div } @@ -39,8 +51,9 @@ define i64 @d1(i64 %a0, i64 %a1) nounwind readnone { entry: ; ALL-LABEL: d1: -; ALL: ddiv $zero, $4, $5 -; ALL: mflo $2 +; ACC: ddiv $zero, $4, $5 +; ACC: mflo $2 +; GPR: ddiv $2, $4, $5 %div = sdiv i64 %a0, %a1 ret i64 %div } @@ -48,8 +61,9 @@ define i64 @d2(i64 %a0, i64 %a1) nounwind readnone { entry: ; ALL-LABEL: d2: -; ALL: ddivu $zero, $4, $5 -; ALL: mfhi $2 +; ACC: ddivu $zero, $4, $5 +; ACC: mfhi $2 +; GPR: dmodu $2, $4, $5 %rem = urem i64 %a0, %a1 ret i64 %rem } @@ -57,8 +71,9 @@ define i64 @d3(i64 %a0, i64 %a1) nounwind readnone { entry: ; ALL-LABEL: d3: -; ALL: ddiv $zero, $4, $5 -; ALL: mfhi $2 +; ACC: ddiv $zero, $4, $5 +; ACC: mfhi $2 +; GPR: dmod $2, $4, $5 %rem = srem i64 %a0, %a1 ret i64 %rem } Index: test/MC/Mips/mips32r6/invalid-mips1.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips1.s +++ test/MC/Mips/mips32r6/invalid-mips1.s @@ -6,3 +6,15 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$s4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$v0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $9,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $gp,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled +# div has been re-encoded. See valid.s +# divu has been re-encoded. See valid.s Index: test/MC/Mips/mips32r6/invalid-mips2.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips2.s +++ test/MC/Mips/mips32r6/invalid-mips2.s @@ -6,9 +6,21 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$s4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$v0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $9,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $gp,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled teqi $s5,-17504 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgei $s1,5025 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgeiu $sp,-28621 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tlti $14,-21059 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tltiu $ra,-5076 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tnei $12,-29647 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled +# div has been re-encoded. See valid.s +# divu has been re-encoded. See valid.s Index: test/MC/Mips/mips32r6/valid.s =================================================================== --- test/MC/Mips/mips32r6/valid.s +++ test/MC/Mips/mips32r6/valid.s @@ -96,7 +96,7 @@ lwupc $2,268 # CHECK: lwupc $2, 268 # encoding: [0xec,0x50,0x00,0x43] mod $2,$3,$4 # CHECK: mod $2, $3, $4 # encoding: [0x00,0x64,0x10,0xda] modu $2,$3,$4 # CHECK: modu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xdb] -# mul $2,$3,$4 # CHECK-TODO: mul $2, $3, $4 # encoding: [0x00,0x64,0x10,0x98] + mul $2,$3,$4 # CHECK: mul $2, $3, $4 # encoding: [0x00,0x64,0x10,0x98] muh $2,$3,$4 # CHECK: muh $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd8] mulu $2,$3,$4 # CHECK: mulu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x99] muhu $2,$3,$4 # CHECK: muhu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd9] Index: test/MC/Mips/mips64r6/invalid-mips1.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips1.s +++ test/MC/Mips/mips64r6/invalid-mips1.s @@ -6,3 +6,15 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$s4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$v0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $9,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $gp,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled +# div has been re-encoded. See valid.s +# divu has been re-encoded. See valid.s Index: test/MC/Mips/mips64r6/invalid-mips2.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips2.s +++ test/MC/Mips/mips64r6/invalid-mips2.s @@ -6,9 +6,21 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$s4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$v0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $9,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $gp,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled teqi $s5,-17504 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgei $s1,5025 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgeiu $sp,-28621 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tlti $14,-21059 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tltiu $ra,-5076 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tnei $12,-29647 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled +# div has been re-encoded. See valid.s +# divu has been re-encoded. See valid.s Index: test/MC/Mips/mips64r6/invalid-mips3.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips3.s +++ test/MC/Mips/mips64r6/invalid-mips3.s @@ -6,9 +6,25 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + dmult $s7,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + dmultu $a1,$a2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$s4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + mult $sp,$v0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $9,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + multu $gp,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled teqi $s5,-17504 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgei $s1,5025 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tgeiu $sp,-28621 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tlti $14,-21059 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tltiu $ra,-5076 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled tnei $12,-29647 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled +# ddiv has been re-encoded. See valid.s +# ddivu has been re-encoded. See valid.s +# div has been re-encoded. See valid.s +# divu has been re-encoded. See valid.s Index: test/MC/Mips/mips64r6/valid.s =================================================================== --- test/MC/Mips/mips64r6/valid.s +++ test/MC/Mips/mips64r6/valid.s @@ -105,7 +105,7 @@ dmodu $2,$3,$4 # CHECK: dmodu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xdf] lwpc $2,268 # CHECK: lwpc $2, 268 # encoding: [0xec,0x48,0x00,0x43] lwupc $2,268 # CHECK: lwupc $2, 268 # encoding: [0xec,0x50,0x00,0x43] -# mul $2,$3,$4 # CHECK-TODO: mul $2, $3, $4 # encoding: [0x00,0x64,0x10,0x98] + mul $2,$3,$4 # CHECK: mul $2, $3, $4 # encoding: [0x00,0x64,0x10,0x98] muh $2,$3,$4 # CHECK: muh $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd8] mulu $2,$3,$4 # CHECK: mulu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x99] muhu $2,$3,$4 # CHECK: muhu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd9]