From: Ju-Zhe Zhong <juzhe.zh...@rivai.ai>

gcc/ChangeLog:

        * config/riscv/iterators.md: Add saturating Addition && Subtraction.
        * config/riscv/riscv-v.cc (has_vi_variant_p): Ditto.
        * config/riscv/riscv-vector-builtins-bases.cc (BASE): Ditto. 
        * config/riscv/riscv-vector-builtins-bases.h: Ditto.
        * config/riscv/riscv-vector-builtins-functions.def (vsadd): New def.
        (vssub): Ditto.
        (vsaddu): Ditto.
        (vssubu): Ditto.
        * config/riscv/vector-iterators.md (sll.vi): Adjust for Saturating 
support.
        (sll.vv): Ditto.
        (%3,%v4): Ditto.
        (%3,%4): Ditto.
        * config/riscv/vector.md (@pred_<optab><mode>): New pattern.
        (@pred_<optab><mode>_scalar): New pattern.
        (*pred_<optab><mode>_scalar): New pattern.
        (*pred_<optab><mode>_extended_scalar): New pattern.

---
 gcc/config/riscv/iterators.md                 |  12 +-
 gcc/config/riscv/riscv-v.cc                   |   5 +-
 .../riscv/riscv-vector-builtins-bases.cc      |   8 +
 .../riscv/riscv-vector-builtins-bases.h       |   4 +
 .../riscv/riscv-vector-builtins-functions.def |   9 +
 gcc/config/riscv/vector-iterators.md          |  52 +++-
 gcc/config/riscv/vector.md                    | 250 +++++++++++++++++-
 7 files changed, 320 insertions(+), 20 deletions(-)

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 6013f58db6e..7e5415cc80b 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -203,7 +203,11 @@
                         (umax "umax")
                         (mult "mul")
                         (not "one_cmpl")
-                        (neg "neg")])
+                        (neg "neg")
+                        (ss_plus "ssadd")
+                        (us_plus "usadd")
+                        (ss_minus "sssub")
+                        (us_minus "ussub")])
 
 ;; <or_optab> code attributes
 (define_code_attr or_optab [(ior "ior")
@@ -228,7 +232,11 @@
                        (umax "maxu")
                        (mult "mul")
                        (not "not")
-                       (neg "neg")])
+                       (neg "neg")
+                       (ss_plus "sadd")
+                       (us_plus "saddu")
+                       (ss_minus "ssub")
+                       (us_minus "ssubu")])
 
 ; atomics code attribute
 (define_code_attr atomic_optab
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 3bc1ee36e5a..df89c9be308 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -427,8 +427,9 @@ neg_simm5_p (rtx x)
 bool
 has_vi_variant_p (rtx_code code, rtx x)
 {
-  if (code != PLUS && code != MINUS && code != AND && code != IOR
-      && code != XOR)
+  if (code != PLUS && code != MINUS && code != AND && code != IOR && code != 
XOR
+      && code != SS_PLUS && code != SS_MINUS && code != US_PLUS
+      && code != US_MINUS)
     return false;
   return simm5_p (x);
 }
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc 
b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 0d86bbcd6b1..7e6ee1d7b53 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -241,6 +241,10 @@ static CONSTEXPR const binop<UDIV> vdivu_obj;
 static CONSTEXPR const binop<UMOD> vremu_obj;
 static CONSTEXPR const unop<NEG> vneg_obj;
 static CONSTEXPR const unop<NOT> vnot_obj;
+static CONSTEXPR const binop<SS_PLUS> vsadd_obj;
+static CONSTEXPR const binop<SS_MINUS> vssub_obj;
+static CONSTEXPR const binop<US_PLUS> vsaddu_obj;
+static CONSTEXPR const binop<US_MINUS> vssubu_obj;
 
 /* Declare the function base NAME, pointing it to an instance
    of class <NAME>_obj.  */
@@ -291,5 +295,9 @@ BASE (vdivu)
 BASE (vremu)
 BASE (vneg)
 BASE (vnot)
+BASE (vsadd)
+BASE (vssub)
+BASE (vsaddu)
+BASE (vssubu)
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h 
b/gcc/config/riscv/riscv-vector-builtins-bases.h
index 72ee25655b2..a59fd918af8 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -68,6 +68,10 @@ extern const function_base *const vdivu;
 extern const function_base *const vremu;
 extern const function_base *const vneg;
 extern const function_base *const vnot;
+extern const function_base *const vsadd;
+extern const function_base *const vssub;
+extern const function_base *const vsaddu;
+extern const function_base *const vssubu;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def 
b/gcc/config/riscv/riscv-vector-builtins-functions.def
index b94e780e916..74a1864b725 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -100,5 +100,14 @@ DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vremu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vneg, alu, full_preds, iu_v_ops)
 DEF_RVV_FUNCTION (vnot, alu, full_preds, iu_v_ops)
+/* 12. Vector Fixed-Point Arithmetic Instructions. */
+DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops)
+DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops)
+DEF_RVV_FUNCTION (vsaddu, alu, full_preds, u_vvv_ops)
+DEF_RVV_FUNCTION (vssubu, alu, full_preds, u_vvv_ops)
+DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvx_ops)
+DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvx_ops)
+DEF_RVV_FUNCTION (vsaddu, alu, full_preds, u_vvx_ops)
+DEF_RVV_FUNCTION (vssubu, alu, full_preds, u_vvx_ops)
 
 #undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/vector-iterators.md 
b/gcc/config/riscv/vector-iterators.md
index 9cc60da91f4..2460ed670c0 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -217,6 +217,10 @@
 
 (define_code_iterator any_non_commutative_binop [minus div udiv mod umod])
 
+(define_code_iterator any_sat_int_binop [ss_plus ss_minus us_plus us_minus])
+(define_code_iterator sat_int_plus_binop [ss_plus us_plus])
+(define_code_iterator sat_int_minus_binop [ss_minus us_minus])
+
 (define_code_attr binop_rhs1_predicate [
                        (plus "register_operand")
                        (minus "vector_arith_operand")
@@ -234,7 +238,11 @@
                        (div "register_operand")
                        (mod "register_operand")
                        (udiv "register_operand")
-                       (umod "register_operand")])
+                       (umod "register_operand")
+                       (ss_plus "register_operand")
+                       (us_plus "register_operand")
+                       (ss_minus "register_operand")
+                       (us_minus "register_operand")])
 
 (define_code_attr binop_rhs2_predicate [
                        (plus "vector_arith_operand")
@@ -253,7 +261,11 @@
                        (div "register_operand")
                        (mod "register_operand")
                        (udiv "register_operand")
-                       (umod "register_operand")])
+                       (umod "register_operand")
+                       (ss_plus "vector_arith_operand")
+                       (us_plus "vector_arith_operand")
+                       (ss_minus "vector_neg_arith_operand")
+                       (us_minus "register_operand")])
 
 (define_code_attr binop_rhs1_constraint [
                        (plus "vr,vr,vr,vr,vr,vr")
@@ -291,7 +303,11 @@
                        (div "vr,vr,vr,vr,vr,vr")
                        (mod "vr,vr,vr,vr,vr,vr")
                        (udiv "vr,vr,vr,vr,vr,vr")
-                       (umod "vr,vr,vr,vr,vr,vr")])
+                       (umod "vr,vr,vr,vr,vr,vr")
+                       (ss_plus "vr,vr,vi,vi")
+                       (us_plus "vr,vr,vi,vi")
+                       (ss_minus "vr,vr,vj,vj")
+                       (us_minus "vr,vr,vr,vr")])
 
 (define_code_attr int_binop_insn_type [
                        (plus "vialu")
@@ -310,11 +326,15 @@
                        (div "vidiv")
                        (mod "vidiv")
                        (udiv "vidiv")
-                       (umod "vidiv")])
+                       (umod "vidiv")
+                       (ss_plus "vsalu")
+                       (us_plus "vsalu")
+                       (ss_minus "vsalu")
+                       (us_minus "vsalu")])
 
-;; <binop_imm_rhs1_insn> expands to the insn name of binop matching constraint 
rhs1 is immediate.
+;; <binop_vi_variant_insn> expands to the insn name of binop matching 
constraint rhs1 is immediate.
 ;; minus is negated as vadd and ss_minus is negated as vsadd, others remain 
<insn>.
-(define_code_attr binop_imm_rhs1_insn [(ashift "sll.vi")
+(define_code_attr binop_vi_variant_insn [(ashift "sll.vi")
                               (ashiftrt "sra.vi")
                               (lshiftrt "srl.vi")
                               (div "div.vv")
@@ -330,11 +350,15 @@
                               (smax "max.vv")
                               (umin "minu.vv")
                               (umax "maxu.vv")
-                              (mult "mul.vv")])
+                              (mult "mul.vv")
+                              (ss_plus "sadd.vi")
+                              (us_plus "saddu.vi")
+                              (ss_minus "sadd.vi")
+                              (us_minus "ssubu.vv")])
 
-;; <binop_imm_rhs2_insn> expands to the insn name of binop matching constraint 
rhs2 is immediate.
+;; <binop_reverse_vi_variant_insn> expands to the insn name of binop matching 
constraint rhs2 is immediate.
 ;; minus is reversed as vrsub, others remain <insn>.
-(define_code_attr binop_imm_rhs2_insn [(ashift "sll.vv")
+(define_code_attr binop_reverse_vi_variant_insn [(ashift "sll.vv")
                               (ashiftrt "sra.vv")
                               (lshiftrt "srl.vv")
                               (div "div.vv")
@@ -352,7 +376,7 @@
                               (umax "maxu.vv")
                               (mult "mul.vv")])
 
-(define_code_attr binop_imm_rhs1_op [(ashift "%3,%v4")
+(define_code_attr binop_vi_variant_op [(ashift "%3,%v4")
                             (ashiftrt "%3,%v4")
                             (lshiftrt "%3,%v4")
                             (div "%3,%4")
@@ -368,9 +392,13 @@
                             (smax "%3,%4")
                             (umin "%3,%4")
                             (umax "%3,%4")
-                            (mult "%3,%4")])
+                            (mult "%3,%4")
+                            (ss_plus "%3,%v4")
+                            (us_plus "%3,%v4")
+                            (ss_minus "%3,%V4")
+                            (us_minus "%3,%4")])
 
-(define_code_attr binop_imm_rhs2_op [(ashift "%3,%4")
+(define_code_attr binop_reverse_vi_variant_op [(ashift "%3,%4")
                              (ashiftrt "%3,%4")
                              (lshiftrt "%3,%4")
                              (div "%3,%4")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 73c839f45c3..44584e17105 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -1170,10 +1170,10 @@
   "@
    v<insn>.vv\t%0,%3,%4%p1
    v<insn>.vv\t%0,%3,%4%p1
-   v<binop_imm_rhs1_insn>\t%0,<binop_imm_rhs1_op>%p1
-   v<binop_imm_rhs1_insn>\t%0,<binop_imm_rhs1_op>%p1
-   v<binop_imm_rhs2_insn>\t%0,<binop_imm_rhs2_op>%p1
-   v<binop_imm_rhs2_insn>\t%0,<binop_imm_rhs2_op>%p1"
+   v<binop_vi_variant_insn>\t%0,<binop_vi_variant_op>%p1
+   v<binop_vi_variant_insn>\t%0,<binop_vi_variant_op>%p1
+   v<binop_reverse_vi_variant_insn>\t%0,<binop_reverse_vi_variant_op>%p1
+   v<binop_reverse_vi_variant_insn>\t%0,<binop_reverse_vi_variant_op>%p1"
   [(set_attr "type" "<int_binop_insn_type>")
    (set_attr "mode" "<MODE>")])
 
@@ -1532,6 +1532,248 @@
   [(set_attr "type" "vialu")
    (set_attr "mode" "<MODE>")])
 
+;; Saturating Add and Subtract
+(define_insn "@pred_<optab><mode>"
+  [(set (match_operand:VI 0 "register_operand"                   "=vd, vr, vd, 
vr")
+       (if_then_else:VI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"         " vm,Wc1, 
vm,Wc1")
+            (match_operand 5 "vector_length_operand"            " rK, rK, rK, 
rK")
+            (match_operand 6 "const_int_operand"                "  i,  i,  i,  
i")
+            (match_operand 7 "const_int_operand"                "  i,  i,  i,  
i")
+            (match_operand 8 "const_int_operand"                "  i,  i,  i,  
i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (any_sat_int_binop:VI
+           (match_operand:VI 3 "<binop_rhs1_predicate>"         " vr, vr, vr, 
vr")
+           (match_operand:VI 4 "<binop_rhs2_predicate>" 
"<binop_rhs2_constraint>"))
+         (match_operand:VI 2 "vector_merge_operand"             
"0vu,0vu,0vu,0vu")))]
+  "TARGET_VECTOR"
+  "@
+   v<insn>.vv\t%0,%3,%4%p1
+   v<insn>.vv\t%0,%3,%4%p1
+   v<binop_vi_variant_insn>\t%0,<binop_vi_variant_op>%p1
+   v<binop_vi_variant_insn>\t%0,<binop_vi_variant_op>%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+;; Handle GET_MODE_INNER (mode) = QImode, HImode, SImode.
+(define_insn "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_QHS 0 "register_operand"       "=vd, vr")
+       (if_then_else:VI_QHS
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_plus_binop:VI_QHS
+           (vec_duplicate:VI_QHS
+             (match_operand:<VEL> 4 "register_operand"  "  r,  r"))
+           (match_operand:VI_QHS 3 "register_operand"   " vr, vr"))
+         (match_operand:VI_QHS 2 "vector_merge_operand" "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_QHS 0 "register_operand"       "=vd, vr")
+       (if_then_else:VI_QHS
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_minus_binop:VI_QHS
+           (match_operand:VI_QHS 3 "register_operand"   " vr, vr")
+           (vec_duplicate:VI_QHS
+             (match_operand:<VEL> 4 "register_operand"  "  r,  r")))
+         (match_operand:VI_QHS 2 "vector_merge_operand" "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand")
+            (match_operand 5 "vector_length_operand")
+            (match_operand 6 "const_int_operand")
+            (match_operand 7 "const_int_operand")
+            (match_operand 8 "const_int_operand")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_plus_binop:VI_D
+           (vec_duplicate:VI_D
+             (match_operand:<VEL> 4 "reg_or_int_operand"))
+           (match_operand:VI_D 3 "register_operand"))
+         (match_operand:VI_D 2 "vector_merge_operand")))]
+  "TARGET_VECTOR"
+  {
+    if (riscv_vector::has_vi_variant_p (<CODE>, operands[4]))
+      operands[4] = force_reg (<VEL>mode, operands[4]);
+    else if (!TARGET_64BIT)
+      {
+       rtx v = gen_reg_rtx (<MODE>mode);
+
+       if (riscv_vector::simm32_p (operands[4]))
+         operands[4] = gen_rtx_SIGN_EXTEND (<VEL>mode,
+               force_reg (Pmode, operands[4]));
+       else
+         {
+           if (CONST_INT_P (operands[4]))
+             operands[4] = force_reg (<VEL>mode, operands[4]);
+
+           riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast 
(<MODE>mode),
+                       v, operands[4], operands[5], <VM>mode);
+           emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
+                       operands[2], operands[3], v, operands[5],
+                       operands[6], operands[7], operands[8]));
+           DONE;
+         }
+      }
+    else
+      operands[4] = force_reg (<VEL>mode, operands[4]);
+  })
+
+(define_insn "*pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"         "=vd, vr")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_plus_binop:VI_D
+           (vec_duplicate:VI_D
+             (match_operand:<VEL> 4 "register_operand"  "  r,  r"))
+           (match_operand:VI_D 3 "register_operand"     " vr, vr"))
+         (match_operand:VI_D 2 "vector_merge_operand"   "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "*pred_<optab><mode>_extended_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"             "=vd, vr")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"     " vm,Wc1")
+            (match_operand 5 "vector_length_operand"        " rK, rK")
+            (match_operand 6 "const_int_operand"            "  i,  i")
+            (match_operand 7 "const_int_operand"            "  i,  i")
+            (match_operand 8 "const_int_operand"            "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_plus_binop:VI_D
+           (vec_duplicate:VI_D
+             (sign_extend:<VEL>
+               (match_operand:<VSUBEL> 4 "register_operand" "  r,  r")))
+           (match_operand:VI_D 3 "register_operand"         " vr, vr"))
+         (match_operand:VI_D 2 "vector_merge_operand"       "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand")
+            (match_operand 5 "vector_length_operand")
+            (match_operand 6 "const_int_operand")
+            (match_operand 7 "const_int_operand")
+            (match_operand 8 "const_int_operand")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_minus_binop:VI_D
+           (match_operand:VI_D 3 "register_operand")
+           (vec_duplicate:VI_D
+             (match_operand:<VEL> 4 "reg_or_int_operand")))
+         (match_operand:VI_D 2 "vector_merge_operand")))]
+  "TARGET_VECTOR"
+  {
+    if (riscv_vector::has_vi_variant_p (<CODE>, operands[4]))
+      operands[4] = force_reg (<VEL>mode, operands[4]);
+    else if (!TARGET_64BIT)
+      {
+       rtx v = gen_reg_rtx (<MODE>mode);
+
+       if (riscv_vector::simm32_p (operands[4]))
+         operands[4] = gen_rtx_SIGN_EXTEND (<VEL>mode,
+               force_reg (Pmode, operands[4]));
+       else
+         {
+           if (CONST_INT_P (operands[4]))
+             operands[4] = force_reg (<VEL>mode, operands[4]);
+
+           riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast 
(<MODE>mode),
+                       v, operands[4], operands[5], <VM>mode);
+           emit_insn (gen_pred_<optab><mode> (operands[0], operands[1],
+                       operands[2], operands[3], v, operands[5],
+                       operands[6], operands[7], operands[8]));
+           DONE;
+         }
+      }
+    else
+      operands[4] = force_reg (<VEL>mode, operands[4]);
+  })
+
+(define_insn "*pred_<optab><mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"         "=vd, vr")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+            (match_operand 5 "vector_length_operand"    " rK, rK")
+            (match_operand 6 "const_int_operand"        "  i,  i")
+            (match_operand 7 "const_int_operand"        "  i,  i")
+            (match_operand 8 "const_int_operand"        "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_minus_binop:VI_D
+           (match_operand:VI_D 3 "register_operand"     " vr, vr")
+           (vec_duplicate:VI_D
+             (match_operand:<VEL> 4 "register_operand"  "  r,  r")))
+         (match_operand:VI_D 2 "vector_merge_operand"   "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "*pred_<optab><mode>_extended_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"             "=vd, vr")
+       (if_then_else:VI_D
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"     " vm,Wc1")
+            (match_operand 5 "vector_length_operand"        " rK, rK")
+            (match_operand 6 "const_int_operand"            "  i,  i")
+            (match_operand 7 "const_int_operand"            "  i,  i")
+            (match_operand 8 "const_int_operand"            "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (sat_int_minus_binop:VI_D
+           (match_operand:VI_D 3 "register_operand"         " vr, vr")
+           (vec_duplicate:VI_D
+             (sign_extend:<VEL>
+               (match_operand:<VSUBEL> 4 "register_operand" "  r,  r"))))
+         (match_operand:VI_D 2 "vector_merge_operand"       "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "v<insn>.vx\t%0,%3,%4%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])
+
 ;; 
-------------------------------------------------------------------------------
 ;; ---- Predicated integer unary operations
 ;; 
-------------------------------------------------------------------------------
-- 
2.36.1

Reply via email to