Like what we've done for {lsx_,lasx_x}v{add,sub,mul}l{ev,od}, use special predicates instead of hard-coded const vectors.
This is not suitable for LASX where lasx_xvpick has a different semantic. gcc/ChangeLog: * config/loongarch/simd.md (LVEC): New define_mode_attr. (simdfmt_as_i): Make it same as simdfmt for integer vector modes. (_f): New define_mode_attr. * config/loongarch/lsx.md (lsx_vpickev_b): Remove. (lsx_vpickev_h): Remove. (lsx_vpickev_w): Remove. (lsx_vpickev_w_f): Remove. (lsx_vpickod_b): Remove. (lsx_vpickod_h): Remove. (lsx_vpickod_w): Remove. (lsx_vpickev_w_f): Remove. (lsx_pick_evod_<mode>): New define_insn. (lsx_<x>vpick<ev_od>_<simdfmt_as_i><_f>): New define_expand. --- gcc/config/loongarch/lsx.md | 142 ++++++----------------------------- gcc/config/loongarch/simd.md | 24 +++++- 2 files changed, 47 insertions(+), 119 deletions(-) diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md index c7df04c6389..9d7254768ae 100644 --- a/gcc/config/loongarch/lsx.md +++ b/gcc/config/loongarch/lsx.md @@ -1624,125 +1624,33 @@ (define_insn "lsx_nor_<lsxfmt>" [(set_attr "type" "simd_logic") (set_attr "mode" "<MODE>")]) -(define_insn "lsx_vpickev_b" -[(set (match_operand:V16QI 0 "register_operand" "=f") - (vec_select:V16QI - (vec_concat:V32QI - (match_operand:V16QI 1 "register_operand" "f") - (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) - (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_LSX" - "vpickev.b\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V16QI")]) - -(define_insn "lsx_vpickev_h" -[(set (match_operand:V8HI 0 "register_operand" "=f") - (vec_select:V8HI - (vec_concat:V16HI - (match_operand:V8HI 1 "register_operand" "f") - (match_operand:V8HI 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" - "vpickev.h\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_vpickev_w" -[(set (match_operand:V4SI 0 "register_operand" "=f") - (vec_select:V4SI - (vec_concat:V8SI - (match_operand:V4SI 1 "register_operand" "f") - (match_operand:V4SI 2 "register_operand" "f")) - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))] - "ISA_HAS_LSX" - "vpickev.w\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V4SI")]) - -(define_insn "lsx_vpickev_w_f" -[(set (match_operand:V4SF 0 "register_operand" "=f") - (vec_select:V4SF - (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "f") - (match_operand:V4SF 2 "register_operand" "f")) - (parallel [(const_int 0) (const_int 2) - (const_int 4) (const_int 6)])))] - "ISA_HAS_LSX" - "vpickev.w\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V4SF")]) - -(define_insn "lsx_vpickod_b" -[(set (match_operand:V16QI 0 "register_operand" "=f") - (vec_select:V16QI - (vec_concat:V32QI - (match_operand:V16QI 1 "register_operand" "f") - (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) - (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_LSX" - "vpickod.b\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V16QI")]) - -(define_insn "lsx_vpickod_h" -[(set (match_operand:V8HI 0 "register_operand" "=f") - (vec_select:V8HI - (vec_concat:V16HI - (match_operand:V8HI 1 "register_operand" "f") - (match_operand:V8HI 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" - "vpickod.h\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V8HI")]) - -(define_insn "lsx_vpickod_w" -[(set (match_operand:V4SI 0 "register_operand" "=f") - (vec_select:V4SI - (vec_concat:V8SI - (match_operand:V4SI 1 "register_operand" "f") - (match_operand:V4SI 2 "register_operand" "f")) - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))] - "ISA_HAS_LSX" - "vpickod.w\t%w0,%w2,%w1" +;; Picking even/odd elements. +(define_insn "lsx_pick_evod_<mode>" + [(set (match_operand:LSX 0 "register_operand" "=f") + (vec_select:LSX + (vec_concat:<LVEC> + (match_operand:LSX 1 "register_operand" "f") + (match_operand:LSX 2 "register_operand" "f")) + (match_operand:<LVEC> 3 "vect_par_cnst_even_or_odd_half")))] + "GET_MODE_SIZE (<UNITMODE>mode) != 8" ;; Use vilvl.d instead + "vpick%O3.<simdfmt_as_i>\t%<wu>0,%<wu>2,%<wu>1" [(set_attr "type" "simd_permute") - (set_attr "mode" "V4SI")]) + (set_attr "mode" "<MODE>")]) -(define_insn "lsx_vpickod_w_f" -[(set (match_operand:V4SF 0 "register_operand" "=f") - (vec_select:V4SF - (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "f") - (match_operand:V4SF 2 "register_operand" "f")) - (parallel [(const_int 1) (const_int 3) - (const_int 5) (const_int 7)])))] - "ISA_HAS_LSX" - "vpickod.w\t%w0,%w2,%w1" - [(set_attr "type" "simd_permute") - (set_attr "mode" "V4SF")]) +(define_expand "lsx_vpick<ev_od>_<simdfmt_as_i><_f>" + [(match_operand:LSX 0 "register_operand" "=f") + (match_operand:LSX 1 "register_operand" " f") + (match_operand:LSX 2 "register_operand" " f") + (const_int zero_one)] + "GET_MODE_SIZE (<UNITMODE>mode) != 8" ;; Use vilvl.d instead +{ + int nelts = GET_MODE_NUNITS (<MODE>mode); + rtx op3 = loongarch_gen_stepped_int_parallel (nelts, <zero_one>, 2); + rtx insn = gen_lsx_pick_evod_<mode> (operands[0], operands[1], + operands[2], op3); + emit_insn (insn); + DONE; +}) (define_insn "popcount<mode>2" [(set (match_operand:ILSX 0 "register_operand" "=f") diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md index 1bf113d65be..b7a28f7b3f2 100644 --- a/gcc/config/loongarch/simd.md +++ b/gcc/config/loongarch/simd.md @@ -75,6 +75,14 @@ (define_mode_attr VEC_HALF [(V2DI "V1DI") (V4DI "V2DI") (V8HI "V4HI") (V16HI "V8HI") (V16QI "V8QI") (V32QI "V16QI")]) +;; Modes with doubled length for intermediate values in RTX pattern. +(define_mode_attr LVEC [(V2DF "V4DF") (V4DF "V8DF") + (V4SF "V8SF") (V8SF "V16SF") + (V2DI "V4DI") (V4DI "V8DI") + (V4SI "V8SI") (V8SI "V16SI") + (V8HI "V16HI") (V16HI "V32HI") + (V16QI "V32QI") (V32QI "V64QI")]) + ;; 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") @@ -121,10 +129,22 @@ (define_mode_attr simdfmt_w [(V2DI "q") (V4DI "q") (define_mode_attr simdifmt_for_f [(V2DF "l") (V4DF "l") (V4SF "w") (V8SF "w")]) -;; Suffix for integer mode in LSX or LASX instructions to operating FP +;; Suffix for integer mode in LSX or LASX instructions to operate FP ;; vectors using integer vector operations. (define_mode_attr simdfmt_as_i [(V2DF "d") (V4DF "d") - (V4SF "w") (V8SF "w")]) + (V4SF "w") (V8SF "w") + (V2DI "d") (V4DI "d") + (V4SI "w") (V8SI "w") + (V8HI "h") (V16HI "h") + (V16QI "b") (V32QI "b")]) + +;; "_f" for FP vectors, "" for integer vectors +(define_mode_attr _f [(V2DF "_f") (V4DF "_f") + (V4SF "_f") (V8SF "_f") + (V2DI "") (V4DI "") + (V4SI "") (V8SI "") + (V8HI "") (V16HI "") + (V16QI "") (V32QI "")]) ;; Size of vector elements in bits. (define_mode_attr elmbits [(V2DI "64") (V4DI "64") -- 2.48.1