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.sandif...@arm.com> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@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. */