aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/riscv/riscv-builtins.cc44
-rw-r--r--gcc/config/riscv/riscv-protos.h17
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.cc475
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.def245
-rw-r--r--gcc/config/riscv/riscv-vector-builtins.h363
6 files changed, 1065 insertions, 81 deletions
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 3950b41..acd1a74 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -520,6 +520,8 @@ riscv*)
extra_objs="${extra_objs} riscv-vector-builtins.o"
d_target_objs="riscv-d.o"
extra_headers="riscv_vector.h"
+ target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.cc"
+ target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.h"
;;
rs6000*-*-*)
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 14865d7..9fa4d6c 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -223,7 +223,10 @@ riscv_init_builtins (void)
{
tree type = riscv_build_function_type (d->prototype);
riscv_builtin_decls[i]
- = add_builtin_function (d->name, type, i, BUILT_IN_MD, NULL, NULL);
+ = add_builtin_function (d->name, type,
+ (i << RISCV_BUILTIN_SHIFT)
+ + RISCV_BUILTIN_GENERAL,
+ BUILT_IN_MD, NULL, NULL);
riscv_builtin_decl_index[d->icode] = i;
}
}
@@ -234,9 +237,18 @@ riscv_init_builtins (void)
tree
riscv_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
{
- if (code >= ARRAY_SIZE (riscv_builtins))
- return error_mark_node;
- return riscv_builtin_decls[code];
+ unsigned int subcode = code >> RISCV_BUILTIN_SHIFT;
+ switch (code & RISCV_BUILTIN_CLASS)
+ {
+ case RISCV_BUILTIN_GENERAL:
+ if (subcode >= ARRAY_SIZE (riscv_builtins))
+ return error_mark_node;
+ return riscv_builtin_decls[subcode];
+
+ case RISCV_BUILTIN_VECTOR:
+ return riscv_vector::builtin_decl (subcode, initialize_p);
+ }
+ return error_mark_node;
}
/* Take argument ARGNO from EXP's argument list and convert it into
@@ -303,15 +315,23 @@ riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
- const struct riscv_builtin_description *d = &riscv_builtins[fcode];
-
- switch (d->builtin_type)
+ unsigned int subcode = fcode >> RISCV_BUILTIN_SHIFT;
+ switch (fcode & RISCV_BUILTIN_CLASS)
{
- case RISCV_BUILTIN_DIRECT:
- return riscv_expand_builtin_direct (d->icode, target, exp, true);
-
- case RISCV_BUILTIN_DIRECT_NO_TARGET:
- return riscv_expand_builtin_direct (d->icode, target, exp, false);
+ case RISCV_BUILTIN_VECTOR:
+ return riscv_vector::expand_builtin (subcode, exp, target);
+ case RISCV_BUILTIN_GENERAL: {
+ const struct riscv_builtin_description *d = &riscv_builtins[subcode];
+
+ switch (d->builtin_type)
+ {
+ case RISCV_BUILTIN_DIRECT:
+ return riscv_expand_builtin_direct (d->icode, target, exp, true);
+
+ case RISCV_BUILTIN_DIRECT_NO_TARGET:
+ return riscv_expand_builtin_direct (d->icode, target, exp, false);
+ }
+ }
}
gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index a44b34d..f8c9932 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -124,6 +124,23 @@ extern const char *mangle_builtin_type (const_tree);
extern bool verify_type_context (location_t, type_context_kind, const_tree, bool);
#endif
extern void handle_pragma_vector (void);
+extern tree builtin_decl (unsigned, bool);
+extern rtx expand_builtin (unsigned int, tree, rtx);
}
+/* We classify builtin types into two classes:
+ 1. General builtin class which is defined in riscv_builtins.
+ 2. Vector builtin class which is a special builtin architecture
+ that implement intrinsic short into "pragma". */
+enum riscv_builtin_class
+{
+ RISCV_BUILTIN_GENERAL,
+ RISCV_BUILTIN_VECTOR
+};
+
+const unsigned int RISCV_BUILTIN_SHIFT = 1;
+
+/* Mask that selects the riscv_builtin_class part of a function code. */
+const unsigned int RISCV_BUILTIN_CLASS = (1 << RISCV_BUILTIN_SHIFT) - 1;
+
#endif /* ! GCC_RISCV_PROTOS_H */
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 55d4565..5c20788 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -66,13 +66,55 @@ struct vector_type_info
const char *mangled_name;
};
-/* Information about each RVV type. */
+/* Describes a function decl. */
+class GTY (()) registered_function
+{
+public:
+ function_instance GTY ((skip)) instance;
+
+ /* The decl itself. */
+ tree GTY ((skip)) decl;
+};
+
+/* Hash traits for registered_function. */
+struct registered_function_hasher : nofree_ptr_hash<registered_function>
+{
+ typedef function_instance compare_type;
+
+ static hashval_t hash (value_type);
+ static bool equal (value_type, const compare_type &);
+};
+
+/* Static information about each RVV type. */
static CONSTEXPR const vector_type_info vector_types[] = {
#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...) \
{#NAME, #ABI_NAME, "u" #NCHARS #ABI_NAME},
#include "riscv-vector-builtins.def"
};
+/* Static information about operand suffix for each RVV type. */
+const char *const operand_suffixes[NUM_OP_TYPES] = {
+ "", /* OP_TYPE_none. */
+#define DEF_RVV_OP_TYPE(NAME) "_" # NAME,
+#include "riscv-vector-builtins.def"
+};
+
+/* Static information about type suffix for each RVV type. */
+const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1] = {
+#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \
+ VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \
+ VSETVL_SUFFIX) \
+ {#VECTOR_SUFFIX, #SCALAR_SUFFIX, #VSETVL_SUFFIX},
+#include "riscv-vector-builtins.def"
+};
+
+/* Static information about predication suffix for each RVV type. */
+const char *const predication_suffixes[NUM_PRED_TYPES] = {
+ "", /* PRED_TYPE_none. */
+#define DEF_RVV_PRED_TYPE(NAME) "_" # NAME,
+#include "riscv-vector-builtins.def"
+};
+
/* The RVV types, with their built-in
"__rvv..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
yields a null tree. */
@@ -82,6 +124,14 @@ static GTY (()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];
extern GTY (()) rvv_builtin_types_t builtin_types[NUM_VECTOR_TYPES + 1];
rvv_builtin_types_t builtin_types[NUM_VECTOR_TYPES + 1];
+/* The list of all registered function decls, indexed by code. */
+static GTY (()) vec<registered_function *, va_gc> *registered_functions;
+
+/* All registered function decls, hashed on the function_instance
+ that they implement. This is used for looking up implementations of
+ overloaded functions. */
+static hash_table<registered_function_hasher> *function_table;
+
/* RAII class for enabling enough RVV features to define the built-in
types and implement the riscv_vector.h pragma.
@@ -118,6 +168,13 @@ rvv_switcher::~rvv_switcher ()
sizeof (have_regs_of_mode));
}
+/* Add attribute NAME to ATTRS. */
+static tree
+add_attribute (const char *name, tree attrs)
+{
+ return tree_cons (get_identifier (name), NULL_TREE, attrs);
+}
+
/* Add type attributes to builtin type tree, currently only the mangled name. */
static void
add_vector_type_attribute (tree type, const char *mangled_name)
@@ -215,6 +272,7 @@ static void
register_vector_type (vector_type_index type)
{
tree vectype = abi_vector_types[type];
+
/* When vectype is NULL, the corresponding builtin type
is disabled according to '-march'. */
if (!vectype)
@@ -237,6 +295,386 @@ register_vector_type (vector_type_index type)
builtin_types[type].vector_ptr = build_pointer_type (vectype);
}
+/* Check whether all the RVV_REQUIRE_* values in REQUIRED_EXTENSIONS are
+ enabled. */
+static bool
+check_required_extensions (uint64_t required_extensions)
+{
+ uint64_t riscv_isa_flags = 0;
+
+ if (TARGET_VECTOR_ELEN_FP_32)
+ riscv_isa_flags |= RVV_REQUIRE_ELEN_FP_32;
+ if (TARGET_VECTOR_ELEN_FP_64)
+ riscv_isa_flags |= RVV_REQUIRE_ELEN_FP_64;
+ if (TARGET_MIN_VLEN > 32)
+ riscv_isa_flags |= RVV_REQUIRE_ZVE64;
+ if (TARGET_64BIT)
+ riscv_isa_flags |= RVV_REQUIRE_RV64BIT;
+
+ uint64_t missing_extensions = required_extensions & ~riscv_isa_flags;
+ if (missing_extensions != 0)
+ return false;
+ return true;
+}
+
+tree
+rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
+{
+ switch (base_type)
+ {
+ case RVV_BASE_vector:
+ return builtin_types[type_idx].vector;
+ case RVV_BASE_scalar:
+ return builtin_types[type_idx].scalar;
+ case RVV_BASE_vector_ptr:
+ return builtin_types[type_idx].vector_ptr;
+ case RVV_BASE_scalar_ptr:
+ return builtin_types[type_idx].scalar_ptr;
+ case RVV_BASE_scalar_const_ptr:
+ return builtin_types[type_idx].scalar_const_ptr;
+ case RVV_BASE_void:
+ return void_type_node;
+ case RVV_BASE_size:
+ return size_type_node;
+ case RVV_BASE_ptrdiff:
+ return ptrdiff_type_node;
+ case RVV_BASE_unsigned_long:
+ return long_unsigned_type_node;
+ case RVV_BASE_long:
+ return long_integer_type_node;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+function_instance::function_instance (const char *base_name_in,
+ const function_base *base_in,
+ const function_shape *shape_in,
+ rvv_type_info type_in,
+ predication_type_index pred_in,
+ const rvv_op_info *op_info_in)
+ : base_name (base_name_in), base (base_in), shape (shape_in), type (type_in),
+ pred (pred_in), op_info (op_info_in)
+{
+}
+
+bool
+function_instance::operator== (const function_instance &other) const
+{
+ for (unsigned int i = 0; op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
+ if (op_info->args[i].base_type != other.op_info->args[i].base_type)
+ return false;
+ return (base == other.base && shape == other.shape
+ && type.index == other.type.index && op_info->op == other.op_info->op
+ && pred == other.pred
+ && op_info->ret.base_type == other.op_info->ret.base_type);
+}
+
+bool
+function_instance::any_type_float_p () const
+{
+ if (FLOAT_MODE_P (TYPE_MODE (get_return_type ())))
+ return true;
+
+ for (int i = 0; op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
+ if (FLOAT_MODE_P (TYPE_MODE (get_arg_type (i))))
+ return true;
+
+ return false;
+}
+
+tree
+function_instance::get_return_type () const
+{
+ return op_info->ret.get_tree_type (type.index);
+}
+
+tree
+function_instance::get_arg_type (unsigned opno) const
+{
+ return op_info->args[opno].get_tree_type (type.index);
+}
+
+/* Return a hash code for a function_instance. */
+hashval_t
+function_instance::hash () const
+{
+ inchash::hash h;
+ /* BASE uniquely determines BASE_NAME, so we don't need to hash both. */
+ h.add_ptr (base);
+ h.add_ptr (shape);
+ h.add_int (type.index);
+ h.add_int (op_info->op);
+ h.add_int (pred);
+ h.add_int (op_info->ret.base_type);
+ for (unsigned int i = 0; op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
+ h.add_int (op_info->args[i].base_type);
+ return h.end ();
+}
+
+/* Return a set of CP_* flags that describe what the function could do,
+ taking the command-line flags into account. */
+unsigned int
+function_instance::call_properties () const
+{
+ unsigned int flags = base->call_properties (*this);
+
+ /* -fno-trapping-math means that we can assume any FP exceptions
+ are not user-visible. */
+ if (!flag_trapping_math)
+ flags &= ~CP_RAISE_FP_EXCEPTIONS;
+
+ return flags;
+}
+
+/* Return true if calls to the function could read some form of
+ global state. */
+bool
+function_instance::reads_global_state_p () const
+{
+ unsigned int flags = call_properties ();
+
+ /* Preserve any dependence on rounding mode, flush to zero mode, etc.
+ There is currently no way of turning this off; in particular,
+ -fno-rounding-math (which is the default) means that we should make
+ the usual assumptions about rounding mode, which for intrinsics means
+ acting as the instructions do. */
+ if (flags & CP_READ_FPCR)
+ return true;
+
+ /* Handle direct reads of global state. */
+ return flags & (CP_READ_MEMORY | CP_READ_CSR);
+}
+
+/* Return true if calls to the function could modify some form of
+ global state. */
+bool
+function_instance::modifies_global_state_p () const
+{
+ unsigned int flags = call_properties ();
+
+ /* Preserve any exception state written back to the FPCR,
+ unless -fno-trapping-math says this is unnecessary. */
+ if (flags & CP_RAISE_FP_EXCEPTIONS)
+ return true;
+
+ /* Handle direct modifications of global state. */
+ return flags & (CP_WRITE_MEMORY | CP_WRITE_CSR);
+}
+
+/* Return true if calls to the function could raise a signal. */
+bool
+function_instance::could_trap_p () const
+{
+ unsigned int flags = call_properties ();
+
+ /* Handle functions that could raise SIGFPE. */
+ if (flags & CP_RAISE_FP_EXCEPTIONS)
+ return true;
+
+ /* Handle functions that could raise SIGBUS or SIGSEGV. */
+ if (flags & (CP_READ_MEMORY | CP_WRITE_MEMORY))
+ return true;
+
+ return false;
+}
+
+function_builder::function_builder ()
+{
+ m_direct_overloads = lang_GNU_CXX ();
+ gcc_obstack_init (&m_string_obstack);
+}
+
+function_builder::~function_builder ()
+{
+ obstack_free (&m_string_obstack, NULL);
+}
+
+/* Allocate arguments of the function. */
+void
+function_builder::allocate_argument_types (const function_instance &instance,
+ vec<tree> &argument_types) const
+{
+ for (unsigned int i = 0;
+ instance.op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
+ argument_types.quick_push (
+ instance.op_info->args[i].get_tree_type (instance.type.index));
+}
+
+/* Register all the functions in GROUP. */
+void
+function_builder::register_function_group (const function_group_info &group)
+{
+ (*group.shape)->build (*this, group);
+}
+
+/* Add NAME to the end of the function name being built. */
+void
+function_builder::append_name (const char *name)
+{
+ obstack_grow (&m_string_obstack, name, strlen (name));
+}
+
+/* Zero-terminate and complete the function name being built. */
+char *
+function_builder::finish_name ()
+{
+ obstack_1grow (&m_string_obstack, 0);
+ return (char *) obstack_finish (&m_string_obstack);
+}
+
+/* Return the appropriate function attributes for INSTANCE. */
+tree
+function_builder::get_attributes (const function_instance &instance)
+{
+ tree attrs = NULL_TREE;
+
+ if (!instance.modifies_global_state_p ())
+ {
+ if (instance.reads_global_state_p ())
+ attrs = add_attribute ("pure", attrs);
+ else
+ attrs = add_attribute ("const", attrs);
+ }
+
+ if (!flag_non_call_exceptions || !instance.could_trap_p ())
+ attrs = add_attribute ("nothrow", attrs);
+
+ return add_attribute ("leaf", attrs);
+}
+
+/* Add a function called NAME with type FNTYPE and attributes ATTRS.
+ INSTANCE describes what the function does. */
+registered_function &
+function_builder::add_function (const function_instance &instance,
+ const char *name, tree fntype, tree attrs,
+ bool placeholder_p)
+{
+ unsigned int code = vec_safe_length (registered_functions);
+ code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
+
+ /* We need to be able to generate placeholders to enusre that we have a
+ consistent numbering scheme for function codes between the C and C++
+ frontends, so that everything ties up in LTO.
+
+ Currently, tree-streamer-in.c:unpack_ts_function_decl_value_fields
+ validates that tree nodes returned by TARGET_BUILTIN_DECL are non-NULL and
+ some node other than error_mark_node. This is a holdover from when builtin
+ decls were streamed by code rather than by value.
+
+ Ultimately, we should be able to remove this validation of BUILT_IN_MD
+ nodes and remove the target hook. For now, however, we need to appease the
+ validation and return a non-NULL, non-error_mark_node node, so we
+ arbitrarily choose integer_zero_node. */
+ tree decl = placeholder_p
+ ? integer_zero_node
+ : simulate_builtin_function_decl (input_location, name, fntype,
+ code, NULL, attrs);
+
+ registered_function &rfn = *ggc_alloc<registered_function> ();
+ rfn.instance = instance;
+ rfn.decl = decl;
+ vec_safe_push (registered_functions, &rfn);
+
+ return rfn;
+}
+
+/* Add a built-in function for INSTANCE, with the argument types given
+ by ARGUMENT_TYPES and the return type given by RETURN_TYPE. NAME is
+ the "full" name for C function. OVERLOAD_NAME is the "short" name for
+ C++ overloaded function. OVERLOAD_NAME can be nullptr because some
+ instance doesn't have C++ overloaded function. */
+void
+function_builder::add_unique_function (const function_instance &instance,
+ const function_shape *shape,
+ tree return_type,
+ vec<tree> &argument_types)
+{
+ /* Do not add this function if it is invalid. */
+ if (!check_required_extensions (instance.type.required_extensions))
+ return;
+
+ /* Add the function under its full (unique) name. */
+ char *name = shape->get_name (*this, instance, false);
+ tree fntype
+ = build_function_type_array (return_type, argument_types.length (),
+ argument_types.address ());
+ tree attrs = get_attributes (instance);
+ registered_function &rfn
+ = add_function (instance, name, fntype, attrs, false);
+
+ /* Enter the function into the hash table. */
+ hashval_t hash = instance.hash ();
+ registered_function **rfn_slot
+ = function_table->find_slot_with_hash (instance, hash, INSERT);
+ gcc_assert (!*rfn_slot);
+ *rfn_slot = &rfn;
+
+ /* Also add the function under its overloaded alias, if we want
+ a separate decl for each instance of an overloaded function. */
+ char *overload_name = shape->get_name (*this, instance, true);
+ if (overload_name)
+ {
+ /* Attribute lists shouldn't be shared. */
+ tree attrs = get_attributes (instance);
+ bool placeholder_p = !m_direct_overloads;
+ add_function (instance, overload_name, fntype, attrs, placeholder_p);
+ }
+ obstack_free (&m_string_obstack, name);
+}
+
+function_call_info::function_call_info (location_t location_in,
+ const function_instance &instance_in,
+ tree fndecl_in)
+ : function_instance (instance_in), location (location_in), fndecl (fndecl_in)
+{}
+
+function_expander::function_expander (const function_instance &instance,
+ tree fndecl_in, tree exp_in,
+ rtx target_in)
+ : function_call_info (EXPR_LOCATION (exp_in), instance, fndecl_in),
+ exp (exp_in), target (target_in), opno (0)
+{
+ if (!function_returns_void_p ())
+ create_output_operand (&m_ops[opno++], target, TYPE_MODE (TREE_TYPE (exp)));
+}
+
+/* Take argument ARGNO from EXP's argument list and convert it into
+ an expand operand. Store the operand in *M_OPS. */
+void
+function_expander::add_input_operand (unsigned argno)
+{
+ tree arg = CALL_EXPR_ARG (exp, argno);
+ rtx x = expand_normal (arg);
+ add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
+}
+
+/* Generate instruction ICODE, given that its operands have already
+ been added to M_OPS. Return the value of the first operand. */
+rtx
+function_expander::generate_insn (insn_code icode)
+{
+ gcc_assert (opno == insn_data[icode].n_generator_args);
+ if (!maybe_expand_insn (icode, opno, m_ops))
+ {
+ error ("invalid argument to built-in function");
+ return NULL_RTX;
+ }
+ return function_returns_void_p () ? const0_rtx : m_ops[0].value;
+}
+
+inline hashval_t
+registered_function_hasher::hash (value_type value)
+{
+ return value->instance.hash ();
+}
+
+inline bool
+registered_function_hasher::equal (value_type value, const compare_type &key)
+{
+ return value->instance == key;
+}
+
/* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
otherwise return NULL. */
const char *
@@ -356,4 +794,39 @@ handle_pragma_vector ()
register_vector_type ((enum vector_type_index) type_i);
}
+/* Return the function decl with RVV function subcode CODE, or error_mark_node
+ if no such function exists. */
+tree
+builtin_decl (unsigned int code, bool)
+{
+ if (code >= vec_safe_length (registered_functions))
+ return error_mark_node;
+
+ return (*registered_functions)[code]->decl;
+}
+
+/* Expand a call to the RVV function with subcode CODE. EXP is the call
+ expression and TARGET is the preferred location for the result.
+ Return the value of the lhs. */
+rtx
+expand_builtin (unsigned int code, tree exp, rtx target)
+{
+ registered_function &rfn = *(*registered_functions)[code];
+ return function_expander (rfn.instance, rfn.decl, exp, target).expand ();
+}
+
} // end namespace riscv_vector
+
+inline void
+gt_ggc_mx (function_instance *)
+{}
+
+inline void
+gt_pch_nx (function_instance *)
+{}
+
+inline void
+gt_pch_nx (function_instance *, gt_pointer_operator, void *)
+{}
+
+#include "gt-riscv-vector-builtins.h"
diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def
index 83603fe..b7a633e 100644
--- a/gcc/config/riscv/riscv-vector-builtins.def
+++ b/gcc/config/riscv/riscv-vector-builtins.def
@@ -19,181 +19,290 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Use "DEF_RVV_TYPE" macro to define RVV datatype builtins.
- 1.The 1 argument is the name exposed to users.
+ 1.The 'NAME' argument is the name exposed to users.
For example, "vint32m1_t".
- 2.The 2 argument is the length of ABI-name.
+ 2.The 'NCHARS' argument is the length of ABI-name.
For example, length of "__rvv_int32m1_t" is 15.
- 3.The 3 argument is the ABI-name. For example, "__rvv_int32m1_t".
- 4.The 4 argument is associated scalar type which is used in
+ 3.The 'ABI_NAME' argument is the ABI-name. For example, "__rvv_int32m1_t".
+ 4.The 'SCALAR_TYPE' argument is associated scalar type which is used in
"build_vector_type_for_mode". For "vint32m1_t", we use "intSI_type_node" in
RV64. Otherwise, we use "long_integer_type_node".
- 5.The 5 and 6 argument are the machine modes of corresponding RVV type used
- in "build_vector_type_for_mode". For "vint32m1_t", we use VNx2SImode when
- TARGET_MIN_VLEN > 32. Otherwise the machine mode is VNx1SImode. */
+ 5.The 'VECTOR_MODE' is the machine modes of corresponding RVV type used
+ in "build_vector_type_for_mode" when TARGET_MIN_VLEN > 32.
+ For example: VECTOR_MODE = VNx2SI for "vint32m1_t".
+ 6.The 'VECTOR_MODE_MIN_VLEN_32' is the machine modes of corresponding RVV
+ type used in "build_vector_type_for_mode" when TARGET_MIN_VLEN = 32. For
+ example: VECTOR_MODE_MIN_VLEN_32 = VNx1SI for "vint32m1_t".
+ 7.The 'VECTOR_SUFFIX' define mode suffix for vector type.
+ For example: type_suffixes[VECTOR_TYPE_vin32m1_t].vector = i32m1.
+ 8.The 'SCALAR_SUFFIX' define mode suffix for scalar type.
+ For example: type_suffixes[VECTOR_TYPE_vin32m1_t].scalar = i32.
+ 9.The 'VSETVL_SUFFIX' define mode suffix for vsetvli instruction.
+ For example: type_suffixes[VECTOR_TYPE_vin32m1_t].vsetvl = e32m1.
+*/
#ifndef DEF_RVV_TYPE
#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \
- VECTOR_MODE_MIN_VLEN_32)
+ VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \
+ VSETVL_SUFFIX)
+#endif
+
+/* Use "DEF_RVV_OP_TYPE" macro to define RVV operand types.
+ The 'NAME' will be concatenated into intrinsic function name. */
+#ifndef DEF_RVV_OP_TYPE
+#define DEF_RVV_OP_TYPE(NAME)
+#endif
+
+/* Use "DEF_RVV_PRED_TYPE" macro to define RVV predication types.
+ The 'NAME' will be concatenated into intrinsic function name. */
+#ifndef DEF_RVV_PRED_TYPE
+#define DEF_RVV_PRED_TYPE(NAME)
#endif
/* SEW/LMUL = 64:
Only enable when TARGET_MIN_VLEN > 32 and machine mode = VNx1BImode. */
-DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, VNx1BI, VOID)
+DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, VNx1BI, VOID, _b64, , )
/* SEW/LMUL = 32:
Machine mode = VNx2BImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx1BImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, VNx2BI, VNx1BI)
+DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, VNx2BI, VNx1BI, _b32, , )
/* SEW/LMUL = 16:
Machine mode = VNx2BImode when TARGET_MIN_VLEN = 32.
Machine mode = VNx4BImode when TARGET_MIN_VLEN > 32. */
-DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, VNx4BI, VNx2BI)
+DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, VNx4BI, VNx2BI, _b16, , )
/* SEW/LMUL = 8:
Machine mode = VNx8BImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx4BImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, VNx8BI, VNx4BI)
+DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, VNx8BI, VNx4BI, _b8, , )
/* SEW/LMUL = 4:
Machine mode = VNx16BImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx8BImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, VNx16BI, VNx8BI)
+DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, VNx16BI, VNx8BI, _b4, , )
/* SEW/LMUL = 2:
Machine mode = VNx32BImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx16BImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, VNx32BI, VNx16BI)
+DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, VNx32BI, VNx16BI, _b2, , )
/* SEW/LMUL = 1:
Machine mode = VNx64BImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx32BImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, VNx64BI, VNx32BI)
+DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, VNx64BI, VNx32BI, _b1, , )
/* LMUL = 1/8:
Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1QImode. */
-DEF_RVV_TYPE (vint8mf8_t, 15, __rvv_int8mf8_t, intQI, VNx1QI, VOID)
-DEF_RVV_TYPE (vuint8mf8_t, 16, __rvv_uint8mf8_t, unsigned_intQI, VNx1QI, VOID)
+DEF_RVV_TYPE (vint8mf8_t, 15, __rvv_int8mf8_t, intQI, VNx1QI, VOID, _i8mf8, _i8,
+ _e8mf8)
+DEF_RVV_TYPE (vuint8mf8_t, 16, __rvv_uint8mf8_t, unsigned_intQI, VNx1QI, VOID,
+ _u8mf8, _u8, _e8mf8)
/* LMUL = 1/4:
Machine mode = VNx2QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx1QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8mf4_t, 15, __rvv_int8mf4_t, intQI, VNx2QI, VNx1QI)
-DEF_RVV_TYPE (vuint8mf4_t, 16, __rvv_uint8mf4_t, unsigned_intQI, VNx2QI, VNx1QI)
+DEF_RVV_TYPE (vint8mf4_t, 15, __rvv_int8mf4_t, intQI, VNx2QI, VNx1QI, _i8mf4,
+ _i8, _e8mf4)
+DEF_RVV_TYPE (vuint8mf4_t, 16, __rvv_uint8mf4_t, unsigned_intQI, VNx2QI, VNx1QI,
+ _u8mf4, _u8, _e8mf4)
/* LMUL = 1/2:
Machine mode = VNx4QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx2QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8mf2_t, 15, __rvv_int8mf2_t, intQI, VNx4QI, VNx2QI)
-DEF_RVV_TYPE (vuint8mf2_t, 16, __rvv_uint8mf2_t, unsigned_intQI, VNx4QI, VNx2QI)
+DEF_RVV_TYPE (vint8mf2_t, 15, __rvv_int8mf2_t, intQI, VNx4QI, VNx2QI, _i8mf2,
+ _i8, _e8mf2)
+DEF_RVV_TYPE (vuint8mf2_t, 16, __rvv_uint8mf2_t, unsigned_intQI, VNx4QI, VNx2QI,
+ _u8mf2, _u8, _e8mf2)
/* LMUL = 1:
Machine mode = VNx8QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx4QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8m1_t, 14, __rvv_int8m1_t, intQI, VNx8QI, VNx4QI)
-DEF_RVV_TYPE (vuint8m1_t, 15, __rvv_uint8m1_t, unsigned_intQI, VNx8QI, VNx4QI)
+DEF_RVV_TYPE (vint8m1_t, 14, __rvv_int8m1_t, intQI, VNx8QI, VNx4QI, _i8m1, _i8,
+ _e8m1)
+DEF_RVV_TYPE (vuint8m1_t, 15, __rvv_uint8m1_t, unsigned_intQI, VNx8QI, VNx4QI,
+ _u8m1, _u8, _e8m1)
/* LMUL = 2:
Machine mode = VNx16QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx8QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8m2_t, 14, __rvv_int8m2_t, intQI, VNx16QI, VNx8QI)
-DEF_RVV_TYPE (vuint8m2_t, 15, __rvv_uint8m2_t, unsigned_intQI, VNx16QI, VNx8QI)
+DEF_RVV_TYPE (vint8m2_t, 14, __rvv_int8m2_t, intQI, VNx16QI, VNx8QI, _i8m2, _i8,
+ _e8m2)
+DEF_RVV_TYPE (vuint8m2_t, 15, __rvv_uint8m2_t, unsigned_intQI, VNx16QI, VNx8QI,
+ _u8m2, _u8, _e8m2)
/* LMUL = 4:
Machine mode = VNx32QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx16QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8m4_t, 14, __rvv_int8m4_t, intQI, VNx32QI, VNx16QI)
-DEF_RVV_TYPE (vuint8m4_t, 15, __rvv_uint8m4_t, unsigned_intQI, VNx32QI, VNx16QI)
+DEF_RVV_TYPE (vint8m4_t, 14, __rvv_int8m4_t, intQI, VNx32QI, VNx16QI, _i8m4,
+ _i8, _e8m4)
+DEF_RVV_TYPE (vuint8m4_t, 15, __rvv_uint8m4_t, unsigned_intQI, VNx32QI, VNx16QI,
+ _u8m4, _u8, _e8m4)
/* LMUL = 8:
Machine mode = VNx64QImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx32QImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint8m8_t, 14, __rvv_int8m8_t, intQI, VNx64QI, VNx32QI)
-DEF_RVV_TYPE (vuint8m8_t, 15, __rvv_uint8m8_t, unsigned_intQI, VNx64QI, VNx32QI)
+DEF_RVV_TYPE (vint8m8_t, 14, __rvv_int8m8_t, intQI, VNx64QI, VNx32QI, _i8m8,
+ _i8, _e8m8)
+DEF_RVV_TYPE (vuint8m8_t, 15, __rvv_uint8m8_t, unsigned_intQI, VNx64QI, VNx32QI,
+ _u8m8, _u8, _e8m8)
/* LMUL = 1/4:
Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1HImode. */
-DEF_RVV_TYPE (vint16mf4_t, 16, __rvv_int16mf4_t, intHI, VNx1HI, VOID)
-DEF_RVV_TYPE (vuint16mf4_t, 17, __rvv_uint16mf4_t, unsigned_intHI, VNx1HI, VOID)
+DEF_RVV_TYPE (vint16mf4_t, 16, __rvv_int16mf4_t, intHI, VNx1HI, VOID, _i16mf4,
+ _i16, _e16mf4)
+DEF_RVV_TYPE (vuint16mf4_t, 17, __rvv_uint16mf4_t, unsigned_intHI, VNx1HI, VOID,
+ _u16mf4, _u16, _e16mf4)
/* LMUL = 1/2:
Machine mode = VNx2HImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx1HImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint16mf2_t, 16, __rvv_int16mf2_t, intHI, VNx2HI, VNx1HI)
+DEF_RVV_TYPE (vint16mf2_t, 16, __rvv_int16mf2_t, intHI, VNx2HI, VNx1HI, _i16mf2,
+ _i16, _e16mf2)
DEF_RVV_TYPE (vuint16mf2_t, 17, __rvv_uint16mf2_t, unsigned_intHI, VNx2HI,
- VNx1HI)
+ VNx1HI, _u16mf2, _u16, _e16mf2)
/* LMUL = 1:
Machine mode = VNx4HImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx2HImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint16m1_t, 15, __rvv_int16m1_t, intHI, VNx4HI, VNx2HI)
-DEF_RVV_TYPE (vuint16m1_t, 16, __rvv_uint16m1_t, unsigned_intHI, VNx4HI, VNx2HI)
+DEF_RVV_TYPE (vint16m1_t, 15, __rvv_int16m1_t, intHI, VNx4HI, VNx2HI, _i16m1,
+ _i16, _e16m1)
+DEF_RVV_TYPE (vuint16m1_t, 16, __rvv_uint16m1_t, unsigned_intHI, VNx4HI, VNx2HI,
+ _u16m1, _u16, _e16m1)
/* LMUL = 2:
Machine mode = VNx8HImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx4HImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint16m2_t, 15, __rvv_int16m2_t, intHI, VNx8HI, VNx4HI)
-DEF_RVV_TYPE (vuint16m2_t, 16, __rvv_uint16m2_t, unsigned_intHI, VNx8HI, VNx4HI)
+DEF_RVV_TYPE (vint16m2_t, 15, __rvv_int16m2_t, intHI, VNx8HI, VNx4HI, _i16m2,
+ _i16, _e16m2)
+DEF_RVV_TYPE (vuint16m2_t, 16, __rvv_uint16m2_t, unsigned_intHI, VNx8HI, VNx4HI,
+ _u16m2, _u16, _e16m2)
/* LMUL = 4:
Machine mode = VNx16HImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx8HImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint16m4_t, 15, __rvv_int16m4_t, intHI, VNx16HI, VNx8HI)
+DEF_RVV_TYPE (vint16m4_t, 15, __rvv_int16m4_t, intHI, VNx16HI, VNx8HI, _i16m4,
+ _i16, _e16m4)
DEF_RVV_TYPE (vuint16m4_t, 16, __rvv_uint16m4_t, unsigned_intHI, VNx16HI,
- VNx8HI)
+ VNx8HI, _u16m4, _u16, _e16m4)
/* LMUL = 8:
Machine mode = VNx32HImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx16HImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint16m8_t, 15, __rvv_int16m8_t, intHI, VNx32HI, VNx16HI)
+DEF_RVV_TYPE (vint16m8_t, 15, __rvv_int16m8_t, intHI, VNx32HI, VNx16HI, _i16m8,
+ _i16, _e16m8)
DEF_RVV_TYPE (vuint16m8_t, 16, __rvv_uint16m8_t, unsigned_intHI, VNx32HI,
- VNx16HI)
+ VNx16HI, _u16m8, _u16, _e16m8)
/* LMUL = 1/2:
Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1SImode. */
-DEF_RVV_TYPE (vint32mf2_t, 16, __rvv_int32mf2_t, int32, VNx1SI, VOID)
-DEF_RVV_TYPE (vuint32mf2_t, 17, __rvv_uint32mf2_t, unsigned_int32, VNx1SI, VOID)
+DEF_RVV_TYPE (vint32mf2_t, 16, __rvv_int32mf2_t, int32, VNx1SI, VOID, _i32mf2,
+ _i32, _e32mf2)
+DEF_RVV_TYPE (vuint32mf2_t, 17, __rvv_uint32mf2_t, unsigned_int32, VNx1SI, VOID,
+ _u32mf2, _u32, _e32mf2)
/* LMUL = 1:
Machine mode = VNx2SImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx1SImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint32m1_t, 15, __rvv_int32m1_t, int32, VNx2SI, VNx1SI)
-DEF_RVV_TYPE (vuint32m1_t, 16, __rvv_uint32m1_t, unsigned_int32, VNx2SI, VNx1SI)
+DEF_RVV_TYPE (vint32m1_t, 15, __rvv_int32m1_t, int32, VNx2SI, VNx1SI, _i32m1,
+ _i32, _e32m1)
+DEF_RVV_TYPE (vuint32m1_t, 16, __rvv_uint32m1_t, unsigned_int32, VNx2SI, VNx1SI,
+ _u32m1, _u32, _e32m1)
/* LMUL = 2:
Machine mode = VNx4SImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx2SImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint32m2_t, 15, __rvv_int32m2_t, int32, VNx4SI, VNx2SI)
-DEF_RVV_TYPE (vuint32m2_t, 16, __rvv_uint32m2_t, unsigned_int32, VNx4SI, VNx2SI)
+DEF_RVV_TYPE (vint32m2_t, 15, __rvv_int32m2_t, int32, VNx4SI, VNx2SI, _i32m2,
+ _i32, _e32m2)
+DEF_RVV_TYPE (vuint32m2_t, 16, __rvv_uint32m2_t, unsigned_int32, VNx4SI, VNx2SI,
+ _u32m2, _u32, _e32m2)
/* LMUL = 4:
Machine mode = VNx8SImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx4SImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint32m4_t, 15, __rvv_int32m4_t, int32, VNx8SI, VNx4SI)
-DEF_RVV_TYPE (vuint32m4_t, 16, __rvv_uint32m4_t, unsigned_int32, VNx8SI, VNx4SI)
+DEF_RVV_TYPE (vint32m4_t, 15, __rvv_int32m4_t, int32, VNx8SI, VNx4SI, _i32m4,
+ _i32, _e32m4)
+DEF_RVV_TYPE (vuint32m4_t, 16, __rvv_uint32m4_t, unsigned_int32, VNx8SI, VNx4SI,
+ _u32m4, _u32, _e32m4)
/* LMUL = 8:
Machine mode = VNx16SImode when TARGET_MIN_VLEN > 32.
Machine mode = VNx8SImode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vint32m8_t, 15, __rvv_int32m8_t, int32, VNx16SI, VNx8SI)
+DEF_RVV_TYPE (vint32m8_t, 15, __rvv_int32m8_t, int32, VNx16SI, VNx8SI, _i32m8,
+ _i32, _e32m8)
DEF_RVV_TYPE (vuint32m8_t, 16, __rvv_uint32m8_t, unsigned_int32, VNx16SI,
- VNx8SI)
+ VNx8SI, _u32m8, _u32, _e32m8)
/* SEW = 64:
Disable when TARGET_MIN_VLEN > 32. */
-DEF_RVV_TYPE (vint64m1_t, 15, __rvv_int64m1_t, intDI, VNx1DI, VOID)
-DEF_RVV_TYPE (vuint64m1_t, 16, __rvv_uint64m1_t, unsigned_intDI, VNx1DI, VOID)
-DEF_RVV_TYPE (vint64m2_t, 15, __rvv_int64m2_t, intDI, VNx2DI, VOID)
-DEF_RVV_TYPE (vuint64m2_t, 16, __rvv_uint64m2_t, unsigned_intDI, VNx2DI, VOID)
-DEF_RVV_TYPE (vint64m4_t, 15, __rvv_int64m4_t, intDI, VNx4DI, VOID)
-DEF_RVV_TYPE (vuint64m4_t, 16, __rvv_uint64m4_t, unsigned_intDI, VNx4DI, VOID)
-DEF_RVV_TYPE (vint64m8_t, 15, __rvv_int64m8_t, intDI, VNx8DI, VOID)
-DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, unsigned_intDI, VNx8DI, VOID)
+DEF_RVV_TYPE (vint64m1_t, 15, __rvv_int64m1_t, intDI, VNx1DI, VOID, _i64m1,
+ _i64, _e64m1)
+DEF_RVV_TYPE (vuint64m1_t, 16, __rvv_uint64m1_t, unsigned_intDI, VNx1DI, VOID,
+ _u64m1, _u64, _e64m1)
+DEF_RVV_TYPE (vint64m2_t, 15, __rvv_int64m2_t, intDI, VNx2DI, VOID, _i64m2,
+ _i64, _e64m2)
+DEF_RVV_TYPE (vuint64m2_t, 16, __rvv_uint64m2_t, unsigned_intDI, VNx2DI, VOID,
+ _u64m2, _u64, _e64m2)
+DEF_RVV_TYPE (vint64m4_t, 15, __rvv_int64m4_t, intDI, VNx4DI, VOID, _i64m4,
+ _i64, _e64m4)
+DEF_RVV_TYPE (vuint64m4_t, 16, __rvv_uint64m4_t, unsigned_intDI, VNx4DI, VOID,
+ _u64m4, _u64, _e64m4)
+DEF_RVV_TYPE (vint64m8_t, 15, __rvv_int64m8_t, intDI, VNx8DI, VOID, _i64m8,
+ _i64, _e64m8)
+DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, unsigned_intDI, VNx8DI, VOID,
+ _u64m8, _u64, _e64m8)
/* LMUL = 1/2:
Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1SFmode. */
-DEF_RVV_TYPE (vfloat32mf2_t, 18, __rvv_float32mf2_t, float, VNx1SF, VOID)
+DEF_RVV_TYPE (vfloat32mf2_t, 18, __rvv_float32mf2_t, float, VNx1SF, VOID,
+ _f32mf2, _f32, _e32mf2)
/* LMUL = 1:
Machine mode = VNx2SFmode when TARGET_MIN_VLEN > 32.
Machine mode = VNx1SFmode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vfloat32m1_t, 17, __rvv_float32m1_t, float, VNx2SF, VNx1SF)
+DEF_RVV_TYPE (vfloat32m1_t, 17, __rvv_float32m1_t, float, VNx2SF, VNx1SF,
+ _f32m1, _f32, _e32m1)
/* LMUL = 2:
Machine mode = VNx4SFmode when TARGET_MIN_VLEN > 32.
Machine mode = VNx2SFmode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vfloat32m2_t, 17, __rvv_float32m2_t, float, VNx4SF, VNx2SF)
+DEF_RVV_TYPE (vfloat32m2_t, 17, __rvv_float32m2_t, float, VNx4SF, VNx2SF,
+ _f32m2, _f32, _e32m2)
/* LMUL = 4:
Machine mode = VNx8SFmode when TARGET_MIN_VLEN > 32.
Machine mode = VNx4SFmode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vfloat32m4_t, 17, __rvv_float32m4_t, float, VNx8SF, VNx4SF)
+DEF_RVV_TYPE (vfloat32m4_t, 17, __rvv_float32m4_t, float, VNx8SF, VNx4SF,
+ _f32m4, _f32, _e32m4)
/* LMUL = 8:
Machine mode = VNx16SFmode when TARGET_MIN_VLEN > 32.
Machine mode = VNx8SFmode when TARGET_MIN_VLEN = 32. */
-DEF_RVV_TYPE (vfloat32m8_t, 17, __rvv_float32m8_t, float, VNx16SF, VNx8SF)
+DEF_RVV_TYPE (vfloat32m8_t, 17, __rvv_float32m8_t, float, VNx16SF, VNx8SF,
+ _f32m8, _f32, _e32m8)
/* SEW = 64:
Disable when TARGET_VECTOR_FP64. */
-DEF_RVV_TYPE (vfloat64m1_t, 17, __rvv_float64m1_t, double, VNx1DF, VOID)
-DEF_RVV_TYPE (vfloat64m2_t, 17, __rvv_float64m2_t, double, VNx2DF, VOID)
-DEF_RVV_TYPE (vfloat64m4_t, 17, __rvv_float64m4_t, double, VNx4DF, VOID)
-DEF_RVV_TYPE (vfloat64m8_t, 17, __rvv_float64m8_t, double, VNx8DF, VOID)
+DEF_RVV_TYPE (vfloat64m1_t, 17, __rvv_float64m1_t, double, VNx1DF, VOID, _f64m1,
+ _f64, _e64m1)
+DEF_RVV_TYPE (vfloat64m2_t, 17, __rvv_float64m2_t, double, VNx2DF, VOID, _f64m2,
+ _f64, _e64m2)
+DEF_RVV_TYPE (vfloat64m4_t, 17, __rvv_float64m4_t, double, VNx4DF, VOID, _f64m4,
+ _f64, _e64m4)
+DEF_RVV_TYPE (vfloat64m8_t, 17, __rvv_float64m8_t, double, VNx8DF, VOID, _f64m8,
+ _f64, _e64m8)
+
+DEF_RVV_OP_TYPE (vv)
+DEF_RVV_OP_TYPE (vx)
+DEF_RVV_OP_TYPE (v)
+DEF_RVV_OP_TYPE (wv)
+DEF_RVV_OP_TYPE (wx)
+DEF_RVV_OP_TYPE (x_x_v)
+DEF_RVV_OP_TYPE (vf2)
+DEF_RVV_OP_TYPE (vf4)
+DEF_RVV_OP_TYPE (vf8)
+DEF_RVV_OP_TYPE (vvm)
+DEF_RVV_OP_TYPE (vxm)
+DEF_RVV_OP_TYPE (x_x_w)
+DEF_RVV_OP_TYPE (v_v)
+DEF_RVV_OP_TYPE (v_x)
+DEF_RVV_OP_TYPE (vs)
+DEF_RVV_OP_TYPE (mm)
+DEF_RVV_OP_TYPE (m)
+DEF_RVV_OP_TYPE (vf)
+DEF_RVV_OP_TYPE (vm)
+DEF_RVV_OP_TYPE (wf)
+DEF_RVV_OP_TYPE (vfm)
+DEF_RVV_OP_TYPE (v_f)
+
+DEF_RVV_PRED_TYPE (ta)
+DEF_RVV_PRED_TYPE (tu)
+DEF_RVV_PRED_TYPE (ma)
+DEF_RVV_PRED_TYPE (mu)
+DEF_RVV_PRED_TYPE (tama)
+DEF_RVV_PRED_TYPE (tamu)
+DEF_RVV_PRED_TYPE (tuma)
+DEF_RVV_PRED_TYPE (tumu)
+DEF_RVV_PRED_TYPE (m)
+DEF_RVV_PRED_TYPE (tam)
+DEF_RVV_PRED_TYPE (tum)
+#undef DEF_RVV_PRED_TYPE
+#undef DEF_RVV_OP_TYPE
#undef DEF_RVV_TYPE
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index ea67da9..425da12 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -21,8 +21,101 @@
#ifndef GCC_RISCV_VECTOR_BUILTINS_H
#define GCC_RISCV_VECTOR_BUILTINS_H
+/* The full name of an RVV intrinsic function is the concatenation of:
+
+ - the base name ("vadd", etc.)
+ - the operand suffix ("_vv", "_vx", etc.)
+ - the type suffix ("_i32m1", "_i32mf2", etc.)
+ - the predication suffix ("_tamu", "_tumu", etc.)
+
+ Each piece of information is individually useful, so we retain this
+ classification throughout:
+
+ - function_base represents the base name.
+
+ - operand_type_index can be used as an index to get operand suffix.
+
+ - rvv_op_info can be used as an index to get argument suffix.
+
+ - predication_type_index can be used as an index to get predication suffix.
+
+ In addition to its unique full name, a function may have a shorter
+ overloaded alias. This alias removes pieces of the suffixes that
+ can be inferred from the arguments, such as by shortening the mode
+ suffix or dropping some of the type suffixes. The base name and the
+ predication suffix stay the same.
+
+ - The function_instance class describes contains all properties of each
+ individual function. Such these information will be used by
+ function_builder, function_base, function_shape, gimple_folder,
+ function_expander, etc.
+
+ - The function_builder class provides several helper function to add an
+ intrinsic function.
+
+ - The function_shape class describes how that instruction has been presented
+ at the language level:
+
+ 1. Determine the function name for C and C++ overload function which can
+ be recognized by compiler at language level for each instruction
+ according to members of function_instance (base name, operand suffix,
+ type suffix, predication suffix, etc.).
+
+ 2. Specify the arguments type and return type of each function to
+ describe how that instruction has presented at language level.
+
+ - The function_base describes how the underlying instruction behaves.
+
+ The static list of functions uses function_group to describe a group
+ of related functions. The function_builder class is responsible for
+ expanding this static description into a list of individual functions
+ and registering the associated built-in functions. function_instance
+ describes one of these individual functions in terms of the properties
+ described above.
+
+ The classes involved in compiling a function call are:
+
+ - function_resolver, which resolves an overloaded function call to a
+ specific function_instance and its associated function decl.
+
+ - function_checker, which checks whether the values of the arguments
+ conform to the RVV ISA specification.
+
+ - gimple_folder, which tries to fold a function call at the gimple level
+
+ - function_expander, which expands a function call into rtl instructions
+
+ function_resolver and function_checker operate at the language level
+ and so are associated with the function_shape. gimple_folder and
+ function_expander are concerned with the behavior of the function
+ and so are associated with the function_base. */
+
namespace riscv_vector {
+/* Flags that describe what a function might do, in addition to reading
+ its arguments and returning a result. */
+static const unsigned int CP_READ_FPCR = 1U << 0;
+static const unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1;
+static const unsigned int CP_READ_MEMORY = 1U << 2;
+static const unsigned int CP_WRITE_MEMORY = 1U << 3;
+static const unsigned int CP_READ_CSR = 1U << 4;
+static const unsigned int CP_WRITE_CSR = 1U << 5;
+
+/* Bit values used to identify required extensions for RVV intrinsics. */
+#define RVV_REQUIRE_RV64BIT (1 << 0) /* Require RV64. */
+#define RVV_REQUIRE_ZVE64 (1 << 1) /* Require TARGET_MIN_VLEN > 32. */
+#define RVV_REQUIRE_ELEN_FP_32 (1 << 2) /* Require FP ELEN >= 32. */
+#define RVV_REQUIRE_ELEN_FP_64 (1 << 3) /* Require FP ELEN >= 64. */
+
+/* Enumerates the RVV operand types. */
+enum operand_type_index
+{
+ OP_TYPE_none,
+#define DEF_RVV_OP_TYPE(NAME) OP_TYPE_##NAME,
+#include "riscv-vector-builtins.def"
+ NUM_OP_TYPES
+};
+
/* Enumerates the RVV types, together called
"vector types" for brevity. */
enum vector_type_index
@@ -32,6 +125,31 @@ enum vector_type_index
NUM_VECTOR_TYPES
};
+/* Enumerates the RVV governing predication types. */
+enum predication_type_index
+{
+ PRED_TYPE_none,
+#define DEF_RVV_PRED_TYPE(NAME) PRED_TYPE_##NAME,
+#include "riscv-vector-builtins.def"
+ NUM_PRED_TYPES
+};
+
+/* Enumerates the RVV base types. */
+enum rvv_base_type
+{
+ RVV_BASE_vector,
+ RVV_BASE_scalar,
+ RVV_BASE_vector_ptr,
+ RVV_BASE_scalar_ptr,
+ RVV_BASE_scalar_const_ptr,
+ RVV_BASE_void,
+ RVV_BASE_size,
+ RVV_BASE_ptrdiff,
+ RVV_BASE_unsigned_long,
+ RVV_BASE_long,
+ NUM_BASE_TYPES
+};
+
/* Builtin types that are used to register RVV intrinsics. */
struct GTY (()) rvv_builtin_types_t
{
@@ -42,6 +160,251 @@ struct GTY (()) rvv_builtin_types_t
tree scalar_const_ptr;
};
+/* Builtin suffix that are used to register RVV intrinsics. */
+struct rvv_builtin_suffixes
+{
+ const char *vector;
+ const char *scalar;
+ const char *vsetvl;
+};
+
+/* RVV Builtin argument information. */
+struct rvv_arg_type_info
+{
+ CONSTEXPR rvv_arg_type_info (rvv_base_type base_type_in)
+ : base_type (base_type_in)
+ {}
+ enum rvv_base_type base_type;
+
+ tree get_tree_type (vector_type_index) const;
+};
+
+/* Static information for each operand. */
+struct rvv_type_info
+{
+ enum vector_type_index index;
+ uint64_t required_extensions;
+};
+
+/* RVV Builtin operands information. */
+struct rvv_op_info
+{
+ const rvv_type_info *types;
+ const operand_type_index op;
+ rvv_arg_type_info ret;
+ const rvv_arg_type_info *args;
+};
+
+class registered_function;
+class function_base;
+class function_shape;
+
+/* Static information about a set of functions. */
+struct function_group_info
+{
+ /* The base name, as a string. */
+ const char *base_name;
+
+ /* Describes the behavior associated with the function base name. */
+ const function_base *const *base;
+
+ /* The shape of the functions, as described above the class definition.
+ It's possible to have entries with the same base name but different
+ shapes. */
+ const function_shape *const *shape;
+
+ /* A list of the available operand types, predication types,
+ and of the available operand datatype.
+ The function supports every combination of the two.
+ The list of predication is terminated by two NUM_PRED_TYPES,
+ while the list of operand info is terminated by NUM_BASE_TYPES.
+ The list of these type suffix is lexicographically ordered based
+ on the index value. */
+ const predication_type_index *preds;
+ const rvv_op_info ops_infos;
+};
+
+class GTY ((user)) function_instance
+{
+public:
+ function_instance (const char *, const function_base *,
+ const function_shape *, rvv_type_info,
+ predication_type_index, const rvv_op_info *);
+
+ bool operator== (const function_instance &) const;
+ bool operator!= (const function_instance &) const;
+ hashval_t hash () const;
+
+ unsigned int call_properties () const;
+ bool reads_global_state_p () const;
+ bool modifies_global_state_p () const;
+ bool could_trap_p () const;
+
+ /* Return true if return type or arguments are floating point type. */
+ bool any_type_float_p () const;
+
+ tree get_return_type () const;
+ tree get_arg_type (unsigned opno) const;
+
+ /* The properties of the function. (The explicit "enum"s are required
+ for gengtype.) */
+ const char *base_name;
+ const function_base *base;
+ const function_shape *shape;
+ rvv_type_info type;
+ enum predication_type_index pred;
+ const rvv_op_info *op_info;
+};
+
+/* A class for building and registering function decls. */
+class function_builder
+{
+public:
+ function_builder ();
+ ~function_builder ();
+
+ void allocate_argument_types (const function_instance &, vec<tree> &) const;
+ void add_unique_function (const function_instance &, const function_shape *,
+ tree, vec<tree> &);
+ void register_function_group (const function_group_info &);
+ void append_name (const char *);
+ char *finish_name ();
+
+private:
+ tree get_attributes (const function_instance &);
+
+ registered_function &add_function (const function_instance &, const char *,
+ tree, tree, bool);
+
+ /* True if we should create a separate decl for each instance of an
+ overloaded function, instead of using function_builder. */
+ bool m_direct_overloads;
+
+ /* Used for building up function names. */
+ obstack m_string_obstack;
+};
+
+/* A base class for handling calls to built-in functions. */
+class function_call_info : public function_instance
+{
+public:
+ function_call_info (location_t, const function_instance &, tree);
+
+ bool function_returns_void_p ();
+
+ /* The location of the call. */
+ location_t location;
+
+ /* The FUNCTION_DECL that is being called. */
+ tree fndecl;
+};
+
+/* Return true if the function has no return value. */
+inline bool
+function_call_info::function_returns_void_p ()
+{
+ return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
+}
+
+/* A class for expanding a function call into RTL. */
+class function_expander : public function_call_info
+{
+public:
+ function_expander (const function_instance &, tree, tree, rtx);
+ rtx expand ();
+
+ void add_input_operand (machine_mode, rtx);
+ void add_input_operand (unsigned argno);
+ rtx generate_insn (insn_code);
+
+ /* The function call expression. */
+ tree exp;
+
+ /* For functions that return a value, this is the preferred location
+ of that value. It could be null or could have a different mode
+ from the function return type. */
+ rtx target;
+
+ /* The number of the operands. */
+ int opno;
+
+private:
+ /* Used to build up the operands to an instruction. */
+ struct expand_operand m_ops[MAX_RECOG_OPERANDS];
+};
+
+/* Provides information about a particular function base name, and handles
+ tasks related to the base name. */
+class function_base
+{
+public:
+ /* Return a set of CP_* flags that describe what the function might do,
+ in addition to reading its arguments and returning a result. */
+ virtual unsigned int call_properties (const function_instance &) const;
+
+ /* Expand the given call into rtl. Return the result of the function,
+ or an arbitrary value if the function doesn't return a result. */
+ virtual rtx expand (function_expander &) const = 0;
+};
+
+/* Classifies functions into "shapes" base on:
+
+ - Base name of the intrinsic function.
+
+ - Operand types list.
+
+ - Argument type list.
+
+ - Predication type list. */
+class function_shape
+{
+public:
+ /* Shape the function name according to function_instance. */
+ virtual char *get_name (function_builder &, const function_instance &,
+ bool) const
+ = 0;
+
+ /* Define all functions associated with the given group. */
+ virtual void build (function_builder &, const function_group_info &) const
+ = 0;
+};
+
+extern const char *const operand_suffixes[NUM_OP_TYPES];
+extern const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1];
+extern const char *const predication_suffixes[NUM_PRED_TYPES];
+extern rvv_builtin_types_t builtin_types[NUM_VECTOR_TYPES + 1];
+
+inline bool
+function_instance::operator!= (const function_instance &other) const
+{
+ return !operator== (other);
+}
+
+/* Expand the call and return its lhs. */
+inline rtx
+function_expander::expand ()
+{
+ return base->expand (*this);
+}
+
+/* Create op and add it into M_OPS and increase OPNO. */
+inline void
+function_expander::add_input_operand (machine_mode mode, rtx op)
+{
+ create_input_operand (&m_ops[opno++], op, mode);
+}
+
+/* Default implementation of function_base::call_properties, with conservatively
+ correct behavior for floating-point instructions. */
+inline unsigned int
+function_base::call_properties (const function_instance &instance) const
+{
+ unsigned int flags = 0;
+ if (instance.any_type_float_p ())
+ return flags | CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
+ return flags;
+}
+
} // end namespace riscv_vector
#endif