Index: lib/Target/Hexagon/HexagonIntrinsics.td =================================================================== --- lib/Target/Hexagon/HexagonIntrinsics.td +++ lib/Target/Hexagon/HexagonIntrinsics.td @@ -13,10 +13,12 @@ // March 4, 2008 //===----------------------------------------------------------------------===// -// MTYPE / MPYS / Scalar 16x16 multiply signed/unsigned. +//===----------------------------------------------------------------------===// +// Template Class +// MPYS / Multipy signed/unsigned halfwords //Rd=mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:rnd][:sat] +//===----------------------------------------------------------------------===// -// M2_mpyu_lh_s1: let hasNewValue = 1, opNewValue = 0 in class T_M2_mpy < bits<2> LHbits, bit isSat, bit isRnd, bit hasShift, bit isUnsigned, Intrinsic IntID > @@ -92,7 +94,7 @@ T_M2_mpy <0b11, 1, 0, 0, 0, int_hexagon_M2_mpy_sat_hh_s0>; } -//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1][:rnd] +//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1]:rnd def HEXAGON_M2_mpy_rnd_ll_s1 : T_M2_mpy <0b00, 0, 1, 1, 0, int_hexagon_M2_mpy_rnd_ll_s1>; def HEXAGON_M2_mpy_rnd_ll_s0 : @@ -130,6 +132,149 @@ T_M2_mpy <0b11, 1, 1, 0, 0, int_hexagon_M2_mpy_sat_rnd_hh_s0>; } + +//===----------------------------------------------------------------------===// +// Template Class +// MPYS / Multipy signed/unsigned halfwords and add/subtract the +// result from the accumulator. +//Rx [-+]= mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:sat] +//===----------------------------------------------------------------------===// + +let hasNewValue = 1, opNewValue = 0 in +class T_M2_mpy_acc < bits<2> LHbits, bit isSat, bit isNac, + bit hasShift, bit isUnsigned, Intrinsic IntID > + : MInst_acc<(outs IntRegs:$Rx), (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt), + "$Rx "#!if(isNac,"-= ","+= ")#!if(isUnsigned,"mpyu","mpy") + #"($Rs."#!if(LHbits{1},"h","l") + #", $Rt."#!if(LHbits{0},"h)","l)") + #!if(hasShift,":<<1","") + #!if(isSat,":sat",""), + [(set IntRegs:$Rx, (IntID IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt))] , + "$dst2 = $Rx", M_tc_3x_SLOT23 > { + bits<5> Rx; + bits<5> Rs; + bits<5> Rt; + + let IClass = 0b1110; + let Inst{27-24} = 0b1110; + let Inst{23} = hasShift; + let Inst{22} = isUnsigned; + let Inst{21} = isNac; + let Inst{7} = isSat; + let Inst{6-5} = LHbits; + let Inst{4-0} = Rx; + let Inst{20-16} = Rs; + let Inst{12-8} = Rt; + } + +//Rx += mpy(Rs.[H|L],Rt.[H|L])[:<<1] +def HEXAGON_M2_mpy_acc_ll_s1 : + T_M2_mpy_acc < 0b00, 0, 0, 1, 0, int_hexagon_M2_mpy_acc_ll_s1>; +def HEXAGON_M2_mpy_acc_ll_s0 : + T_M2_mpy_acc < 0b00, 0, 0, 0, 0, int_hexagon_M2_mpy_acc_ll_s0>; +def HEXAGON_M2_mpy_acc_lh_s1 : + T_M2_mpy_acc < 0b01, 0, 0, 1, 0, int_hexagon_M2_mpy_acc_lh_s1>; +def HEXAGON_M2_mpy_acc_lh_s0 : + T_M2_mpy_acc < 0b01, 0, 0, 0, 0, int_hexagon_M2_mpy_acc_lh_s0>; +def HEXAGON_M2_mpy_acc_hl_s1 : + T_M2_mpy_acc < 0b10, 0, 0, 1, 0, int_hexagon_M2_mpy_acc_hl_s1>; +def HEXAGON_M2_mpy_acc_hl_s0 : + T_M2_mpy_acc < 0b10, 0, 0, 0, 0, int_hexagon_M2_mpy_acc_hl_s0>; +def HEXAGON_M2_mpy_acc_hh_s1 : + T_M2_mpy_acc < 0b11, 0, 0, 1, 0, int_hexagon_M2_mpy_acc_hh_s1>; +def HEXAGON_M2_mpy_acc_hh_s0 : + T_M2_mpy_acc < 0b11, 0, 0, 0, 0, int_hexagon_M2_mpy_acc_hh_s0>; + +//Rx += mpyu(Rs.[H|L],Rt.[H|L])[:<<1] +def HEXAGON_M2_mpyu_acc_ll_s1 : + T_M2_mpy_acc < 0b00, 0, 0, 1, 1, int_hexagon_M2_mpyu_acc_ll_s1>; +def HEXAGON_M2_mpyu_acc_ll_s0 : + T_M2_mpy_acc < 0b00, 0, 0, 0, 1, int_hexagon_M2_mpyu_acc_ll_s0>; +def HEXAGON_M2_mpyu_acc_lh_s1 : + T_M2_mpy_acc < 0b01, 0, 0, 1, 1, int_hexagon_M2_mpyu_acc_lh_s1>; +def HEXAGON_M2_mpyu_acc_lh_s0 : + T_M2_mpy_acc < 0b01, 0, 0, 0, 1, int_hexagon_M2_mpyu_acc_lh_s0>; +def HEXAGON_M2_mpyu_acc_hl_s1 : + T_M2_mpy_acc < 0b10, 0, 0, 1, 1, int_hexagon_M2_mpyu_acc_hl_s1>; +def HEXAGON_M2_mpyu_acc_hl_s0 : + T_M2_mpy_acc < 0b10, 0, 0, 0, 1, int_hexagon_M2_mpyu_acc_hl_s0>; +def HEXAGON_M2_mpyu_acc_hh_s1 : + T_M2_mpy_acc < 0b11, 0, 0, 1, 1, int_hexagon_M2_mpyu_acc_hh_s1>; +def HEXAGON_M2_mpyu_acc_hh_s0 : + T_M2_mpy_acc < 0b11, 0, 0, 0, 1, int_hexagon_M2_mpyu_acc_hh_s0>; + +//Rx -= mpy(Rs.[H|L],Rt.[H|L])[:<<1] +def HEXAGON_M2_mpy_nac_ll_s1 : + T_M2_mpy_acc < 0b00, 0, 1, 1, 0, int_hexagon_M2_mpy_nac_ll_s1>; +def HEXAGON_M2_mpy_nac_ll_s0 : + T_M2_mpy_acc < 0b00, 0, 1, 0, 0, int_hexagon_M2_mpy_nac_ll_s0>; +def HEXAGON_M2_mpy_nac_lh_s1 : + T_M2_mpy_acc < 0b01, 0, 1, 1, 0, int_hexagon_M2_mpy_nac_lh_s1>; +def HEXAGON_M2_mpy_nac_lh_s0 : + T_M2_mpy_acc < 0b01, 0, 1, 0, 0, int_hexagon_M2_mpy_nac_lh_s0>; +def HEXAGON_M2_mpy_nac_hl_s1 : + T_M2_mpy_acc < 0b10, 0, 1, 1, 0, int_hexagon_M2_mpy_nac_hl_s1>; +def HEXAGON_M2_mpy_nac_hl_s0 : + T_M2_mpy_acc < 0b10, 0, 1, 0, 0, int_hexagon_M2_mpy_nac_hl_s0>; +def HEXAGON_M2_mpy_nac_hh_s1 : + T_M2_mpy_acc < 0b11, 0, 1, 1, 0, int_hexagon_M2_mpy_nac_hh_s1>; +def HEXAGON_M2_mpy_nac_hh_s0 : + T_M2_mpy_acc < 0b11, 0, 1, 0, 0, int_hexagon_M2_mpy_nac_hh_s0>; + +//Rx -= mpyu(Rs.[H|L],Rt.[H|L])[:<<1] +def HEXAGON_M2_mpyu_nac_ll_s1 : + T_M2_mpy_acc < 0b00, 0, 1, 1, 1, int_hexagon_M2_mpyu_nac_ll_s1>; +def HEXAGON_M2_mpyu_nac_ll_s0 : + T_M2_mpy_acc < 0b00, 0, 1, 0, 1, int_hexagon_M2_mpyu_nac_ll_s0>; +def HEXAGON_M2_mpyu_nac_lh_s1 : + T_M2_mpy_acc < 0b01, 0, 1, 1, 1, int_hexagon_M2_mpyu_nac_lh_s1>; +def HEXAGON_M2_mpyu_nac_lh_s0 : + T_M2_mpy_acc < 0b01, 0, 1, 0, 1, int_hexagon_M2_mpyu_nac_lh_s0>; +def HEXAGON_M2_mpyu_nac_hl_s1 : + T_M2_mpy_acc < 0b10, 0, 1, 1, 1, int_hexagon_M2_mpyu_nac_hl_s1>; +def HEXAGON_M2_mpyu_nac_hl_s0 : + T_M2_mpy_acc < 0b10, 0, 1, 0, 1, int_hexagon_M2_mpyu_nac_hl_s0>; +def HEXAGON_M2_mpyu_nac_hh_s1 : + T_M2_mpy_acc < 0b11, 0, 1, 1, 1, int_hexagon_M2_mpyu_nac_hh_s1>; +def HEXAGON_M2_mpyu_nac_hh_s0 : + T_M2_mpy_acc < 0b11, 0, 1, 0, 1, int_hexagon_M2_mpyu_nac_hh_s0>; + +//Rx += mpy(Rs.[H|L],Rt.[H|L])[:<<1]:sat +def HEXAGON_M2_mpy_acc_sat_ll_s1 : + T_M2_mpy_acc < 0b00, 1, 0, 1, 0, int_hexagon_M2_mpy_acc_sat_ll_s1>; +def HEXAGON_M2_mpy_acc_sat_ll_s0 : + T_M2_mpy_acc < 0b00, 1, 0, 0, 0, int_hexagon_M2_mpy_acc_sat_ll_s0>; +def HEXAGON_M2_mpy_acc_sat_lh_s1 : + T_M2_mpy_acc < 0b01, 1, 0, 1, 0, int_hexagon_M2_mpy_acc_sat_lh_s1>; +def HEXAGON_M2_mpy_acc_sat_lh_s0 : + T_M2_mpy_acc < 0b01, 1, 0, 0, 0, int_hexagon_M2_mpy_acc_sat_lh_s0>; +def HEXAGON_M2_mpy_acc_sat_hl_s1 : + T_M2_mpy_acc < 0b10, 1, 0, 1, 0, int_hexagon_M2_mpy_acc_sat_hl_s1>; +def HEXAGON_M2_mpy_acc_sat_hl_s0 : + T_M2_mpy_acc < 0b10, 1, 0, 0, 0, int_hexagon_M2_mpy_acc_sat_hl_s0>; +def HEXAGON_M2_mpy_acc_sat_hh_s1 : + T_M2_mpy_acc < 0b11, 1, 0, 1, 0, int_hexagon_M2_mpy_acc_sat_hh_s1>; +def HEXAGON_M2_mpy_acc_sat_hh_s0 : + T_M2_mpy_acc < 0b11, 1, 0, 0, 0, int_hexagon_M2_mpy_acc_sat_hh_s0>; + +//Rx -= mpy(Rs.[H|L],Rt.[H|L])[:<<1]:sat +def HEXAGON_M2_mpy_nac_sat_ll_s1 : + T_M2_mpy_acc < 0b00, 1, 1, 1, 0, int_hexagon_M2_mpy_nac_sat_ll_s1>; +def HEXAGON_M2_mpy_nac_sat_ll_s0 : + T_M2_mpy_acc < 0b00, 1, 1, 0, 0, int_hexagon_M2_mpy_nac_sat_ll_s0>; +def HEXAGON_M2_mpy_nac_sat_lh_s1 : + T_M2_mpy_acc < 0b01, 1, 1, 1, 0, int_hexagon_M2_mpy_nac_sat_lh_s1>; +def HEXAGON_M2_mpy_nac_sat_lh_s0 : + T_M2_mpy_acc < 0b01, 1, 1, 0, 0, int_hexagon_M2_mpy_nac_sat_lh_s0>; +def HEXAGON_M2_mpy_nac_sat_hl_s1 : + T_M2_mpy_acc < 0b10, 1, 1, 1, 0, int_hexagon_M2_mpy_nac_sat_hl_s1>; +def HEXAGON_M2_mpy_nac_sat_hl_s0 : + T_M2_mpy_acc < 0b10, 1, 1, 0, 0, int_hexagon_M2_mpy_nac_sat_hl_s0>; +def HEXAGON_M2_mpy_nac_sat_hh_s1 : + T_M2_mpy_acc < 0b11, 1, 1, 1, 0, int_hexagon_M2_mpy_nac_sat_hh_s1>; +def HEXAGON_M2_mpy_nac_sat_hh_s0 : + T_M2_mpy_acc < 0b11, 1, 1, 0, 0, int_hexagon_M2_mpy_nac_sat_hh_s0>; + // // ALU 32 types. // @@ -1164,358 +1309,6 @@ imm:$src3))], "$dst2 = $dst">; -class si_MInst_sisisi_acc_hh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , "($src1.H, $src2.H)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_lh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_lh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_hh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_hh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_hh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.H):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , "($src1.H, $src2.H)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_hh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_hh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_hl_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_hl - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_lh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_lh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_ll_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_sat_ll - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.H):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_hl - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , "($src1.H, $src2.L)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_hl_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.L):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hl - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , "($src1.H, $src2.L)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hl_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.L):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_lh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , "($src1.L, $src2.H)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_lh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.H):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_lh - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , "($src1.L, $src2.H)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_lh_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.H):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_ll - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , "($src1.L, $src2.L)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_ll_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.L):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_ll_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_hl_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_ll - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.L, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_acc_sat_hl - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst += ", !strconcat(opc , - "($src1.H, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_ll - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , "($src1.L, $src2.L)")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_ll_s1 - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.L):<<1")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hh_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hh_s1_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hl_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_hl_s1_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.H, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_lh_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.H):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_lh_s1_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.H):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_ll_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.L):sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - -class si_MInst_sisisi_nac_ll_s1_sat - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1.L, $src2.L):<<1:sat")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2))], - "$dst2 = $dst">; - class di_ALU32_sisi : ALU32_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), !strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")), @@ -2557,80 +2350,6 @@ def HEXAGON_M2_mpyd_rnd_ll_s0: di_MInst_sisi_rnd_ll <"mpy", int_hexagon_M2_mpyd_rnd_ll_s0>; -//Rx+=mpy(Rs.[H|L],Rt.[H|L])[[[:<<0|:<<1]|[:<<0:sat|:<<1:sat]] -def HEXAGON_M2_mpy_acc_hh_s0: - si_MInst_sisisi_acc_hh <"mpy", int_hexagon_M2_mpy_acc_hh_s0>; -def HEXAGON_M2_mpy_acc_hh_s1: - si_MInst_sisisi_acc_hh_s1 <"mpy", int_hexagon_M2_mpy_acc_hh_s1>; -def HEXAGON_M2_mpy_acc_sat_hh_s1: - si_MInst_sisisi_acc_sat_hh_s1 <"mpy", int_hexagon_M2_mpy_acc_sat_hh_s1>; -def HEXAGON_M2_mpy_acc_sat_hh_s0: - si_MInst_sisisi_acc_sat_hh <"mpy", int_hexagon_M2_mpy_acc_sat_hh_s0>; - -def HEXAGON_M2_mpy_acc_hl_s0: - si_MInst_sisisi_acc_hl <"mpy", int_hexagon_M2_mpy_acc_hl_s0>; -def HEXAGON_M2_mpy_acc_hl_s1: - si_MInst_sisisi_acc_hl_s1 <"mpy", int_hexagon_M2_mpy_acc_hl_s1>; -def HEXAGON_M2_mpy_acc_sat_hl_s1: - si_MInst_sisisi_acc_sat_hl_s1 <"mpy", int_hexagon_M2_mpy_acc_sat_hl_s1>; -def HEXAGON_M2_mpy_acc_sat_hl_s0: - si_MInst_sisisi_acc_sat_hl <"mpy", int_hexagon_M2_mpy_acc_sat_hl_s0>; - -def HEXAGON_M2_mpy_acc_lh_s0: - si_MInst_sisisi_acc_lh <"mpy", int_hexagon_M2_mpy_acc_lh_s0>; -def HEXAGON_M2_mpy_acc_lh_s1: - si_MInst_sisisi_acc_lh_s1 <"mpy", int_hexagon_M2_mpy_acc_lh_s1>; -def HEXAGON_M2_mpy_acc_sat_lh_s1: - si_MInst_sisisi_acc_sat_lh_s1 <"mpy", int_hexagon_M2_mpy_acc_sat_lh_s1>; -def HEXAGON_M2_mpy_acc_sat_lh_s0: - si_MInst_sisisi_acc_sat_lh <"mpy", int_hexagon_M2_mpy_acc_sat_lh_s0>; - -def HEXAGON_M2_mpy_acc_ll_s0: - si_MInst_sisisi_acc_ll <"mpy", int_hexagon_M2_mpy_acc_ll_s0>; -def HEXAGON_M2_mpy_acc_ll_s1: - si_MInst_sisisi_acc_ll_s1 <"mpy", int_hexagon_M2_mpy_acc_ll_s1>; -def HEXAGON_M2_mpy_acc_sat_ll_s1: - si_MInst_sisisi_acc_sat_ll_s1 <"mpy", int_hexagon_M2_mpy_acc_sat_ll_s1>; -def HEXAGON_M2_mpy_acc_sat_ll_s0: - si_MInst_sisisi_acc_sat_ll <"mpy", int_hexagon_M2_mpy_acc_sat_ll_s0>; - -//Rx-=mpy(Rs.[H|L],Rt.[H|L])[[[:<<0|:<<1]|[:<<0:sat|:<<1:sat]] -def HEXAGON_M2_mpy_nac_hh_s0: - si_MInst_sisisi_nac_hh <"mpy", int_hexagon_M2_mpy_nac_hh_s0>; -def HEXAGON_M2_mpy_nac_hh_s1: - si_MInst_sisisi_nac_hh_s1 <"mpy", int_hexagon_M2_mpy_nac_hh_s1>; -def HEXAGON_M2_mpy_nac_sat_hh_s1: - si_MInst_sisisi_nac_sat_hh_s1 <"mpy", int_hexagon_M2_mpy_nac_sat_hh_s1>; -def HEXAGON_M2_mpy_nac_sat_hh_s0: - si_MInst_sisisi_nac_sat_hh <"mpy", int_hexagon_M2_mpy_nac_sat_hh_s0>; - -def HEXAGON_M2_mpy_nac_hl_s0: - si_MInst_sisisi_nac_hl <"mpy", int_hexagon_M2_mpy_nac_hl_s0>; -def HEXAGON_M2_mpy_nac_hl_s1: - si_MInst_sisisi_nac_hl_s1 <"mpy", int_hexagon_M2_mpy_nac_hl_s1>; -def HEXAGON_M2_mpy_nac_sat_hl_s1: - si_MInst_sisisi_nac_sat_hl_s1 <"mpy", int_hexagon_M2_mpy_nac_sat_hl_s1>; -def HEXAGON_M2_mpy_nac_sat_hl_s0: - si_MInst_sisisi_nac_sat_hl <"mpy", int_hexagon_M2_mpy_nac_sat_hl_s0>; - -def HEXAGON_M2_mpy_nac_lh_s0: - si_MInst_sisisi_nac_lh <"mpy", int_hexagon_M2_mpy_nac_lh_s0>; -def HEXAGON_M2_mpy_nac_lh_s1: - si_MInst_sisisi_nac_lh_s1 <"mpy", int_hexagon_M2_mpy_nac_lh_s1>; -def HEXAGON_M2_mpy_nac_sat_lh_s1: - si_MInst_sisisi_nac_sat_lh_s1 <"mpy", int_hexagon_M2_mpy_nac_sat_lh_s1>; -def HEXAGON_M2_mpy_nac_sat_lh_s0: - si_MInst_sisisi_nac_sat_lh <"mpy", int_hexagon_M2_mpy_nac_sat_lh_s0>; - -def HEXAGON_M2_mpy_nac_ll_s0: - si_MInst_sisisi_nac_ll <"mpy", int_hexagon_M2_mpy_nac_ll_s0>; -def HEXAGON_M2_mpy_nac_ll_s1: - si_MInst_sisisi_nac_ll_s1 <"mpy", int_hexagon_M2_mpy_nac_ll_s1>; -def HEXAGON_M2_mpy_nac_sat_ll_s1: - si_MInst_sisisi_nac_sat_ll_s1 <"mpy", int_hexagon_M2_mpy_nac_sat_ll_s1>; -def HEXAGON_M2_mpy_nac_sat_ll_s0: - si_MInst_sisisi_nac_sat_ll <"mpy", int_hexagon_M2_mpy_nac_sat_ll_s0>; - //Rx+=mpy(Rs.[H|L],Rt.[H|L:<<0|:<<1] def HEXAGON_M2_mpyd_acc_hh_s0: di_MInst_disisi_acc_hh <"mpy", int_hexagon_M2_mpyd_acc_hh_s0>; @@ -2692,42 +2411,6 @@ def HEXAGON_M2_mpyud_ll_s1: di_MInst_sisi_ll_s1 <"mpyu", int_hexagon_M2_mpyud_ll_s1>; -//Rd+=mpyu(Rs.[H|L],Rt.[H|L])[:<<0|:<<1] -def HEXAGON_M2_mpyu_acc_hh_s0: - si_MInst_sisisi_acc_hh <"mpyu", int_hexagon_M2_mpyu_acc_hh_s0>; -def HEXAGON_M2_mpyu_acc_hh_s1: - si_MInst_sisisi_acc_hh_s1 <"mpyu", int_hexagon_M2_mpyu_acc_hh_s1>; -def HEXAGON_M2_mpyu_acc_hl_s0: - si_MInst_sisisi_acc_hl <"mpyu", int_hexagon_M2_mpyu_acc_hl_s0>; -def HEXAGON_M2_mpyu_acc_hl_s1: - si_MInst_sisisi_acc_hl_s1 <"mpyu", int_hexagon_M2_mpyu_acc_hl_s1>; -def HEXAGON_M2_mpyu_acc_lh_s0: - si_MInst_sisisi_acc_lh <"mpyu", int_hexagon_M2_mpyu_acc_lh_s0>; -def HEXAGON_M2_mpyu_acc_lh_s1: - si_MInst_sisisi_acc_lh_s1 <"mpyu", int_hexagon_M2_mpyu_acc_lh_s1>; -def HEXAGON_M2_mpyu_acc_ll_s0: - si_MInst_sisisi_acc_ll <"mpyu", int_hexagon_M2_mpyu_acc_ll_s0>; -def HEXAGON_M2_mpyu_acc_ll_s1: - si_MInst_sisisi_acc_ll_s1 <"mpyu", int_hexagon_M2_mpyu_acc_ll_s1>; - -//Rd+=mpyu(Rs.[H|L],Rt.[H|L])[:<<0|:<<1] -def HEXAGON_M2_mpyu_nac_hh_s0: - si_MInst_sisisi_nac_hh <"mpyu", int_hexagon_M2_mpyu_nac_hh_s0>; -def HEXAGON_M2_mpyu_nac_hh_s1: - si_MInst_sisisi_nac_hh_s1 <"mpyu", int_hexagon_M2_mpyu_nac_hh_s1>; -def HEXAGON_M2_mpyu_nac_hl_s0: - si_MInst_sisisi_nac_hl <"mpyu", int_hexagon_M2_mpyu_nac_hl_s0>; -def HEXAGON_M2_mpyu_nac_hl_s1: - si_MInst_sisisi_nac_hl_s1 <"mpyu", int_hexagon_M2_mpyu_nac_hl_s1>; -def HEXAGON_M2_mpyu_nac_lh_s0: - si_MInst_sisisi_nac_lh <"mpyu", int_hexagon_M2_mpyu_nac_lh_s0>; -def HEXAGON_M2_mpyu_nac_lh_s1: - si_MInst_sisisi_nac_lh_s1 <"mpyu", int_hexagon_M2_mpyu_nac_lh_s1>; -def HEXAGON_M2_mpyu_nac_ll_s0: - si_MInst_sisisi_nac_ll <"mpyu", int_hexagon_M2_mpyu_nac_ll_s0>; -def HEXAGON_M2_mpyu_nac_ll_s1: - si_MInst_sisisi_nac_ll_s1 <"mpyu", int_hexagon_M2_mpyu_nac_ll_s1>; - //Rdd+=mpyu(Rs.[H|L],Rt.[H|L])[:<<0|:<<1] def HEXAGON_M2_mpyud_acc_hh_s0: di_MInst_disisi_acc_hh <"mpyu", int_hexagon_M2_mpyud_acc_hh_s0>; Index: test/CodeGen/Hexagon/intrinsics-mpy2.ll =================================================================== --- /dev/null +++ test/CodeGen/Hexagon/intrinsics-mpy2.ll @@ -0,0 +1,784 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s + +; Verify that the mpy intrinsics with add/subtract are being lowered to the right instruction. + +@c = external global i64 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test1(i64 %a1, i64 %b1) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a1 to i32 + %conv2 = trunc i64 %b1 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test2(i64 %a2, i64 %b2) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a2 to i32 + %conv2 = trunc i64 %b2 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test3(i64 %a3, i64 %b3) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a3 to i32 + %conv2 = trunc i64 %b3 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test4(i64 %a4, i64 %b4) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a4 to i32 + %conv2 = trunc i64 %b4 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):sat + +define void @test5(i64 %a5, i64 %b5) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a5 to i32 + %conv2 = trunc i64 %b5 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):sat + +define void @test6(i64 %a6, i64 %b6) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a6 to i32 + %conv2 = trunc i64 %b6 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):sat + +define void @test7(i64 %a7, i64 %b7) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a7 to i32 + %conv2 = trunc i64 %b7 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):sat + +define void @test8(i64 %a8, i64 %b8) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a8 to i32 + %conv2 = trunc i64 %b8 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test9(i64 %a9, i64 %b9) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a9 to i32 + %conv2 = trunc i64 %b9 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test10(i64 %a10, i64 %b10) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a10 to i32 + %conv2 = trunc i64 %b10 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test11(i64 %a11, i64 %b11) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a11 to i32 + %conv2 = trunc i64 %b11 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test12(i64 %a12, i64 %b12) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a12 to i32 + %conv2 = trunc i64 %b12 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):sat + +define void @test13(i64 %a13, i64 %b13) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a13 to i32 + %conv2 = trunc i64 %b13 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):sat + +define void @test14(i64 %a14, i64 %b14) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a14 to i32 + %conv2 = trunc i64 %b14 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):sat + +define void @test15(i64 %a15, i64 %b15) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a15 to i32 + %conv2 = trunc i64 %b15 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):sat + +define void @test16(i64 %a16, i64 %b16) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a16 to i32 + %conv2 = trunc i64 %b16 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test17(i64 %a17, i64 %b17) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a17 to i32 + %conv2 = trunc i64 %b17 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test18(i64 %a18, i64 %b18) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a18 to i32 + %conv2 = trunc i64 %b18 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test19(i64 %a19, i64 %b19) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a19 to i32 + %conv2 = trunc i64 %b19 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test20(i64 %a20, i64 %b20) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a20 to i32 + %conv2 = trunc i64 %b20 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test21(i64 %a21, i64 %b21) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a21 to i32 + %conv2 = trunc i64 %b21 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.ll.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.ll.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test22(i64 %a22, i64 %b22) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a22 to i32 + %conv2 = trunc i64 %b22 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.lh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.lh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l) + +define void @test23(i64 %a23, i64 %b23) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a23 to i32 + %conv2 = trunc i64 %b23 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.hl.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.hl.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h) + +define void @test24(i64 %a24, i64 %b24) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a24 to i32 + %conv2 = trunc i64 %b24 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.hh.s0(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.hh.s0(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test25(i64 %a25, i64 %b25) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a25 to i32 + %conv2 = trunc i64 %b25 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test26(i64 %a26, i64 %b26) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a26 to i32 + %conv2 = trunc i64 %b26 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test27(i64 %a27, i64 %b27) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a27 to i32 + %conv2 = trunc i64 %b27 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test28(i64 %a28, i64 %b28) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a28 to i32 + %conv2 = trunc i64 %b28 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.hh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1:sat + +define void @test29(i64 %a29, i64 %b29) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a29 to i32 + %conv2 = trunc i64 %b29 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1:sat + +define void @test30(i64 %a30, i64 %b30) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a30 to i32 + %conv2 = trunc i64 %b30 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1:sat + +define void @test31(i64 %a31, i64 %b31) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a31 to i32 + %conv2 = trunc i64 %b31 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1:sat + +define void @test32(i64 %a32, i64 %b32) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a32 to i32 + %conv2 = trunc i64 %b32 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.acc.sat.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.acc.sat.hh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test33(i64 %a33, i64 %b33) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a33 to i32 + %conv2 = trunc i64 %b33 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test34(i64 %a34, i64 %b34) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a34 to i32 + %conv2 = trunc i64 %b34 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test35(i64 %a35, i64 %b35) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a35 to i32 + %conv2 = trunc i64 %b35 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test36(i64 %a36, i64 %b36) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a36 to i32 + %conv2 = trunc i64 %b36 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.hh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1:sat + +define void @test37(i64 %a37, i64 %b37) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a37 to i32 + %conv2 = trunc i64 %b37 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1:sat + +define void @test38(i64 %a38, i64 %b38) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a38 to i32 + %conv2 = trunc i64 %b38 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1:sat + +define void @test39(i64 %a39, i64 %b39) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a39 to i32 + %conv2 = trunc i64 %b39 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpy(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1:sat + +define void @test40(i64 %a40, i64 %b40) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a40 to i32 + %conv2 = trunc i64 %b40 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpy.nac.sat.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpy.nac.sat.hh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test41(i64 %a41, i64 %b41) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a41 to i32 + %conv2 = trunc i64 %b41 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test42(i64 %a42, i64 %b42) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a42 to i32 + %conv2 = trunc i64 %b42 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test43(i64 %a43, i64 %b43) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a43 to i32 + %conv2 = trunc i64 %b43 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}+={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test44(i64 %a44, i64 %b44) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a44 to i32 + %conv2 = trunc i64 %b44 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.acc.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.acc.hh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test45(i64 %a45, i64 %b45) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a45 to i32 + %conv2 = trunc i64 %b45 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.ll.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.ll.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.l{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test46(i64 %a46, i64 %b46) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a46 to i32 + %conv2 = trunc i64 %b46 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.lh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.lh.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.l):<<1 + +define void @test47(i64 %a47, i64 %b47) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a47 to i32 + %conv2 = trunc i64 %b47 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.hl.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.hl.s1(i32, i32, i32) #1 + +; CHECK: r{{[0-9]+}}{{ *}}-={{ *}}mpyu(r{{[0-9]+}}.h{{ *}},{{ *}}r{{[0-9]+}}.h):<<1 + +define void @test48(i64 %a48, i64 %b48) #0 { +entry: + %0 = load i64* @c, align 8, !tbaa !1 + %conv = trunc i64 %0 to i32 + %conv1 = trunc i64 %a48 to i32 + %conv2 = trunc i64 %b48 to i32 + %1 = tail call i32 @llvm.hexagon.M2.mpyu.nac.hh.s1(i32 %conv, i32 %conv1, i32 %conv2) + %conv3 = sext i32 %1 to i64 + store i64 %conv3, i64* @c, align 8, !tbaa !1 + ret void +} + +declare i32 @llvm.hexagon.M2.mpyu.nac.hh.s1(i32, i32, i32) #1 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.ident = !{!0} + +!0 = metadata !{metadata !"QuIC LLVM Hexagon Clang version 7.1-internal"} +!1 = metadata !{metadata !2, metadata !2, i64 0} +!2 = metadata !{metadata !"long long", metadata !3, i64 0} +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} +!4 = metadata !{metadata !"Simple C/C++ TBAA"} Index: test/MC/Hexagon/mpy_acc.s =================================================================== --- /dev/null +++ test/MC/Hexagon/mpy_acc.s @@ -0,0 +1,149 @@ +#REQUIRES: object-emission +#This test will be enabled when assembler support has been added. + +#RUN: llvm-mc -filetype=obj %s | llvm-objdump -d - | FileCheck %s + +fp-=mpyu(r23.l,r27.h):<<1 +#CHECK: eef7db3e { r30 -= mpyu(r23.l, r27.h):<<1 } + +r20-=mpyu(sp.l,r17.h) +#CHECK: ee7dd134 { r20 -= mpyu(r29.l, r17.h) } + +lr-=mpyu(r14.l,r21.l):<<1 +#CHECK: eeeed51f { r31 -= mpyu(r14.l, r21.l):<<1 } + +r8-=mpyu(r8.l,r10.l) +#CHECK: ee68ca08 { r8 -= mpyu(r8.l, r10.l) } + +r24-=mpy(r19.h,r5.h):<<1 +#CHECK: eeb3c578 { r24 -= mpy(r19.h, r5.h):<<1 } + +r31-=mpy(r2.h,r22.h) +#CHECK: ee22d67f { r31 -= mpy(r2.h, r22.h) } + +r20-=mpy(r9.h,r28.l):<<1 +#CHECK: eea9dc54 { r20 -= mpy(r9.h, r28.l):<<1 } + +r24-=mpy(lr.h,r14.l) +#CHECK: ee3fce58 { r24 -= mpy(r31.h, r14.l) } + +sp-=mpyu(r31.h,r15.l):<<1 +#CHECK: eeffcf5d { r29 -= mpyu(r31.h, r15.l):<<1 } + +r15-=mpyu(r25.h,r10.l) +#CHECK: ee79ca4f { r15 -= mpyu(r25.h, r10.l) } + +r28+=mpy(r25.h,r13.h):sat +#CHECK: ee19cdfc { r28 += mpy(r25.h, r13.h):sat } + +r9+=mpy(r11.h,r0.h):<<1:sat +#CHECK: ee8bc0e9 { r9 += mpy(r11.h, r0.h):<<1:sat } + +r22-=mpyu(r9.h,r21.h) +#CHECK: ee69d576 { r22 -= mpyu(r9.h, r21.h) } + +r3-=mpyu(r16.h,r18.h):<<1 +#CHECK: eef0d263 { r3 -= mpyu(r16.h, r18.h):<<1 } + +r14+=mpy(r24.l,r3.l):sat +#CHECK: ee18c38e { r14 += mpy(r24.l, r3.l):sat } + +r4+=mpy(r6.l,r13.l):<<1:sat +#CHECK: ee86cd84 { r4 += mpy(r6.l, r13.l):<<1:sat } + +r0+=mpy(r13.l,r1.h):sat +#CHECK: ee0dc1a0 { r0 += mpy(r13.l, r1.h):sat } + +r16+=mpy(r0.l,r22.h):<<1:sat +#CHECK: ee80d6b0 { r16 += mpy(r0.l, r22.h):<<1:sat } + +r29+=mpy(r2.h,r7.l):sat +#CHECK: ee02c7dd { r29 += mpy(r2.h, r7.l):sat } + +r9+=mpy(r0.h,r15.l):<<1:sat +#CHECK: ee80cfc9 { r9 += mpy(r0.h, r15.l):<<1:sat } + +r5+=mpyu(r1.l,r23.l) +#CHECK: ee41d705 { r5 += mpyu(r1.l, r23.l) } + +r31+=mpyu(r28.l,r17.l):<<1 +#CHECK: eedcd11f { r31 += mpyu(r28.l, r17.l):<<1 } + +r0+=mpy(r29.h,r20.h) +#CHECK: ee1dd460 { r0 += mpy(r29.h, r20.h) } + +r15+=mpy(r1.h,r15.h):<<1 +#CHECK: ee81cf6f { r15 += mpy(r1.h, r15.h):<<1 } + +r14+=mpy(r20.h,r4.l) +#CHECK: ee14c44e { r14 += mpy(r20.h, r4.l) } + +r3+=mpy(r5.h,r11.l):<<1 +#CHECK: ee85cb43 { r3 += mpy(r5.h, r11.l):<<1 } + +r22+=mpy(r2.l,fp.h) +#CHECK: ee02de36 { r22 += mpy(r2.l, r30.h) } + +r5+=mpy(r13.l,r7.h):<<1 +#CHECK: ee8dc725 { r5 += mpy(r13.l, r7.h):<<1 } + +r10+=mpy(r19.l,r8.l) +#CHECK: ee13c80a { r10 += mpy(r19.l, r8.l) } + +r11+=mpy(r22.l,r26.l):<<1 +#CHECK: ee96da0b { r11 += mpy(r22.l, r26.l):<<1 } + +r2-=mpy(r21.h,r10.l):<<1:sat +#CHECK: eeb5cac2 { r2 -= mpy(r21.h, r10.l):<<1:sat } + +r13-=mpy(r24.h,r8.l):sat +#CHECK: ee38c8cd { r13 -= mpy(r24.h, r8.l):sat } + +fp-=mpy(r27.h,r27.h):<<1:sat +#CHECK: eebbdbfe { r30 -= mpy(r27.h, r27.h):<<1:sat } + +r30-=mpy(r16.h,r27.h):sat +#CHECK: ee30dbfe { r30 -= mpy(r16.h, r27.h):sat } + +r17-=mpy(r9.l,r30.l):<<1:sat +#CHECK: eea9de91 { r17 -= mpy(r9.l, r30.l):<<1:sat } + +r24-=mpy(r18.l,r1.l):sat +#CHECK: ee32c198 { r24 -= mpy(r18.l, r1.l):sat } + +r1-=mpy(r14.l,r26.h):<<1:sat +#CHECK: eeaedaa1 { r1 -= mpy(r14.l, r26.h):<<1:sat } + +r6-=mpy(r29.l,r12.h):sat +#CHECK: ee3dcca6 { r6 -= mpy(r29.l, r12.h):sat } + +r13+=mpyu(r27.h,r16.l) +#CHECK: ee5bd04d { r13 += mpyu(r27.h, r16.l) } + +lr+=mpyu(r8.h,r17.l):<<1 +#CHECK: eec8d15f { r31 += mpyu(r8.h, r17.l):<<1 } + +r30+=mpyu(r5.l,fp.h) +#CHECK: ee45de3e { r30 += mpyu(r5.l, r30.h) } + +r24+=mpyu(r5.l,r28.h):<<1 +#CHECK: eec5dc38 { r24 += mpyu(r5.l, r28.h):<<1 } + +r12-=mpy(r26.l,r9.l) +#CHECK: ee3ac90c { r12 -= mpy(r26.l, r9.l) } + +r25-=mpy(r9.l,r13.l):<<1 +#CHECK: eea9cd19 { r25 -= mpy(r9.l, r13.l):<<1 } + +r12+=mpyu(r8.h,r9.h) +#CHECK: ee48c96c { r12 += mpyu(r8.h, r9.h) } + +r18+=mpyu(r11.h,r16.h):<<1 +#CHECK: eecbd072 { r18 += mpyu(r11.h, r16.h):<<1 } + +sp-=mpy(r27.l,fp.h) +#CHECK: ee3bde3d { r29 -= mpy(r27.l, r30.h) } + +r16-=mpy(r7.l,r12.h):<<1 +#CHECK: eea7cc30 { r16 -= mpy(r7.l, r12.h):<<1 } +