[v2,6/8] LoongArch: Simplify lsx_vpick description
Commit Message
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(-)
@@ -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")
@@ -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")