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

Reply via email to