This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[67/67] Add a complex_mode class
- From: Richard Sandiford <richard dot sandiford at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 09 Dec 2016 13:41:20 +0000
- Subject: [67/67] Add a complex_mode class
- Authentication-results: sourceware.org; auth=none
- References: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com>
This patch adds another machine_mode_enum wrapper for modes
that are known to be COMPLEX_MODE_P. There aren't yet many
places that make use of it, but that might change in future.
gcc/
2016-11-24 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* coretypes.h (complex_mode): New type.
(opt_complex_mode): New typedef.
* machmode.h (complex_mode): New class.
(complex_mode::includes_p): New function.
(complex_mode::from_int): Likewise.
(is_complex_int_mode): Likewise.
* genmodes.c (get_mode_class): Handle complex mode classes.
* function.c (expand_function_end): Use is_complex_int_mode.
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 564d7fe..276127f 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -59,10 +59,12 @@ class machine_mode;
class scalar_mode;
class scalar_int_mode;
class scalar_float_mode;
+class complex_mode;
template<typename> class opt_mode;
typedef opt_mode<scalar_mode> opt_scalar_mode;
typedef opt_mode<scalar_int_mode> opt_scalar_int_mode;
typedef opt_mode<scalar_float_mode> opt_scalar_float_mode;
+typedef opt_mode<complex_mode> opt_complex_mode;
template<typename> class pod_mode;
typedef pod_mode<scalar_mode> scalar_mode_pod;
typedef pod_mode<scalar_int_mode> scalar_int_mode_pod;
diff --git a/gcc/function.c b/gcc/function.c
index 7da0203..9d2f6bb 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5502,6 +5502,7 @@ expand_function_end (void)
: DECL_REGISTER (decl_result))
{
rtx real_decl_rtl = crtl->return_rtx;
+ complex_mode cmode;
/* This should be set in assign_parms. */
gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl));
@@ -5542,8 +5543,8 @@ expand_function_end (void)
need to generate some non-trivial bitfield insertions. Do that
on a pseudo and not the hard register. */
else if (GET_CODE (decl_rtl) == CONCAT
- && GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT
- && GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD)
+ && is_complex_int_mode (GET_MODE (decl_rtl), &cmode)
+ && GET_MODE_BITSIZE (cmode) <= BITS_PER_WORD)
{
int old_generating_concat_p;
rtx tmp;
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 4f10632..05376ca 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -1152,6 +1152,10 @@ get_mode_class (struct mode_data *mode)
case MODE_DECIMAL_FLOAT:
return "scalar_float_mode";
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ return "complex_mode";
+
default:
return NULL;
}
diff --git a/gcc/machmode.h b/gcc/machmode.h
index fe62965..fd93cb0 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -433,6 +433,40 @@ scalar_mode::from_int (int i)
return machine_mode_enum (i);
}
+/* Represents a machine mode that is known to be a COMPLEX_MODE_P. */
+class complex_mode
+{
+public:
+ ALWAYS_INLINE complex_mode () {}
+ ALWAYS_INLINE operator machine_mode_enum () const { return m_mode; }
+
+ static bool includes_p (machine_mode_enum);
+ static complex_mode from_int (int);
+
+PROTECT_ENUM_CONVERSION:
+ ALWAYS_INLINE complex_mode (machine_mode_enum m) : m_mode (m) {}
+
+protected:
+ machine_mode_enum m_mode;
+};
+
+/* Return true if M is a complex_mode. */
+
+inline bool
+complex_mode::includes_p (machine_mode_enum m)
+{
+ return COMPLEX_MODE_P (m);
+}
+
+/* Return M as a complex_mode. This function should only be used by
+ utility functions; general code should use as_a<T> instead. */
+
+ALWAYS_INLINE complex_mode
+complex_mode::from_int (int i)
+{
+ return machine_mode_enum (i);
+}
+
/* Represents a general machine mode (scalar or non-scalar). */
class machine_mode
{
@@ -780,6 +814,21 @@ is_float_mode (machine_mode mode, T *float_mode)
return false;
}
+/* Return true if MODE has class MODE_COMPLEX_INT, storing it as
+ a complex_mode in *CMODE if so. */
+
+template<typename T>
+inline bool
+is_complex_int_mode (machine_mode mode, T *cmode)
+{
+ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
+ {
+ *cmode = complex_mode::from_int (mode);
+ return true;
+ }
+ return false;
+}
+
namespace mode_iterator
{
/* Start mode iterator *ITER at the first mode in class MCLASS, if any. */