Commit a97390bf by Richard Sandiford Committed by Richard Sandiford

[77/77] Add a complex_mode class

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-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@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.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r251527
parent 382615c6
...@@ -2,6 +2,19 @@ ...@@ -2,6 +2,19 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* 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.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* coretypes.h (scalar_mode_pod): New typedef. * coretypes.h (scalar_mode_pod): New typedef.
* gdbhooks.py (build_pretty_printer): Handle it. * gdbhooks.py (build_pretty_printer): Handle it.
* machmode.h (gt_ggc_mx, gt_pch_nx): New functions. * machmode.h (gt_ggc_mx, gt_pch_nx): New functions.
......
...@@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx; ...@@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx;
class scalar_mode; class scalar_mode;
class scalar_int_mode; class scalar_int_mode;
class scalar_float_mode; class scalar_float_mode;
class complex_mode;
template<typename> class opt_mode; template<typename> class opt_mode;
typedef opt_mode<scalar_mode> opt_scalar_mode; typedef opt_mode<scalar_mode> opt_scalar_mode;
typedef opt_mode<scalar_int_mode> opt_scalar_int_mode; typedef opt_mode<scalar_int_mode> opt_scalar_int_mode;
...@@ -323,6 +324,7 @@ union _dont_use_tree_here_; ...@@ -323,6 +324,7 @@ union _dont_use_tree_here_;
typedef struct scalar_mode scalar_mode; typedef struct scalar_mode scalar_mode;
typedef struct scalar_int_mode scalar_int_mode; typedef struct scalar_int_mode scalar_int_mode;
typedef struct scalar_float_mode scalar_float_mode; typedef struct scalar_float_mode scalar_float_mode;
typedef struct complex_mode complex_mode;
#endif #endif
......
...@@ -5491,6 +5491,7 @@ expand_function_end (void) ...@@ -5491,6 +5491,7 @@ expand_function_end (void)
: DECL_REGISTER (decl_result)) : DECL_REGISTER (decl_result))
{ {
rtx real_decl_rtl = crtl->return_rtx; rtx real_decl_rtl = crtl->return_rtx;
complex_mode cmode;
/* This should be set in assign_parms. */ /* This should be set in assign_parms. */
gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl)); gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl));
...@@ -5531,8 +5532,8 @@ expand_function_end (void) ...@@ -5531,8 +5532,8 @@ expand_function_end (void)
need to generate some non-trivial bitfield insertions. Do that need to generate some non-trivial bitfield insertions. Do that
on a pseudo and not the hard register. */ on a pseudo and not the hard register. */
else if (GET_CODE (decl_rtl) == CONCAT else if (GET_CODE (decl_rtl) == CONCAT
&& GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT && is_complex_int_mode (GET_MODE (decl_rtl), &cmode)
&& GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD) && GET_MODE_BITSIZE (cmode) <= BITS_PER_WORD)
{ {
int old_generating_concat_p; int old_generating_concat_p;
rtx tmp; rtx tmp;
......
...@@ -551,7 +551,8 @@ def build_pretty_printer(): ...@@ -551,7 +551,8 @@ def build_pretty_printer():
pp.add_printer_for_types(['scalar_int_mode_pod', pp.add_printer_for_types(['scalar_int_mode_pod',
'scalar_mode_pod'], 'scalar_mode_pod'],
'pod_mode', MachineModePrinter) '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) pp.add_printer_for_types([mode], mode, MachineModePrinter)
return pp return pp
......
...@@ -1152,6 +1152,10 @@ get_mode_class (struct mode_data *mode) ...@@ -1152,6 +1152,10 @@ get_mode_class (struct mode_data *mode)
case MODE_DECIMAL_FLOAT: case MODE_DECIMAL_FLOAT:
return "scalar_float_mode"; return "scalar_float_mode";
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
return "complex_mode";
default: default:
return NULL; return NULL;
} }
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* go-lang.c (go_langhook_type_for_mode): Use is_complex_float_mode.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* go-lang.c (go_langhook_type_for_mode): Use is_int_mode. * go-lang.c (go_langhook_type_for_mode): Use is_int_mode.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org> 2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
......
...@@ -384,7 +384,7 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp) ...@@ -384,7 +384,7 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp)
scalar_int_mode imode; scalar_int_mode imode;
scalar_float_mode fmode; scalar_float_mode fmode;
enum mode_class mc = GET_MODE_CLASS (mode); complex_mode cmode;
if (is_int_mode (mode, &imode)) if (is_int_mode (mode, &imode))
return go_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp); return go_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp);
else if (is_float_mode (mode, &fmode)) else if (is_float_mode (mode, &fmode))
...@@ -402,9 +402,9 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp) ...@@ -402,9 +402,9 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp)
return long_double_type_node; 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: case 64:
return complex_float_type_node; return complex_float_type_node;
...@@ -413,7 +413,7 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp) ...@@ -413,7 +413,7 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp)
default: default:
// We have to check for long double in order to support // We have to check for long double in order to support
// i386 excess precision. // 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; return complex_long_double_type_node;
} }
} }
......
...@@ -450,6 +450,30 @@ scalar_mode::includes_p (machine_mode m) ...@@ -450,6 +450,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. */ /* Return the base GET_MODE_SIZE value for MODE. */
ALWAYS_INLINE unsigned short ALWAYS_INLINE unsigned short
...@@ -771,6 +795,36 @@ is_float_mode (machine_mode mode, T *float_mode) ...@@ -771,6 +795,36 @@ is_float_mode (machine_mode mode, T *float_mode)
return false; 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 namespace mode_iterator
{ {
/* Start mode iterator *ITER at the first mode in class MCLASS, if any. */ /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment