mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
[mips][microMIPS] Add CodeGen support for MUL* and DMUL* instructions
Differential Revision: http://reviews.llvm.org/D15744 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268714 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
886b4ecfe7
commit
76237bdeea
@ -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> {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user