Introduce a function that will be used to build vmull intrinsics with the _int variant.
2023-08-14 Christophe Lyon <christophe.l...@linaro.org> gcc/ * config/arm/arm-mve-builtins-functions.h (class unspec_mve_function_exact_insn_vmull): New. --- gcc/config/arm/arm-mve-builtins-functions.h | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/gcc/config/arm/arm-mve-builtins-functions.h b/gcc/config/arm/arm-mve-builtins-functions.h index a6573844319..c0fc450f886 100644 --- a/gcc/config/arm/arm-mve-builtins-functions.h +++ b/gcc/config/arm/arm-mve-builtins-functions.h @@ -838,6 +838,80 @@ public: } }; + +/* Map the vmull-related function directly to CODE (UNSPEC, UNSPEC, M) + where M is the vector mode associated with type suffix 0. We need + this special case because the builtins have _int in their + names. */ +class unspec_mve_function_exact_insn_vmull : public function_base +{ +public: + CONSTEXPR unspec_mve_function_exact_insn_vmull (int unspec_for_sint, + int unspec_for_uint, + int unspec_for_m_sint, + int unspec_for_m_uint) + : m_unspec_for_sint (unspec_for_sint), + m_unspec_for_uint (unspec_for_uint), + m_unspec_for_m_sint (unspec_for_m_sint), + m_unspec_for_m_uint (unspec_for_m_uint) + {} + + /* The unspec code associated with signed-integer and + unsigned-integer operations respectively. It covers the cases + with and without the _m predicate. */ + int m_unspec_for_sint; + int m_unspec_for_uint; + int m_unspec_for_m_sint; + int m_unspec_for_m_uint; + + rtx + expand (function_expander &e) const override + { + insn_code code; + + if (! e.type_suffix (0).integer_p) + gcc_unreachable (); + + if (e.mode_suffix_id != MODE_none) + gcc_unreachable (); + + switch (e.pred) + { + case PRED_none: + /* No predicate, no suffix. */ + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q_int (m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0)); + else + code = code_for_mve_q_int (m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0)); + + return e.use_exact_insn (code); + + case PRED_m: + /* No suffix, "m" predicate. */ + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q_int_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0)); + else + code = code_for_mve_q_int_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0)); + + return e.use_cond_insn (code, 0); + + case PRED_x: + /* No suffix, "x" predicate. */ + if (e.type_suffix (0).unsigned_p) + code = code_for_mve_q_int_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0)); + else + code = code_for_mve_q_int_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0)); + + return e.use_pred_x_insn (code); + + default: + gcc_unreachable (); + } + + gcc_unreachable (); + } +}; + } /* end namespace arm_mve */ /* Declare the global function base NAME, creating it from an instance -- 2.34.1