@@ -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;
@@ -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;
@@ -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;
}
@@ -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. */