diff mbox series

RISC-V: Add integer binary vv C/C++ API support

Message ID 20230131120631.299018-1-juzhe.zhong@rivai.ai
State New
Headers show
Series RISC-V: Add integer binary vv C/C++ API support | expand

Commit Message

钟居哲 Jan. 31, 2023, 12:06 p.m. UTC
From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>

---
 gcc/config/riscv/constraints.md               |  10 +
 gcc/config/riscv/iterators.md                 |  14 +-
 gcc/config/riscv/predicates.md                |  15 ++
 .../riscv/riscv-vector-builtins-bases.cc      |  48 +++++
 .../riscv/riscv-vector-builtins-bases.h       |  17 ++
 .../riscv/riscv-vector-builtins-functions.def |  18 ++
 .../riscv/riscv-vector-builtins-shapes.cc     |  25 +++
 .../riscv/riscv-vector-builtins-shapes.h      |   1 +
 gcc/config/riscv/riscv-vector-builtins.cc     |  38 ++++
 gcc/config/riscv/riscv-vector-builtins.h      |   1 +
 gcc/config/riscv/riscv.cc                     |  10 +
 gcc/config/riscv/vector-iterators.md          | 183 ++++++++++++++++++
 gcc/config/riscv/vector.md                    |  49 ++++-
 13 files changed, 421 insertions(+), 8 deletions(-)

Comments

Kito Cheng Jan. 31, 2023, 4:46 p.m. UTC | #1
committed with comment log tweak, thanks!

On Tue, Jan 31, 2023 at 8:07 PM <juzhe.zhong@rivai.ai> wrote:
>
> From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
>
> ---
>  gcc/config/riscv/constraints.md               |  10 +
>  gcc/config/riscv/iterators.md                 |  14 +-
>  gcc/config/riscv/predicates.md                |  15 ++
>  .../riscv/riscv-vector-builtins-bases.cc      |  48 +++++
>  .../riscv/riscv-vector-builtins-bases.h       |  17 ++
>  .../riscv/riscv-vector-builtins-functions.def |  18 ++
>  .../riscv/riscv-vector-builtins-shapes.cc     |  25 +++
>  .../riscv/riscv-vector-builtins-shapes.h      |   1 +
>  gcc/config/riscv/riscv-vector-builtins.cc     |  38 ++++
>  gcc/config/riscv/riscv-vector-builtins.h      |   1 +
>  gcc/config/riscv/riscv.cc                     |  10 +
>  gcc/config/riscv/vector-iterators.md          | 183 ++++++++++++++++++
>  gcc/config/riscv/vector.md                    |  49 ++++-
>  13 files changed, 421 insertions(+), 8 deletions(-)
>
> diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
> index 7061201ba37..3637380ee47 100644
> --- a/gcc/config/riscv/constraints.md
> +++ b/gcc/config/riscv/constraints.md
> @@ -140,6 +140,16 @@
>    (and (match_code "const_vector")
>         (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -16, 15)")))
>
> +(define_constraint "vj"
> +  "A vector negated 5-bit signed immediate."
> +  (and (match_code "const_vector")
> +       (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -15, 16)")))
> +
> +(define_constraint "vk"
> +  "A vector 5-bit unsigned immediate."
> +  (and (match_code "const_vector")
> +       (match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)")))
> +
>  (define_constraint "Wc0"
>    "@internal
>   A constraint that matches a vector of immediate all zeros."
> diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
> index 0e8dbcc9e7e..9561403419b 100644
> --- a/gcc/config/riscv/iterators.md
> +++ b/gcc/config/riscv/iterators.md
> @@ -196,7 +196,12 @@
>                          (xor "xor")
>                          (and "and")
>                          (plus "add")
> -                        (minus "sub")])
> +                        (minus "sub")
> +                        (smin "smin")
> +                        (smax "smax")
> +                        (umin "umin")
> +                        (umax "umax")
> +                        (mult "mul")])
>
>  ;; <or_optab> code attributes
>  (define_code_attr or_optab [(ior "ior")
> @@ -214,7 +219,12 @@
>                         (xor "xor")
>                         (and "and")
>                         (plus "add")
> -                       (minus "sub")])
> +                       (minus "sub")
> +                       (smin "min")
> +                       (smax "max")
> +                       (umin "minu")
> +                       (umax "maxu")
> +                       (mult "mul")])
>
>  ; atomics code attribute
>  (define_code_attr atomic_optab
> diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> index f9013bbf8bb..57f7ddfbd7d 100644
> --- a/gcc/config/riscv/predicates.md
> +++ b/gcc/config/riscv/predicates.md
> @@ -286,6 +286,21 @@
>             (match_test "GET_CODE (op) == UNSPEC
>                          && (XINT (op, 1) == UNSPEC_VUNDEF)"))))
>
> +(define_predicate "vector_arith_operand"
> +  (ior (match_operand 0 "register_operand")
> +       (and (match_code "const_vector")
> +            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -16, 15)"))))
> +
> +(define_predicate "vector_neg_arith_operand"
> +  (ior (match_operand 0 "register_operand")
> +       (and (match_code "const_vector")
> +            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -15, 16)"))))
> +
> +(define_predicate "vector_shift_operand"
> +  (ior (match_operand 0 "register_operand")
> +       (and (match_code "const_vector")
> +            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)"))))
> +
>  (define_special_predicate "pmode_reg_or_0_operand"
>    (ior (match_operand 0 "const_0_operand")
>         (match_operand 0 "pmode_register_operand")))
> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 129e89f443e..f4256fedc5b 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -154,6 +154,19 @@ public:
>    }
>  };
>
> +/* Implements
> + * vadd/vsub/vrsub/vand/vor/vxor/vsll/vsra/vsrl/vmin/vmax/vminu/vmaxu/vdiv/vrem/vdivu/vremu/vsadd/vsaddu/vssub/vssubu.
> + */
> +template<rtx_code CODE>
> +class binop : public function_base
> +{
> +public:
> +  rtx expand (function_expander &e) const override
> +  {
> +    return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> +  }
> +};
> +
>  static CONSTEXPR const vsetvl<false> vsetvl_obj;
>  static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
>  static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
> @@ -178,6 +191,24 @@ static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei8_obj;
>  static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei16_obj;
>  static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei32_obj;
>  static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei64_obj;
> +static CONSTEXPR const binop<PLUS> vadd_obj;
> +static CONSTEXPR const binop<MINUS> vsub_obj;
> +static CONSTEXPR const binop<MINUS> vrsub_obj;
> +static CONSTEXPR const binop<AND> vand_obj;
> +static CONSTEXPR const binop<IOR> vor_obj;
> +static CONSTEXPR const binop<XOR> vxor_obj;
> +static CONSTEXPR const binop<ASHIFT> vsll_obj;
> +static CONSTEXPR const binop<ASHIFTRT> vsra_obj;
> +static CONSTEXPR const binop<LSHIFTRT> vsrl_obj;
> +static CONSTEXPR const binop<SMIN> vmin_obj;
> +static CONSTEXPR const binop<SMAX> vmax_obj;
> +static CONSTEXPR const binop<UMIN> vminu_obj;
> +static CONSTEXPR const binop<UMAX> vmaxu_obj;
> +static CONSTEXPR const binop<MULT> vmul_obj;
> +static CONSTEXPR const binop<DIV> vdiv_obj;
> +static CONSTEXPR const binop<MOD> vrem_obj;
> +static CONSTEXPR const binop<UDIV> vdivu_obj;
> +static CONSTEXPR const binop<UMOD> vremu_obj;
>
>  /* Declare the function base NAME, pointing it to an instance
>     of class <NAME>_obj.  */
> @@ -208,5 +239,22 @@ BASE (vsoxei8)
>  BASE (vsoxei16)
>  BASE (vsoxei32)
>  BASE (vsoxei64)
> +BASE (vadd)
> +BASE (vsub)
> +BASE (vand)
> +BASE (vor)
> +BASE (vxor)
> +BASE (vsll)
> +BASE (vsra)
> +BASE (vsrl)
> +BASE (vmin)
> +BASE (vmax)
> +BASE (vminu)
> +BASE (vmaxu)
> +BASE (vmul)
> +BASE (vdiv)
> +BASE (vrem)
> +BASE (vdivu)
> +BASE (vremu)
>
>  } // 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 238c01dbf1f..364de4bae6e 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.h
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
> @@ -48,6 +48,23 @@ extern const function_base *const vsoxei8;
>  extern const function_base *const vsoxei16;
>  extern const function_base *const vsoxei32;
>  extern const function_base *const vsoxei64;
> +extern const function_base *const vadd;
> +extern const function_base *const vsub;
> +extern const function_base *const vand;
> +extern const function_base *const vor;
> +extern const function_base *const vxor;
> +extern const function_base *const vsll;
> +extern const function_base *const vsra;
> +extern const function_base *const vsrl;
> +extern const function_base *const vmin;
> +extern const function_base *const vmax;
> +extern const function_base *const vminu;
> +extern const function_base *const vmaxu;
> +extern const function_base *const vmul;
> +extern const function_base *const vdiv;
> +extern const function_base *const vrem;
> +extern const function_base *const vdivu;
> +extern const function_base *const vremu;
>  }
>
>  } // 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 9719b9b4bf1..9f9678ab6dd 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-functions.def
> +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
> @@ -62,5 +62,23 @@ DEF_RVV_FUNCTION (vsoxei8, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uin
>  DEF_RVV_FUNCTION (vsoxei16, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint16_index_ops)
>  DEF_RVV_FUNCTION (vsoxei32, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint32_index_ops)
>  DEF_RVV_FUNCTION (vsoxei64, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint64_index_ops)
> +/* 11. Vector Integer Arithmetic Instructions.  */
> +DEF_RVV_FUNCTION (vadd, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vsub, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vand, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vor, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vxor, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vsll, binop, full_preds, iu_shift_vvv_ops)
> +DEF_RVV_FUNCTION (vsra, binop, full_preds, iu_shift_vvv_ops)
> +DEF_RVV_FUNCTION (vsrl, binop, full_preds, iu_shift_vvv_ops)
> +DEF_RVV_FUNCTION (vmin, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vmax, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vminu, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vmaxu, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vmul, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vdiv, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vrem, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vdivu, binop, full_preds, iu_vvv_ops)
> +DEF_RVV_FUNCTION (vremu, binop, full_preds, iu_vvv_ops)
>
>  #undef DEF_RVV_FUNCTION
> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> index d261dfbceb7..c8bca3598ac 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> @@ -185,9 +185,34 @@ struct indexed_loadstore_def : public function_shape
>    }
>  };
>
> +/* binop_def class.  */
> +struct binop_def : public build_base
> +{
> +  char *get_name (function_builder &b, const function_instance &instance,
> +                 bool overloaded_p) const override
> +  {
> +    b.append_base_name (instance.base_name);
> +    /* vop<sew>_v --> vop<sew>_v_<type>.  */
> +    if (!overloaded_p)
> +      {
> +       /* vop<sew> --> vop<sew>_v.  */
> +       b.append_name (operand_suffixes[instance.op_info->op]);
> +       /* vop<sew>_v --> vop<sew>_v_<type>.  */
> +       b.append_name (type_suffixes[instance.type.index].vector);
> +      }
> +    /* According to rvv-intrinsic-doc, it does not add "_m" suffix
> +       for vop_m C++ overloaded API.  */
> +    if (overloaded_p && instance.pred == PRED_TYPE_m)
> +      return b.finish_name ();
> +    b.append_name (predication_suffixes[instance.pred]);
> +    return b.finish_name ();
> +  }
> +};
> +
>  SHAPE(vsetvl, vsetvl)
>  SHAPE(vsetvl, vsetvlmax)
>  SHAPE(loadstore, loadstore)
>  SHAPE(indexed_loadstore, indexed_loadstore)
> +SHAPE(binop, binop)
>
>  } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
> index 05bc68b7f12..2903c2dfead 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
> @@ -28,6 +28,7 @@ extern const function_shape *const vsetvl;
>  extern const function_shape *const vsetvlmax;
>  extern const function_shape *const loadstore;
>  extern const function_shape *const indexed_loadstore;
> +extern const function_shape *const binop;
>  }
>
>  } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
> index df4e2ee1841..3a6c2c7c6f2 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -133,6 +133,13 @@ static const rvv_type_info i_ops[] = {
>  #include "riscv-vector-builtins-types.def"
>    {NUM_VECTOR_TYPES, 0}};
>
> +/* A list of all integer will be registered for intrinsic functions.  */
> +static const rvv_type_info iu_ops[] = {
> +#define DEF_RVV_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
> +#define DEF_RVV_U_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
> +#include "riscv-vector-builtins-types.def"
> +  {NUM_VECTOR_TYPES, 0}};
> +
>  /* A list of all types will be registered for intrinsic functions.  */
>  static const rvv_type_info all_ops[] = {
>  #define DEF_RVV_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
> @@ -232,6 +239,16 @@ static CONSTEXPR const rvv_arg_type_info scalar_ptr_uint64_index_args[]
>       rvv_arg_type_info (RVV_BASE_uint64_index),
>       rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
>
> +/* A list of args for vector_type func (vector_type, vector_type) function.  */
> +static CONSTEXPR const rvv_arg_type_info vv_args[]
> +  = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector),
> +     rvv_arg_type_info_end};
> +
> +/* A list of args for vector_type func (vector_type, shift_type) function.  */
> +static CONSTEXPR const rvv_arg_type_info shift_vv_args[]
> +  = {rvv_arg_type_info (RVV_BASE_vector),
> +     rvv_arg_type_info (RVV_BASE_shift_vector), rvv_arg_type_info_end};
> +
>  /* A list of none preds that will be registered for intrinsic functions.  */
>  static CONSTEXPR const predication_type_index none_preds[]
>    = {PRED_TYPE_none, NUM_PRED_TYPES};
> @@ -372,6 +389,22 @@ static CONSTEXPR const rvv_op_info all_v_scalar_ptr_uint64_index_ops
>       rvv_arg_type_info (RVV_BASE_void), /* Return type */
>       scalar_ptr_uint64_index_args /* Args */};
>
> +/* A static operand information for vector_type func (vector_type, vector_type)
> + * function registration. */
> +static CONSTEXPR const rvv_op_info iu_vvv_ops
> +  = {iu_ops,                           /* Types */
> +     OP_TYPE_vv,                       /* Suffix */
> +     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
> +     vv_args /* Args */};
> +
> +/* A static operand information for vector_type func (vector_type, shift_type)
> + * function registration. */
> +static CONSTEXPR const rvv_op_info iu_shift_vvv_ops
> +  = {iu_ops,                           /* Types */
> +     OP_TYPE_vv,                       /* Suffix */
> +     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
> +     shift_vv_args /* Args */};
> +
>  /* A list of all RVV intrinsic functions.  */
>  static function_group_info function_groups[] = {
>  #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         \
> @@ -674,6 +707,10 @@ rvv_arg_type_info::get_base_vector_type (tree type) const
>        inner_mode = E_DImode;
>        unsigned_p = true;
>        break;
> +    case RVV_BASE_shift_vector:
> +      inner_mode = GET_MODE_INNER (TYPE_MODE (type));
> +      unsigned_p = true;
> +      break;
>      default:
>        return NUM_VECTOR_TYPES;
>      }
> @@ -737,6 +774,7 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
>      case RVV_BASE_uint16_index:
>      case RVV_BASE_uint32_index:
>      case RVV_BASE_uint64_index:
> +    case RVV_BASE_shift_vector:
>        if (get_base_vector_type (builtin_types[type_idx].vector)
>           != NUM_VECTOR_TYPES)
>         return builtin_types[get_base_vector_type (
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index aec66b8ca4b..c20d8f8835c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.h
> +++ b/gcc/config/riscv/riscv-vector-builtins.h
> @@ -151,6 +151,7 @@ enum rvv_base_type
>    RVV_BASE_uint16_index,
>    RVV_BASE_uint32_index,
>    RVV_BASE_uint64_index,
> +  RVV_BASE_shift_vector,
>    NUM_BASE_TYPES
>  };
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index a7ba92e4a8c..209d9a53e7b 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -4242,6 +4242,16 @@ riscv_print_operand (FILE *file, rtx op, int letter)
>           output_operand_lossage ("invalid vector constant");
>         break;
>        }
> +      case 'V': {
> +       rtx elt;
> +       if (!const_vec_duplicate_p (op, &elt))
> +         output_operand_lossage ("invalid vector constant");
> +       else if (satisfies_constraint_vj (op))
> +         asm_fprintf (file, "%wd", -INTVAL (elt));
> +       else
> +         output_operand_lossage ("invalid vector constant");
> +       break;
> +      }
>        case 'm': {
>         if (riscv_v_ext_vector_mode_p (mode))
>           {
> diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
> index 2ac75b3f94c..a2f192d6ba0 100644
> --- a/gcc/config/riscv/vector-iterators.md
> +++ b/gcc/config/riscv/vector-iterators.md
> @@ -47,6 +47,14 @@
>    (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
>  ])
>
> +(define_mode_iterator VI [
> +  VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32")
> +  VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
> +  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
> +  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
> +  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
> +])
> +
>  (define_mode_iterator VNX1_QHSD [
>    VNx1QI VNx1HI VNx1SI
>    (VNx1DI "TARGET_MIN_VLEN > 32")
> @@ -177,3 +185,178 @@
>  (define_int_attr order [
>    (UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u")
>  ])
> +
> +(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
> +  smax umax smin umin mult div udiv mod umod
> +])
> +
> +(define_code_attr binop_rhs1_predicate [
> +                       (plus "register_operand")
> +                       (minus "vector_arith_operand")
> +                       (ior "register_operand")
> +                       (xor "register_operand")
> +                       (and "register_operand")
> +                       (ashift "register_operand")
> +                       (ashiftrt "register_operand")
> +                       (lshiftrt "register_operand")
> +                       (smin "register_operand")
> +                       (smax "register_operand")
> +                       (umin "register_operand")
> +                       (umax "register_operand")
> +                       (mult "register_operand")
> +                       (div "register_operand")
> +                       (mod "register_operand")
> +                       (udiv "register_operand")
> +                       (umod "register_operand")])
> +
> +(define_code_attr binop_rhs2_predicate [
> +                       (plus "vector_arith_operand")
> +                       (minus "vector_neg_arith_operand")
> +                       (ior "vector_arith_operand")
> +                       (xor "vector_arith_operand")
> +                       (and "vector_arith_operand")
> +                       (ashift "vector_shift_operand")
> +                       (ashiftrt "vector_shift_operand")
> +                       (lshiftrt "vector_shift_operand")
> +                       (smin "register_operand")
> +                       (smax "register_operand")
> +                       (umin "register_operand")
> +                       (umax "register_operand")
> +                       (mult "register_operand")
> +                       (div "register_operand")
> +                       (mod "register_operand")
> +                       (udiv "register_operand")
> +                       (umod "register_operand")])
> +
> +(define_code_attr binop_rhs1_constraint [
> +                       (plus "vr,vr,vr")
> +                       (minus "vr,vr,vi")
> +                       (ior "vr,vr,vr")
> +                       (xor "vr,vr,vr")
> +                       (and "vr,vr,vr")
> +                       (ashift "vr,vr,vr")
> +                       (ashiftrt "vr,vr,vr")
> +                       (lshiftrt "vr,vr,vr")
> +                       (smin "vr,vr,vr")
> +                       (smax "vr,vr,vr")
> +                       (umin "vr,vr,vr")
> +                       (umax "vr,vr,vr")
> +                       (mult "vr,vr,vr")
> +                       (div "vr,vr,vr")
> +                       (mod "vr,vr,vr")
> +                       (udiv "vr,vr,vr")
> +                       (umod "vr,vr,vr")])
> +
> +(define_code_attr binop_rhs2_constraint [
> +                       (plus "vr,vi,vr")
> +                       (minus "vr,vj,vr")
> +                       (ior "vr,vi,vr")
> +                       (xor "vr,vi,vr")
> +                       (and "vr,vi,vr")
> +                       (ashift "vr,vk,vr")
> +                       (ashiftrt "vr,vk,vr")
> +                       (lshiftrt "vr,vk,vr")
> +                       (smin "vr,vr,vr")
> +                       (smax "vr,vr,vr")
> +                       (umin "vr,vr,vr")
> +                       (umax "vr,vr,vr")
> +                       (mult "vr,vr,vr")
> +                       (div "vr,vr,vr")
> +                       (mod "vr,vr,vr")
> +                       (udiv "vr,vr,vr")
> +                       (umod "vr,vr,vr")])
> +
> +(define_code_attr int_binop_insn_type [
> +                       (plus "vialu")
> +                       (minus "vialu")
> +                       (ior "vialu")
> +                       (xor "vialu")
> +                       (and "vialu")
> +                       (ashift "vshift")
> +                       (ashiftrt "vshift")
> +                       (lshiftrt "vshift")
> +                       (smin "vicmp")
> +                       (smax "vicmp")
> +                       (umin "vicmp")
> +                       (umax "vicmp")
> +                       (mult "vimul")
> +                       (div "vidiv")
> +                       (mod "vidiv")
> +                       (udiv "vidiv")
> +                       (umod "vidiv")])
> +
> +;; <binop_alt1_insn> expands to the insn name of binop matching constraint alternative = 1.
> +;; minus is negated as vadd and ss_minus is negated as vsadd, others remain <insn>.
> +(define_code_attr binop_alt1_insn [(ashift "sll.vi")
> +                              (ashiftrt "sra.vi")
> +                              (lshiftrt "srl.vi")
> +                              (div "div.vv")
> +                              (mod "rem.vv")
> +                              (udiv "divu.vv")
> +                              (umod "remu.vv")
> +                              (ior "or.vv")
> +                              (xor "xor.vv")
> +                              (and "and.vv")
> +                              (plus "add.vi")
> +                              (minus "add.vi")
> +                              (smin "min.vv")
> +                              (smax "max.vv")
> +                              (umin "minu.vv")
> +                              (umax "maxu.vv")
> +                              (mult "mul.vv")])
> +
> +;; <binop_alt2_insn> expands to the insn name of binop matching constraint alternative = 2.
> +;; minus is reversed as vrsub, others remain <insn>.
> +(define_code_attr binop_alt2_insn [(ashift "sll.vv")
> +                              (ashiftrt "sra.vv")
> +                              (lshiftrt "srl.vv")
> +                              (div "div.vv")
> +                              (mod "rem.vv")
> +                              (udiv "divu.vv")
> +                              (umod "remu.vv")
> +                              (ior "or.vv")
> +                              (xor "xor.vv")
> +                              (and "and.vv")
> +                              (plus "add.vv")
> +                              (minus "rsub.vi")
> +                              (smin "min.vv")
> +                              (smax "max.vv")
> +                              (umin "minu.vv")
> +                              (umax "maxu.vv")
> +                              (mult "mul.vv")])
> +
> +(define_code_attr binop_alt1_op [(ashift "%3,%4")
> +                            (ashiftrt "%3,%4")
> +                            (lshiftrt "%3,%4")
> +                            (div "%3,%4")
> +                            (mod "%3,%4")
> +                            (udiv "%3,%4")
> +                            (umod "%3,%4")
> +                            (ior "%3,%4")
> +                            (xor "%3,%4")
> +                            (and "%3,%4")
> +                            (plus "%3,%4")
> +                            (minus "%3,%V4")
> +                            (smin "%3,%4")
> +                            (smax "%3,%4")
> +                            (umin "%3,%4")
> +                            (umax "%3,%4")
> +                            (mult "%3,%4")])
> +
> +(define_code_attr binop_alt2_op [(ashift "%3,%4")
> +                             (ashiftrt "%3,%4")
> +                             (lshiftrt "%3,%4")
> +                             (div "%3,%4")
> +                             (mod "%3,%4")
> +                             (udiv "%3,%4")
> +                             (umod "%3,%4")
> +                             (ior "%3,%4")
> +                             (xor "%3,%4")
> +                             (and "%3,%4")
> +                             (plus "%3,%4")
> +                             (minus "%4,%v3")
> +                             (smin "%3,%4")
> +                             (smax "%3,%4")
> +                             (umin "%3,%4")
> +                             (umax "%3,%4")
> +                             (mult "%3,%4")])
> diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
> index 403d2f6cda3..e8d75f164e3 100644
> --- a/gcc/config/riscv/vector.md
> +++ b/gcc/config/riscv/vector.md
> @@ -141,7 +141,8 @@
>
>  ;; It is valid for instruction that require sew/lmul ratio.
>  (define_attr "ratio" ""
> -  (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox")
> +  (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
> +                         vialu,vshift,vicmp,vimul,vidiv,vsalu")
>            (const_int INVALID_ATTRIBUTE)
>          (eq_attr "mode" "VNx1QI,VNx1BI")
>            (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
> @@ -191,7 +192,8 @@
>
>  ;; The index of operand[] to get the merge op.
>  (define_attr "merge_op_idx" ""
> -       (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox")
> +       (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
> +                               vialu,vshift,vicmp,vimul,vidiv,vsalu")
>          (const_int 2)]
>         (const_int INVALID_ATTRIBUTE)))
>
> @@ -207,7 +209,7 @@
>               (const_int 5)
>               (const_int 4))
>
> -        (eq_attr "type" "vldux,vldox")
> +        (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
>            (const_int 5)]
>    (const_int INVALID_ATTRIBUTE)))
>
> @@ -223,7 +225,7 @@
>              (symbol_ref "riscv_vector::get_ta(operands[6])")
>              (symbol_ref "riscv_vector::get_ta(operands[5])"))
>
> -        (eq_attr "type" "vldux,vldox")
> +        (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
>            (symbol_ref "riscv_vector::get_ta(operands[6])")]
>         (const_int INVALID_ATTRIBUTE)))
>
> @@ -239,7 +241,7 @@
>              (symbol_ref "riscv_vector::get_ma(operands[7])")
>              (symbol_ref "riscv_vector::get_ma(operands[6])"))
>
> -        (eq_attr "type" "vldux,vldox")
> +        (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
>            (symbol_ref "riscv_vector::get_ma(operands[7])")]
>         (const_int INVALID_ATTRIBUTE)))
>
> @@ -257,7 +259,7 @@
>              (const_int INVALID_ATTRIBUTE)
>              (symbol_ref "INTVAL (operands[7])"))
>
> -        (eq_attr "type" "vldux,vldox")
> +        (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
>            (symbol_ref "INTVAL (operands[8])")
>          (eq_attr "type" "vstux,vstox")
>            (symbol_ref "INTVAL (operands[5])")]
> @@ -1111,3 +1113,38 @@
>    "vs<order>xei<VNX64_Q:sew>.v\t%3,(%1),%2%p0"
>    [(set_attr "type" "vst<order>x")
>     (set_attr "mode" "<VNX64_Q:MODE>")])
> +
> +;; -------------------------------------------------------------------------------
> +;; ---- Predicated integer binary operations
> +;; -------------------------------------------------------------------------------
> +;; Includes:
> +;; - 11.1 Vector Single-Width Integer Add and Subtract
> +;; - 11.5 Vector Bitwise Logical Instructions
> +;; - 11.6 Vector Single-Width Bit Shift Instructions
> +;; - 11.9 Vector Integer Min/Max Instructions
> +;; - 11.11 Vector Integer Divide Instructions
> +;; - 12.1 Vector Single-Width Saturating Add and Subtract
> +;; -------------------------------------------------------------------------------
> +
> +(define_insn "@pred_<optab><mode>"
> +  [(set (match_operand:VI 0 "register_operand"                   "=vr,   vr,   vr")
> +       (if_then_else:VI
> +         (unspec:<VM>
> +           [(match_operand:<VM> 1 "vector_mask_operand" "      vmWc1,vmWc1,vmWc1")
> +            (match_operand 5 "vector_length_operand"    "         rK,   rK,   rK")
> +            (match_operand 6 "const_int_operand"        "          i,    i,    i")
> +            (match_operand 7 "const_int_operand"        "          i,    i,    i")
> +            (match_operand 8 "const_int_operand"        "          i,    i,    i")
> +            (reg:SI VL_REGNUM)
> +            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
> +         (any_int_binop:VI
> +           (match_operand:VI 3 "<binop_rhs1_predicate>" "<binop_rhs1_constraint>")
> +           (match_operand:VI 4 "<binop_rhs2_predicate>" "<binop_rhs2_constraint>"))
> +         (match_operand:VI 2 "vector_merge_operand"     "        0vu,  0vu,  0vu")))]
> +  "TARGET_VECTOR"
> +  "@
> +   v<insn>.vv\t%0,%3,%4%p1
> +   v<binop_alt1_insn>\t%0,<binop_alt1_op>%p1
> +   v<binop_alt2_insn>\t%0,<binop_alt2_op>%p1"
> +  [(set_attr "type" "<int_binop_insn_type>")
> +   (set_attr "mode" "<MODE>")])
> --
> 2.36.3
>
diff mbox series

Patch

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 7061201ba37..3637380ee47 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -140,6 +140,16 @@ 
   (and (match_code "const_vector")
        (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -16, 15)")))
 
+(define_constraint "vj"
+  "A vector negated 5-bit signed immediate."
+  (and (match_code "const_vector")
+       (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -15, 16)")))
+
+(define_constraint "vk"
+  "A vector 5-bit unsigned immediate."
+  (and (match_code "const_vector")
+       (match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)")))
+
 (define_constraint "Wc0"
   "@internal
  A constraint that matches a vector of immediate all zeros."
diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 0e8dbcc9e7e..9561403419b 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -196,7 +196,12 @@ 
 			 (xor "xor")
 			 (and "and")
 			 (plus "add")
-			 (minus "sub")])
+			 (minus "sub")
+			 (smin "smin")
+			 (smax "smax")
+			 (umin "umin")
+			 (umax "umax")
+			 (mult "mul")])
 
 ;; <or_optab> code attributes
 (define_code_attr or_optab [(ior "ior")
@@ -214,7 +219,12 @@ 
 			(xor "xor")
 			(and "and")
 			(plus "add")
-			(minus "sub")])
+			(minus "sub")
+			(smin "min")
+			(smax "max")
+			(umin "minu")
+			(umax "maxu")
+			(mult "mul")])
 
 ; atomics code attribute
 (define_code_attr atomic_optab
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index f9013bbf8bb..57f7ddfbd7d 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -286,6 +286,21 @@ 
 	    (match_test "GET_CODE (op) == UNSPEC
 			 && (XINT (op, 1) == UNSPEC_VUNDEF)"))))
 
+(define_predicate "vector_arith_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_code "const_vector")
+            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -16, 15)"))))
+
+(define_predicate "vector_neg_arith_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_code "const_vector")
+            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, -15, 16)"))))
+
+(define_predicate "vector_shift_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_code "const_vector")
+            (match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)"))))
+
 (define_special_predicate "pmode_reg_or_0_operand"
   (ior (match_operand 0 "const_0_operand")
        (match_operand 0 "pmode_register_operand")))
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 129e89f443e..f4256fedc5b 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -154,6 +154,19 @@  public:
   }
 };
 
+/* Implements
+ * vadd/vsub/vrsub/vand/vor/vxor/vsll/vsra/vsrl/vmin/vmax/vminu/vmaxu/vdiv/vrem/vdivu/vremu/vsadd/vsaddu/vssub/vssubu.
+ */
+template<rtx_code CODE>
+class binop : public function_base
+{
+public:
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
+  }
+};
+
 static CONSTEXPR const vsetvl<false> vsetvl_obj;
 static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
 static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@@ -178,6 +191,24 @@  static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei8_obj;
 static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei16_obj;
 static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei32_obj;
 static CONSTEXPR const loadstore<true, LST_INDEXED, true> vsoxei64_obj;
+static CONSTEXPR const binop<PLUS> vadd_obj;
+static CONSTEXPR const binop<MINUS> vsub_obj;
+static CONSTEXPR const binop<MINUS> vrsub_obj;
+static CONSTEXPR const binop<AND> vand_obj;
+static CONSTEXPR const binop<IOR> vor_obj;
+static CONSTEXPR const binop<XOR> vxor_obj;
+static CONSTEXPR const binop<ASHIFT> vsll_obj;
+static CONSTEXPR const binop<ASHIFTRT> vsra_obj;
+static CONSTEXPR const binop<LSHIFTRT> vsrl_obj;
+static CONSTEXPR const binop<SMIN> vmin_obj;
+static CONSTEXPR const binop<SMAX> vmax_obj;
+static CONSTEXPR const binop<UMIN> vminu_obj;
+static CONSTEXPR const binop<UMAX> vmaxu_obj;
+static CONSTEXPR const binop<MULT> vmul_obj;
+static CONSTEXPR const binop<DIV> vdiv_obj;
+static CONSTEXPR const binop<MOD> vrem_obj;
+static CONSTEXPR const binop<UDIV> vdivu_obj;
+static CONSTEXPR const binop<UMOD> vremu_obj;
 
 /* Declare the function base NAME, pointing it to an instance
    of class <NAME>_obj.  */
@@ -208,5 +239,22 @@  BASE (vsoxei8)
 BASE (vsoxei16)
 BASE (vsoxei32)
 BASE (vsoxei64)
+BASE (vadd)
+BASE (vsub)
+BASE (vand)
+BASE (vor)
+BASE (vxor)
+BASE (vsll)
+BASE (vsra)
+BASE (vsrl)
+BASE (vmin)
+BASE (vmax)
+BASE (vminu)
+BASE (vmaxu)
+BASE (vmul)
+BASE (vdiv)
+BASE (vrem)
+BASE (vdivu)
+BASE (vremu)
 
 } // 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 238c01dbf1f..364de4bae6e 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -48,6 +48,23 @@  extern const function_base *const vsoxei8;
 extern const function_base *const vsoxei16;
 extern const function_base *const vsoxei32;
 extern const function_base *const vsoxei64;
+extern const function_base *const vadd;
+extern const function_base *const vsub;
+extern const function_base *const vand;
+extern const function_base *const vor;
+extern const function_base *const vxor;
+extern const function_base *const vsll;
+extern const function_base *const vsra;
+extern const function_base *const vsrl;
+extern const function_base *const vmin;
+extern const function_base *const vmax;
+extern const function_base *const vminu;
+extern const function_base *const vmaxu;
+extern const function_base *const vmul;
+extern const function_base *const vdiv;
+extern const function_base *const vrem;
+extern const function_base *const vdivu;
+extern const function_base *const vremu;
 }
 
 } // 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 9719b9b4bf1..9f9678ab6dd 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -62,5 +62,23 @@  DEF_RVV_FUNCTION (vsoxei8, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uin
 DEF_RVV_FUNCTION (vsoxei16, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint16_index_ops)
 DEF_RVV_FUNCTION (vsoxei32, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint32_index_ops)
 DEF_RVV_FUNCTION (vsoxei64, indexed_loadstore, none_m_preds, all_v_scalar_ptr_uint64_index_ops)
+/* 11. Vector Integer Arithmetic Instructions.  */
+DEF_RVV_FUNCTION (vadd, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vsub, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vand, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vor, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vxor, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vsll, binop, full_preds, iu_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsra, binop, full_preds, iu_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsrl, binop, full_preds, iu_shift_vvv_ops)
+DEF_RVV_FUNCTION (vmin, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vmax, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vminu, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vmaxu, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vmul, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vdiv, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vrem, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vdivu, binop, full_preds, iu_vvv_ops)
+DEF_RVV_FUNCTION (vremu, binop, full_preds, iu_vvv_ops)
 
 #undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index d261dfbceb7..c8bca3598ac 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -185,9 +185,34 @@  struct indexed_loadstore_def : public function_shape
   }
 };
 
+/* binop_def class.  */
+struct binop_def : public build_base
+{
+  char *get_name (function_builder &b, const function_instance &instance,
+		  bool overloaded_p) const override
+  {
+    b.append_base_name (instance.base_name);
+    /* vop<sew>_v --> vop<sew>_v_<type>.  */
+    if (!overloaded_p)
+      {
+	/* vop<sew> --> vop<sew>_v.  */
+	b.append_name (operand_suffixes[instance.op_info->op]);
+	/* vop<sew>_v --> vop<sew>_v_<type>.  */
+	b.append_name (type_suffixes[instance.type.index].vector);
+      }
+    /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+       for vop_m C++ overloaded API.  */
+    if (overloaded_p && instance.pred == PRED_TYPE_m)
+      return b.finish_name ();
+    b.append_name (predication_suffixes[instance.pred]);
+    return b.finish_name ();
+  }
+};
+
 SHAPE(vsetvl, vsetvl)
 SHAPE(vsetvl, vsetvlmax)
 SHAPE(loadstore, loadstore)
 SHAPE(indexed_loadstore, indexed_loadstore)
+SHAPE(binop, binop)
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
index 05bc68b7f12..2903c2dfead 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -28,6 +28,7 @@  extern const function_shape *const vsetvl;
 extern const function_shape *const vsetvlmax;
 extern const function_shape *const loadstore;
 extern const function_shape *const indexed_loadstore;
+extern const function_shape *const binop;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index df4e2ee1841..3a6c2c7c6f2 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -133,6 +133,13 @@  static const rvv_type_info i_ops[] = {
 #include "riscv-vector-builtins-types.def"
   {NUM_VECTOR_TYPES, 0}};
 
+/* A list of all integer will be registered for intrinsic functions.  */
+static const rvv_type_info iu_ops[] = {
+#define DEF_RVV_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#define DEF_RVV_U_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
 /* A list of all types will be registered for intrinsic functions.  */
 static const rvv_type_info all_ops[] = {
 #define DEF_RVV_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
@@ -232,6 +239,16 @@  static CONSTEXPR const rvv_arg_type_info scalar_ptr_uint64_index_args[]
      rvv_arg_type_info (RVV_BASE_uint64_index),
      rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (vector_type, vector_type) function.  */
+static CONSTEXPR const rvv_arg_type_info vv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (vector_type, shift_type) function.  */
+static CONSTEXPR const rvv_arg_type_info shift_vv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_shift_vector), rvv_arg_type_info_end};
+
 /* A list of none preds that will be registered for intrinsic functions.  */
 static CONSTEXPR const predication_type_index none_preds[]
   = {PRED_TYPE_none, NUM_PRED_TYPES};
@@ -372,6 +389,22 @@  static CONSTEXPR const rvv_op_info all_v_scalar_ptr_uint64_index_ops
      rvv_arg_type_info (RVV_BASE_void), /* Return type */
      scalar_ptr_uint64_index_args /* Args */};
 
+/* A static operand information for vector_type func (vector_type, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_vvv_ops
+  = {iu_ops,				/* Types */
+     OP_TYPE_vv,			/* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, shift_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_shift_vvv_ops
+  = {iu_ops,				/* Types */
+     OP_TYPE_vv,			/* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     shift_vv_args /* Args */};
+
 /* A list of all RVV intrinsic functions.  */
 static function_group_info function_groups[] = {
 #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         \
@@ -674,6 +707,10 @@  rvv_arg_type_info::get_base_vector_type (tree type) const
       inner_mode = E_DImode;
       unsigned_p = true;
       break;
+    case RVV_BASE_shift_vector:
+      inner_mode = GET_MODE_INNER (TYPE_MODE (type));
+      unsigned_p = true;
+      break;
     default:
       return NUM_VECTOR_TYPES;
     }
@@ -737,6 +774,7 @@  rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
     case RVV_BASE_uint16_index:
     case RVV_BASE_uint32_index:
     case RVV_BASE_uint64_index:
+    case RVV_BASE_shift_vector:
       if (get_base_vector_type (builtin_types[type_idx].vector)
 	  != NUM_VECTOR_TYPES)
 	return builtin_types[get_base_vector_type (
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index aec66b8ca4b..c20d8f8835c 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -151,6 +151,7 @@  enum rvv_base_type
   RVV_BASE_uint16_index,
   RVV_BASE_uint32_index,
   RVV_BASE_uint64_index,
+  RVV_BASE_shift_vector,
   NUM_BASE_TYPES
 };
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a7ba92e4a8c..209d9a53e7b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4242,6 +4242,16 @@  riscv_print_operand (FILE *file, rtx op, int letter)
 	  output_operand_lossage ("invalid vector constant");
 	break;
       }
+      case 'V': {
+	rtx elt;
+	if (!const_vec_duplicate_p (op, &elt))
+	  output_operand_lossage ("invalid vector constant");
+	else if (satisfies_constraint_vj (op))
+	  asm_fprintf (file, "%wd", -INTVAL (elt));
+	else
+	  output_operand_lossage ("invalid vector constant");
+	break;
+      }
       case 'm': {
 	if (riscv_v_ext_vector_mode_p (mode))
 	  {
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 2ac75b3f94c..a2f192d6ba0 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -47,6 +47,14 @@ 
   (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
 ])
 
+(define_mode_iterator VI [
+  VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32")
+  VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
+  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
 (define_mode_iterator VNX1_QHSD [
   VNx1QI VNx1HI VNx1SI
   (VNx1DI "TARGET_MIN_VLEN > 32")
@@ -177,3 +185,178 @@ 
 (define_int_attr order [
   (UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u")
 ])
+
+(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
+  smax umax smin umin mult div udiv mod umod
+])
+
+(define_code_attr binop_rhs1_predicate [
+			(plus "register_operand")
+			(minus "vector_arith_operand")
+			(ior "register_operand")
+			(xor "register_operand")
+			(and "register_operand")
+			(ashift "register_operand")
+			(ashiftrt "register_operand")
+			(lshiftrt "register_operand")
+			(smin "register_operand")
+			(smax "register_operand")
+			(umin "register_operand")
+			(umax "register_operand")
+			(mult "register_operand")
+			(div "register_operand")
+			(mod "register_operand")
+			(udiv "register_operand")
+			(umod "register_operand")])
+
+(define_code_attr binop_rhs2_predicate [
+			(plus "vector_arith_operand")
+			(minus "vector_neg_arith_operand")
+			(ior "vector_arith_operand")
+			(xor "vector_arith_operand")
+			(and "vector_arith_operand")
+			(ashift "vector_shift_operand")
+			(ashiftrt "vector_shift_operand")
+			(lshiftrt "vector_shift_operand")
+			(smin "register_operand")
+			(smax "register_operand")
+			(umin "register_operand")
+			(umax "register_operand")
+			(mult "register_operand")
+			(div "register_operand")
+			(mod "register_operand")
+			(udiv "register_operand")
+			(umod "register_operand")])
+
+(define_code_attr binop_rhs1_constraint [
+			(plus "vr,vr,vr")
+			(minus "vr,vr,vi")
+			(ior "vr,vr,vr")
+			(xor "vr,vr,vr")
+			(and "vr,vr,vr")
+			(ashift "vr,vr,vr")
+			(ashiftrt "vr,vr,vr")
+			(lshiftrt "vr,vr,vr")
+			(smin "vr,vr,vr")
+			(smax "vr,vr,vr")
+			(umin "vr,vr,vr")
+			(umax "vr,vr,vr")
+			(mult "vr,vr,vr")
+			(div "vr,vr,vr")
+			(mod "vr,vr,vr")
+			(udiv "vr,vr,vr")
+			(umod "vr,vr,vr")])
+
+(define_code_attr binop_rhs2_constraint [
+			(plus "vr,vi,vr")
+			(minus "vr,vj,vr")
+			(ior "vr,vi,vr")
+			(xor "vr,vi,vr")
+			(and "vr,vi,vr")
+			(ashift "vr,vk,vr")
+			(ashiftrt "vr,vk,vr")
+			(lshiftrt "vr,vk,vr")
+			(smin "vr,vr,vr")
+			(smax "vr,vr,vr")
+			(umin "vr,vr,vr")
+			(umax "vr,vr,vr")
+			(mult "vr,vr,vr")
+			(div "vr,vr,vr")
+			(mod "vr,vr,vr")
+			(udiv "vr,vr,vr")
+			(umod "vr,vr,vr")])
+
+(define_code_attr int_binop_insn_type [
+			(plus "vialu")
+			(minus "vialu")
+			(ior "vialu")
+			(xor "vialu")
+			(and "vialu")
+			(ashift "vshift")
+			(ashiftrt "vshift")
+			(lshiftrt "vshift")
+			(smin "vicmp")
+			(smax "vicmp")
+			(umin "vicmp")
+			(umax "vicmp")
+			(mult "vimul")
+			(div "vidiv")
+			(mod "vidiv")
+			(udiv "vidiv")
+			(umod "vidiv")])
+
+;; <binop_alt1_insn> expands to the insn name of binop matching constraint alternative = 1.
+;; minus is negated as vadd and ss_minus is negated as vsadd, others remain <insn>.
+(define_code_attr binop_alt1_insn [(ashift "sll.vi")
+			       (ashiftrt "sra.vi")
+			       (lshiftrt "srl.vi")
+			       (div "div.vv")
+			       (mod "rem.vv")
+			       (udiv "divu.vv")
+			       (umod "remu.vv")
+			       (ior "or.vv")
+			       (xor "xor.vv")
+			       (and "and.vv")
+			       (plus "add.vi")
+			       (minus "add.vi")
+			       (smin "min.vv")
+			       (smax "max.vv")
+			       (umin "minu.vv")
+			       (umax "maxu.vv")
+			       (mult "mul.vv")])
+
+;; <binop_alt2_insn> expands to the insn name of binop matching constraint alternative = 2.
+;; minus is reversed as vrsub, others remain <insn>.
+(define_code_attr binop_alt2_insn [(ashift "sll.vv")
+			       (ashiftrt "sra.vv")
+			       (lshiftrt "srl.vv")
+			       (div "div.vv")
+			       (mod "rem.vv")
+			       (udiv "divu.vv")
+			       (umod "remu.vv")
+			       (ior "or.vv")
+			       (xor "xor.vv")
+			       (and "and.vv")
+			       (plus "add.vv")
+			       (minus "rsub.vi")
+			       (smin "min.vv")
+			       (smax "max.vv")
+			       (umin "minu.vv")
+			       (umax "maxu.vv")
+			       (mult "mul.vv")])
+
+(define_code_attr binop_alt1_op [(ashift "%3,%4")
+			     (ashiftrt "%3,%4")
+			     (lshiftrt "%3,%4")
+			     (div "%3,%4")
+			     (mod "%3,%4")
+			     (udiv "%3,%4")
+			     (umod "%3,%4")
+			     (ior "%3,%4")
+			     (xor "%3,%4")
+			     (and "%3,%4")
+			     (plus "%3,%4")
+			     (minus "%3,%V4")
+			     (smin "%3,%4")
+			     (smax "%3,%4")
+			     (umin "%3,%4")
+			     (umax "%3,%4")
+			     (mult "%3,%4")])
+
+(define_code_attr binop_alt2_op [(ashift "%3,%4")
+			      (ashiftrt "%3,%4")
+			      (lshiftrt "%3,%4")
+			      (div "%3,%4")
+			      (mod "%3,%4")
+			      (udiv "%3,%4")
+			      (umod "%3,%4")
+			      (ior "%3,%4")
+			      (xor "%3,%4")
+			      (and "%3,%4")
+			      (plus "%3,%4")
+			      (minus "%4,%v3")
+			      (smin "%3,%4")
+			      (smax "%3,%4")
+			      (umin "%3,%4")
+			      (umax "%3,%4")
+			      (mult "%3,%4")])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 403d2f6cda3..e8d75f164e3 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -141,7 +141,8 @@ 
 
 ;; It is valid for instruction that require sew/lmul ratio.
 (define_attr "ratio" ""
-  (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox")
+  (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
+			  vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	   (const_int INVALID_ATTRIBUTE)
 	 (eq_attr "mode" "VNx1QI,VNx1BI")
 	   (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
@@ -191,7 +192,8 @@ 
 
 ;; The index of operand[] to get the merge op.
 (define_attr "merge_op_idx" ""
-	(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox")
+	(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
+				vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	 (const_int 2)]
 	(const_int INVALID_ATTRIBUTE)))
 
@@ -207,7 +209,7 @@ 
              (const_int 5)
              (const_int 4))
 
-	 (eq_attr "type" "vldux,vldox")
+	 (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	   (const_int 5)]
   (const_int INVALID_ATTRIBUTE)))
 
@@ -223,7 +225,7 @@ 
 	     (symbol_ref "riscv_vector::get_ta(operands[6])")
 	     (symbol_ref "riscv_vector::get_ta(operands[5])"))
 
-	 (eq_attr "type" "vldux,vldox")
+	 (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	   (symbol_ref "riscv_vector::get_ta(operands[6])")]
 	(const_int INVALID_ATTRIBUTE)))
 
@@ -239,7 +241,7 @@ 
 	     (symbol_ref "riscv_vector::get_ma(operands[7])")
 	     (symbol_ref "riscv_vector::get_ma(operands[6])"))
 
-	 (eq_attr "type" "vldux,vldox")
+	 (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	   (symbol_ref "riscv_vector::get_ma(operands[7])")]
 	(const_int INVALID_ATTRIBUTE)))
 
@@ -257,7 +259,7 @@ 
 	     (const_int INVALID_ATTRIBUTE)
 	     (symbol_ref "INTVAL (operands[7])"))
 
-	 (eq_attr "type" "vldux,vldox")
+	 (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu")
 	   (symbol_ref "INTVAL (operands[8])")
 	 (eq_attr "type" "vstux,vstox")
 	   (symbol_ref "INTVAL (operands[5])")]
@@ -1111,3 +1113,38 @@ 
   "vs<order>xei<VNX64_Q:sew>.v\t%3,(%1),%2%p0"
   [(set_attr "type" "vst<order>x")
    (set_attr "mode" "<VNX64_Q:MODE>")])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated integer binary operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 11.1 Vector Single-Width Integer Add and Subtract
+;; - 11.5 Vector Bitwise Logical Instructions
+;; - 11.6 Vector Single-Width Bit Shift Instructions
+;; - 11.9 Vector Integer Min/Max Instructions
+;; - 11.11 Vector Integer Divide Instructions
+;; - 12.1 Vector Single-Width Saturating Add and Subtract
+;; -------------------------------------------------------------------------------
+
+(define_insn "@pred_<optab><mode>"
+  [(set (match_operand:VI 0 "register_operand"                   "=vr,   vr,   vr")
+	(if_then_else:VI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand" "      vmWc1,vmWc1,vmWc1")
+	     (match_operand 5 "vector_length_operand"    "         rK,   rK,   rK")
+	     (match_operand 6 "const_int_operand"        "          i,    i,    i")
+	     (match_operand 7 "const_int_operand"        "          i,    i,    i")
+	     (match_operand 8 "const_int_operand"        "          i,    i,    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (any_int_binop:VI
+	    (match_operand:VI 3 "<binop_rhs1_predicate>" "<binop_rhs1_constraint>")
+	    (match_operand:VI 4 "<binop_rhs2_predicate>" "<binop_rhs2_constraint>"))
+	  (match_operand:VI 2 "vector_merge_operand"     "        0vu,  0vu,  0vu")))]
+  "TARGET_VECTOR"
+  "@
+   v<insn>.vv\t%0,%3,%4%p1
+   v<binop_alt1_insn>\t%0,<binop_alt1_op>%p1
+   v<binop_alt2_insn>\t%0,<binop_alt2_op>%p1"
+  [(set_attr "type" "<int_binop_insn_type>")
+   (set_attr "mode" "<MODE>")])