@@ -40,17 +40,23 @@ public:
};
/* An incomplete function_base for functions that have an associated
- rtx_code for signed integers, unsigned integers and floating-point
- values for the non-predicated, non-suffixed intrinsic, and unspec
- codes, with separate codes for signed integers, unsigned integers
- and floating-point values. The class simply records information
- about the mapping for derived classes to use. */
+ rtx_code or an unspec for signed integers, unsigned integers and
+ floating-point values for the non-predicated, non-suffixed
+ intrinsics, and unspec codes, with separate codes for signed
+ integers, unsigned integers and floating-point values for
+ predicated and/or suffixed intrinsics. The class simply records
+ information about the mapping for derived classes to use and
+ provides a generic expand_unspec () to avoid duplicating expansion
+ code in derived classes. */
class unspec_based_mve_function_base : public function_base
{
public:
CONSTEXPR unspec_based_mve_function_base (rtx_code code_for_sint,
rtx_code code_for_uint,
rtx_code code_for_fp,
+ int unspec_for_sint,
+ int unspec_for_uint,
+ int unspec_for_fp,
int unspec_for_n_sint,
int unspec_for_n_uint,
int unspec_for_n_fp,
@@ -63,6 +69,9 @@ public:
: m_code_for_sint (code_for_sint),
m_code_for_uint (code_for_uint),
m_code_for_fp (code_for_fp),
+ m_unspec_for_sint (unspec_for_sint),
+ m_unspec_for_uint (unspec_for_uint),
+ m_unspec_for_fp (unspec_for_fp),
m_unspec_for_n_sint (unspec_for_n_sint),
m_unspec_for_n_uint (unspec_for_n_uint),
m_unspec_for_n_fp (unspec_for_n_fp),
@@ -83,6 +92,9 @@ public:
/* The unspec code associated with signed-integer, unsigned-integer
and floating-point operations respectively. It covers the cases
with the _n suffix, and/or the _m predicate. */
+ int m_unspec_for_sint;
+ int m_unspec_for_uint;
+ int m_unspec_for_fp;
int m_unspec_for_n_sint;
int m_unspec_for_n_uint;
int m_unspec_for_n_fp;
@@ -92,142 +104,146 @@ public:
int m_unspec_for_m_n_sint;
int m_unspec_for_m_n_uint;
int m_unspec_for_m_n_fp;
+
+ rtx expand_unspec (function_expander &e) const;
};
-/* Map the function directly to CODE (UNSPEC, M) where M is the vector
- mode associated with type suffix 0, except when there is no
- predicate and no _n suffix, in which case we use the appropriate
- rtx_code. This is useful when the basic operation is mapped to a
- standard RTX code and all other versions use different unspecs. */
-class unspec_based_mve_function_exact_insn : public unspec_based_mve_function_base
+/* Expand the unspecs, which is common to all intrinsics using
+ unspec_based_mve_function_base. If some combinations are not
+ supported for an intrinsics family, they should be handled by the
+ caller (and not crash here). */
+rtx
+unspec_based_mve_function_base::expand_unspec (function_expander &e) const
{
-public:
- CONSTEXPR unspec_based_mve_function_exact_insn (rtx_code code_for_sint,
- rtx_code code_for_uint,
- rtx_code code_for_fp,
- int unspec_for_n_sint,
- int unspec_for_n_uint,
- int unspec_for_n_fp,
- int unspec_for_m_sint,
- int unspec_for_m_uint,
- int unspec_for_m_fp,
- int unspec_for_m_n_sint,
- int unspec_for_m_n_uint,
- int unspec_for_m_n_fp)
- : unspec_based_mve_function_base (code_for_sint,
- code_for_uint,
- code_for_fp,
- unspec_for_n_sint,
- unspec_for_n_uint,
- unspec_for_n_fp,
- unspec_for_m_sint,
- unspec_for_m_uint,
- unspec_for_m_fp,
- unspec_for_m_n_sint,
- unspec_for_m_n_uint,
- unspec_for_m_n_fp)
- {}
-
- rtx
- expand (function_expander &e) const override
- {
- /* No suffix, no predicate, use the right RTX code. */
- if ((e.mode_suffix_id != MODE_n)
- && (e.pred == PRED_none))
- return e.map_to_rtx_codes (m_code_for_sint, m_code_for_uint,
- m_code_for_fp);
-
+ machine_mode mode = e.vector_mode (0);
insn_code code;
+
switch (e.pred)
{
case PRED_none:
- if (e.mode_suffix_id == MODE_n)
- /* No predicate, _n suffix. */
- {
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_n (m_unspec_for_n_uint, m_unspec_for_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_n (m_unspec_for_n_sint, m_unspec_for_n_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_n_f (m_unspec_for_n_fp, e.vector_mode (0));
-
- return e.use_exact_insn (code);
- }
- gcc_unreachable ();
- break;
-
- case PRED_m:
switch (e.mode_suffix_id)
{
case MODE_none:
- /* No suffix, "m" predicate. */
+ /* No predicate, no suffix. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
+ code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, mode);
else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
+ code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, mode);
else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode (0));
+ code = code_for_mve_q_f (m_unspec_for_fp, mode);
break;
case MODE_n:
- /* _n suffix, "m" predicate. */
+ /* No predicate, _n suffix. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
+ code = code_for_mve_q_n (m_unspec_for_n_uint, m_unspec_for_n_uint, mode);
else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
+ code = code_for_mve_q_n (m_unspec_for_n_sint, m_unspec_for_n_sint, mode);
else
- code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, e.vector_mode (0));
+ code = code_for_mve_q_n_f (m_unspec_for_n_fp, mode);
break;
default:
gcc_unreachable ();
}
- return e.use_cond_insn (code, 0);
+ return e.use_exact_insn (code);
+ case PRED_m:
case PRED_x:
switch (e.mode_suffix_id)
{
case MODE_none:
- /* No suffix, "x" predicate. */
+ /* No suffix, "m" or "x" predicate. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
+ code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, mode);
else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
+ code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, mode);
else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode (0));
+ code = code_for_mve_q_m_f (m_unspec_for_m_fp, mode);
break;
case MODE_n:
- /* _n suffix, "x" predicate. */
+ /* _n suffix, "m" or "x" predicate. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
+ code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, mode);
else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
+ code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, mode);
else
- code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, e.vector_mode (0));
+ code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, mode);
break;
default:
gcc_unreachable ();
}
- return e.use_pred_x_insn (code);
+
+ if (e.pred == PRED_m)
+ return e.use_cond_insn (code, 0);
+ else
+ return e.use_pred_x_insn (code);
+ break;
default:
gcc_unreachable ();
}
+}
- gcc_unreachable ();
+/* Map the function directly to CODE (UNSPEC, M) where M is the vector
+ mode associated with type suffix 0, except when there is no
+ predicate and no _n suffix, in which case we use the appropriate
+ rtx_code. This is useful when the basic operation is mapped to a
+ standard RTX code and all other versions use different unspecs. */
+class unspec_based_mve_function_exact_insn : public unspec_based_mve_function_base
+{
+public:
+ CONSTEXPR unspec_based_mve_function_exact_insn (rtx_code code_for_sint,
+ rtx_code code_for_uint,
+ rtx_code code_for_fp,
+ int unspec_for_n_sint,
+ int unspec_for_n_uint,
+ int unspec_for_n_fp,
+ int unspec_for_m_sint,
+ int unspec_for_m_uint,
+ int unspec_for_m_fp,
+ int unspec_for_m_n_sint,
+ int unspec_for_m_n_uint,
+ int unspec_for_m_n_fp)
+ : unspec_based_mve_function_base (code_for_sint,
+ code_for_uint,
+ code_for_fp,
+ -1,
+ -1,
+ -1,
+ unspec_for_n_sint,
+ unspec_for_n_uint,
+ unspec_for_n_fp,
+ unspec_for_m_sint,
+ unspec_for_m_uint,
+ unspec_for_m_fp,
+ unspec_for_m_n_sint,
+ unspec_for_m_n_uint,
+ unspec_for_m_n_fp)
+ {}
+
+ rtx
+ expand (function_expander &e) const override
+ {
+ /* No suffix, no predicate, use the right RTX code. */
+ if ((e.mode_suffix_id != MODE_n)
+ && (e.pred == PRED_none))
+ return e.map_to_rtx_codes (m_code_for_sint, m_code_for_uint,
+ m_code_for_fp);
+
+ return expand_unspec (e);
}
};
/* Map the function directly to CODE (UNSPEC, M) where M is the vector
mode associated with type suffix 0. */
-class unspec_mve_function_exact_insn : public function_base
+class unspec_mve_function_exact_insn : public unspec_based_mve_function_base
{
public:
CONSTEXPR unspec_mve_function_exact_insn (int unspec_for_sint,
@@ -242,143 +258,33 @@ public:
int unspec_for_m_n_sint,
int unspec_for_m_n_uint,
int unspec_for_m_n_fp)
- : m_unspec_for_sint (unspec_for_sint),
- m_unspec_for_uint (unspec_for_uint),
- m_unspec_for_fp (unspec_for_fp),
- m_unspec_for_n_sint (unspec_for_n_sint),
- m_unspec_for_n_uint (unspec_for_n_uint),
- m_unspec_for_n_fp (unspec_for_n_fp),
- m_unspec_for_m_sint (unspec_for_m_sint),
- m_unspec_for_m_uint (unspec_for_m_uint),
- m_unspec_for_m_fp (unspec_for_m_fp),
- m_unspec_for_m_n_sint (unspec_for_m_n_sint),
- m_unspec_for_m_n_uint (unspec_for_m_n_uint),
- m_unspec_for_m_n_fp (unspec_for_m_n_fp)
+ : unspec_based_mve_function_base (UNKNOWN,
+ UNKNOWN,
+ UNKNOWN,
+ unspec_for_sint,
+ unspec_for_uint,
+ unspec_for_fp,
+ unspec_for_n_sint,
+ unspec_for_n_uint,
+ unspec_for_n_fp,
+ unspec_for_m_sint,
+ unspec_for_m_uint,
+ unspec_for_m_fp,
+ unspec_for_m_n_sint,
+ unspec_for_m_n_uint,
+ unspec_for_m_n_fp)
{}
- /* The unspec code associated with signed-integer, unsigned-integer
- and floating-point operations respectively. It covers the cases
- with the _n suffix, and/or the _m predicate. */
- int m_unspec_for_sint;
- int m_unspec_for_uint;
- int m_unspec_for_fp;
- int m_unspec_for_n_sint;
- int m_unspec_for_n_uint;
- int m_unspec_for_n_fp;
- int m_unspec_for_m_sint;
- int m_unspec_for_m_uint;
- int m_unspec_for_m_fp;
- int m_unspec_for_m_n_sint;
- int m_unspec_for_m_n_uint;
- int m_unspec_for_m_n_fp;
-
rtx
expand (function_expander &e) const override
{
- insn_code code;
- switch (e.pred)
- {
- case PRED_none:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No predicate, no suffix. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0));
- else
- code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_f (m_unspec_for_fp, e.vector_mode (0));
- break;
-
- case MODE_n:
- /* No predicate, _n suffix. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_n (m_unspec_for_n_uint, m_unspec_for_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_n (m_unspec_for_n_sint, m_unspec_for_n_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_n_f (m_unspec_for_n_fp, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_exact_insn (code);
-
- case PRED_m:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No suffix, "m" predicate. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode (0));
- break;
-
- case MODE_n:
- /* _n suffix, "m" predicate. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_cond_insn (code, 0);
-
- case PRED_x:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No suffix, "x" predicate. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode (0));
- break;
-
- case MODE_n:
- /* _n suffix, "x" predicate. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_pred_x_insn (code);
-
- default:
- gcc_unreachable ();
- }
-
- gcc_unreachable ();
+ return expand_unspec (e);
}
};
/* Map the function directly to CODE (UNSPEC), when there is a
non-predicated version and one with the "_p" predicate. */
-class unspec_mve_function_exact_insn_pred_p : public function_base
+class unspec_mve_function_exact_insn_pred_p : public unspec_based_mve_function_base
{
public:
CONSTEXPR unspec_mve_function_exact_insn_pred_p (int unspec_for_sint,
@@ -387,19 +293,23 @@ public:
int unspec_for_p_sint,
int unspec_for_p_uint,
int unspec_for_p_fp)
- : m_unspec_for_sint (unspec_for_sint),
- m_unspec_for_uint (unspec_for_uint),
- m_unspec_for_fp (unspec_for_fp),
+ : unspec_based_mve_function_base (UNKNOWN, /* No RTX code. */
+ UNKNOWN,
+ UNKNOWN,
+ unspec_for_sint,
+ unspec_for_uint,
+ unspec_for_fp,
+ -1, -1, -1, /* No _n intrinsics. */
+ -1, -1, -1, /* No _m intrinsics. */
+ -1, -1, -1), /* No _m_n intrinsics. */
m_unspec_for_p_sint (unspec_for_p_sint),
m_unspec_for_p_uint (unspec_for_p_uint),
m_unspec_for_p_fp (unspec_for_p_fp)
{}
- /* The unspec code associated with signed-integer and unsigned-integer
- operations, with no predicate, or with "_p" predicate. */
- int m_unspec_for_sint;
- int m_unspec_for_uint;
- int m_unspec_for_fp;
+ /* The unspec code associated with signed-integer and
+ unsigned-integer or floating-point operations with "_p"
+ predicate. */
int m_unspec_for_p_sint;
int m_unspec_for_p_uint;
int m_unspec_for_p_fp;
@@ -440,45 +350,30 @@ public:
gcc_unreachable ();
}
}
- else
- {
- switch (e.pred)
- {
- case PRED_none:
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0));
- else
- code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_f (m_unspec_for_fp, e.vector_mode (0));
-
- return e.use_exact_insn (code);
- case PRED_p:
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_p (m_unspec_for_p_uint, m_unspec_for_p_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_p (m_unspec_for_p_sint, m_unspec_for_p_sint, e.vector_mode (0));
- else
- code = code_for_mve_q_p_f (m_unspec_for_p_fp, e.vector_mode (0));
+ if (e.pred == PRED_p)
+ {
+ machine_mode mode = e.vector_mode (0);
- return e.use_exact_insn (code);
+ if (e.type_suffix (0).integer_p)
+ if (e.type_suffix (0).unsigned_p)
+ code = code_for_mve_q_p (m_unspec_for_p_uint, m_unspec_for_p_uint, mode);
+ else
+ code = code_for_mve_q_p (m_unspec_for_p_sint, m_unspec_for_p_sint, mode);
+ else
+ code = code_for_mve_q_p_f (m_unspec_for_p_fp, mode);
- default:
- gcc_unreachable ();
- }
+ return e.use_exact_insn (code);
}
- gcc_unreachable ();
+ return expand_unspec (e);
}
};
/* Map the function directly to CODE (UNSPEC, M) for vshl-like
builtins. The difference with unspec_mve_function_exact_insn is
that this function handles MODE_r and the related unspecs.. */
-class unspec_mve_function_exact_insn_vshl : public function_base
+class unspec_mve_function_exact_insn_vshl : public unspec_based_mve_function_base
{
public:
CONSTEXPR unspec_mve_function_exact_insn_vshl (int unspec_for_sint,
@@ -493,31 +388,29 @@ public:
int unspec_for_m_r_uint,
int unspec_for_r_sint,
int unspec_for_r_uint)
- : m_unspec_for_sint (unspec_for_sint),
- m_unspec_for_uint (unspec_for_uint),
- m_unspec_for_n_sint (unspec_for_n_sint),
- m_unspec_for_n_uint (unspec_for_n_uint),
- m_unspec_for_m_sint (unspec_for_m_sint),
- m_unspec_for_m_uint (unspec_for_m_uint),
- m_unspec_for_m_n_sint (unspec_for_m_n_sint),
- m_unspec_for_m_n_uint (unspec_for_m_n_uint),
+ : unspec_based_mve_function_base (UNKNOWN,
+ UNKNOWN,
+ UNKNOWN,
+ unspec_for_sint,
+ unspec_for_uint,
+ -1,
+ unspec_for_n_sint,
+ unspec_for_n_uint,
+ -1,
+ unspec_for_m_sint,
+ unspec_for_m_uint,
+ -1,
+ unspec_for_m_n_sint,
+ unspec_for_m_n_uint,
+ -1),
m_unspec_for_m_r_sint (unspec_for_m_r_sint),
m_unspec_for_m_r_uint (unspec_for_m_r_uint),
m_unspec_for_r_sint (unspec_for_r_sint),
m_unspec_for_r_uint (unspec_for_r_uint)
{}
- /* The unspec code associated with signed-integer, unsigned-integer
- and floating-point operations respectively. It covers the cases
- with the _n suffix, and/or the _m predicate. */
- int m_unspec_for_sint;
- int m_unspec_for_uint;
- int m_unspec_for_n_sint;
- int m_unspec_for_n_uint;
- int m_unspec_for_m_sint;
- int m_unspec_for_m_uint;
- int m_unspec_for_m_n_sint;
- int m_unspec_for_m_n_uint;
+ /* The unspec code associated with signed-integer and unsigned-integer
+ operations with MODE_r with or without PRED_m. */
int m_unspec_for_m_r_sint;
int m_unspec_for_m_r_uint;
int m_unspec_for_r_sint;
@@ -527,101 +420,38 @@ public:
expand (function_expander &e) const override
{
insn_code code;
- switch (e.pred)
+ if (e.mode_suffix_id == MODE_r)
{
- case PRED_none:
- switch (e.mode_suffix_id)
+ machine_mode mode = e.vector_mode (0);
+ switch (e.pred)
{
- case MODE_none:
- /* No predicate, no suffix. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0));
- else
- code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0));
- break;
-
- case MODE_n:
- /* No predicate, _n suffix. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_n (m_unspec_for_n_uint, m_unspec_for_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_n (m_unspec_for_n_sint, m_unspec_for_n_sint, e.vector_mode (0));
- break;
-
- case MODE_r:
+ case PRED_none:
/* No predicate, _r suffix. */
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_r (m_unspec_for_r_uint, m_unspec_for_r_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_r (m_unspec_for_r_sint, m_unspec_for_r_sint, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_exact_insn (code);
-
- case PRED_m:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No suffix, "m" predicate. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
- break;
-
- case MODE_n:
- /* _n suffix, "m" predicate. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
- break;
-
- case MODE_r:
- /* _r suffix, "m" predicate. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_r (m_unspec_for_m_r_uint, m_unspec_for_m_r_uint, e.vector_mode (0));
+ code = code_for_mve_q_r (m_unspec_for_r_uint, m_unspec_for_r_uint, mode);
else
- code = code_for_mve_q_m_r (m_unspec_for_m_r_sint, m_unspec_for_m_r_sint, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_cond_insn (code, 0);
+ code = code_for_mve_q_r (m_unspec_for_r_sint, m_unspec_for_r_sint, mode);
+ return e.use_exact_insn (code);
- case PRED_x:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No suffix, "x" predicate. */
+ case PRED_m:
+ case PRED_x:
+ /* _r suffix, "m" or "x" predicate. */
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
+ code = code_for_mve_q_m_r (m_unspec_for_m_r_uint, m_unspec_for_m_r_uint, mode);
else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
- break;
+ code = code_for_mve_q_m_r (m_unspec_for_m_r_sint, m_unspec_for_m_r_sint, mode);
- case MODE_n:
- /* _n suffix, "x" predicate. */
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m_n (m_unspec_for_m_n_uint, m_unspec_for_m_n_uint, e.vector_mode (0));
+ if (e.pred == PRED_m)
+ return e.use_cond_insn (code, 0);
else
- code = code_for_mve_q_m_n (m_unspec_for_m_n_sint, m_unspec_for_m_n_sint, e.vector_mode (0));
- break;
+ return e.use_pred_x_insn (code);
default:
gcc_unreachable ();
}
- return e.use_pred_x_insn (code);
-
- default:
- gcc_unreachable ();
}
- gcc_unreachable ();
+ return expand_unspec (e);
}
};
@@ -641,9 +471,8 @@ public:
: unspec_based_mve_function_base (code_for_sint,
code_for_uint,
code_for_fp,
- -1,
- -1,
- -1,
+ -1, -1, -1, /* No non-predicated, no mode intrinsics. */
+ -1, -1, -1, /* No _n intrinsics. */
unspec_for_m_sint,
unspec_for_m_uint,
unspec_for_m_fp,
@@ -738,7 +567,9 @@ public:
/* Map the function directly to CODE (UNSPEC, UNSPEC, UNSPEC, M) where
M is the vector mode associated with type suffix 0. USed for the
operations where there is a "rot90" or "rot270" suffix, depending
- on the UNSPEC. */
+ on the UNSPEC. We cannot use
+ unspec_based_mve_function_base::expand_unspec () because we call
+ code_for_mve_q with one more parameter. */
class unspec_mve_function_exact_insn_rot : public function_base
{
public:
@@ -769,6 +600,7 @@ public:
rtx
expand (function_expander &e) const override
{
+ machine_mode mode = e.vector_mode (0);
insn_code code;
switch (e.pred)
@@ -780,11 +612,11 @@ public:
/* No predicate, no suffix. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, m_unspec_for_uint, e.vector_mode (0));
+ code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, m_unspec_for_uint, mode);
else
- code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0));
+ code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, m_unspec_for_sint, mode);
else
- code = code_for_mve_q_f (m_unspec_for_fp, m_unspec_for_fp, e.vector_mode (0));
+ code = code_for_mve_q_f (m_unspec_for_fp, m_unspec_for_fp, mode);
break;
default:
@@ -793,42 +625,28 @@ public:
return e.use_exact_insn (code);
case PRED_m:
+ case PRED_x:
switch (e.mode_suffix_id)
{
case MODE_none:
- /* No suffix, "m" predicate. */
+ /* No suffix, "m" or "x" predicate. */
if (e.type_suffix (0).integer_p)
if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
+ code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, m_unspec_for_m_uint, mode);
else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
+ code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, m_unspec_for_m_sint, mode);
else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, m_unspec_for_m_fp, e.vector_mode (0));
- break;
-
- default:
- gcc_unreachable ();
- }
- return e.use_cond_insn (code, 0);
+ code = code_for_mve_q_m_f (m_unspec_for_m_fp, m_unspec_for_m_fp, mode);
- case PRED_x:
- switch (e.mode_suffix_id)
- {
- case MODE_none:
- /* No suffix, "x" predicate. */
- if (e.type_suffix (0).integer_p)
- if (e.type_suffix (0).unsigned_p)
- code = code_for_mve_q_m (m_unspec_for_m_uint, m_unspec_for_m_uint, m_unspec_for_m_uint, e.vector_mode (0));
- else
- code = code_for_mve_q_m (m_unspec_for_m_sint, m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
+ if (e.pred == PRED_m)
+ return e.use_cond_insn (code, 0);
else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, m_unspec_for_m_fp, e.vector_mode (0));
+ return e.use_pred_x_insn (code);
break;
default:
gcc_unreachable ();
}
- return e.use_pred_x_insn (code);
default:
gcc_unreachable ();
@@ -866,6 +684,7 @@ public:
rtx
expand (function_expander &e) const override
{
+ machine_mode mode = e.vector_mode (0);
insn_code code;
if (! e.type_suffix (0).integer_p)
@@ -879,29 +698,24 @@ public:
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));
+ code = code_for_mve_q_int (m_unspec_for_uint, m_unspec_for_uint, mode);
else
- code = code_for_mve_q_int (m_unspec_for_sint, m_unspec_for_sint, e.vector_mode (0));
+ code = code_for_mve_q_int (m_unspec_for_sint, m_unspec_for_sint, mode);
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. */
+ /* No suffix, "m" or "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));
+ code = code_for_mve_q_int_m (m_unspec_for_m_uint, m_unspec_for_m_uint, mode);
else
- code = code_for_mve_q_int_m (m_unspec_for_m_sint, m_unspec_for_m_sint, e.vector_mode (0));
+ code = code_for_mve_q_int_m (m_unspec_for_m_sint, m_unspec_for_m_sint, mode);
- return e.use_pred_x_insn (code);
+ if (e.pred == PRED_m)
+ return e.use_cond_insn (code, 0);
+ else
+ return e.use_pred_x_insn (code);
default:
gcc_unreachable ();
@@ -933,6 +747,7 @@ public:
rtx
expand (function_expander &e) const override
{
+ machine_mode mode = e.vector_mode (0);
insn_code code;
if (e.mode_suffix_id != MODE_none)
@@ -945,18 +760,18 @@ public:
{
case PRED_none:
/* No predicate, no suffix. */
- code = code_for_mve_q_poly (m_unspec_for_poly, m_unspec_for_poly, e.vector_mode (0));
+ code = code_for_mve_q_poly (m_unspec_for_poly, m_unspec_for_poly, mode);
return e.use_exact_insn (code);
case PRED_m:
- /* No suffix, "m" predicate. */
- code = code_for_mve_q_poly_m (m_unspec_for_m_poly, m_unspec_for_m_poly, e.vector_mode (0));
- return e.use_cond_insn (code, 0);
-
case PRED_x:
- /* No suffix, "x" predicate. */
- code = code_for_mve_q_poly_m (m_unspec_for_m_poly, m_unspec_for_m_poly, e.vector_mode (0));
- return e.use_pred_x_insn (code);
+ /* No suffix, "m" or "x" predicate. */
+ code = code_for_mve_q_poly_m (m_unspec_for_m_poly, m_unspec_for_m_poly, mode);
+
+ if (e.pred == PRED_m)
+ return e.use_cond_insn (code, 0);
+ else
+ return e.use_pred_x_insn (code);
default:
gcc_unreachable ();