blob: 22b77ccd3d5c30b35edc9b88f9d6903875ebdc57 [file] [log] [blame]
/* function_base implementation for RISC-V 'V' Extension for GNU compiler.
Copyright (C) 2022-2025 Free Software Foundation, Inc.
Contributed by Ju-Zhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "memmodel.h"
#include "insn-codes.h"
#include "optabs.h"
#include "recog.h"
#include "expr.h"
#include "basic-block.h"
#include "function.h"
#include "fold-const.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "explow.h"
#include "emit-rtl.h"
#include "tree-vector-builder.h"
#include "rtx-vector-builder.h"
#include "riscv-vector-builtins.h"
#include "riscv-vector-builtins-shapes.h"
#include "riscv-vector-builtins-bases.h"
using namespace riscv_vector;
namespace riscv_vector {
/* Enumerates types of loads/stores operations.
It's only used in here so we don't define it
in riscv-vector-builtins-bases.h. */
enum lst_type
{
LST_UNIT_STRIDE,
LST_STRIDED,
LST_INDEXED,
};
/* Helper function to fold vleff and vlsegff. */
static gimple *
fold_fault_load (gimple_folder &f)
{
/* fold fault_load (const *base, size_t *new_vl, size_t vl)
====> fault_load (const *base, size_t vl)
new_vl = MEM_REF[read_vl ()]. */
auto_vec<tree> vargs (gimple_call_num_args (f.call) - 1);
for (unsigned i = 0; i < gimple_call_num_args (f.call); i++)
{
/* Exclude size_t *new_vl argument. */
if (i == gimple_call_num_args (f.call) - 2)
continue;
vargs.quick_push (gimple_call_arg (f.call, i));
}
gimple *repl = gimple_build_call_vec (gimple_call_fn (f.call), vargs);
gimple_call_set_lhs (repl, f.lhs);
/* Handle size_t *new_vl by read_vl. */
tree new_vl = gimple_call_arg (f.call, gimple_call_num_args (f.call) - 2);
if (integer_zerop (new_vl))
{
/* This case happens when user passes the nullptr to new_vl argument.
In this case, we just need to ignore the new_vl argument and return
fault_load instruction directly. */
return repl;
}
tree tmp_var = create_tmp_var (size_type_node, "new_vl");
tree decl = get_read_vl_decl ();
gimple *g = gimple_build_call (decl, 0);
gimple_call_set_lhs (g, tmp_var);
tree indirect
= fold_build2 (MEM_REF, size_type_node,
gimple_call_arg (f.call, gimple_call_num_args (f.call) - 2),
build_int_cst (build_pointer_type (size_type_node), 0));
gassign *assign = gimple_build_assign (indirect, tmp_var);
gsi_insert_after (f.gsi, assign, GSI_SAME_STMT);
gsi_insert_after (f.gsi, g, GSI_SAME_STMT);
return repl;
}
/* Implements vsetvl<mode> && vsetvlmax<mode>. */
template<bool VLMAX_P>
class vsetvl : public function_base
{
public:
bool apply_vl_p () const override
{
return false;
}
rtx expand (function_expander &e) const override
{
if (VLMAX_P)
e.add_input_operand (Pmode, gen_rtx_REG (Pmode, 0));
else
e.add_input_operand (0);
tree type = builtin_types[e.type.index].vector;
machine_mode mode = TYPE_MODE (type);
if (TARGET_XTHEADVECTOR)
{
machine_mode inner_mode = GET_MODE_INNER (mode);
/* SEW. */
e.add_input_operand (Pmode,
gen_int_mode (GET_MODE_BITSIZE (inner_mode), Pmode));
/* LMUL. */
e.add_input_operand (Pmode,
gen_int_mode (get_vlmul (mode), Pmode));
}
else
{
/* Normalize same RATO (SEW/LMUL) into same vsetvl instruction.
- e8,mf8/e16,mf4/e32,mf2/e64,m1 --> e8mf8
- e8,mf4/e16,mf2/e32,m1/e64,m2 --> e8mf4
- e8,mf2/e16,m1/e32,m2/e64,m4 --> e8mf2
- e8,m1/e16,m2/e32,m4/e64,m8 --> e8m1
- e8,m2/e16,m4/e32,m8 --> e8m2
- e8,m4/e16,m8 --> e8m4
- e8,m8 --> e8m8
*/
/* SEW. */
e.add_input_operand (Pmode, gen_int_mode (8, Pmode));
/* LMUL. */
machine_mode e8_mode
= get_vector_mode (QImode, GET_MODE_NUNITS (mode)).require ();
e.add_input_operand (Pmode, gen_int_mode (get_vlmul (e8_mode), Pmode));
}
/* TAIL_ANY. */
e.add_input_operand (Pmode,
gen_int_mode (get_prefer_tail_policy (), Pmode));
/* MASK_ANY. */
e.add_input_operand (Pmode,
gen_int_mode (get_prefer_mask_policy (), Pmode));
return e.generate_insn (code_for_vsetvl_no_side_effects (Pmode));
}
};
/* Implements
* vle.v/vse.v/vlm.v/vsm.v/vlse.v/vsse.v/vluxei.v/vloxei.v/vsuxei.v/vsoxei.v
* codegen. */
template<bool STORE_P, lst_type LST_TYPE, bool ORDERED_P>
class loadstore : public function_base
{
public:
bool apply_tail_policy_p () const override { return !STORE_P; }
bool apply_mask_policy_p () const override { return !STORE_P; }
unsigned int call_properties (const function_instance &) const override
{
if (STORE_P)
return CP_WRITE_MEMORY;
else
return CP_READ_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
if (STORE_P || LST_TYPE == LST_INDEXED)
return true;
return pred != PRED_TYPE_none;
}
rtx expand (function_expander &e) const override
{
if (LST_TYPE == LST_INDEXED)
{
int unspec = ORDERED_P ? UNSPEC_ORDERED : UNSPEC_UNORDERED;
if (STORE_P)
return e.use_exact_insn (
code_for_pred_indexed_store (unspec, e.vector_mode (),
e.index_mode ()));
else
{
unsigned src_eew_bitsize
= GET_MODE_BITSIZE (GET_MODE_INNER (e.index_mode ()));
unsigned dst_eew_bitsize
= GET_MODE_BITSIZE (GET_MODE_INNER (e.vector_mode ()));
if (dst_eew_bitsize == src_eew_bitsize)
return e.use_exact_insn (
code_for_pred_indexed_load_same_eew (unspec, e.vector_mode ()));
else if (dst_eew_bitsize > src_eew_bitsize)
{
unsigned factor = dst_eew_bitsize / src_eew_bitsize;
switch (factor)
{
case 2:
return e.use_exact_insn (
code_for_pred_indexed_load_x2_greater_eew (
unspec, e.vector_mode ()));
case 4:
return e.use_exact_insn (
code_for_pred_indexed_load_x4_greater_eew (
unspec, e.vector_mode ()));
case 8:
return e.use_exact_insn (
code_for_pred_indexed_load_x8_greater_eew (
unspec, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
else
{
unsigned factor = src_eew_bitsize / dst_eew_bitsize;
switch (factor)
{
case 2:
return e.use_exact_insn (
code_for_pred_indexed_load_x2_smaller_eew (
unspec, e.vector_mode ()));
case 4:
return e.use_exact_insn (
code_for_pred_indexed_load_x4_smaller_eew (
unspec, e.vector_mode ()));
case 8:
return e.use_exact_insn (
code_for_pred_indexed_load_x8_smaller_eew (
unspec, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
}
}
else if (LST_TYPE == LST_STRIDED)
{
if (STORE_P)
return e.use_contiguous_store_insn (
code_for_pred_strided_store (e.vector_mode ()));
else
return e.use_contiguous_load_insn (
code_for_pred_strided_load (e.vector_mode ()));
}
else
{
if (STORE_P)
return e.use_contiguous_store_insn (
code_for_pred_store (e.vector_mode ()));
else
return e.use_contiguous_load_insn (
code_for_pred_mov (e.vector_mode ()));
}
}
};
/* Implements
vadd/vsub/vand/vor/vxor/vsll/vsra/vsrl/
vmin/vmax/vminu/vmaxu/vdiv/vrem/vdivu/
vremu/vsadd/vsaddu/vssub/vssubu
vfadd/vfsub/
*/
template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
enum frm_op_type FRM_OP = NO_FRM>
class binop : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vx:
gcc_assert (FRM_OP == NO_FRM);
case OP_TYPE_vf:
return e.use_exact_insn (code_for_pred_scalar (CODE, e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vrsub. */
class vrsub : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_sub_reverse_scalar (e.vector_mode ()));
}
};
/* Implements vneg/vnot. */
template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
class unop : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
}
};
/* Implements vsext.vf2/vsext.vf4/vsext.vf8/vzext.vf2/vzext.vf4/vzext.vf8. */
template<rtx_code CODE>
class ext : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vf2:
return e.use_exact_insn (code_for_pred_vf2 (CODE, e.vector_mode ()));
case OP_TYPE_vf4:
return e.use_exact_insn (code_for_pred_vf4 (CODE, e.vector_mode ()));
case OP_TYPE_vf8:
return e.use_exact_insn (code_for_pred_vf8 (CODE, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vmulh/vmulhu/vmulhsu. */
template<int UNSPEC>
class vmulh : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_mulh_scalar (UNSPEC, e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_mulh (UNSPEC, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vwadd/vwsub/vwmul. */
template<rtx_code CODE1, rtx_code CODE2 = FLOAT_EXTEND>
class widen_binop : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_dual_widen (CODE1, CODE2, e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_dual_widen_scalar (CODE1, CODE2, e.vector_mode ()));
case OP_TYPE_wv:
if (CODE1 == PLUS)
return e.use_exact_insn (
code_for_pred_single_widen_add (CODE2, e.vector_mode ()));
else
return e.use_exact_insn (
code_for_pred_single_widen_sub (CODE2, e.vector_mode ()));
case OP_TYPE_wx:
return e.use_exact_insn (
code_for_pred_single_widen_scalar (CODE1, CODE2, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implement vfwadd/vfwsub/vfwmul. */
template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
class widen_binop_fp : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_dual_widen (CODE, e.vector_mode ()));
case OP_TYPE_vf:
return e.use_exact_insn (
code_for_pred_dual_widen_scalar (CODE, e.vector_mode ()));
case OP_TYPE_wv:
if (CODE == PLUS)
return e.use_exact_insn (
code_for_pred_single_widen_add (e.vector_mode ()));
else
return e.use_exact_insn (
code_for_pred_single_widen_sub (e.vector_mode ()));
case OP_TYPE_wf:
return e.use_exact_insn (
code_for_pred_single_widen_scalar (CODE, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vwmulsu. */
class vwmulsu : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred_widen_mulsu (e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_widen_mulsu_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vwcvt. */
template<rtx_code CODE>
class vwcvt : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
}
};
/* Implements vadc. */
class vadc : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vvm:
return e.use_exact_insn (code_for_pred_adc (e.vector_mode ()));
case OP_TYPE_vxm:
return e.use_exact_insn (code_for_pred_adc_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vsbc. */
class vsbc : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vvm:
return e.use_exact_insn (code_for_pred_sbc (e.vector_mode ()));
case OP_TYPE_vxm:
return e.use_exact_insn (code_for_pred_sbc_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vmadc. */
class vmadc : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vvm:
return e.use_exact_insn (code_for_pred_madc (e.vector_mode ()));
case OP_TYPE_vxm:
return e.use_exact_insn (code_for_pred_madc_scalar (e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_madc_overflow (e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_madc_overflow_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vmsbc. */
class vmsbc : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vvm:
return e.use_exact_insn (code_for_pred_msbc (e.vector_mode ()));
case OP_TYPE_vxm:
return e.use_exact_insn (code_for_pred_msbc_scalar (e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_msbc_overflow (e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_msbc_overflow_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vnsrl/vnsra. */
template<rtx_code CODE>
class vnshift : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_wx:
return e.use_exact_insn (
code_for_pred_narrow_scalar (CODE, e.vector_mode ()));
case OP_TYPE_wv:
return e.use_exact_insn (code_for_pred_narrow (CODE, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vncvt. */
class vncvt_x : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_trunc (e.vector_mode ()));
}
};
/* Implements vmerge/vfmerge. */
class vmerge : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vvm:
return e.use_exact_insn (code_for_pred_merge (e.vector_mode ()));
case OP_TYPE_vxm:
case OP_TYPE_vfm:
return e.use_exact_insn (code_for_pred_merge_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vmv.v.x/vmv.v.v/vfmv.v.f. */
class vmv_v : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_v:
return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
case OP_TYPE_x:
case OP_TYPE_f:
return e.use_scalar_broadcast_insn
(code_for_pred_broadcast (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vaadd/vasub/vsmul/vssra/vssrl. */
template<int UNSPEC>
class sat_op : public function_base
{
public:
bool has_rounding_mode_operand_p () const override { return true; }
bool may_require_vxrm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_scalar (UNSPEC, e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vnclip/vnclipu. */
template<int UNSPEC>
class vnclip : public function_base
{
public:
bool has_rounding_mode_operand_p () const override { return true; }
bool may_require_vxrm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_wx:
return e.use_exact_insn (
code_for_pred_narrow_clip_scalar (UNSPEC, e.vector_mode ()));
case OP_TYPE_wv:
return e.use_exact_insn (
code_for_pred_narrow_clip (UNSPEC, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vmseq/vmsne/vmslt/vmsgt/vmsle/vmsge. */
template<rtx_code CODE>
class icmp : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vx: {
if (CODE == GE || CODE == GEU)
return e.use_compare_insn (CODE, code_for_pred_ge_scalar (
e.vector_mode ()));
else
return e.use_compare_insn (CODE, code_for_pred_cmp_scalar (
e.vector_mode ()));
}
case OP_TYPE_vv: {
if (CODE == LT || CODE == LTU || CODE == GE || CODE == GEU)
return e.use_compare_insn (CODE,
code_for_pred_ltge (e.vector_mode ()));
else
return e.use_compare_insn (CODE,
code_for_pred_cmp (e.vector_mode ()));
}
default:
gcc_unreachable ();
}
}
};
/* Implements vmacc/vnmsac/vmadd/vnmsub. */
class vmacc : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_ternop_insn (true, code_for_pred_mul_plus_scalar (
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_mul_plus (e.vector_mode ()));
gcc_unreachable ();
}
};
class vnmsac : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_ternop_insn (true, code_for_pred_minus_mul_scalar (
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_minus_mul (e.vector_mode ()));
gcc_unreachable ();
}
};
class vmadd : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_ternop_insn (false, code_for_pred_mul_plus_scalar (
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_mul_plus (e.vector_mode ()));
gcc_unreachable ();
}
};
class vnmsub : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_ternop_insn (false, code_for_pred_minus_mul_scalar (
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_minus_mul (e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vwmacc<su><su>. */
class vwmacc : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plus_scalar (SIGN_EXTEND, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plus (SIGN_EXTEND, e.vector_mode ()));
gcc_unreachable ();
}
};
class vwmaccu : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plus_scalar (ZERO_EXTEND, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plus (ZERO_EXTEND, e.vector_mode ()));
gcc_unreachable ();
}
};
class vwmaccsu : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vx)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plussu_scalar (e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plussu (e.vector_mode ()));
gcc_unreachable ();
}
};
class vwmaccus : public function_base
{
public:
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_plusus_scalar (e.vector_mode ()));
}
};
/* Implements vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor */
template<rtx_code CODE>
class mask_logic : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
}
};
template<rtx_code CODE>
class mask_nlogic : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_n (CODE, e.vector_mode ()));
}
};
template<rtx_code CODE>
class mask_notlogic : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_not (CODE, e.vector_mode ()));
}
};
/* Implements vmmv. */
class vmmv : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
}
};
/* Implements vmclr. */
class vmclr : public function_base
{
public:
bool can_be_overloaded_p (enum predication_type_index) const override
{
return false;
}
rtx expand (function_expander &e) const override
{
machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
e.add_all_one_mask_operand (mode);
e.add_vundef_operand (mode);
e.add_input_operand (mode, CONST0_RTX (mode));
e.add_input_operand (call_expr_nargs (e.exp) - 1);
e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
}
};
/* Implements vmset. */
class vmset : public function_base
{
public:
bool can_be_overloaded_p (enum predication_type_index) const override
{
return false;
}
rtx expand (function_expander &e) const override
{
machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
e.add_all_one_mask_operand (mode);
e.add_vundef_operand (mode);
e.add_input_operand (mode, CONSTM1_RTX (mode));
e.add_input_operand (call_expr_nargs (e.exp) - 1);
e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
}
};
/* Implements vmnot. */
class vmnot : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_not (e.vector_mode ()));
}
};
/* Implements vcpop. */
class vcpop : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_popcount (e.vector_mode (), Pmode));
}
};
/* Implements vfirst. */
class vfirst : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_ffs (e.vector_mode (), Pmode));
}
};
/* Implements vmsbf/vmsif/vmsof. */
template<int UNSPEC>
class mask_misc : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
}
};
/* Implements viota. */
class viota : public function_base
{
public:
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
|| pred == PRED_TYPE_tumu || pred == PRED_TYPE_mu;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_iota (e.vector_mode ()));
}
};
/* Implements vid. */
class vid : public function_base
{
public:
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
|| pred == PRED_TYPE_tumu || pred == PRED_TYPE_mu;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_series (e.vector_mode ()));
}
};
/* Implements vfrsub/vfrdiv. */
template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
class reverse_binop : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_reverse_scalar (CODE, e.vector_mode ()));
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfmacc : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (true,
code_for_pred_mul_scalar (PLUS,
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_mul (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfnmsac : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (
true, code_for_pred_mul_neg_scalar (PLUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_mul_neg (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfmadd : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (false,
code_for_pred_mul_scalar (PLUS,
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_mul (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfnmsub : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (
false, code_for_pred_mul_neg_scalar (PLUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_mul_neg (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfnmacc : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (
true, code_for_pred_mul_neg_scalar (MINUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_mul_neg (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfmsac : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (true,
code_for_pred_mul_scalar (MINUS,
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (true,
code_for_pred_mul (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfnmadd : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (
false, code_for_pred_mul_neg_scalar (MINUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_mul_neg (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfmsub : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_ternop_insn (false,
code_for_pred_mul_scalar (MINUS,
e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_ternop_insn (false,
code_for_pred_mul (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfwmacc : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_scalar (PLUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfwnmacc : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_neg_scalar (MINUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_neg (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfwmsac : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_scalar (MINUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul (MINUS, e.vector_mode ()));
gcc_unreachable ();
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfwnmsac : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_neg_scalar (PLUS, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_mul_neg (PLUS, e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vfsqrt7/vfrec7/vfclass/vfsgnj/vfsgnjx. */
template<int UNSPEC, enum frm_op_type FRM_OP = NO_FRM>
class float_misc : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_exact_insn (code_for_pred_scalar (UNSPEC, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv || e.op_info->op == OP_TYPE_v)
return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vfsgnjn. */
class vfsgnjn : public function_base
{
public:
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_exact_insn (code_for_pred_ncopysign_scalar (e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_exact_insn (code_for_pred_ncopysign (e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vmfeq/vmfne/vmflt/vmfgt/vmfle/vmfge. */
template<rtx_code CODE>
class fcmp : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vf: {
return e.use_compare_insn (CODE, code_for_pred_cmp_scalar (
e.vector_mode ()));
}
case OP_TYPE_vv: {
return e.use_compare_insn (CODE,
code_for_pred_cmp (e.vector_mode ()));
}
default:
gcc_unreachable ();
}
}
};
/* Implements vfclass. */
class vfclass : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_class (e.arg_mode (0)));
}
};
/* Implements vfcvt.x. */
template<int UNSPEC, enum frm_op_type FRM_OP = NO_FRM>
class vfcvt_x : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
}
};
/* Implements vfcvt.rtz.x. */
template<rtx_code CODE>
class vfcvt_rtz_x : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (CODE, e.arg_mode (0)));
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfcvt_f : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_x_v)
return e.use_exact_insn (code_for_pred (FLOAT, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_xu_v)
return e.use_exact_insn (
code_for_pred (UNSIGNED_FLOAT, e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vfwcvt.x. */
template<int UNSPEC, enum frm_op_type FRM_OP = NO_FRM>
class vfwcvt_x : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_widen_fcvt_x_f (UNSPEC, e.vector_mode ()));
}
};
/* Implements vfwcvt.rtz.x. */
template<rtx_code CODE>
class vfwcvt_rtz_x : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_widen (CODE, e.vector_mode ()));
}
};
class vfwcvt_f : public function_base
{
public:
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_f_v)
return e.use_exact_insn (code_for_pred_extend (e.vector_mode ()));
if (e.op_info->op == OP_TYPE_x_v)
return e.use_exact_insn (code_for_pred_widen (FLOAT, e.vector_mode ()));
if (e.op_info->op == OP_TYPE_xu_v)
return e.use_exact_insn (
code_for_pred_widen (UNSIGNED_FLOAT, e.vector_mode ()));
gcc_unreachable ();
}
};
/* Implements vfncvt.x. */
template<int UNSPEC, enum frm_op_type FRM_OP = NO_FRM>
class vfncvt_x : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_narrow_fcvt_x_f (UNSPEC, e.arg_mode (0)));
}
};
/* Implements vfncvt.rtz.x. */
template<rtx_code CODE>
class vfncvt_rtz_x : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_narrow (CODE, e.vector_mode ()));
}
};
template<enum frm_op_type FRM_OP = NO_FRM>
class vfncvt_f : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_f_w)
return e.use_exact_insn (code_for_pred_trunc (e.vector_mode ()));
if (e.op_info->op == OP_TYPE_x_w)
return e.use_exact_insn (code_for_pred_narrow (FLOAT, e.arg_mode (0)));
if (e.op_info->op == OP_TYPE_xu_w)
return e.use_exact_insn (
code_for_pred_narrow (UNSIGNED_FLOAT, e.arg_mode (0)));
gcc_unreachable ();
}
};
class vfncvt_rod_f : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_rod_trunc (e.vector_mode ()));
}
};
/* Implements reduction instructions. */
template<unsigned UNSPEC>
class reducop : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
}
};
/* Implements floating-point reduction instructions. */
template<unsigned UNSPEC, enum frm_op_type FRM_OP = NO_FRM>
class freducop : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool apply_mask_policy_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
}
};
/* Implements vmv/vfmv instructions. */
class vmv : public function_base
{
public:
bool apply_vl_p () const override { return false; }
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_extract_first (e.vector_mode ()));
}
};
/* Implements vmv.s.x/vfmv.s.f. */
class vmv_s : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_scalar_move_insn (code_for_pred_broadcast (e.vector_mode ()));
}
};
template<int UNSPEC>
class slideop : public function_base
{
public:
bool has_merge_operand_p () const override
{
if (UNSPEC == UNSPEC_VSLIDEUP)
return false;
return true;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_slide (UNSPEC, e.vector_mode ()));
}
};
class vrgather : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vx:
return e.use_exact_insn (
code_for_pred_gather_scalar (e.vector_mode ()));
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred_gather (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
class vrgatherei16 : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_gatherei16 (e.vector_mode ()));
}
};
class vcompress : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_compress (e.vector_mode ()));
}
};
class vundefined : public function_base
{
public:
bool apply_vl_p () const override
{
return false;
}
rtx expand (function_expander &e) const override
{
return e.generate_insn (code_for_vundefined (e.vector_mode ()));
}
};
class vreinterpret : public function_base
{
public:
bool apply_vl_p () const override
{
return false;
}
rtx expand (function_expander &e) const override
{
e.add_input_operand (0);
return e.generate_insn (code_for_vreinterpret (e.ret_mode ()));
}
};
class vlmul_ext : public function_base
{
public:
bool apply_vl_p () const override
{
return false;
}
rtx expand (function_expander &e) const override
{
if (!e.target)
return NULL_RTX;
tree arg = CALL_EXPR_ARG (e.exp, 0);
rtx src = expand_normal (arg);
emit_move_insn (gen_lowpart (e.vector_mode (), e.target), src);
return e.target;
}
};
class vlmul_trunc : public function_base
{
public:
bool apply_vl_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (!e.target)
return NULL_RTX;
rtx src = expand_normal (CALL_EXPR_ARG (e.exp, 0));
emit_move_insn (e.target, gen_lowpart (GET_MODE (e.target), src));
return e.target;
}
};
class vset : public function_base
{
public:
bool apply_vl_p () const override { return false; }
gimple *fold (gimple_folder &f) const override
{
tree rhs_tuple = gimple_call_arg (f.call, 0);
/* LMUL > 1 non-tuple vector types are not structure,
we can't use __val[index] to set the subpart. */
if (!riscv_v_ext_tuple_mode_p (TYPE_MODE (TREE_TYPE (rhs_tuple))))
return NULL;
tree index = gimple_call_arg (f.call, 1);
tree rhs_vector = gimple_call_arg (f.call, 2);
/* Replace the call with two statements: a copy of the full tuple
to the call result, followed by an update of the individual vector.
The fold routines expect the replacement statement to have the
same lhs as the original call, so return the copy statement
rather than the field update. */
gassign *copy = gimple_build_assign (f.lhs, rhs_tuple);
/* Get a reference to the individual vector. */
tree field = tuple_type_field (TREE_TYPE (f.lhs));
tree lhs_array
= build3 (COMPONENT_REF, TREE_TYPE (field), unshare_expr (f.lhs),
field, NULL_TREE);
tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), lhs_array,
index, NULL_TREE, NULL_TREE);
gassign *update = gimple_build_assign (lhs_vector, rhs_vector);
gsi_insert_after (f.gsi, update, GSI_SAME_STMT);
return copy;
}
rtx expand (function_expander &e) const override
{
if (!e.target)
return NULL_RTX;
rtx dest = expand_normal (CALL_EXPR_ARG (e.exp, 0));
gcc_assert (riscv_v_ext_vector_mode_p (GET_MODE (dest)));
rtx index = expand_normal (CALL_EXPR_ARG (e.exp, 1));
rtx src = expand_normal (CALL_EXPR_ARG (e.exp, 2));
poly_int64 offset = INTVAL (index) * GET_MODE_SIZE (GET_MODE (src));
emit_move_insn (e.target, dest);
rtx subreg = simplify_gen_subreg (GET_MODE (src), e.target,
GET_MODE (e.target), offset);
emit_move_insn (subreg, src);
return e.target;
}
};
class vget : public function_base
{
public:
bool apply_vl_p () const override { return false; }
gimple *fold (gimple_folder &f) const override
{
/* Fold into a normal gimple component access. */
tree rhs_tuple = gimple_call_arg (f.call, 0);
/* LMUL > 1 non-tuple vector types are not structure,
we can't use __val[index] to get the subpart. */
if (!riscv_v_ext_tuple_mode_p (TYPE_MODE (TREE_TYPE (rhs_tuple))))
return NULL;
tree index = gimple_call_arg (f.call, 1);
tree field = tuple_type_field (TREE_TYPE (rhs_tuple));
tree rhs_array
= build3 (COMPONENT_REF, TREE_TYPE (field), rhs_tuple, field, NULL_TREE);
tree rhs_vector = build4 (ARRAY_REF, TREE_TYPE (f.lhs), rhs_array, index,
NULL_TREE, NULL_TREE);
return gimple_build_assign (f.lhs, rhs_vector);
}
rtx expand (function_expander &e) const override
{
if (!e.target)
return NULL_RTX;
rtx src = expand_normal (CALL_EXPR_ARG (e.exp, 0));
gcc_assert (riscv_v_ext_vector_mode_p (GET_MODE (src)));
rtx index = expand_normal (CALL_EXPR_ARG (e.exp, 1));
poly_int64 offset = INTVAL (index) * GET_MODE_SIZE (GET_MODE (e.target));
rtx subreg
= simplify_gen_subreg (GET_MODE (e.target), src, GET_MODE (src), offset);
return subreg;
}
};
class vcreate : public function_base
{
public:
gimple *fold (gimple_folder &f) const override
{
unsigned int nargs = gimple_call_num_args (f.call);
tree lhs_type = TREE_TYPE (f.lhs);
/* LMUL > 1 non-tuple vector types are not structure,
we can't use __val[index] to set the subpart. */
if (!riscv_v_ext_tuple_mode_p (TYPE_MODE (lhs_type)))
return NULL;
/* Replace the call with a clobber of the result (to prevent it from
becoming upwards exposed) followed by stores into each individual
vector of tuple.
The fold routines expect the replacement statement to have the
same lhs as the original call, so return the clobber statement
rather than the final vector store. */
gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type));
for (unsigned int i = nargs; i-- > 0; )
{
tree rhs_vector = gimple_call_arg (f.call, i);
tree field = tuple_type_field (TREE_TYPE (f.lhs));
tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field),
unshare_expr (f.lhs), field, NULL_TREE);
tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector),
lhs_array, size_int (i),
NULL_TREE, NULL_TREE);
gassign *assign = gimple_build_assign (lhs_vector, rhs_vector);
gsi_insert_after (f.gsi, assign, GSI_SAME_STMT);
}
return clobber;
}
rtx expand (function_expander &e) const override
{
if (!e.target)
return NULL_RTX;
gcc_assert (riscv_v_ext_vector_mode_p (GET_MODE (e.target)));
unsigned int nargs = call_expr_nargs (e.exp);
for (unsigned int i = 0; i < nargs; i++)
{
rtx src = expand_normal (CALL_EXPR_ARG (e.exp, i));
poly_int64 offset = i * GET_MODE_SIZE (GET_MODE (src));
rtx subreg = simplify_gen_subreg (GET_MODE (src), e.target,
GET_MODE (e.target), offset);
emit_move_insn (subreg, src);
}
return e.target;
}
};
class read_vl : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_CSR;
}
rtx expand (function_expander &e) const override
{
if (Pmode == SImode)
emit_insn (gen_read_vlsi (e.target));
else
emit_insn (gen_read_vldi_zero_extend (e.target));
return e.target;
}
};
class vleff : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_MEMORY | CP_WRITE_CSR;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred != PRED_TYPE_none;
}
gimple *fold (gimple_folder &f) const override
{
return fold_fault_load (f);
}
rtx expand (function_expander &e) const override
{
return e.use_contiguous_load_insn (
code_for_pred_fault_load (e.vector_mode ()));
}
};
/* Implements vlenb. */
class vlenb : public function_base
{
public:
bool apply_vl_p () const override { return false; }
rtx expand (function_expander &e) const override
{
machine_mode mode = GET_MODE (e.target);
rtx vlenb = gen_int_mode (BYTES_PER_RISCV_VECTOR, mode);
emit_move_insn (e.target, vlenb);
return e.target;
}
};
/* Implements vlseg.v. */
class vlseg : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred != PRED_TYPE_none;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_unit_strided_load (e.vector_mode ()));
}
};
/* Implements vsseg.v. */
class vsseg : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
unsigned int call_properties (const function_instance &) const override
{
return CP_WRITE_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index) const override
{
return true;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_unit_strided_store (e.vector_mode ()));
}
};
/* Implements vlsseg.v. */
class vlsseg : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred != PRED_TYPE_none;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_strided_load (e.vector_mode ()));
}
};
/* Implements vssseg.v. */
class vssseg : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
unsigned int call_properties (const function_instance &) const override
{
return CP_WRITE_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index) const override
{
return true;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_strided_store (e.vector_mode ()));
}
};
template<int UNSPEC>
class seg_indexed_load : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index) const override
{
return true;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_indexed_load (UNSPEC, e.vector_mode (), e.index_mode ()));
}
};
template<int UNSPEC>
class seg_indexed_store : public function_base
{
public:
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
unsigned int call_properties (const function_instance &) const override
{
return CP_WRITE_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index) const override
{
return true;
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (
code_for_pred_indexed_store (UNSPEC, e.vector_mode (), e.index_mode ()));
}
};
/* Implements vlsegff.v. */
class vlsegff : public function_base
{
public:
unsigned int call_properties (const function_instance &) const override
{
return CP_READ_MEMORY | CP_WRITE_CSR;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
return pred != PRED_TYPE_none;
}
gimple *fold (gimple_folder &f) const override
{
return fold_fault_load (f);
}
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_fault_load (e.vector_mode ()));
}
};
/* Implements
* th.vl(b/h/w)[u].v/th.vs(b/h/w)[u].v/th.vls(b/h/w)[u].v/th.vss(b/h/w)[u].v/
* th.vlx(b/h/w)[u].v/th.vs[u]x(b/h/w).v
* codegen. */
template<bool STORE_P, lst_type LST_TYPE, int UNSPEC>
class th_loadstore_width : public function_base
{
public:
bool apply_tail_policy_p () const override { return !STORE_P; }
bool apply_mask_policy_p () const override { return !STORE_P; }
unsigned int call_properties (const function_instance &) const override
{
if (STORE_P)
return CP_WRITE_MEMORY;
else
return CP_READ_MEMORY;
}
bool can_be_overloaded_p (enum predication_type_index pred) const override
{
if (STORE_P || LST_TYPE == LST_INDEXED)
return true;
return pred != PRED_TYPE_none;
}
rtx expand (function_expander &e) const override
{
gcc_assert (TARGET_XTHEADVECTOR);
if (LST_TYPE == LST_INDEXED)
{
if (STORE_P)
return e.use_exact_insn (
code_for_pred_indexed_store_width (UNSPEC, UNSPEC,
e.vector_mode ()));
else
return e.use_exact_insn (
code_for_pred_indexed_load_width (UNSPEC, e.vector_mode ()));
}
else if (LST_TYPE == LST_STRIDED)
{
if (STORE_P)
return e.use_contiguous_store_insn (
code_for_pred_strided_store_width (UNSPEC, e.vector_mode ()));
else
return e.use_contiguous_load_insn (
code_for_pred_strided_load_width (UNSPEC, e.vector_mode ()));
}
else
{
if (STORE_P)
return e.use_contiguous_store_insn (
code_for_pred_store_width (UNSPEC, e.vector_mode ()));
else
return e.use_contiguous_load_insn (
code_for_pred_mov_width (UNSPEC, e.vector_mode ()));
}
}
};
/* Implements vext.x.v. */
class th_extract : public function_base
{
public:
bool apply_vl_p () const override { return false; }
bool apply_tail_policy_p () const override { return false; }
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
gcc_assert (TARGET_XTHEADVECTOR);
return e.use_exact_insn (code_for_pred_th_extract (e.vector_mode ()));
}
};
/* Below implements are vector crypto */
/* Implements vandn.[vv,vx] */
class vandn : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred_vandn (e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (code_for_pred_vandn_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vrol/vror/clz/ctz. */
template<rtx_code CODE>
class bitmanip : public function_base
{
public:
bool apply_tail_policy_p () const override
{
return (CODE == CLZ || CODE == CTZ) ? false : true;
}
bool apply_mask_policy_p () const override
{
return (CODE == CLZ || CODE == CTZ) ? false : true;
}
bool has_merge_operand_p () const override
{
return (CODE == CLZ || CODE == CTZ) ? false : true;
}
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_v:
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred_v (CODE, e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (code_for_pred_v_scalar (CODE, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vbrev/vbrev8/vrev8. */
template<int UNSPEC>
class b_reverse : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_v (UNSPEC, e.vector_mode ()));
}
};
class vwsll : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (code_for_pred_vwsll (e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn (code_for_pred_vwsll_scalar (e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements clmul */
template<int UNSPEC>
class clmul : public function_base
{
public:
rtx expand (function_expander &e) const override
{
switch (e.op_info->op)
{
case OP_TYPE_vv:
return e.use_exact_insn (
code_for_pred_vclmul (UNSPEC, e.vector_mode ()));
case OP_TYPE_vx:
return e.use_exact_insn
(code_for_pred_vclmul_scalar (UNSPEC, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vghsh/vsh2ms/vsha2c[hl]. */
template<int UNSPEC>
class vg_nhab : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_v (UNSPEC, e.vector_mode ()));
}
};
/* Implements vgmul/vaes*. */
template<int UNSPEC>
class crypto_vv : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
poly_uint64 nunits = 0U;
switch (e.op_info->op)
{
case OP_TYPE_vv:
if (UNSPEC == UNSPEC_VGMUL)
return e.use_exact_insn
(code_for_pred_crypto_vv (UNSPEC, UNSPEC, e.vector_mode ()));
else
return e.use_exact_insn
(code_for_pred_crypto_vv (UNSPEC + 1, UNSPEC + 1, e.vector_mode ()));
case OP_TYPE_vs:
/* Calculate the ratio between arg0 and arg1*/
gcc_assert (multiple_p (GET_MODE_BITSIZE (e.arg_mode (0)),
GET_MODE_BITSIZE (e.arg_mode (1)), &nunits));
if (maybe_eq (nunits, 1U))
return e.use_exact_insn (code_for_pred_crypto_vvx1_scalar
(UNSPEC + 2, UNSPEC + 2, e.vector_mode ()));
else if (maybe_eq (nunits, 2U))
return e.use_exact_insn (code_for_pred_crypto_vvx2_scalar
(UNSPEC + 2, UNSPEC + 2, e.vector_mode ()));
else if (maybe_eq (nunits, 4U))
return e.use_exact_insn (code_for_pred_crypto_vvx4_scalar
(UNSPEC + 2, UNSPEC + 2, e.vector_mode ()));
else if (maybe_eq (nunits, 8U))
return e.use_exact_insn (code_for_pred_crypto_vvx8_scalar
(UNSPEC + 2, UNSPEC + 2, e.vector_mode ()));
else
return e.use_exact_insn (code_for_pred_crypto_vvx16_scalar
(UNSPEC + 2, UNSPEC + 2, e.vector_mode ()));
default:
gcc_unreachable ();
}
}
};
/* Implements vaeskf1/vsm4k. */
template<int UNSPEC>
class crypto_vi : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn
(code_for_pred_crypto_vi_scalar (UNSPEC, e.vector_mode ()));
}
};
/* Implements vaeskf2/vsm3c. */
template<int UNSPEC>
class vaeskf2_vsm3c : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn
(code_for_pred_vi_nomaskedoff_scalar (UNSPEC, e.vector_mode ()));
}
};
/* Implements vsm3me. */
class vsm3me : public function_base
{
public:
bool apply_mask_policy_p () const override { return false; }
bool use_mask_predication_p () const override { return false; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_vsm3me (e.vector_mode ()));
}
};
/* Implements vfncvtbf16_f. */
template <enum frm_op_type FRM_OP = NO_FRM>
class vfncvtbf16_f : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_trunc_to_bf16 (e.vector_mode ()));
}
};
/* Implements vfwcvtbf16_f. */
class vfwcvtbf16_f : public function_base
{
public:
rtx expand (function_expander &e) const override
{
return e.use_exact_insn (code_for_pred_extend_bf16_to (e.vector_mode ()));
}
};
/* Implements vfwmaccbf16. */
template <enum frm_op_type FRM_OP = NO_FRM>
class vfwmaccbf16 : public function_base
{
public:
bool has_rounding_mode_operand_p () const override
{
return FRM_OP == HAS_FRM;
}
bool may_require_frm_p () const override { return true; }
bool has_merge_operand_p () const override { return false; }
rtx expand (function_expander &e) const override
{
if (e.op_info->op == OP_TYPE_vf)
return e.use_widen_ternop_insn (
code_for_pred_widen_bf16_mul_scalar (e.vector_mode ()));
if (e.op_info->op == OP_TYPE_vv)
return e.use_widen_ternop_insn (
code_for_pred_widen_bf16_mul (e.vector_mode ()));
gcc_unreachable ();
}
};
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;
static CONSTEXPR const loadstore<true, LST_UNIT_STRIDE, false> vse_obj;
static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vlm_obj;
static CONSTEXPR const loadstore<true, LST_UNIT_STRIDE, false> vsm_obj;
static CONSTEXPR const loadstore<false, LST_STRIDED, false> vlse_obj;
static CONSTEXPR const loadstore<true, LST_STRIDED, false> vsse_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, false> vluxei8_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, false> vluxei16_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, false> vluxei32_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, false> vluxei64_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, true> vloxei8_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, true> vloxei16_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, true> vloxei32_obj;
static CONSTEXPR const loadstore<false, LST_INDEXED, true> vloxei64_obj;
static CONSTEXPR const loadstore<true, LST_INDEXED, false> vsuxei8_obj;
static CONSTEXPR const loadstore<true, LST_INDEXED, false> vsuxei16_obj;
static CONSTEXPR const loadstore<true, LST_INDEXED, false> vsuxei32_obj;
static CONSTEXPR const loadstore<true, LST_INDEXED, false> vsuxei64_obj;
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 vrsub 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 vmulh<UNSPEC_VMULHS> vmulh_obj;
static CONSTEXPR const vmulh<UNSPEC_VMULHU> vmulhu_obj;
static CONSTEXPR const vmulh<UNSPEC_VMULHSU> vmulhsu_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;
static CONSTEXPR const unop<NEG> vneg_obj;
static CONSTEXPR const unop<NOT> vnot_obj;
static CONSTEXPR const ext<SIGN_EXTEND> vsext_obj;
static CONSTEXPR const ext<ZERO_EXTEND> vzext_obj;
static CONSTEXPR const widen_binop<PLUS, SIGN_EXTEND>vwadd_obj;
static CONSTEXPR const widen_binop<MINUS, SIGN_EXTEND>vwsub_obj;
static CONSTEXPR const widen_binop<MULT, SIGN_EXTEND>vwmul_obj;
static CONSTEXPR const widen_binop<PLUS, ZERO_EXTEND>vwaddu_obj;
static CONSTEXPR const widen_binop<MINUS, ZERO_EXTEND>vwsubu_obj;
static CONSTEXPR const widen_binop<MULT, ZERO_EXTEND>vwmulu_obj;
static CONSTEXPR const vwmulsu vwmulsu_obj;
static CONSTEXPR const vwcvt<SIGN_EXTEND> vwcvt_x_obj;
static CONSTEXPR const vwcvt<ZERO_EXTEND> vwcvtu_x_obj;
static CONSTEXPR const vadc vadc_obj;
static CONSTEXPR const vsbc vsbc_obj;
static CONSTEXPR const vmadc vmadc_obj;
static CONSTEXPR const vmsbc vmsbc_obj;
static CONSTEXPR const vnshift<LSHIFTRT> vnsrl_obj;
static CONSTEXPR const vnshift<ASHIFTRT> vnsra_obj;
static CONSTEXPR const vncvt_x vncvt_x_obj;
static CONSTEXPR const vmerge vmerge_obj;
static CONSTEXPR const vmv_v vmv_v_obj;
static CONSTEXPR const icmp<EQ> vmseq_obj;
static CONSTEXPR const icmp<NE> vmsne_obj;
static CONSTEXPR const icmp<LT> vmslt_obj;
static CONSTEXPR const icmp<GT> vmsgt_obj;
static CONSTEXPR const icmp<LE> vmsle_obj;
static CONSTEXPR const icmp<GE> vmsge_obj;
static CONSTEXPR const icmp<LTU> vmsltu_obj;
static CONSTEXPR const icmp<GTU> vmsgtu_obj;
static CONSTEXPR const icmp<LEU> vmsleu_obj;
static CONSTEXPR const icmp<GEU> vmsgeu_obj;
static CONSTEXPR const vmacc vmacc_obj;
static CONSTEXPR const vnmsac vnmsac_obj;
static CONSTEXPR const vmadd vmadd_obj;
static CONSTEXPR const vnmsub vnmsub_obj;
static CONSTEXPR const vwmacc vwmacc_obj;
static CONSTEXPR const vwmaccu vwmaccu_obj;
static CONSTEXPR const vwmaccsu vwmaccsu_obj;
static CONSTEXPR const vwmaccus vwmaccus_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;
static CONSTEXPR const sat_op<UNSPEC_VAADDU> vaaddu_obj;
static CONSTEXPR const sat_op<UNSPEC_VAADD> vaadd_obj;
static CONSTEXPR const sat_op<UNSPEC_VASUBU> vasubu_obj;
static CONSTEXPR const sat_op<UNSPEC_VASUB> vasub_obj;
static CONSTEXPR const sat_op<UNSPEC_VSMUL> vsmul_obj;
static CONSTEXPR const sat_op<UNSPEC_VSSRL> vssrl_obj;
static CONSTEXPR const sat_op<UNSPEC_VSSRA> vssra_obj;
static CONSTEXPR const vnclip<UNSPEC_VNCLIP> vnclip_obj;
static CONSTEXPR const vnclip<UNSPEC_VNCLIPU> vnclipu_obj;
static CONSTEXPR const mask_logic<AND> vmand_obj;
static CONSTEXPR const mask_nlogic<AND> vmnand_obj;
static CONSTEXPR const mask_notlogic<AND> vmandn_obj;
static CONSTEXPR const mask_logic<XOR> vmxor_obj;
static CONSTEXPR const mask_logic<IOR> vmor_obj;
static CONSTEXPR const mask_nlogic<IOR> vmnor_obj;
static CONSTEXPR const mask_notlogic<IOR> vmorn_obj;
static CONSTEXPR const mask_nlogic<XOR> vmxnor_obj;
static CONSTEXPR const vmmv vmmv_obj;
static CONSTEXPR const vmclr vmclr_obj;
static CONSTEXPR const vmset vmset_obj;
static CONSTEXPR const vmnot vmnot_obj;
static CONSTEXPR const vcpop vcpop_obj;
static CONSTEXPR const vfirst vfirst_obj;
static CONSTEXPR const mask_misc<UNSPEC_VMSBF> vmsbf_obj;
static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
static CONSTEXPR const viota viota_obj;
static CONSTEXPR const vid vid_obj;
static CONSTEXPR const binop<PLUS, true> vfadd_obj;
static CONSTEXPR const binop<MINUS, true> vfsub_obj;
static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
static CONSTEXPR const binop<MULT, true> vfmul_obj;
static CONSTEXPR const binop<MULT, true, HAS_FRM> vfmul_frm_obj;
static CONSTEXPR const binop<DIV, true> vfdiv_obj;
static CONSTEXPR const binop<DIV, true, HAS_FRM> vfdiv_frm_obj;
static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
static CONSTEXPR const widen_binop_fp<MULT, HAS_FRM> vfwmul_frm_obj;
static CONSTEXPR const vfmacc<NO_FRM> vfmacc_obj;
static CONSTEXPR const vfmacc<HAS_FRM> vfmacc_frm_obj;
static CONSTEXPR const vfnmsac<NO_FRM> vfnmsac_obj;
static CONSTEXPR const vfnmsac<HAS_FRM> vfnmsac_frm_obj;
static CONSTEXPR const vfmadd<NO_FRM> vfmadd_obj;
static CONSTEXPR const vfmadd<HAS_FRM> vfmadd_frm_obj;
static CONSTEXPR const vfnmsub<NO_FRM> vfnmsub_obj;
static CONSTEXPR const vfnmsub<HAS_FRM> vfnmsub_frm_obj;
static CONSTEXPR const vfnmacc<NO_FRM> vfnmacc_obj;
static CONSTEXPR const vfnmacc<HAS_FRM> vfnmacc_frm_obj;
static CONSTEXPR const vfmsac<NO_FRM> vfmsac_obj;
static CONSTEXPR const vfmsac<HAS_FRM> vfmsac_frm_obj;
static CONSTEXPR const vfnmadd<NO_FRM> vfnmadd_obj;
static CONSTEXPR const vfnmadd<HAS_FRM> vfnmadd_frm_obj;
static CONSTEXPR const vfmsub<NO_FRM> vfmsub_obj;
static CONSTEXPR const vfmsub<HAS_FRM> vfmsub_frm_obj;
static CONSTEXPR const vfwmacc<NO_FRM> vfwmacc_obj;
static CONSTEXPR const vfwmacc<HAS_FRM> vfwmacc_frm_obj;
static CONSTEXPR const vfwnmacc<NO_FRM> vfwnmacc_obj;
static CONSTEXPR const vfwnmacc<HAS_FRM> vfwnmacc_frm_obj;
static CONSTEXPR const vfwmsac<NO_FRM> vfwmsac_obj;
static CONSTEXPR const vfwmsac<HAS_FRM> vfwmsac_frm_obj;
static CONSTEXPR const vfwnmsac<NO_FRM> vfwnmsac_obj;
static CONSTEXPR const vfwnmsac<HAS_FRM> vfwnmsac_frm_obj;
static CONSTEXPR const unop<SQRT> vfsqrt_obj;
static CONSTEXPR const unop<SQRT, HAS_FRM> vfsqrt_frm_obj;
static CONSTEXPR const float_misc<UNSPEC_VFRSQRT7> vfrsqrt7_obj;
static CONSTEXPR const float_misc<UNSPEC_VFREC7> vfrec7_obj;
static CONSTEXPR const float_misc<UNSPEC_VFREC7, HAS_FRM> vfrec7_frm_obj;
static CONSTEXPR const binop<SMIN> vfmin_obj;
static CONSTEXPR const binop<SMAX> vfmax_obj;
static CONSTEXPR const float_misc<UNSPEC_VCOPYSIGN> vfsgnj_obj;
static CONSTEXPR const vfsgnjn vfsgnjn_obj;
static CONSTEXPR const float_misc<UNSPEC_VXORSIGN> vfsgnjx_obj;
static CONSTEXPR const unop<NEG> vfneg_obj;
static CONSTEXPR const unop<ABS> vfabs_obj;
static CONSTEXPR const fcmp<EQ> vmfeq_obj;
static CONSTEXPR const fcmp<NE> vmfne_obj;
static CONSTEXPR const fcmp<LT> vmflt_obj;
static CONSTEXPR const fcmp<GT> vmfgt_obj;
static CONSTEXPR const fcmp<LE> vmfle_obj;
static CONSTEXPR const fcmp<GE> vmfge_obj;
static CONSTEXPR const vfclass vfclass_obj;
static CONSTEXPR const vmerge vfmerge_obj;
static CONSTEXPR const vmv_v vfmv_v_obj;
static CONSTEXPR const vfcvt_x<UNSPEC_VFCVT> vfcvt_x_obj;
static CONSTEXPR const vfcvt_x<UNSPEC_VFCVT, HAS_FRM> vfcvt_x_frm_obj;
static CONSTEXPR const vfcvt_x<UNSPEC_UNSIGNED_VFCVT> vfcvt_xu_obj;
static CONSTEXPR const vfcvt_x<UNSPEC_UNSIGNED_VFCVT, HAS_FRM> vfcvt_xu_frm_obj;
static CONSTEXPR const vfcvt_rtz_x<FIX> vfcvt_rtz_x_obj;
static CONSTEXPR const vfcvt_rtz_x<UNSIGNED_FIX> vfcvt_rtz_xu_obj;
static CONSTEXPR const vfcvt_f<NO_FRM> vfcvt_f_obj;
static CONSTEXPR const vfcvt_f<HAS_FRM> vfcvt_f_frm_obj;
static CONSTEXPR const vfwcvt_x<UNSPEC_VFCVT> vfwcvt_x_obj;
static CONSTEXPR const vfwcvt_x<UNSPEC_VFCVT, HAS_FRM> vfwcvt_x_frm_obj;
static CONSTEXPR const vfwcvt_x<UNSPEC_UNSIGNED_VFCVT> vfwcvt_xu_obj;
static CONSTEXPR const vfwcvt_x<UNSPEC_UNSIGNED_VFCVT, HAS_FRM> vfwcvt_xu_frm_obj;
static CONSTEXPR const vfwcvt_rtz_x<FIX> vfwcvt_rtz_x_obj;
static CONSTEXPR const vfwcvt_rtz_x<UNSIGNED_FIX> vfwcvt_rtz_xu_obj;
static CONSTEXPR const vfwcvt_f vfwcvt_f_obj;
static CONSTEXPR const vfncvt_x<UNSPEC_VFCVT> vfncvt_x_obj;
static CONSTEXPR const vfncvt_x<UNSPEC_VFCVT, HAS_FRM> vfncvt_x_frm_obj;
static CONSTEXPR const vfncvt_x<UNSPEC_UNSIGNED_VFCVT> vfncvt_xu_obj;
static CONSTEXPR const vfncvt_x<UNSPEC_UNSIGNED_VFCVT, HAS_FRM> vfncvt_xu_frm_obj;
static CONSTEXPR const vfncvt_rtz_x<FIX> vfncvt_rtz_x_obj;
static CONSTEXPR const vfncvt_rtz_x<UNSIGNED_FIX> vfncvt_rtz_xu_obj;
static CONSTEXPR const vfncvt_f<NO_FRM> vfncvt_f_obj;
static CONSTEXPR const vfncvt_f<HAS_FRM> vfncvt_f_frm_obj;
static CONSTEXPR const vfncvt_rod_f vfncvt_rod_f_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_SUM> vredsum_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MAXU> vredmaxu_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MAX> vredmax_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MINU> vredminu_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MIN> vredmin_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_AND> vredand_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_OR> vredor_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_XOR> vredxor_obj;
static CONSTEXPR const reducop<UNSPEC_WREDUC_SUM> vwredsum_obj;
static CONSTEXPR const reducop<UNSPEC_WREDUC_SUMU> vwredsumu_obj;
static CONSTEXPR const freducop<UNSPEC_REDUC_SUM_UNORDERED> vfredusum_obj;
static CONSTEXPR const freducop<UNSPEC_REDUC_SUM_UNORDERED, HAS_FRM> vfredusum_frm_obj;
static CONSTEXPR const freducop<UNSPEC_REDUC_SUM_ORDERED> vfredosum_obj;
static CONSTEXPR const freducop<UNSPEC_REDUC_SUM_ORDERED, HAS_FRM> vfredosum_frm_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MAX> vfredmax_obj;
static CONSTEXPR const reducop<UNSPEC_REDUC_MIN> vfredmin_obj;
static CONSTEXPR const freducop<UNSPEC_WREDUC_SUM_UNORDERED> vfwredusum_obj;
static CONSTEXPR const freducop<UNSPEC_WREDUC_SUM_UNORDERED, HAS_FRM> vfwredusum_frm_obj;
static CONSTEXPR const freducop<UNSPEC_WREDUC_SUM_ORDERED> vfwredosum_obj;
static CONSTEXPR const freducop<UNSPEC_WREDUC_SUM_ORDERED, HAS_FRM> vfwredosum_frm_obj;
static CONSTEXPR const vmv vmv_x_obj;
static CONSTEXPR const vmv_s vmv_s_obj;
static CONSTEXPR const vmv vfmv_f_obj;
static CONSTEXPR const vmv_s vfmv_s_obj;
static CONSTEXPR const slideop<UNSPEC_VSLIDEUP> vslideup_obj;
static CONSTEXPR const slideop<UNSPEC_VSLIDEDOWN> vslidedown_obj;
static CONSTEXPR const slideop<UNSPEC_VSLIDE1UP> vslide1up_obj;
static CONSTEXPR const slideop<UNSPEC_VSLIDE1DOWN> vslide1down_obj;
static CONSTEXPR const slideop<UNSPEC_VFSLIDE1UP> vfslide1up_obj;
static CONSTEXPR const slideop<UNSPEC_VFSLIDE1DOWN> vfslide1down_obj;
static CONSTEXPR const vrgather vrgather_obj;
static CONSTEXPR const vrgatherei16 vrgatherei16_obj;
static CONSTEXPR const vcompress vcompress_obj;
static CONSTEXPR const vundefined vundefined_obj;
static CONSTEXPR const vreinterpret vreinterpret_obj;
static CONSTEXPR const vlmul_ext vlmul_ext_obj;
static CONSTEXPR const vlmul_trunc vlmul_trunc_obj;
static CONSTEXPR const vset vset_obj;
static CONSTEXPR const vget vget_obj;
static CONSTEXPR const vcreate vcreate_obj;
static CONSTEXPR const read_vl read_vl_obj;
static CONSTEXPR const vleff vleff_obj;
static CONSTEXPR const vlenb vlenb_obj;
static CONSTEXPR const vlseg vlseg_obj;
static CONSTEXPR const vsseg vsseg_obj;
static CONSTEXPR const vlsseg vlsseg_obj;
static CONSTEXPR const vssseg vssseg_obj;
static CONSTEXPR const seg_indexed_load<UNSPEC_UNORDERED> vluxseg_obj;
static CONSTEXPR const seg_indexed_load<UNSPEC_ORDERED> vloxseg_obj;
static CONSTEXPR const seg_indexed_store<UNSPEC_UNORDERED> vsuxseg_obj;
static CONSTEXPR const seg_indexed_store<UNSPEC_ORDERED> vsoxseg_obj;
static CONSTEXPR const vlsegff vlsegff_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLB> vlb_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLBU> vlbu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLH> vlh_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLHU> vlhu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLW> vlw_obj;
static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLWU> vlwu_obj;
static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLB> vsb_obj;
static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLH> vsh_obj;
static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLW> vsw_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSB> vlsb_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSBU> vlsbu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSH> vlsh_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSHU> vlshu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSW> vlsw_obj;
static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSWU> vlswu_obj;
static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSB> vssb_obj;
static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSH> vssh_obj;
static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSW> vssw_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXB> vlxb_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXBU> vlxbu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXH> vlxh_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXHU> vlxhu_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXW> vlxw_obj;
static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXWU> vlxwu_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXB> vsxb_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXH> vsxh_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXW> vsxw_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXB> vsuxb_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXH> vsuxh_obj;
static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXW> vsuxw_obj;
static CONSTEXPR const th_extract vext_x_v_obj;
/* Crypto Vector */
static CONSTEXPR const vandn vandn_obj;
static CONSTEXPR const bitmanip<ROTATE> vrol_obj;
static CONSTEXPR const bitmanip<ROTATERT> vror_obj;
static CONSTEXPR const b_reverse<UNSPEC_VBREV> vbrev_obj;
static CONSTEXPR const b_reverse<UNSPEC_VBREV8> vbrev8_obj;
static CONSTEXPR const b_reverse<UNSPEC_VREV8> vrev8_obj;
static CONSTEXPR const bitmanip<CLZ> vclz_obj;
static CONSTEXPR const bitmanip<CTZ> vctz_obj;
static CONSTEXPR const vwsll vwsll_obj;
static CONSTEXPR const clmul<UNSPEC_VCLMUL> vclmul_obj;
static CONSTEXPR const clmul<UNSPEC_VCLMULH> vclmulh_obj;
static CONSTEXPR const vg_nhab<UNSPEC_VGHSH> vghsh_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VGMUL> vgmul_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VAESEF> vaesef_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VAESEM> vaesem_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VAESDF> vaesdf_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VAESDM> vaesdm_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VAESZ> vaesz_obj;
static CONSTEXPR const crypto_vi<UNSPEC_VAESKF1> vaeskf1_obj;
static CONSTEXPR const vaeskf2_vsm3c<UNSPEC_VAESKF2> vaeskf2_obj;
static CONSTEXPR const vg_nhab<UNSPEC_VSHA2MS> vsha2ms_obj;
static CONSTEXPR const vg_nhab<UNSPEC_VSHA2CH> vsha2ch_obj;
static CONSTEXPR const vg_nhab<UNSPEC_VSHA2CL> vsha2cl_obj;
static CONSTEXPR const crypto_vi<UNSPEC_VSM4K> vsm4k_obj;
static CONSTEXPR const crypto_vv<UNSPEC_VSM4R> vsm4r_obj;
static CONSTEXPR const vsm3me vsm3me_obj;
static CONSTEXPR const vaeskf2_vsm3c<UNSPEC_VSM3C> vsm3c_obj;
/* Zvfbfmin */
static CONSTEXPR const vfncvtbf16_f<NO_FRM> vfncvtbf16_f_obj;
static CONSTEXPR const vfncvtbf16_f<HAS_FRM> vfncvtbf16_f_frm_obj;
static CONSTEXPR const vfwcvtbf16_f vfwcvtbf16_f_obj;
/* Zvfbfwma; */
static CONSTEXPR const vfwmaccbf16<NO_FRM> vfwmaccbf16_obj;
static CONSTEXPR const vfwmaccbf16<HAS_FRM> vfwmaccbf16_frm_obj;
/* Declare the function base NAME, pointing it to an instance
of class <NAME>_obj. */
#define BASE(NAME) \
namespace bases { const function_base *const NAME = &NAME##_obj; }
BASE (vsetvl)
BASE (vsetvlmax)
BASE (vle)
BASE (vse)
BASE (vlm)
BASE (vsm)
BASE (vlse)
BASE (vsse)
BASE (vluxei8)
BASE (vluxei16)
BASE (vluxei32)
BASE (vluxei64)
BASE (vloxei8)
BASE (vloxei16)
BASE (vloxei32)
BASE (vloxei64)
BASE (vsuxei8)
BASE (vsuxei16)
BASE (vsuxei32)
BASE (vsuxei64)
BASE (vsoxei8)
BASE (vsoxei16)
BASE (vsoxei32)
BASE (vsoxei64)
BASE (vadd)
BASE (vsub)
BASE (vrsub)
BASE (vand)
BASE (vor)
BASE (vxor)
BASE (vsll)
BASE (vsra)
BASE (vsrl)
BASE (vmin)
BASE (vmax)
BASE (vminu)
BASE (vmaxu)
BASE (vmul)
BASE (vmulh)
BASE (vmulhu)
BASE (vmulhsu)
BASE (vdiv)
BASE (vrem)
BASE (vdivu)
BASE (vremu)
BASE (vneg)
BASE (vnot)
BASE (vsext)
BASE (vzext)
BASE (vwadd)
BASE (vwsub)
BASE (vwmul)
BASE (vwaddu)
BASE (vwsubu)
BASE (vwmulu)
BASE (vwmulsu)
BASE (vwcvt_x)
BASE (vwcvtu_x)
BASE (vadc)
BASE (vsbc)
BASE (vmadc)
BASE (vmsbc)
BASE (vnsrl)
BASE (vnsra)
BASE (vncvt_x)
BASE (vmerge)
BASE (vmv_v)
BASE (vmseq)
BASE (vmsne)
BASE (vmslt)
BASE (vmsgt)
BASE (vmsle)
BASE (vmsge)
BASE (vmsltu)
BASE (vmsgtu)
BASE (vmsleu)
BASE (vmsgeu)
BASE (vmacc)
BASE (vnmsac)
BASE (vmadd)
BASE (vnmsub)
BASE (vwmacc)
BASE (vwmaccu)
BASE (vwmaccsu)
BASE (vwmaccus)
BASE (vsadd)
BASE (vssub)
BASE (vsaddu)
BASE (vssubu)
BASE (vaadd)
BASE (vasub)
BASE (vaaddu)
BASE (vasubu)
BASE (vsmul)
BASE (vssra)
BASE (vssrl)
BASE (vnclip)
BASE (vnclipu)
BASE (vmand)
BASE (vmnand)
BASE (vmandn)
BASE (vmxor)
BASE (vmor)
BASE (vmnor)
BASE (vmorn)
BASE (vmxnor)
BASE (vmmv)
BASE (vmclr)
BASE (vmset)
BASE (vmnot)
BASE (vcpop)
BASE (vfirst)
BASE (vmsbf)
BASE (vmsif)
BASE (vmsof)
BASE (viota)
BASE (vid)
BASE (vfadd)
BASE (vfadd_frm)
BASE (vfsub)
BASE (vfsub_frm)
BASE (vfrsub)
BASE (vfrsub_frm)
BASE (vfwadd)
BASE (vfwadd_frm)
BASE (vfwsub)
BASE (vfwsub_frm)
BASE (vfmul)
BASE (vfmul_frm)
BASE (vfdiv)
BASE (vfdiv_frm)
BASE (vfrdiv)
BASE (vfrdiv_frm)
BASE (vfwmul)
BASE (vfwmul_frm)
BASE (vfmacc)
BASE (vfmacc_frm)
BASE (vfnmsac)
BASE (vfnmsac_frm)
BASE (vfmadd)
BASE (vfmadd_frm)
BASE (vfnmsub)
BASE (vfnmsub_frm)
BASE (vfnmacc)
BASE (vfnmacc_frm)
BASE (vfmsac)
BASE (vfmsac_frm)
BASE (vfnmadd)
BASE (vfnmadd_frm)
BASE (vfmsub)
BASE (vfmsub_frm)
BASE (vfwmacc)
BASE (vfwmacc_frm)
BASE (vfwnmacc)
BASE (vfwnmacc_frm)
BASE (vfwmsac)
BASE (vfwmsac_frm)
BASE (vfwnmsac)
BASE (vfwnmsac_frm)
BASE (vfsqrt)
BASE (vfsqrt_frm)
BASE (vfrsqrt7)
BASE (vfrec7)
BASE (vfrec7_frm)
BASE (vfmin)
BASE (vfmax)
BASE (vfsgnj)
BASE (vfsgnjn)
BASE (vfsgnjx)
BASE (vfneg)
BASE (vfabs)
BASE (vmfeq)
BASE (vmfne)
BASE (vmflt)
BASE (vmfgt)
BASE (vmfle)
BASE (vmfge)
BASE (vfclass)
BASE (vfmerge)
BASE (vfmv_v)
BASE (vfcvt_x)
BASE (vfcvt_x_frm)
BASE (vfcvt_xu)
BASE (vfcvt_xu_frm)
BASE (vfcvt_rtz_x)
BASE (vfcvt_rtz_xu)
BASE (vfcvt_f)
BASE (vfcvt_f_frm)
BASE (vfwcvt_x)
BASE (vfwcvt_x_frm)
BASE (vfwcvt_xu)
BASE (vfwcvt_xu_frm)
BASE (vfwcvt_rtz_x)
BASE (vfwcvt_rtz_xu)
BASE (vfwcvt_f)
BASE (vfncvt_x)
BASE (vfncvt_x_frm)
BASE (vfncvt_xu)
BASE (vfncvt_xu_frm)
BASE (vfncvt_rtz_x)
BASE (vfncvt_rtz_xu)
BASE (vfncvt_f)
BASE (vfncvt_f_frm)
BASE (vfncvt_rod_f)
BASE (vredsum)
BASE (vredmaxu)
BASE (vredmax)
BASE (vredminu)
BASE (vredmin)
BASE (vredand)
BASE (vredor)
BASE (vredxor)
BASE (vwredsum)
BASE (vwredsumu)
BASE (vfredusum)
BASE (vfredusum_frm)
BASE (vfredosum)
BASE (vfredosum_frm)
BASE (vfredmax)
BASE (vfredmin)
BASE (vfwredosum)
BASE (vfwredosum_frm)
BASE (vfwredusum)
BASE (vfwredusum_frm)
BASE (vmv_x)
BASE (vmv_s)
BASE (vfmv_f)
BASE (vfmv_s)
BASE (vslideup)
BASE (vslidedown)
BASE (vslide1up)
BASE (vslide1down)
BASE (vfslide1up)
BASE (vfslide1down)
BASE (vrgather)
BASE (vrgatherei16)
BASE (vcompress)
BASE (vundefined)
BASE (vreinterpret)
BASE (vlmul_ext)
BASE (vlmul_trunc)
BASE (vset)
BASE (vget)
BASE (vcreate)
BASE (read_vl)
BASE (vleff)
BASE (vlenb)
BASE (vlseg)
BASE (vsseg)
BASE (vlsseg)
BASE (vssseg)
BASE (vluxseg)
BASE (vloxseg)
BASE (vsuxseg)
BASE (vsoxseg)
BASE (vlsegff)
BASE (vlb)
BASE (vlh)
BASE (vlw)
BASE (vlbu)
BASE (vlhu)
BASE (vlwu)
BASE (vsb)
BASE (vsh)
BASE (vsw)
BASE (vlsb)
BASE (vlsh)
BASE (vlsw)
BASE (vlsbu)
BASE (vlshu)
BASE (vlswu)
BASE (vssb)
BASE (vssh)
BASE (vssw)
BASE (vlxb)
BASE (vlxh)
BASE (vlxw)
BASE (vlxbu)
BASE (vlxhu)
BASE (vlxwu)
BASE (vsxb)
BASE (vsxh)
BASE (vsxw)
BASE (vsuxb)
BASE (vsuxh)
BASE (vsuxw)
BASE (vext_x_v)
/* Crypto vector */
BASE (vandn)
BASE (vbrev)
BASE (vbrev8)
BASE (vrev8)
BASE (vclz)
BASE (vctz)
BASE (vrol)
BASE (vror)
BASE (vwsll)
BASE (vclmul)
BASE (vclmulh)
BASE (vghsh)
BASE (vgmul)
BASE (vaesef)
BASE (vaesem)
BASE (vaesdf)
BASE (vaesdm)
BASE (vaesz)
BASE (vaeskf1)
BASE (vaeskf2)
BASE (vsha2ms)
BASE (vsha2ch)
BASE (vsha2cl)
BASE (vsm4k)
BASE (vsm4r)
BASE (vsm3me)
BASE (vsm3c)
/* Zvfbfmin */
BASE (vfncvtbf16_f)
BASE (vfncvtbf16_f_frm)
BASE (vfwcvtbf16_f)
/* Zvfbfwma */
BASE (vfwmaccbf16)
BASE (vfwmaccbf16_frm)
} // end namespace riscv_vector