This patch adds another machine_mode 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.
2017-07-13 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * coretypes.h (complex_mode): New type. * gdbhooks.py (build_pretty_printer): Handle it. * machmode.h (complex_mode): New class. (complex_mode::includes_p): New function. (is_complex_int_mode): Likewise. (is_complex_float_mode): Likewise. * genmodes.c (get_mode_class): Handle complex mode classes. * function.c (expand_function_end): Use is_complex_int_mode. gcc/go/ * go-lang.c (go_langhook_type_for_mode): Use is_complex_float_mode. Index: gcc/coretypes.h =================================================================== --- gcc/coretypes.h 2017-07-13 09:19:00.088160188 +0100 +++ gcc/coretypes.h 2017-07-13 09:19:00.526129740 +0100 @@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx; 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; @@ -323,6 +324,7 @@ #define const_tree union _dont_use_tree_ typedef struct scalar_mode scalar_mode; typedef struct scalar_int_mode scalar_int_mode; typedef struct scalar_float_mode scalar_float_mode; +typedef struct complex_mode complex_mode; #endif Index: gcc/gdbhooks.py =================================================================== --- gcc/gdbhooks.py 2017-07-13 09:19:00.090160049 +0100 +++ gcc/gdbhooks.py 2017-07-13 09:19:00.527129670 +0100 @@ -551,7 +551,8 @@ def build_pretty_printer(): pp.add_printer_for_types(['scalar_int_mode_pod', 'scalar_mode_pod'], 'pod_mode', MachineModePrinter) - for mode in 'scalar_mode', 'scalar_int_mode', 'scalar_float_mode': + for mode in ('scalar_mode', 'scalar_int_mode', 'scalar_float_mode', + 'complex_mode'): pp.add_printer_for_types([mode], mode, MachineModePrinter) return pp Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-07-13 09:19:00.090160049 +0100 +++ gcc/machmode.h 2017-07-13 09:19:00.528129601 +0100 @@ -451,6 +451,30 @@ scalar_mode::includes_p (machine_mode m) } } +/* Represents a machine mode that is known to be a COMPLEX_MODE_P. */ +class complex_mode +{ +public: + typedef mode_traits<complex_mode>::from_int from_int; + + ALWAYS_INLINE complex_mode () {} + ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {} + ALWAYS_INLINE operator machine_mode () const { return m_mode; } + + static bool includes_p (machine_mode); + +protected: + machine_mode m_mode; +}; + +/* Return true if M is a complex_mode. */ + +inline bool +complex_mode::includes_p (machine_mode m) +{ + return COMPLEX_MODE_P (m); +} + /* Return the base GET_MODE_SIZE value for MODE. */ ALWAYS_INLINE unsigned short @@ -770,6 +794,36 @@ is_float_mode (machine_mode mode, T *flo return true; } 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 (complex_mode::from_int (mode)); + return true; + } + return false; +} + +/* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as + a complex_mode in *CMODE if so. */ + +template<typename T> +inline bool +is_complex_float_mode (machine_mode mode, T *cmode) +{ + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) + { + *cmode = complex_mode (complex_mode::from_int (mode)); + return true; + } + return false; } namespace mode_iterator Index: gcc/genmodes.c =================================================================== --- gcc/genmodes.c 2017-07-13 09:18:53.274650323 +0100 +++ gcc/genmodes.c 2017-07-13 09:19:00.527129670 +0100 @@ -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; } Index: gcc/function.c =================================================================== --- gcc/function.c 2017-07-13 09:18:53.273650396 +0100 +++ gcc/function.c 2017-07-13 09:19:00.527129670 +0100 @@ -5503,6 +5503,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)); @@ -5543,8 +5544,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; Index: gcc/go/go-lang.c =================================================================== --- gcc/go/go-lang.c 2017-07-13 09:18:31.699428322 +0100 +++ gcc/go/go-lang.c 2017-07-13 09:19:00.527129670 +0100 @@ -384,7 +384,7 @@ go_langhook_type_for_mode (machine_mode scalar_int_mode imode; scalar_float_mode fmode; - enum mode_class mc = GET_MODE_CLASS (mode); + complex_mode cmode; if (is_int_mode (mode, &imode)) return go_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp); else if (is_float_mode (mode, &fmode)) @@ -402,9 +402,9 @@ go_langhook_type_for_mode (machine_mode return long_double_type_node; } } - else if (mc == MODE_COMPLEX_FLOAT) + else if (is_complex_float_mode (mode, &cmode)) { - switch (GET_MODE_BITSIZE (mode)) + switch (GET_MODE_BITSIZE (cmode)) { case 64: return complex_float_type_node; @@ -413,7 +413,7 @@ go_langhook_type_for_mode (machine_mode default: // We have to check for long double in order to support // i386 excess precision. - if (mode == TYPE_MODE(complex_long_double_type_node)) + if (cmode == TYPE_MODE(complex_long_double_type_node)) return complex_long_double_type_node; } }