mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[ARM] Refactor Thumb2 Mul and Mla instr descs
Recommitting after r274347 was reverted. This patch introduces some classes to refactor the 3 and 4 register Thumb2 multiplication instruction descriptions, plus improved tests for some of those instructions. Differential Revision: https://reviews.llvm.org/D21929 llvm-svn: 275979
This commit is contained in:
parent
b0f149dd81
commit
de7eeee861
@ -536,9 +536,9 @@ class T2FourReg<dag oops, dag iops, InstrItinClass itin,
|
||||
}
|
||||
|
||||
class T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
|
||||
dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: T2I<oops, iops, itin, opc, asm, pattern> {
|
||||
string opc, list<dag> pattern>
|
||||
: T2I<(outs rGPR:$RdLo, rGPR:$RdHi), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
|
||||
opc, "\t$RdLo, $RdHi, $Rn, $Rm", pattern> {
|
||||
bits<4> RdLo;
|
||||
bits<4> RdHi;
|
||||
bits<4> Rn;
|
||||
@ -552,10 +552,11 @@ class T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
|
||||
let Inst{7-4} = opc7_4;
|
||||
let Inst{3-0} = Rm;
|
||||
}
|
||||
class T2MlaLong<bits<3> opc22_20, bits<4> opc7_4,
|
||||
dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: T2I<oops, iops, itin, opc, asm, pattern> {
|
||||
class T2MlaLong<bits<3> opc22_20, bits<4> opc7_4, string opc>
|
||||
: T2I<(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
|
||||
opc, "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||
RegConstraint<"$RLo = $RdLo, $RHi = $RdHi"> {
|
||||
bits<4> RdLo;
|
||||
bits<4> RdHi;
|
||||
bits<4> Rn;
|
||||
@ -2544,367 +2545,182 @@ def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
|
||||
let Inst{7-4} = 0b0000; // Multiply
|
||||
}
|
||||
|
||||
def t2MLA: T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"mla", "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]>,
|
||||
Requires<[IsThumb2, UseMulOps]> {
|
||||
class T2FourRegMLA<bits<4> op7_4, string opc, list<dag> pattern>
|
||||
: T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>,
|
||||
Requires<[IsThumb2, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b000;
|
||||
let Inst{7-4} = 0b0000; // Multiply
|
||||
let Inst{7-4} = op7_4;
|
||||
}
|
||||
|
||||
def t2MLS: T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"mls", "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]>,
|
||||
Requires<[IsThumb2, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b000;
|
||||
let Inst{7-4} = 0b0001; // Multiply and Subtract
|
||||
}
|
||||
def t2MLA : T2FourRegMLA<0b0000, "mla",
|
||||
[(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm),
|
||||
rGPR:$Ra))]>;
|
||||
def t2MLS: T2FourRegMLA<0b0001, "mls",
|
||||
[(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn,
|
||||
rGPR:$Rm)))]>;
|
||||
|
||||
// Extra precision multiplies with low / high results
|
||||
let hasSideEffects = 0 in {
|
||||
let isCommutable = 1 in {
|
||||
def t2SMULL : T2MulLong<0b000, 0b0000,
|
||||
(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
|
||||
"smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
|
||||
|
||||
def t2UMULL : T2MulLong<0b010, 0b0000,
|
||||
(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
|
||||
"umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
|
||||
def t2SMULL : T2MulLong<0b000, 0b0000, "smull", []>;
|
||||
def t2UMULL : T2MulLong<0b010, 0b0000, "umull", []>;
|
||||
} // isCommutable
|
||||
|
||||
// Multiply + accumulate
|
||||
def t2SMLAL : T2MlaLong<0b100, 0b0000,
|
||||
(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
|
||||
"smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||
RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">;
|
||||
|
||||
def t2UMLAL : T2MlaLong<0b110, 0b0000,
|
||||
(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
|
||||
"umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||
RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">;
|
||||
|
||||
def t2UMAAL : T2MulLong<0b110, 0b0110,
|
||||
(outs rGPR:$RdLo, rGPR:$RdHi),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
|
||||
"umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||
RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLAL : T2MlaLong<0b100, 0b0000, "smlal">;
|
||||
def t2UMLAL : T2MlaLong<0b110, 0b0000, "umlal">;
|
||||
def t2UMAAL : T2MlaLong<0b110, 0b0110, "umaal">, Requires<[IsThumb2, HasDSP]>;
|
||||
} // hasSideEffects
|
||||
|
||||
// Rounding variants of the below included for disassembly only
|
||||
|
||||
// Most significant word multiply
|
||||
def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
|
||||
"smmul", "\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
class T2SMMUL<bits<4> op7_4, string opc, list<dag> pattern>
|
||||
: T2ThreeReg<(outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
|
||||
opc, "\t$Rd, $Rn, $Rm", pattern>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b101;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
|
||||
let Inst{7-4} = op7_4;
|
||||
}
|
||||
def t2SMMUL : T2SMMUL<0b0000, "smmul", [(set rGPR:$Rd, (mulhs rGPR:$Rn,
|
||||
rGPR:$Rm))]>;
|
||||
def t2SMMULR : T2SMMUL<0b0001, "smmulr", []>;
|
||||
|
||||
def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
|
||||
"smmulr", "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b101;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
|
||||
}
|
||||
|
||||
def t2SMMLA : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"smmla", "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>,
|
||||
class T2FourRegSMMLA<bits<3> op22_20, bits<4> op7_4, string opc,
|
||||
list<dag> pattern>
|
||||
: T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b101;
|
||||
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
|
||||
let Inst{22-20} = op22_20;
|
||||
let Inst{7-4} = op7_4;
|
||||
}
|
||||
|
||||
def t2SMMLAR: T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b101;
|
||||
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
|
||||
def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla",
|
||||
[(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>;
|
||||
def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>;
|
||||
def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls",
|
||||
[(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>;
|
||||
def t2SMMLSR:T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>;
|
||||
|
||||
class T2ThreeRegSMUL<bits<3> op22_20, bits<2> op5_4, string opc,
|
||||
list<dag> pattern>
|
||||
: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, opc,
|
||||
"\t$Rd, $Rn, $Rm", pattern>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = op22_20;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = op5_4;
|
||||
}
|
||||
|
||||
def t2SMMLS: T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"smmls", "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b110;
|
||||
let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
|
||||
def t2SMULBB : T2ThreeRegSMUL<0b001, 0b00, "smulbb",
|
||||
[(set rGPR:$Rd, (mul (sext_inreg rGPR:$Rn, i16),
|
||||
(sext_inreg rGPR:$Rm, i16)))]>;
|
||||
def t2SMULBT : T2ThreeRegSMUL<0b001, 0b01, "smulbt",
|
||||
[(set rGPR:$Rd, (mul (sext_inreg rGPR:$Rn, i16),
|
||||
(sra rGPR:$Rm, (i32 16))))]>;
|
||||
def t2SMULTB : T2ThreeRegSMUL<0b001, 0b10, "smultb",
|
||||
[(set rGPR:$Rd, (mul (sra rGPR:$Rn, (i32 16)),
|
||||
(sext_inreg rGPR:$Rm, i16)))]>;
|
||||
def t2SMULTT : T2ThreeRegSMUL<0b001, 0b11, "smultt",
|
||||
[(set rGPR:$Rd, (mul (sra rGPR:$Rn, (i32 16)),
|
||||
(sra rGPR:$Rm, (i32 16))))]>;
|
||||
def t2SMULWB : T2ThreeRegSMUL<0b011, 0b00, "smulwb", []>;
|
||||
def t2SMULWT : T2ThreeRegSMUL<0b011, 0b01, "smulwt", []>;
|
||||
|
||||
class T2FourRegSMLA<bits<2> op5_4, string opc, list<dag> pattern>
|
||||
: T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMUL16,
|
||||
opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = op5_4;
|
||||
}
|
||||
|
||||
def t2SMMLSR:T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
|
||||
"smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b110;
|
||||
let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
|
||||
def t2SMLABB : T2FourRegSMLA<0b00, "smlabb",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra,
|
||||
(mul (sext_inreg rGPR:$Rn, i16),
|
||||
(sext_inreg rGPR:$Rm, i16))))]>;
|
||||
def t2SMLABT : T2FourRegSMLA<0b01, "smlabt",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (mul (sext_inreg rGPR:$Rn, i16),
|
||||
(sra rGPR:$Rm, (i32 16)))))]>;
|
||||
def t2SMLATB : T2FourRegSMLA<0b10, "smlatb",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (mul (sra rGPR:$Rn, (i32 16)),
|
||||
(sext_inreg rGPR:$Rm, i16))))]>;
|
||||
def t2SMLATT : T2FourRegSMLA<0b11, "smlatt",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (mul (sra rGPR:$Rn, (i32 16)),
|
||||
(sra rGPR:$Rm, (i32 16)))))]>;
|
||||
def t2SMLAWB : T2FourRegSMLA<0b00, "smlawb", []> {
|
||||
let Inst{22-20} = 0b011;
|
||||
}
|
||||
def t2SMLAWT : T2FourRegSMLA<0b01, "smlawt", []> {
|
||||
let Inst{22-20} = 0b011;
|
||||
}
|
||||
|
||||
multiclass T2I_smul<string opc, SDNode opnode> {
|
||||
def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
|
||||
(sext_inreg rGPR:$Rm, i16)))]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b00;
|
||||
}
|
||||
|
||||
def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
|
||||
(sra rGPR:$Rm, (i32 16))))]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b01;
|
||||
}
|
||||
|
||||
def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
|
||||
(sext_inreg rGPR:$Rm, i16)))]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b10;
|
||||
}
|
||||
|
||||
def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
|
||||
(sra rGPR:$Rm, (i32 16))))]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b11;
|
||||
}
|
||||
|
||||
def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
|
||||
[]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b011;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b00;
|
||||
}
|
||||
|
||||
def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
|
||||
!strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
|
||||
[]>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b011;
|
||||
let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
multiclass T2I_smla<string opc, SDNode opnode> {
|
||||
def BB : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra,
|
||||
(opnode (sext_inreg rGPR:$Rn, i16),
|
||||
(sext_inreg rGPR:$Rm, i16))))]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b00;
|
||||
}
|
||||
|
||||
def BT : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
|
||||
(sra rGPR:$Rm, (i32 16)))))]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b01;
|
||||
}
|
||||
|
||||
def TB : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
|
||||
(sext_inreg rGPR:$Rm, i16))))]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b10;
|
||||
}
|
||||
|
||||
def TT : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
|
||||
(sra rGPR:$Rm, (i32 16)))))]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b001;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b11;
|
||||
}
|
||||
|
||||
def WB : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b011;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b00;
|
||||
}
|
||||
|
||||
def WT : T2FourReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
|
||||
!strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
|
||||
[]>,
|
||||
Requires<[IsThumb2, HasDSP, UseMulOps]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0110;
|
||||
let Inst{22-20} = 0b011;
|
||||
let Inst{7-6} = 0b00;
|
||||
let Inst{5-4} = 0b01;
|
||||
}
|
||||
}
|
||||
|
||||
defm t2SMUL : T2I_smul<"smul", mul>;
|
||||
defm t2SMLA : T2I_smla<"smla", mul>;
|
||||
class T2SMLAL<bits<3> op22_20, bits<4> op7_4, string opc, list<dag> pattern>
|
||||
: T2FourReg_mac<1, op22_20, op7_4,
|
||||
(outs rGPR:$Ra, rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC64, opc, "\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
|
||||
// Halfword multiple accumulate long: SMLAL<x><y>
|
||||
def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
|
||||
[/* For disassembly only; pattern left blank */]>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALBB : T2SMLAL<0b100, 0b1000, "smlalbb", []>;
|
||||
def t2SMLALBT : T2SMLAL<0b100, 0b1001, "smlalbt", []>;
|
||||
def t2SMLALTB : T2SMLAL<0b100, 0b1010, "smlaltb", []>;
|
||||
def t2SMLALTT : T2SMLAL<0b100, 0b1011, "smlaltt", []>;
|
||||
|
||||
class T2DualHalfMul<bits<3> op22_20, bits<4> op7_4, string opc>
|
||||
: T2ThreeReg_mac<0, op22_20, op7_4,
|
||||
(outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC32, opc, "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
|
||||
// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
|
||||
def t2SMUAD: T2ThreeReg_mac<
|
||||
0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUADX:T2ThreeReg_mac<
|
||||
0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUSD: T2ThreeReg_mac<
|
||||
0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUSDX:T2ThreeReg_mac<
|
||||
0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMLAD : T2FourReg_mac<
|
||||
0, 0b010, 0b0000, (outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
|
||||
"\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLADX : T2FourReg_mac<
|
||||
0, 0b010, 0b0001, (outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
|
||||
"\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
|
||||
"\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
|
||||
"\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, "smlald",
|
||||
"\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaldx",
|
||||
"\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlsld",
|
||||
"\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
|
||||
(ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
|
||||
"\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
def t2SMUAD: T2DualHalfMul<0b010, 0b0000, "smuad">;
|
||||
def t2SMUADX: T2DualHalfMul<0b010, 0b0001, "smuadx">;
|
||||
def t2SMUSD: T2DualHalfMul<0b100, 0b0000, "smusd">;
|
||||
def t2SMUSDX: T2DualHalfMul<0b100, 0b0001, "smusdx">;
|
||||
|
||||
class T2DualHalfMulAdd<bits<3> op22_20, bits<4> op7_4, string opc>
|
||||
: T2FourReg_mac<0, op22_20, op7_4,
|
||||
(outs rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra),
|
||||
IIC_iMAC32, opc, "\t$Rd, $Rn, $Rm, $Ra", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
|
||||
def t2SMLAD : T2DualHalfMulAdd<0b010, 0b0000, "smlad">;
|
||||
def t2SMLADX : T2DualHalfMulAdd<0b010, 0b0001, "smladx">;
|
||||
def t2SMLSD : T2DualHalfMulAdd<0b100, 0b0000, "smlsd">;
|
||||
def t2SMLSDX : T2DualHalfMulAdd<0b100, 0b0001, "smlsdx">;
|
||||
|
||||
class T2DualHalfMulAddLong<bits<3> op22_20, bits<4> op7_4, string opc>
|
||||
: T2FourReg_mac<1, op22_20, op7_4,
|
||||
(outs rGPR:$Ra, rGPR:$Rd),
|
||||
(ins rGPR:$Rn, rGPR:$Rm),
|
||||
IIC_iMAC64, opc, "\t$Ra, $Rd, $Rn, $Rm", []>,
|
||||
Requires<[IsThumb2, HasDSP]>;
|
||||
|
||||
def t2SMLALD : T2DualHalfMulAddLong<0b100, 0b1100, "smlald">;
|
||||
def t2SMLALDX : T2DualHalfMulAddLong<0b100, 0b1101, "smlaldx">;
|
||||
def t2SMLSLD : T2DualHalfMulAddLong<0b101, 0b1100, "smlsld">;
|
||||
def t2SMLSLDX : T2DualHalfMulAddLong<0b101, 0b1101, "smlsldx">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Division Instructions.
|
||||
|
@ -2,6 +2,8 @@
|
||||
; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7-LE
|
||||
; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
|
||||
; RUN: llc -mtriple=armebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-BE
|
||||
; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB
|
||||
; RUN: llc -mtriple=thumbebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB-BE
|
||||
; Check generated signed and unsigned multiply accumulate long.
|
||||
|
||||
define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) {
|
||||
@ -118,8 +120,18 @@ define i64 @MACLongTest8(i64 %acc, i32 %lhs, i32 %rhs) {
|
||||
|
||||
define i64 @MACLongTest9(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) {
|
||||
;CHECK-LABEL: MACLongTest9:
|
||||
;CHECK-V7-LE:umaal
|
||||
;CHECK-V7-BE:umaal
|
||||
;CHECK-V7-LE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-LE: mov r0, [[RDLO]]
|
||||
;CHECK-V7-LE: mov r1, [[RDHI]]
|
||||
;CHECK-V7-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-BE: mov r0, [[RDHI]]
|
||||
;CHECK-V7-BE: mov r1, [[RDLO]]
|
||||
;CHECK-V7-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-THUMB: mov r0, [[RDLO]]
|
||||
;CHECK-V7-THUMB: mov r1, [[RDHI]]
|
||||
;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-THUMB-BE: mov r0, [[RDHI]]
|
||||
;CHECK-V7-THUMB-BE: mov r1, [[RDLO]]
|
||||
;CHECK-NOT:umaal
|
||||
%conv = zext i32 %lhs to i64
|
||||
%conv1 = zext i32 %rhs to i64
|
||||
@ -133,8 +145,18 @@ define i64 @MACLongTest9(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) {
|
||||
|
||||
define i64 @MACLongTest10(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) {
|
||||
;CHECK-LABEL: MACLongTest10:
|
||||
;CHECK-V7-LE:umaal
|
||||
;CHECK-V7-BE:umaal
|
||||
;CHECK-V7-LE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-LE: mov r0, [[RDLO]]
|
||||
;CHECK-V7-LE: mov r1, [[RDHI]]
|
||||
;CHECK-V7-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-BE: mov r0, [[RDHI]]
|
||||
;CHECK-V7-BE: mov r1, [[RDLO]]
|
||||
;CHECK-V7-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-THUMB: mov r0, [[RDLO]]
|
||||
;CHECK-V7-THUMB: mov r1, [[RDHI]]
|
||||
;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]]
|
||||
;CHECK-V7-THUMB-BE: mov r0, [[RDHI]]
|
||||
;CHECK-V7-THUMB-BE: mov r1, [[RDLO]]
|
||||
;CHECK-NOT:umaal
|
||||
%conv = zext i32 %lhs to i64
|
||||
%conv1 = zext i32 %rhs to i64
|
||||
|
Loading…
Reference in New Issue
Block a user