diff options
author | Zlatko Buljan <Zlatko.Buljan@imgtec.com> | 2016-05-06 08:24:14 +0000 |
---|---|---|
committer | Zlatko Buljan <Zlatko.Buljan@imgtec.com> | 2016-05-06 08:24:14 +0000 |
commit | 31c9ebe2818b0a47a45867732d946356ca80423e (patch) | |
tree | 40d25a96d719a17219b39af82e78859605d8415e | |
parent | 6dccd5bc1f35a15403dd9b1f1f9ccc75d5394a2f (diff) | |
download | bcm5719-llvm-31c9ebe2818b0a47a45867732d946356ca80423e.tar.gz bcm5719-llvm-31c9ebe2818b0a47a45867732d946356ca80423e.zip |
[mips][microMIPS] Add CodeGen support for MUL* and DMUL* instructions
Differential Revision: http://reviews.llvm.org/D15744
llvm-svn: 268714
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td | 29 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 15 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/llvm-ir/mul.ll | 38 | ||||
-rw-r--r-- | llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt | 8 | ||||
-rw-r--r-- | llvm/test/MC/Mips/micromips64r6/valid.s | 8 |
8 files changed, 106 insertions, 20 deletions
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 9c78d77bd36..8df942fec4a 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -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> { diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td index 45b1522d8be..29de4ceefd0 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -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; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index f249ff2d610..8bd7b7be90f 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -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 { diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 19be533401c..8cb0589dc68 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -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, diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index 0c2039da410..3a474b204b7 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -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; diff --git a/llvm/test/CodeGen/Mips/llvm-ir/mul.ll b/llvm/test/CodeGen/Mips/llvm-ir/mul.ll index f270d715f65..fa1d200320f 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/mul.ll +++ b/llvm/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 -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 } diff --git a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt index 0a41c5d9c76..757e6e3d103 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -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 diff --git a/llvm/test/MC/Mips/micromips64r6/valid.s b/llvm/test/MC/Mips/micromips64r6/valid.s index 2f47229b5fc..45172a796e9 100644 --- a/llvm/test/MC/Mips/micromips64r6/valid.s +++ b/llvm/test/MC/Mips/micromips64r6/valid.s @@ -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: |