Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -536,9 +536,9 @@ } class T2MulLong opc22_20, bits<4> opc7_4, - dag oops, dag iops, InstrItinClass itin, - string opc, string asm, list pattern> - : T2I { + string opc, list 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 @@ let Inst{7-4} = opc7_4; let Inst{3-0} = Rm; } -class T2MlaLong opc22_20, bits<4> opc7_4, - dag oops, dag iops, InstrItinClass itin, - string opc, string asm, list pattern> - : T2I { +class T2MlaLong 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,183 @@ 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 op7_4, string opc, list 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]> { - 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) -} - -def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, - "smmulr", "\t$Rd, $Rn, $Rm", []>, - Requires<[IsThumb2, HasDSP]> { +class T2SMMUL op7_4, string opc, list 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} = 0b0001; // Rounding (Inst{4} = 1) + 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 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 op22_20, bits<4> op7_4, string opc, + list 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) -} - -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 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 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) + let Inst{22-20} = op22_20; + let Inst{7-4} = op7_4; } -multiclass T2I_smul { - 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 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", []>; - 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]> { +class T2ThreeRegSMUL op22_20, bits<2> op5_4, string opc, + list 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} = 0b011; + let Inst{22-20} = op22_20; let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) let Inst{7-6} = 0b00; - let Inst{5-4} = 0b01; - } -} - - -multiclass T2I_smla { - 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{5-4} = op5_4; +} + +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 op5_4, string opc, list 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} = 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>; + let Inst{5-4} = op5_4; +} + +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; +} + +class T2SMLAL op22_20, bits<4> op7_4, string opc, list 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 -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]>; - -// 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]> { +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 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; } -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]>; + +// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD +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 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 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. Index: test/CodeGen/ARM/longMAC.ll =================================================================== --- test/CodeGen/ARM/longMAC.ll +++ test/CodeGen/ARM/longMAC.ll @@ -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 @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 @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