diff mbox

[67/67] Add a complex_mode class

Message ID 87fulxdxtr.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford Dec. 9, 2016, 1:41 p.m. UTC
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 mbox

Patch

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.  */