This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

invalid GET_MODE_WIDER_MODE assumption


expanding multiplies assume that the next wider mode happens to be the
twice-wider mode.  This is an invalid assumption, which breaks if you
have partial_int, fractional_int, or even just odd-sized int modes.
This patch makes a separate table for the actual twice-wider modes,
just for the expanding multiply.  We use this for an internal port,
I'll do regression testing if this patch is generally acceptable.

	* genmodes.c (mode_data): Add wider_2x.
	(calc_wider_mode): Calculate twice-wider mode too.
	(emit_mode_wider): Emit twice-wider mode too.

	* machmode.h (mode_2xwider, GET_MODE_2XWIDER_MODE): New.

	* expr.c (expand_expr_real_1): Use it for expanding
	multiplies.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.790
diff -p -U3 -r1.790 expr.c
--- expr.c	17 May 2005 09:55:16 -0000	1.790
+++ expr.c	28 May 2005 02:32:42 -0000
@@ -7747,7 +7747,7 @@ expand_expr_real_1 (tree exp, rtx target
 	  optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
 	  this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
 
-	  if (mode == GET_MODE_WIDER_MODE (innermode))
+	  if (mode == GET_MODE_2XWIDER_MODE (innermode))
 	    {
 	      if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
 		{
Index: genmodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genmodes.c,v
retrieving revision 1.15
diff -p -U3 -r1.15 genmodes.c
--- genmodes.c	15 Oct 2004 14:47:07 -0000	1.15
+++ genmodes.c	28 May 2005 02:32:42 -0000
@@ -64,6 +64,7 @@ struct mode_data
 
   struct mode_data *component;	/* mode of components */
   struct mode_data *wider;	/* next wider mode */
+  struct mode_data *wider_2x;	/* 2x wider mode */
 
   struct mode_data *contained;  /* Pointer to list of modes that have
 				   this mode as a component.  */
@@ -80,7 +81,7 @@ static struct mode_data *void_mode;
 static const struct mode_data blank_mode = {
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
-  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
   "<unknown>", 0
 };
 
@@ -717,6 +718,7 @@ calc_wider_mode (void)
 	  for (prev = 0, m = modes[c]; m; m = next)
 	    {
 	      m->wider = void_mode;
+	      m->wider_2x = void_mode;
 
 	      /* this is nreverse */
 	      next = m->next;
@@ -951,6 +953,39 @@ emit_mode_wider (void)
 		   m->name);
 
   print_closer ();
+  print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
+
+  for_all_modes (c, m)
+    {
+      struct mode_data * m2;
+
+      for (m2 = m;
+	   m2 && m2 != void_mode;
+	   m2 = m2->wider)
+	{
+	  if (m2->bytesize < 2 * m->bytesize)
+	    continue;
+	  if (m->precision != (unsigned int) -1)
+	    {
+	      if (m2->precision != 2 * m->precision)
+		continue;
+	    }
+	  else
+	    {
+	      if (m2->precision != (unsigned int) -1)
+		continue;
+	    }
+
+	  break;
+	}
+      if (m2 == void_mode)
+	m2 = 0;
+      tagged_printf ("%smode",
+		     m2 ? m2->name : void_mode->name,
+		     m->name);
+    }
+
+  print_closer ();
 }
 
 static void
Index: machmode.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/machmode.h,v
retrieving revision 1.38
diff -p -U3 -r1.38 machmode.h
--- machmode.h	6 Nov 2003 08:38:50 -0000	1.38
+++ machmode.h	28 May 2005 02:32:42 -0000
@@ -115,6 +115,9 @@ extern const unsigned char mode_nunits[N
 extern const unsigned char mode_wider[NUM_MACHINE_MODES];
 #define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE]
 
+extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
+#define GET_MODE_2XWIDER_MODE(MODE) mode_2xwider[MODE]
+
 /* Return the mode for data of a given size SIZE and mode class CLASS.
    If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
    The value is BLKmode if no other mode is found.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]