These pattern definitions are tediously long, invoking 32 UNSPECs and many hard-coded long const vectors. To simplify them, at first we use the TImode vector operations instead of the UNSPECs, then we adopt an approach in AArch64: using a special predicate to match the const vectors for odd/even indices for define_insn's, and generate those vectors in define_expand's.
For "backward compatibilty" we need to provide a "punned" version for the operations invoking TImode vectors as the intrinsics still expect DImode vectors. The stat is "201 insertions, 905 deletions." gcc/ChangeLog: * config/loongarch/lasx.md (UNSPEC_LASX_XVADDWEV): Remove. (UNSPEC_LASX_XVADDWEV2): Remove. (UNSPEC_LASX_XVADDWEV3): Remove. (UNSPEC_LASX_XVSUBWEV): Remove. (UNSPEC_LASX_XVSUBWEV2): Remove. (UNSPEC_LASX_XVMULWEV): Remove. (UNSPEC_LASX_XVMULWEV2): Remove. (UNSPEC_LASX_XVMULWEV3): Remove. (UNSPEC_LASX_XVADDWOD): Remove. (UNSPEC_LASX_XVADDWOD2): Remove. (UNSPEC_LASX_XVADDWOD3): Remove. (UNSPEC_LASX_XVSUBWOD): Remove. (UNSPEC_LASX_XVSUBWOD2): Remove. (UNSPEC_LASX_XVMULWOD): Remove. (UNSPEC_LASX_XVMULWOD2): Remove. (UNSPEC_LASX_XVMULWOD3): Remove. (lasx_xv<addsubmul:optab>wev_h_b<u>): Remove. (lasx_xv<addsubmul:optab>wev_w_h<u>): Remove. (lasx_xv<addsubmul:optab>wev_d_w<u>): Remove. (lasx_xvaddwev_q_d): Remove. (lasx_xvsubwev_q_d): Remove. (lasx_xvmulwev_q_d): Remove. (lasx_xv<addsubmul:optab>wod_h_b<u>): Remove. (lasx_xv<addsubmul:optab>wod_w_h<u>): Remove. (lasx_xv<addsubmul:optab>wod_d_w<u>): Remove. (lasx_xvaddwod_q_d): Remove. (lasx_xvsubwod_q_d): Remove. (lasx_xvmulwod_q_d): Remove. (lasx_xvaddwev_q_du): Remove. (lasx_xvsubwev_q_du): Remove. (lasx_xvmulwev_q_du): Remove. (lasx_xvaddwod_q_du): Remove. (lasx_xvsubwod_q_du): Remove. (lasx_xvmulwod_q_du): Remove. (lasx_xv<addmul:optab>wev_h_bu_b): Remove. (lasx_xv<addmul:optab>wev_w_hu_h): Remove. (lasx_xv<addmul:optab>wev_d_wu_w): Remove. (lasx_xv<addmul:optab>wod_h_bu_b): Remove. (lasx_xv<addmul:optab>wod_w_hu_h): Remove. (lasx_xv<addmul:optab>wod_d_wu_w): Remove. (lasx_xvaddwev_q_du_d): Remove. (lasx_xvsubwev_q_du_d): Remove. (lasx_xvmulwev_q_du_d): Remove. (lasx_xvaddwod_q_du_d): Remove. (lasx_xvsubwod_q_du_d): Remove. * config/loongarch/lsx.md (UNSPEC_LSX_XVADDWEV): Remove. (UNSPEC_LSX_VADDWEV2): Remove. (UNSPEC_LSX_VADDWEV3): Remove. (UNSPEC_LSX_VSUBWEV): Remove. (UNSPEC_LSX_VSUBWEV2): Remove. (UNSPEC_LSX_VMULWEV): Remove. (UNSPEC_LSX_VMULWEV2): Remove. (UNSPEC_LSX_VMULWEV3): Remove. (UNSPEC_LSX_VADDWOD): Remove. (UNSPEC_LSX_VADDWOD2): Remove. (UNSPEC_LSX_VADDWOD3): Remove. (UNSPEC_LSX_VSUBWOD): Remove. (UNSPEC_LSX_VSUBWOD2): Remove. (UNSPEC_LSX_VMULWOD): Remove. (UNSPEC_LSX_VMULWOD2): Remove. (UNSPEC_LSX_VMULWOD3): Remove. (lsx_v<addsubmul:optab>wev_h_b<u>): Remove. (lsx_v<addsubmul:optab>wev_w_h<u>): Remove. (lsx_v<addsubmul:optab>wev_d_w<u>): Remove. (lsx_vaddwev_q_d): Remove. (lsx_vsubwev_q_d): Remove. (lsx_vmulwev_q_d): Remove. (lsx_v<addsubmul:optab>wod_h_b<u>): Remove. (lsx_v<addsubmul:optab>wod_w_h<u>): Remove. (lsx_v<addsubmul:optab>wod_d_w<u>): Remove. (lsx_vaddwod_q_d): Remove. (lsx_vsubwod_q_d): Remove. (lsx_vmulwod_q_d): Remove. (lsx_vaddwev_q_du): Remove. (lsx_vsubwev_q_du): Remove. (lsx_vmulwev_q_du): Remove. (lsx_vaddwod_q_du): Remove. (lsx_vsubwod_q_du): Remove. (lsx_vmulwod_q_du): Remove. (lsx_v<addmul:optab>wev_h_bu_b): Remove. (lsx_v<addmul:optab>wev_w_hu_h): Remove. (lsx_v<addmul:optab>wev_d_wu_w): Remove. (lsx_v<addmul:optab>wod_h_bu_b): Remove. (lsx_v<addmul:optab>wod_w_hu_h): Remove. (lsx_v<addmul:optab>wod_d_wu_w): Remove. (lsx_vaddwev_q_du_d): Remove. (lsx_vsubwev_q_du_d): Remove. (lsx_vmulwev_q_du_d): Remove. (lsx_vaddwod_q_du_d): Remove. (lsx_vsubwod_q_du_d): Remove. (lsx_vmulwod_q_du_d): Remove. * config/loongarch/loongarch-modes.def: Add V1TI and V4TI. * config/loongarch/loongarch-protos.h (loongarch_gen_stepped_int_parallel): New function prototype. * config/loongarch/loongarch.cc (loongarch_print_operand): Accept 'O' for printing "ev" or "od." (loongarch_gen_stepped_int_parallel): Implement. * config/loongarch/loongarch.md (mode): Add V1TI and V2TI. * config/loongarch/predicates.md (vect_par_cnst_even_or_odd_half): New define_predicate. * config/loongarch/simd.md (WVEC_HALF): New define_mode_attr. (simdfmt_w): Likewise. (zero_one): New define_int_iterator. (ev_od): New define_int_attr. (simd_<optab>w_evod_<mode:IVEC>_<su>): New define_insn. (<simd_isa>_<x>v<optab>w<ev_od>_<simdfmt_w>_<simdfmt><u>): New define_expand. (simd_<optab>w_evod_<mode>_hetero): New define_insn. (<simd_isa>_<x>v<optab>w<ev_od>_<simdfmt_w>_<simdfmt>u_<simdfmt>): New define_expand. (DIVEC): New define_mode_iterator. (<simd_isa>_<optab>w<ev_od>_q_d<u>_punned): New define_expand. (<simd_isa>_<optab>w<ev_od>_q_du_d_punned): Likewise. * config/loongarch/loongarch-builtins.cc (CODE_FOR_lsx_vaddwev_q_d): Define as a macro to override it with the punned expand. (CODE_FOR_lsx_vaddwev_q_du): Likewise. (CODE_FOR_lsx_vsubwev_q_d): Likewise. (CODE_FOR_lsx_vsubwev_q_du): Likewise. (CODE_FOR_lsx_vmulwev_q_d): Likewise. (CODE_FOR_lsx_vmulwev_q_du): Likewise. (CODE_FOR_lsx_vaddwod_q_d): Likewise. (CODE_FOR_lsx_vaddwod_q_du): Likewise. (CODE_FOR_lsx_vsubwod_q_d): Likewise. (CODE_FOR_lsx_vsubwod_q_du): Likewise. (CODE_FOR_lsx_vmulwod_q_d): Likewise. (CODE_FOR_lsx_vmulwod_q_du): Likewise. (CODE_FOR_lsx_vaddwev_q_du_d): Likewise. (CODE_FOR_lsx_vmulwev_q_du_d): Likewise. (CODE_FOR_lsx_vaddwod_q_du_d): Likewise. (CODE_FOR_lsx_vmulwod_q_du_d): Likewise. (CODE_FOR_lasx_xvaddwev_q_d): Likewise. (CODE_FOR_lasx_xvaddwev_q_du): Likewise. (CODE_FOR_lasx_xvsubwev_q_d): Likewise. (CODE_FOR_lasx_xvsubwev_q_du): Likewise. (CODE_FOR_lasx_xvmulwev_q_d): Likewise. (CODE_FOR_lasx_xvmulwev_q_du): Likewise. (CODE_FOR_lasx_xvaddwod_q_d): Likewise. (CODE_FOR_lasx_xvaddwod_q_du): Likewise. (CODE_FOR_lasx_xvsubwod_q_d): Likewise. (CODE_FOR_lasx_xvsubwod_q_du): Likewise. (CODE_FOR_lasx_xvmulwod_q_d): Likewise. (CODE_FOR_lasx_xvmulwod_q_du): Likewise. (CODE_FOR_lasx_xvaddwev_q_du_d): Likewise. (CODE_FOR_lasx_xvmulwev_q_du_d): Likewise. (CODE_FOR_lasx_xvaddwod_q_du_d): Likewise. (CODE_FOR_lasx_xvmulwod_q_du_d): Likewise. --- gcc/config/loongarch/lasx.md | 504 --------------------- gcc/config/loongarch/loongarch-builtins.cc | 36 ++ gcc/config/loongarch/loongarch-modes.def | 2 + gcc/config/loongarch/loongarch-protos.h | 2 + gcc/config/loongarch/loongarch.cc | 16 + gcc/config/loongarch/loongarch.md | 2 +- gcc/config/loongarch/lsx.md | 400 ---------------- gcc/config/loongarch/predicates.md | 27 ++ gcc/config/loongarch/simd.md | 117 +++++ 9 files changed, 201 insertions(+), 905 deletions(-) diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md index d82ad61be60..640fa028f1e 100644 --- a/gcc/config/loongarch/lasx.md +++ b/gcc/config/loongarch/lasx.md @@ -94,22 +94,6 @@ (define_c_enum "unspec" [ UNSPEC_LASX_XVPERMI_Q UNSPEC_LASX_XVPERMI_D - UNSPEC_LASX_XVADDWEV - UNSPEC_LASX_XVADDWEV2 - UNSPEC_LASX_XVADDWEV3 - UNSPEC_LASX_XVSUBWEV - UNSPEC_LASX_XVSUBWEV2 - UNSPEC_LASX_XVMULWEV - UNSPEC_LASX_XVMULWEV2 - UNSPEC_LASX_XVMULWEV3 - UNSPEC_LASX_XVADDWOD - UNSPEC_LASX_XVADDWOD2 - UNSPEC_LASX_XVADDWOD3 - UNSPEC_LASX_XVSUBWOD - UNSPEC_LASX_XVSUBWOD2 - UNSPEC_LASX_XVMULWOD - UNSPEC_LASX_XVMULWOD2 - UNSPEC_LASX_XVMULWOD3 UNSPEC_LASX_XVMADDWEV UNSPEC_LASX_XVMADDWEV2 UNSPEC_LASX_XVMADDWEV3 @@ -3212,450 +3196,6 @@ (define_insn "lasx_xvldrepl_<lasxfmt_f>_insn_0" (set_attr "mode" "<MODE>") (set_attr "length" "4")]) -;;XVADDWEV.H.B XVSUBWEV.H.B XVMULWEV.H.B -;;XVADDWEV.H.BU XVSUBWEV.H.BU XVMULWEV.H.BU -(define_insn "lasx_xv<optab>wev_h_b<u>" - [(set (match_operand:V16HI 0 "register_operand" "=f") - (addsubmul:V16HI - (any_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14) - (const_int 16) (const_int 18) - (const_int 20) (const_int 22) - (const_int 24) (const_int 26) - (const_int 28) (const_int 30)]))) - (any_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14) - (const_int 16) (const_int 18) - (const_int 20) (const_int 22) - (const_int 24) (const_int 26) - (const_int 28) (const_int 30)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.h.b<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V16HI")]) - -;;XVADDWEV.W.H XVSUBWEV.W.H XVMULWEV.W.H -;;XVADDWEV.W.HU XVSUBWEV.W.HU XVMULWEV.W.HU -(define_insn "lasx_xv<optab>wev_w_h<u>" - [(set (match_operand:V8SI 0 "register_operand" "=f") - (addsubmul:V8SI - (any_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)]))) - (any_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.w.h<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8SI")]) - -;;XVADDWEV.D.W XVSUBWEV.D.W XVMULWEV.D.W -;;XVADDWEV.D.WU XVSUBWEV.D.WU XVMULWEV.D.WU -(define_insn "lasx_xv<optab>wev_d_w<u>" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (addsubmul:V4DI - (any_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)]))) - (any_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.d.w<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWEV.Q.D -;;TODO2 -(define_insn "lasx_xvaddwev_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWEV))] - "ISA_HAS_LASX" - "xvaddwev.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVSUBWEV.Q.D -;;TODO2 -(define_insn "lasx_xvsubwev_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVSUBWEV))] - "ISA_HAS_LASX" - "xvsubwev.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWEV.Q.D -;;TODO2 -(define_insn "lasx_xvmulwev_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWEV))] - "ISA_HAS_LASX" - "xvmulwev.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - - -;;XVADDWOD.H.B XVSUBWOD.H.B XVMULWOD.H.B -;;XVADDWOD.H.BU XVSUBWOD.H.BU XVMULWOD.H.BU -(define_insn "lasx_xv<optab>wod_h_b<u>" - [(set (match_operand:V16HI 0 "register_operand" "=f") - (addsubmul:V16HI - (any_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15) - (const_int 17) (const_int 19) - (const_int 21) (const_int 23) - (const_int 25) (const_int 27) - (const_int 29) (const_int 31)]))) - (any_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15) - (const_int 17) (const_int 19) - (const_int 21) (const_int 23) - (const_int 25) (const_int 27) - (const_int 29) (const_int 31)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.h.b<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V16HI")]) - -;;XVADDWOD.W.H XVSUBWOD.W.H XVMULWOD.W.H -;;XVADDWOD.W.HU XVSUBWOD.W.HU XVMULWOD.W.HU -(define_insn "lasx_xv<optab>wod_w_h<u>" - [(set (match_operand:V8SI 0 "register_operand" "=f") - (addsubmul:V8SI - (any_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)]))) - (any_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.w.h<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8SI")]) - - -;;XVADDWOD.D.W XVSUBWOD.D.W XVMULWOD.D.W -;;XVADDWOD.D.WU XVSUBWOD.D.WU XVMULWOD.D.WU -(define_insn "lasx_xv<optab>wod_d_w<u>" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (addsubmul:V4DI - (any_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)]))) - (any_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.d.w<u>\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWOD.Q.D -;;TODO2 -(define_insn "lasx_xvaddwod_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWOD))] - "ISA_HAS_LASX" - "xvaddwod.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVSUBWOD.Q.D -;;TODO2 -(define_insn "lasx_xvsubwod_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVSUBWOD))] - "ISA_HAS_LASX" - "xvsubwod.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWOD.Q.D -;;TODO2 -(define_insn "lasx_xvmulwod_q_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWOD))] - "ISA_HAS_LASX" - "xvmulwod.q.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWEV.Q.DU -;;TODO2 -(define_insn "lasx_xvaddwev_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWEV2))] - "ISA_HAS_LASX" - "xvaddwev.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVSUBWEV.Q.DU -;;TODO2 -(define_insn "lasx_xvsubwev_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVSUBWEV2))] - "ISA_HAS_LASX" - "xvsubwev.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWEV.Q.DU -;;TODO2 -(define_insn "lasx_xvmulwev_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWEV2))] - "ISA_HAS_LASX" - "xvmulwev.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWOD.Q.DU -;;TODO2 -(define_insn "lasx_xvaddwod_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWOD2))] - "ISA_HAS_LASX" - "xvaddwod.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVSUBWOD.Q.DU -;;TODO2 -(define_insn "lasx_xvsubwod_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVSUBWOD2))] - "ISA_HAS_LASX" - "xvsubwod.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWOD.Q.DU -;;TODO2 -(define_insn "lasx_xvmulwod_q_du" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWOD2))] - "ISA_HAS_LASX" - "xvmulwod.q.du\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWEV.H.BU.B XVMULWEV.H.BU.B -(define_insn "lasx_xv<optab>wev_h_bu_b" - [(set (match_operand:V16HI 0 "register_operand" "=f") - (addmul:V16HI - (zero_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14) - (const_int 16) (const_int 18) - (const_int 20) (const_int 22) - (const_int 24) (const_int 26) - (const_int 28) (const_int 30)]))) - (sign_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14) - (const_int 16) (const_int 18) - (const_int 20) (const_int 22) - (const_int 24) (const_int 26) - (const_int 28) (const_int 30)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.h.bu.b\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V16HI")]) - -;;XVADDWEV.W.HU.H XVMULWEV.W.HU.H -(define_insn "lasx_xv<optab>wev_w_hu_h" - [(set (match_operand:V8SI 0 "register_operand" "=f") - (addmul:V8SI - (zero_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)]))) - (sign_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.w.hu.h\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8SI")]) - -;;XVADDWEV.D.WU.W XVMULWEV.D.WU.W -(define_insn "lasx_xv<optab>wev_d_wu_w" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (addmul:V4DI - (zero_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)]))) - (sign_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))))] - "ISA_HAS_LASX" - "xv<optab>wev.d.wu.w\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWOD.H.BU.B XVMULWOD.H.BU.B -(define_insn "lasx_xv<optab>wod_h_bu_b" - [(set (match_operand:V16HI 0 "register_operand" "=f") - (addmul:V16HI - (zero_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15) - (const_int 17) (const_int 19) - (const_int 21) (const_int 23) - (const_int 25) (const_int 27) - (const_int 29) (const_int 31)]))) - (sign_extend:V16HI - (vec_select:V16QI - (match_operand:V32QI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15) - (const_int 17) (const_int 19) - (const_int 21) (const_int 23) - (const_int 25) (const_int 27) - (const_int 29) (const_int 31)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.h.bu.b\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V16HI")]) - -;;XVADDWOD.W.HU.H XVMULWOD.W.HU.H -(define_insn "lasx_xv<optab>wod_w_hu_h" - [(set (match_operand:V8SI 0 "register_operand" "=f") - (addmul:V8SI - (zero_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)]))) - (sign_extend:V8SI - (vec_select:V8HI - (match_operand:V16HI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.w.hu.h\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8SI")]) - -;;XVADDWOD.D.WU.W XVMULWOD.D.WU.W -(define_insn "lasx_xv<optab>wod_d_wu_w" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (addmul:V4DI - (zero_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)]))) - (sign_extend:V4DI - (vec_select:V4SI - (match_operand:V8SI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))))] - "ISA_HAS_LASX" - "xv<optab>wod.d.wu.w\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - ;;XVMADDWEV.H.B XVMADDWEV.H.BU (define_insn "lasx_xvmaddwev_h_b<u>" [(set (match_operand:V16HI 0 "register_operand" "=f") @@ -4144,50 +3684,6 @@ (define_insn "lasx_xvreplve_<lasxfmt_f>" [(set_attr "type" "simd_splat") (set_attr "mode" "<MODE>")]) -;;XVADDWEV.Q.DU.D -(define_insn "lasx_xvaddwev_q_du_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWEV3))] - "ISA_HAS_LASX" - "xvaddwev.q.du.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVADDWOD.Q.DU.D -(define_insn "lasx_xvaddwod_q_du_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVADDWOD3))] - "ISA_HAS_LASX" - "xvaddwod.q.du.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWEV.Q.DU.D -(define_insn "lasx_xvmulwev_q_du_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWEV3))] - "ISA_HAS_LASX" - "xvmulwev.q.du.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - -;;XVMULWOD.Q.DU.D -(define_insn "lasx_xvmulwod_q_du_d" - [(set (match_operand:V4DI 0 "register_operand" "=f") - (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f") - (match_operand:V4DI 2 "register_operand" "f")] - UNSPEC_LASX_XVMULWOD3))] - "ISA_HAS_LASX" - "xvmulwod.q.du.d\t%u0,%u1,%u2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4DI")]) - (define_insn "lasx_xvpickve2gr_w<u>" [(set (match_operand:SI 0 "register_operand" "=r") (any_extend:SI diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc index 1849b35357c..abe6e1f3ddc 100644 --- a/gcc/config/loongarch/loongarch-builtins.cc +++ b/gcc/config/loongarch/loongarch-builtins.cc @@ -519,6 +519,24 @@ AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE) #define CODE_FOR_lsx_vfrecip_d CODE_FOR_recipv2df3 #define CODE_FOR_lsx_vfrecip_s CODE_FOR_recipv4sf3 +#define CODE_FOR_lsx_vaddwev_q_d CODE_FOR_lsx_addwev_q_d_punned +#define CODE_FOR_lsx_vaddwev_q_du CODE_FOR_lsx_addwev_q_du_punned +#define CODE_FOR_lsx_vsubwev_q_d CODE_FOR_lsx_subwev_q_d_punned +#define CODE_FOR_lsx_vsubwev_q_du CODE_FOR_lsx_subwev_q_du_punned +#define CODE_FOR_lsx_vmulwev_q_d CODE_FOR_lsx_mulwev_q_d_punned +#define CODE_FOR_lsx_vmulwev_q_du CODE_FOR_lsx_mulwev_q_du_punned +#define CODE_FOR_lsx_vaddwod_q_d CODE_FOR_lsx_addwod_q_d_punned +#define CODE_FOR_lsx_vaddwod_q_du CODE_FOR_lsx_addwod_q_du_punned +#define CODE_FOR_lsx_vsubwod_q_d CODE_FOR_lsx_subwod_q_d_punned +#define CODE_FOR_lsx_vsubwod_q_du CODE_FOR_lsx_subwod_q_du_punned +#define CODE_FOR_lsx_vmulwod_q_d CODE_FOR_lsx_mulwod_q_d_punned +#define CODE_FOR_lsx_vmulwod_q_du CODE_FOR_lsx_mulwod_q_du_punned + +#define CODE_FOR_lsx_vaddwev_q_du_d CODE_FOR_lsx_addwev_q_du_d_punned +#define CODE_FOR_lsx_vmulwev_q_du_d CODE_FOR_lsx_mulwev_q_du_d_punned +#define CODE_FOR_lsx_vaddwod_q_du_d CODE_FOR_lsx_addwod_q_du_d_punned +#define CODE_FOR_lsx_vmulwod_q_du_d CODE_FOR_lsx_mulwod_q_du_d_punned + /* LoongArch ASX define CODE_FOR_lasx_mxxx */ #define CODE_FOR_lasx_xvsadd_b CODE_FOR_ssaddv32qi3 #define CODE_FOR_lasx_xvsadd_h CODE_FOR_ssaddv16hi3 @@ -805,6 +823,24 @@ AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE) #define CODE_FOR_lasx_xvfrecip_d CODE_FOR_recipv4df3 #define CODE_FOR_lasx_xvfrecip_s CODE_FOR_recipv8sf3 +#define CODE_FOR_lasx_xvaddwev_q_d CODE_FOR_lasx_addwev_q_d_punned +#define CODE_FOR_lasx_xvaddwev_q_du CODE_FOR_lasx_addwev_q_du_punned +#define CODE_FOR_lasx_xvsubwev_q_d CODE_FOR_lasx_subwev_q_d_punned +#define CODE_FOR_lasx_xvsubwev_q_du CODE_FOR_lasx_subwev_q_du_punned +#define CODE_FOR_lasx_xvmulwev_q_d CODE_FOR_lasx_mulwev_q_d_punned +#define CODE_FOR_lasx_xvmulwev_q_du CODE_FOR_lasx_mulwev_q_du_punned +#define CODE_FOR_lasx_xvaddwod_q_d CODE_FOR_lasx_addwod_q_d_punned +#define CODE_FOR_lasx_xvaddwod_q_du CODE_FOR_lasx_addwod_q_du_punned +#define CODE_FOR_lasx_xvsubwod_q_d CODE_FOR_lasx_subwod_q_d_punned +#define CODE_FOR_lasx_xvsubwod_q_du CODE_FOR_lasx_subwod_q_du_punned +#define CODE_FOR_lasx_xvmulwod_q_d CODE_FOR_lasx_mulwod_q_d_punned +#define CODE_FOR_lasx_xvmulwod_q_du CODE_FOR_lasx_mulwod_q_du_punned + +#define CODE_FOR_lasx_xvaddwev_q_du_d CODE_FOR_lasx_addwev_q_du_d_punned +#define CODE_FOR_lasx_xvmulwev_q_du_d CODE_FOR_lasx_mulwev_q_du_d_punned +#define CODE_FOR_lasx_xvaddwod_q_du_d CODE_FOR_lasx_addwod_q_du_d_punned +#define CODE_FOR_lasx_xvmulwod_q_du_d CODE_FOR_lasx_mulwod_q_du_d_punned + static const struct loongarch_builtin_description loongarch_builtins[] = { #define LARCH_MOVFCSR2GR 0 DIRECT_BUILTIN (movfcsr2gr, LARCH_USI_FTYPE_UQI, hard_float), diff --git a/gcc/config/loongarch/loongarch-modes.def b/gcc/config/loongarch/loongarch-modes.def index e632f03636b..07cc29fceee 100644 --- a/gcc/config/loongarch/loongarch-modes.def +++ b/gcc/config/loongarch/loongarch-modes.def @@ -32,6 +32,7 @@ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ /* For LARCH LSX 128 bits. */ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ VECTOR_MODES (FLOAT, 16); /* V4SF V2DF */ +VECTOR_MODE (INT, TI, 1); /* V1TI */ /* For LARCH LASX 256 bits. */ VECTOR_MODES (INT, 32); /* V32QI V16HI V8SI V4DI */ @@ -49,6 +50,7 @@ VECTOR_MODE (INT, QI, 64); /* V64QI */ VECTOR_MODE (INT, HI, 32); /* V32HI */ VECTOR_MODE (INT, SI, 16); /* V16SI */ VECTOR_MODE (INT, DI, 8); /* V8DI */ +VECTOR_MODE (INT, TI, 4); /* V4TI */ VECTOR_MODE (FLOAT, SF, 16); /* V16SF */ VECTOR_MODE (FLOAT, DF, 8); /* V8DF */ diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index 20acca690c8..94d3e33cb9a 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -220,4 +220,6 @@ extern void loongarch_option_override_internal (struct loongarch_target *, struc extern void loongarch_reset_previous_fndecl (void); extern void loongarch_save_restore_target_globals (tree new_tree); extern void loongarch_register_pragmas (void); +extern rtx loongarch_gen_stepped_int_parallel (unsigned int nelts, int base, + int step); #endif /* ! GCC_LOONGARCH_PROTOS_H */ diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index e036f802fde..c76c2da1201 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -6276,6 +6276,10 @@ loongarch_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; + case 'O': + fprintf (file, "%s", INTVAL (XVECEXP (op, 0, 0)) ? "od" : "ev"); + break; + case 'F': loongarch_print_float_branch_condition (file, code, letter); break; @@ -11111,6 +11115,18 @@ loongarch_builtin_support_vector_misalignment (machine_mode mode, is_packed); } +/* Return a PARALLEL containing NELTS elements, with element I equal + to BASE + I * STEP. */ +rtx +loongarch_gen_stepped_int_parallel (unsigned int nelts, int base, + int step) +{ + rtvec vec = rtvec_alloc (nelts); + for (unsigned int i = 0; i < nelts; i++) + RTVEC_ELT (vec, i) = GEN_INT (base + i * step); + return gen_rtx_PARALLEL (VOIDmode, vec); +} + /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE. Return TFmode or DFmode for TI_LONG_DOUBLE_TYPE which is for long double type, go with the default one for the others. */ diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 36d140a9e94..19560e4525b 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -187,7 +187,7 @@ (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor,simd_add" ;; Main data type used by the insn (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FCC, - V2DI,V4SI,V8HI,V16QI,V2DF,V4SF,V4DI,V8SI,V16HI,V32QI,V4DF,V8SF" + V1TI,V2DI,V4SI,V8HI,V16QI,V2DF,V4SF,V2TI,V4DI,V8SI,V16HI,V32QI,V4DF,V8SF" (const_string "unknown")) ;; True if the main data type is twice the size of a word. diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md index bcc5ae85fb3..4b664ae6926 100644 --- a/gcc/config/loongarch/lsx.md +++ b/gcc/config/loongarch/lsx.md @@ -93,22 +93,6 @@ (define_c_enum "unspec" [ UNSPEC_LSX_VSTX UNSPEC_LSX_VEXTL_QU_DU UNSPEC_LSX_VSETEQZ_V - UNSPEC_LSX_VADDWEV - UNSPEC_LSX_VADDWEV2 - UNSPEC_LSX_VADDWEV3 - UNSPEC_LSX_VADDWOD - UNSPEC_LSX_VADDWOD2 - UNSPEC_LSX_VADDWOD3 - UNSPEC_LSX_VSUBWEV - UNSPEC_LSX_VSUBWEV2 - UNSPEC_LSX_VSUBWOD - UNSPEC_LSX_VSUBWOD2 - UNSPEC_LSX_VMULWEV - UNSPEC_LSX_VMULWEV2 - UNSPEC_LSX_VMULWEV3 - UNSPEC_LSX_VMULWOD - UNSPEC_LSX_VMULWOD2 - UNSPEC_LSX_VMULWOD3 UNSPEC_LSX_VHADDW_Q_D UNSPEC_LSX_VHADDW_QU_DU UNSPEC_LSX_VHSUBW_Q_D @@ -3166,390 +3150,6 @@ (define_expand "ssadv16qi" DONE; }) -(define_insn "lsx_v<optab>wev_d_w<u>" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (addsubmul:V2DI - (any_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2)]))) - (any_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2)])))))] - "ISA_HAS_LSX" - "v<optab>wev.d.w<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_v<optab>wev_w_h<u>" - [(set (match_operand:V4SI 0 "register_operand" "=f") - (addsubmul:V4SI - (any_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)]))) - (any_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))))] - "ISA_HAS_LSX" - "v<optab>wev.w.h<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4SI")]) - -(define_insn "lsx_v<optab>wev_h_b<u>" - [(set (match_operand:V8HI 0 "register_operand" "=f") - (addsubmul:V8HI - (any_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)]))) - (any_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)])))))] - "ISA_HAS_LSX" - "v<optab>wev.h.b<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_v<optab>wod_d_w<u>" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (addsubmul:V2DI - (any_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3)]))) - (any_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3)])))))] - "ISA_HAS_LSX" - "v<optab>wod.d.w<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_v<optab>wod_w_h<u>" - [(set (match_operand:V4SI 0 "register_operand" "=f") - (addsubmul:V4SI - (any_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)]))) - (any_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))))] - "ISA_HAS_LSX" - "v<optab>wod.w.h<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4SI")]) - -(define_insn "lsx_v<optab>wod_h_b<u>" - [(set (match_operand:V8HI 0 "register_operand" "=f") - (addsubmul:V8HI - (any_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)]))) - (any_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)])))))] - "ISA_HAS_LSX" - "v<optab>wod.h.b<u>\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_v<optab>wev_d_wu_w" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (addmul:V2DI - (zero_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2)]))) - (sign_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2)])))))] - "ISA_HAS_LSX" - "v<optab>wev.d.wu.w\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_v<optab>wev_w_hu_h" - [(set (match_operand:V4SI 0 "register_operand" "=f") - (addmul:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))))] - "ISA_HAS_LSX" - "v<optab>wev.w.hu.h\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4SI")]) - -(define_insn "lsx_v<optab>wev_h_bu_b" - [(set (match_operand:V8HI 0 "register_operand" "=f") - (addmul:V8HI - (zero_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "register_operand" "%f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)]))) - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 2 "register_operand" "f") - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6) - (const_int 8) (const_int 10) - (const_int 12) (const_int 14)])))))] - "ISA_HAS_LSX" - "v<optab>wev.h.bu.b\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_v<optab>wod_d_wu_w" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (addmul:V2DI - (zero_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3)]))) - (sign_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3)])))))] - "ISA_HAS_LSX" - "v<optab>wod.d.wu.w\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_v<optab>wod_w_hu_h" - [(set (match_operand:V4SI 0 "register_operand" "=f") - (addmul:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))))] - "ISA_HAS_LSX" - "v<optab>wod.w.hu.h\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V4SI")]) - -(define_insn "lsx_v<optab>wod_h_bu_b" - [(set (match_operand:V8HI 0 "register_operand" "=f") - (addmul:V8HI - (zero_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "register_operand" "%f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)]))) - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 2 "register_operand" "f") - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7) - (const_int 9) (const_int 11) - (const_int 13) (const_int 15)])))))] - "ISA_HAS_LSX" - "v<optab>wod.h.bu.b\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_vaddwev_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWEV))] - "ISA_HAS_LSX" - "vaddwev.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vaddwev_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWEV2))] - "ISA_HAS_LSX" - "vaddwev.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vaddwod_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWOD))] - "ISA_HAS_LSX" - "vaddwod.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vaddwod_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWOD2))] - "ISA_HAS_LSX" - "vaddwod.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vsubwev_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VSUBWEV))] - "ISA_HAS_LSX" - "vsubwev.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vsubwev_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VSUBWEV2))] - "ISA_HAS_LSX" - "vsubwev.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vsubwod_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VSUBWOD))] - "ISA_HAS_LSX" - "vsubwod.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vsubwod_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VSUBWOD2))] - "ISA_HAS_LSX" - "vsubwod.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vaddwev_q_du_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWEV3))] - "ISA_HAS_LSX" - "vaddwev.q.du.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vaddwod_q_du_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VADDWOD3))] - "ISA_HAS_LSX" - "vaddwod.q.du.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwev_q_du_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWEV3))] - "ISA_HAS_LSX" - "vmulwev.q.du.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwod_q_du_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWOD3))] - "ISA_HAS_LSX" - "vmulwod.q.du.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwev_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWEV))] - "ISA_HAS_LSX" - "vmulwev.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwev_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWEV2))] - "ISA_HAS_LSX" - "vmulwev.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwod_q_d" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWOD))] - "ISA_HAS_LSX" - "vmulwod.q.d\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - -(define_insn "lsx_vmulwod_q_du" - [(set (match_operand:V2DI 0 "register_operand" "=f") - (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") - (match_operand:V2DI 2 "register_operand" "f")] - UNSPEC_LSX_VMULWOD2))] - "ISA_HAS_LSX" - "vmulwod.q.du\t%w0,%w1,%w2" - [(set_attr "type" "simd_int_arith") - (set_attr "mode" "V2DI")]) - (define_insn "lsx_vhaddw_q_d" [(set (match_operand:V2DI 0 "register_operand" "=f") (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f") diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md index b5d6f90678e..fd2d7b9ab55 100644 --- a/gcc/config/loongarch/predicates.md +++ b/gcc/config/loongarch/predicates.md @@ -672,3 +672,30 @@ (define_predicate "reg_or_vector_same_ximm5_operand" (define_predicate "reg_or_vector_same_uimm_operand" (ior (match_operand 0 "register_operand") (match_operand 0 "const_vector_same_uimm_operand"))) + +;; PARALLEL for a vec_select that selects all the even or all the odd +;; elements of a vector of MODE. +(define_special_predicate "vect_par_cnst_even_or_odd_half" + (match_code "parallel") +{ + int nunits = XVECLEN (op, 0); + + if (!known_eq (GET_MODE_NUNITS (mode), nunits * 2)) + return false; + + rtx first = XVECEXP (op, 0, 0); + if (!CONST_INT_P (first)) + return false; + + if (INTVAL (first) != 0 && INTVAL (first) != 1) + return false; + + for (int i = 1; i < nunits; i++) + { + rtx elem = XVECEXP (op, 0, i); + if (!CONST_INT_P (elem) || INTVAL (elem) != INTVAL (first) + i * 2) + return false; + } + + return true; +}) diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md index 61fc1ab20ad..86fc14647e0 100644 --- a/gcc/config/loongarch/simd.md +++ b/gcc/config/loongarch/simd.md @@ -69,6 +69,13 @@ (define_mode_attr WVEC [(V2DI "V2TI") (V4DI "V4TI") (V8HI "V8SI") (V16HI "V16SI") (V16QI "V16HI") (V32QI "V32HI")]) +;; The elements are widen but the total size is unchanged +;; (i.e. the number of elements is halfed). +(define_mode_attr WVEC_HALF [(V2DI "V1TI") (V4DI "V2TI") + (V4SI "V2DI") (V8SI "V4DI") + (V8HI "V4SI") (V16HI "V8SI") + (V16QI "V8HI") (V32QI "V16HI")]) + ;; Integer vector modes with the same length and unit size as a mode. (define_mode_attr VIMODE [(V2DI "V2DI") (V4SI "V4SI") (V8HI "V8HI") (V16QI "V16QI") @@ -97,6 +104,12 @@ (define_mode_attr simdfmt [(V2DF "d") (V4DF "d") (V8HI "h") (V16HI "h") (V16QI "b") (V32QI "b")]) +;; Suffix for widening LSX or LASX instructions. +(define_mode_attr simdfmt_w [(V2DI "q") (V4DI "q") + (V4SI "d") (V8SI "d") + (V8HI "w") (V16HI "w") + (V16QI "h") (V32QI "h")]) + ;; Suffix for integer mode in LSX or LASX instructions with FP input but ;; integer output. (define_mode_attr simdifmt_for_f [(V2DF "l") (V4DF "l") @@ -588,6 +601,110 @@ (define_expand "cbranch<mode>4" DONE; }) +;; Operations on elements at even/odd indices. +(define_int_iterator zero_one [0 1]) +(define_int_attr ev_od [(0 "ev") (1 "od")]) + +;; Integer widening add/sub/mult. +(define_insn "simd_<optab>w_evod_<mode>_<su>" + [(set (match_operand:<WVEC_HALF> 0 "register_operand" "=f") + (addsubmul:<WVEC_HALF> + (vec_select:<WVEC_HALF> + (any_extend:<WVEC> + (match_operand:IVEC 1 "register_operand" "f")) + (match_operand:<WVEC> 3 "vect_par_cnst_even_or_odd_half")) + (vec_select:<WVEC_HALF> + (any_extend:<WVEC> + (match_operand:IVEC 2 "register_operand" "f")) + (match_dup 3))))] + "" + "<x>v<optab>w%O3.<simdfmt_w>.<simdfmt><u>\t%<wu>0,%<wu>1,%<wu>2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<WVEC_HALF>")]) + +(define_expand "<simd_isa>_<x>v<optab>w<ev_od>_<simdfmt_w>_<simdfmt><u>" + [(match_operand:<WVEC_HALF> 0 "register_operand" "=f") + (match_operand:IVEC 1 "register_operand" " f") + (match_operand:IVEC 2 "register_operand" " f") + (any_extend (const_int 0)) + (addsubmul (const_int 0) (const_int 0)) + (const_int zero_one)] + "" +{ + int nelts = GET_MODE_NUNITS (<WVEC_HALF>mode); + rtx op3 = loongarch_gen_stepped_int_parallel (nelts, <zero_one>, 2); + rtx insn = gen_simd_<optab>w_evod_<mode>_<su> (operands[0], operands[1], + operands[2], op3); + emit_insn (insn); + DONE; +}) + +(define_insn "simd_<optab>w_evod_<mode>_hetero" + [(set (match_operand:<WVEC_HALF> 0 "register_operand" "=f") + (addsubmul:<WVEC_HALF> + (vec_select:<WVEC_HALF> + (zero_extend:<WVEC> + (match_operand:IVEC 1 "register_operand" "f")) + (match_operand:<WVEC> 3 "vect_par_cnst_even_or_odd_half")) + (vec_select:<WVEC_HALF> + (sign_extend:<WVEC> + (match_operand:IVEC 2 "register_operand" "f")) + (match_dup 3))))] + "" + "<x>v<optab>w%O3.<simdfmt_w>.<simdfmt>u.<simdfmt>\t%<wu>0,%<wu>1,%<wu>2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<WVEC_HALF>")]) + +(define_expand "<simd_isa>_<x>v<optab>w<ev_od>_<simdfmt_w>_<simdfmt>u_<simdfmt>" + [(match_operand:<WVEC_HALF> 0 "register_operand" "=f") + (match_operand:IVEC 1 "register_operand" " f") + (match_operand:IVEC 2 "register_operand" " f") + (addmul (const_int 0) (const_int 0)) + (const_int zero_one)] + "" +{ + int nelts = GET_MODE_NUNITS (<WVEC_HALF>mode); + rtx op3 = loongarch_gen_stepped_int_parallel (nelts, <zero_one>, 2); + rtx insn = gen_simd_<optab>w_evod_<mode>_hetero (operands[0], operands[1], + operands[2], op3); + emit_insn (insn); + DONE; +}) + +; For "historical" reason we need a punned version of q_d variants. +(define_mode_iterator DIVEC [(V2DI "ISA_HAS_LSX") (V4DI "ISA_HAS_LASX")]) + +(define_expand "<simd_isa>_<optab>w<ev_od>_q_d<u>_punned" + [(match_operand:DIVEC 0 "register_operand" "=f") + (match_operand:DIVEC 1 "register_operand" " f") + (match_operand:DIVEC 2 "register_operand" " f") + (any_extend (const_int 0)) + (addsubmul (const_int 0) (const_int 0)) + (const_int zero_one)] + "" +{ + rtx t = gen_reg_rtx (<WVEC_HALF>mode); + emit_insn (gen_<simd_isa>_<x>v<optab>w<ev_od>_q_d<u> (t, operands[1], + operands[2])); + emit_move_insn (operands[0], gen_lowpart (<MODE>mode, t)); + DONE; +}) + +(define_expand "<simd_isa>_<optab>w<ev_od>_q_du_d_punned" + [(match_operand:DIVEC 0 "register_operand" "=f") + (match_operand:DIVEC 1 "register_operand" " f") + (match_operand:DIVEC 2 "register_operand" " f") + (addmul (const_int 0) (const_int 0)) + (const_int zero_one)] + "" +{ + rtx t = gen_reg_rtx (<WVEC_HALF>mode); + emit_insn (gen_<simd_isa>_<x>v<optab>w<ev_od>_q_du_d (t, operands[1], + operands[2])); + emit_move_insn (operands[0], gen_lowpart (<MODE>mode, t)); + DONE; +}) + ; The LoongArch SX Instructions. (include "lsx.md") -- 2.48.1