Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -254,10 +254,10 @@ class ADD_MMR6_DESC : ArithLogicR<"add", GPR32Opnd>; class ADDIU_MMR6_DESC : ArithLogicI<"addiu", simm16, GPR32Opnd>; class ADDU_MMR6_DESC : ArithLogicR<"addu", GPR32Opnd>; -class MUL_MMR6_DESC : ArithLogicR<"mul", GPR32Opnd>; -class MUH_MMR6_DESC : ArithLogicR<"muh", GPR32Opnd>; +class MUL_MMR6_DESC : ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>; +class MUH_MMR6_DESC : ArithLogicR<"muh", GPR32Opnd, 1, II_MUL, mulhs>; class MULU_MMR6_DESC : ArithLogicR<"mulu", GPR32Opnd>; -class MUHU_MMR6_DESC : ArithLogicR<"muhu", GPR32Opnd>; +class MUHU_MMR6_DESC : ArithLogicR<"muhu", GPR32Opnd, 1, II_MUL, mulhu>; class BC_MMR6_DESC_BASE : BRANCH_DESC_BASE, MMR6Arch { Index: lib/Target/Mips/MicroMips64r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrFormats.td +++ lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -84,3 +84,19 @@ let Inst{10-9} = 0b00; let Inst{8-0} = funct; } + +class POOL32S_ARITH_FM_MMR6 funct> + : MMR6Arch, MipsR6Inst { + bits<5> rt; + bits<5> rs; + bits<5> rd; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = rd; + let Inst{10-9} = 0b00; + let Inst{8-0} = funct; +} Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -28,6 +28,10 @@ class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>; class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>; class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>; +class DMUL_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmul", 0x18>; +class DMUH_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuh", 0x58>; +class DMULU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmulu", 0x98>; +class DMUHU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuhu", 0xd8>; //===----------------------------------------------------------------------===// // @@ -90,6 +94,19 @@ class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>; class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>; +class MUL_MM64R6_DESC_BASE { + 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, (Op GPROpnd:$rs, GPROpnd:$rt))]; +} + +class DMUL_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmul", GPR64Opnd, mul>; +class DMUH_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuh", GPR64Opnd, mulhs>; +class DMULU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmulu", GPR64Opnd>; +class DMUHU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuhu", GPR64Opnd, mulhu>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -116,4 +133,12 @@ ISA_MICROMIPS64R6; def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC, ISA_MICROMIPS64R6; + def DMUL_MM64R6: R6MMR6Rel, DMUL_MM64R6_ENC, DMUL_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DMUH_MM64R6: R6MMR6Rel, DMUH_MM64R6_ENC, DMUH_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DMULU_MM64R6: R6MMR6Rel, DMULU_MM64R6_ENC, DMULU_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DMUHU_MM64R6: R6MMR6Rel, DMUHU_MM64R6_ENC, DMUHU_MM64R6_DESC, + ISA_MICROMIPS64R6; } Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -724,10 +724,12 @@ def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT; def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT; } -def MUH : R6MMR6Rel, MUH_ENC, MUH_DESC, ISA_MIPS32R6; -def MUHU : R6MMR6Rel, MUHU_ENC, MUHU_DESC, ISA_MIPS32R6; -def MUL_R6 : R6MMR6Rel, MUL_R6_ENC, MUL_R6_DESC, ISA_MIPS32R6; -def MULU : R6MMR6Rel, MULU_ENC, MULU_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def MUH : R6MMR6Rel, MUH_ENC, MUH_DESC, ISA_MIPS32R6; + def MUHU : R6MMR6Rel, MUHU_ENC, MUHU_DESC, ISA_MIPS32R6; + def MUL_R6 : R6MMR6Rel, MUL_R6_ENC, MUL_R6_DESC, ISA_MIPS32R6; + def MULU : R6MMR6Rel, MULU_ENC, MULU_DESC, ISA_MIPS32R6; +} def NAL; // BAL with rd=0 def PREF_R6 : R6MMR6Rel, PREF_ENC, PREF_DESC, ISA_MIPS32R6; let AdditionalPredicates = [NotInMicroMips] in { Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -381,8 +381,8 @@ // Multiply Doubleword to GPR let Defs = [HI0, LO0, P0, P1, P2] in -def DMUL : ArithLogicR<"dmul", GPR64Opnd, 1, II_DMUL, mul>, - ADD_FM<0x1c, 0x03>; + def DMUL : ArithLogicR<"dmul", GPR64Opnd, 1, II_DMUL, mul>, + ADD_FM<0x1c, 0x03>, ISA_NOT_MICROMIPS_NOT_64R6; // Extract a signed bit field /+32 def EXTS : ExtsCins<"exts">, EXTS_FM<0x3a>; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -95,10 +95,12 @@ def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6; def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6; def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6; -def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6; -def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6; -def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; -def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6; + def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6; + def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; + def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; +} def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6; def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6; def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -333,6 +333,10 @@ let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6]; } +class ISA_NOT_MICROMIPS_NOT_64R6 { + list InsnPredicates = [NotInMicroMips, NotMips64r6]; +} + //===----------------------------------------------------------------------===// class MipsPat : Pat, PredicateControl { Index: test/CodeGen/Mips/llvm-ir/mul.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/mul.ll +++ test/CodeGen/Mips/llvm-ir/mul.ll @@ -22,6 +22,12 @@ ; RUN: -check-prefix=64R1-R5 -check-prefix=GP64 -check-prefix=GP64-NOT-R6 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL \ ; RUN: -check-prefix=64R6 +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips | FileCheck %s \ +; RUN: -check-prefix=MM32 -check-prefix=MM32R3 +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips | FileCheck %s \ +; RUN: -check-prefix=MM32 -check-prefix=MM32R6 +; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips | FileCheck %s \ +; RUN: -check-prefix=64R6 define signext i1 @mul_i1(i1 signext %a, i1 signext %b) { entry: @@ -53,6 +59,10 @@ ; 64R6: sll $[[T0]], $[[T0]], 31 ; 64R6: sra $2, $[[T0]], 31 + ; MM32: mul $[[T0:[0-9]+]], $4, $5 + ; MM32: sll $[[T0]], $[[T0]], 31 + ; MM32: sra $2, $[[T0]], 31 + %r = mul i1 %a, %b ret i1 %r } @@ -90,6 +100,10 @@ ; 64R6: mul $[[T0:[0-9]+]], $4, $5 ; 64R6: seb $2, $[[T0]] + + ; MM32: mul $[[T0:[0-9]+]], $4, $5 + ; MM32: seb $2, $[[T0]] + %r = mul i8 %a, %b ret i8 %r } @@ -127,6 +141,10 @@ ; 64R6: mul $[[T0:[0-9]+]], $4, $5 ; 64R6: seh $2, $[[T0]] + + ; MM32: mul $[[T0:[0-9]+]], $4, $5 + ; MM32: seh $2, $[[T0]] + %r = mul i16 %a, %b ret i16 %r } @@ -143,6 +161,9 @@ ; 64R1-R5: mul $2, $4, $5 ; 64R6: mul $2, $4, $5 + + ; MM32: mul $2, $4, $5 + %r = mul i32 %a, %b ret i32 %r } @@ -184,6 +205,21 @@ ; 64R6: dmul $2, $4, $5 + ; MM32R3: multu $[[T0:[0-9]+]], $7 + ; MM32R3: mflo $[[T1:[0-9]+]] + ; MM32R3: mfhi $[[T2:[0-9]+]] + ; MM32R3: mul $[[T3:[0-9]+]], $4, $7 + ; MM32R3: mul $[[T0]], $[[T0]], $6 + ; MM32R3: addu16 $[[T2]], $[[T2]], $[[T0]] + ; MM32R3: addu16 $2, $[[T2]], $[[T3]] + + ; MM32R6: mul $[[T0:[0-9]+]], $5, $7 + ; MM32R6: mul $[[T1:[0-9]+]], $4, $7 + ; MM32R6: mul $[[T2:[0-9]+]], $5, $6 + ; MM32R6: muhu $[[T3:[0-9]+]], $5, $7 + ; MM32R6: addu16 $[[T2]], $[[T3]], $[[T2]] + ; MM32R6: addu16 $2, $[[T2]], $[[T1]] + %r = mul i64 %a, %b ret i64 %r } @@ -211,6 +247,8 @@ ; 64R6: daddu $2, $[[T2]], $[[T3]] ; 64R6: dmul $3, $5, $7 + ; MM32: lw $25, %call16(__multi3)($2) + %r = mul i128 %a, %b ret i128 %r } Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -169,3 +169,11 @@ 0x00 0x00 0xe3 0x7c # CHECK: deret 0x00 0x00 0x47 0x7c # CHECK: di 0x00 0x0f 0x47 0x7c # CHECK: di $15 +0x00 0xa4 0x18 0x18 # CHECK: mul $3, $4, $5 +0x00 0xa4 0x18 0x58 # CHECK: muh $3, $4, $5 +0x00 0xa4 0x18 0x98 # CHECK: mulu $3, $4, $5 +0x00 0xa4 0x18 0xd8 # CHECK: muhu $3, $4, $5 +0x58 0xa4 0x18 0x18 # CHECK: dmul $3, $4, $5 +0x58 0xa4 0x18 0x58 # CHECK: dmuh $3, $4, $5 +0x58 0xa4 0x18 0x98 # CHECK: dmulu $3, $4, $5 +0x58 0xa4 0x18 0xd8 # CHECK: dmuhu $3, $4, $5 Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -150,5 +150,13 @@ di # CHECK: di # encoding: [0x00,0x00,0x47,0x7c] di $0 # CHECK: di # encoding: [0x00,0x00,0x47,0x7c] di $15 # CHECK: di $15 # encoding: [0x00,0x0f,0x47,0x7c] + mul $3, $4, $5 # CHECK mul $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x18] + muh $3, $4, $5 # CHECK muh $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x58] + mulu $3, $4, $5 # CHECK mulu $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x98] + muhu $3, $4, $5 # CHECK muhu $3, $4, $5 # encoding: [0x00,0xa4,0x18,0xd8] + dmul $3, $4, $5 # CHECK dmul $3, $4, $5 # encoding: [0x58,0xa4,0x18,0x18] + dmuh $3, $4, $5 # CHECK dmuh $3, $4, $5 # encoding: [0x58,0xa4,0x18,0x58] + dmulu $3, $4, $5 # CHECK dmulu $3, $4, $5 # encoding: [0x58,0xa4,0x18,0x98] + dmuhu $3, $4, $5 # CHECK dmuhu $3, $4, $5 # encoding: [0x58,0xa4,0x18,0xd8] 1: