[mips][microMIPS] Add CodeGen support for MUL* and DMUL* instructions

Differential Revision: http://reviews.llvm.org/D15744

llvm-svn: 268714
This commit is contained in:
Zlatko Buljan 2016-05-06 08:24:14 +00:00
parent 6dccd5bc1f
commit 31c9ebe281
8 changed files with 106 additions and 20 deletions

View File

@ -304,10 +304,10 @@ class CVT_S_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.l", 2, 0b1101101>;
class ADD_MMR6_DESC : ArithLogicR<"add", GPR32Opnd>;
class ADDIU_MMR6_DESC : ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, add>;
class ADDU_MMR6_DESC : ArithLogicR<"addu", GPR32Opnd>;
class MUL_MMR6_DESC : ArithLogicR<"mul", GPR32Opnd>;
class MUH_MMR6_DESC : ArithLogicR<"muh", GPR32Opnd>;
class MULU_MMR6_DESC : ArithLogicR<"mulu", GPR32Opnd>;
class MUHU_MMR6_DESC : ArithLogicR<"muhu", GPR32Opnd>;
class MUL_MMR6_DESC : ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>;
class MUH_MMR6_DESC : ArithLogicR<"muh", GPR32Opnd, 1, II_MUH, mulhs>;
class MULU_MMR6_DESC : ArithLogicR<"mulu", GPR32Opnd, 1, II_MULU>;
class MUHU_MMR6_DESC : ArithLogicR<"muhu", GPR32Opnd, 1, II_MUHU, mulhu>;
class BC_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd>
: BRANCH_DESC_BASE, MMR6Arch<instr_asm> {

View File

@ -43,6 +43,10 @@ class DADDU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"daddu", 0b101010000>;
class LDPC_MMR646_ENC : PCREL18_FM_MMR6<0b110>;
class DSUB_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dsub", 0b110010000>;
class DSUBU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dsubu", 0b111010000>;
class DMUL_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmul", 0b000011000>;
class DMUH_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuh", 0b001011000>;
class DMULU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmulu", 0b010011000>;
class DMUHU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuhu", 0b011011000>;
//===----------------------------------------------------------------------===//
//
@ -146,6 +150,23 @@ class DSUBU_MM64R6_DESC : DSUB_DESC_BASE<"dsubu", GPR64Opnd, II_DSUBU, sub>;
class LDPC_MM64R6_DESC : PCREL_MMR6_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3>;
class MUL_MM64R6_DESC_BASE<string opstr, RegisterOperand GPROpnd,
InstrItinClass Itin = NoItinerary,
SDPatternOperator Op = null_frag> : MipsR6Inst {
dag OutOperandList = (outs GPROpnd:$rd);
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt);
string AsmString = !strconcat(opstr, "\t$rd, $rs, $rt");
InstrItinClass Itinerary = Itin;
list<dag> Pattern = [(set GPROpnd:$rd, (Op GPROpnd:$rs, GPROpnd:$rt))];
}
class DMUL_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmul", GPR64Opnd, II_DMUL, mul>;
class DMUH_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuh", GPR64Opnd, II_DMUH,
mulhs>;
class DMULU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmulu", GPR64Opnd, II_DMULU>;
class DMUHU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuhu", GPR64Opnd, II_DMUHU,
mulhu>;
//===----------------------------------------------------------------------===//
//
// Instruction Definitions
@ -202,6 +223,14 @@ let DecoderNamespace = "MicroMipsR6" in {
ISA_MICROMIPS64R6;
def DSUBU_MM64R6 : StdMMR6Rel, DSUBU_MM64R6_DESC, DSUBU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMUL_MM64R6 : R6MMR6Rel, DMUL_MM64R6_DESC, DMUL_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMUH_MM64R6 : R6MMR6Rel, DMUH_MM64R6_DESC, DMUH_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMULU_MM64R6 : R6MMR6Rel, DMULU_MM64R6_DESC, DMULU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMUHU_MM64R6 : R6MMR6Rel, DMUHU_MM64R6_DESC, DMUHU_MM64R6_ENC,
ISA_MICROMIPS64R6;
}
//===----------------------------------------------------------------------===//

View File

@ -775,19 +775,18 @@ let AdditionalPredicates = [NotInMicroMips] in {
def MINA_S : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT;
def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT;
}
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;
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 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 {

View File

@ -220,10 +220,12 @@ def PseudoReturn64 : PseudoReturnBase<GPR64Opnd>;
def PseudoIndirectBranch64 : PseudoIndirectBranchBase<GPR64Opnd>;
/// Multiply and Divide Instructions.
def DMULT : Mult<"dmult", II_DMULT, GPR64Opnd, [HI0_64, LO0_64]>,
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_NOT_32R6_64R6;
let AdditionalPredicates = [NotInMicroMips] in {
def DMULT : Mult<"dmult", II_DMULT, GPR64Opnd, [HI0_64, LO0_64]>,
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_NOT_32R6_64R6;
}
def PseudoDMULT : MultDivPseudo<DMULT, ACC128, GPR64Opnd, MipsMult,
II_DMULT>, ISA_MIPS3_NOT_32R6_64R6;
def PseudoDMULTu : MultDivPseudo<DMULTu, ACC128, GPR64Opnd, MipsMultu,

View File

@ -110,10 +110,12 @@ let AdditionalPredicates = [NotInMicroMips] in {
def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6;
}
def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_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: R6MMR6Rel, 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;

View File

@ -22,6 +22,12 @@
; RUN: -check-prefix=64R1-R5 -check-prefix=GP64 -check-prefix=GP64-NOT-R6
; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s -check-prefix=ALL \
; RUN: -check-prefix=64R6
; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic | FileCheck %s \
; RUN: -check-prefix=MM32 -check-prefix=MM32R3
; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \
; RUN: -check-prefix=MM32 -check-prefix=MM32R6
; RUN: llc < %s -march=mips -mcpu=mips64r6 -mattr=+micromips -relocation-model=pic | FileCheck %s \
; RUN: -check-prefix=64R6
define signext i1 @mul_i1(i1 signext %a, i1 signext %b) {
entry:
@ -53,6 +59,10 @@ entry:
; 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 @@ entry:
; 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 @@ entry:
; 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 @@ entry:
; 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 @@ entry:
; 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 @@ entry:
; 64R6: daddu $[[T3:[0-9]+]], $[[T2]], $[[T1]]
; 64R6: daddu $2, $[[T1]], $[[T0]]
; MM32: lw $25, %call16(__multi3)($2)
%r = mul i128 %a, %b
ret i128 %r
}

View File

@ -248,3 +248,11 @@
0x59 0x40 0x51 0x90 # CHECK: dneg $10, $10
0x59 0x60 0x09 0xd0 # CHECK: dnegu $1, $11
0x58 0xa0 0x29 0xd0 # CHECK: dnegu $5, $5
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

View File

@ -251,5 +251,13 @@ a:
dneg $10 # CHECK: dneg $10, $10 # encoding: [0x59,0x40,0x51,0x90]
dnegu $1, $11 # CHECK: dnegu $1, $11 # encoding: [0x59,0x60,0x09,0xd0]
dnegu $5 # CHECK: dnegu $5, $5 # encoding: [0x58,0xa0,0x29,0xd0]
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: