Blame SOURCES/gcc32-rh180778.patch

4ac4fd
2005-08-31  Richard Henderson  <rth@redhat.com>
4ac4fd
4ac4fd
	* expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Force subregs
4ac4fd
	into a pseudo before applying gen_lowpart.
4ac4fd
4ac4fd
2005-08-30  Richard Henderson  <rth@redhat.com>
4ac4fd
4ac4fd
	PR target/23630
4ac4fd
	* expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Use gen_lowpart
4ac4fd
	whenever the mode sizes match.
4ac4fd
4ac4fd
2002-08-19  Geoffrey Keating  <geoffk@redhat.com>
4ac4fd
	    Steve Ellcey  <sje@cup.hp.com>
4ac4fd
4ac4fd
	* machmode.h (SCALAR_INT_MODE_P): New macro to test for
4ac4fd
	scaler integer mode (MODE_INT or MODE_PARTIAL_INT).
4ac4fd
4ac4fd
2006-02-22  Alexandre Oliva  <aoliva@redhat.com>
4ac4fd
4ac4fd
	* gcc.dg/i386-mmx-3.c: New test.
4ac4fd
4ac4fd
--- gcc/convert.c.orig	2003-08-01 20:24:42.000000000 -0300
4ac4fd
+++ gcc/convert.c	2006-02-24 03:51:35.000000000 -0300
4ac4fd
@@ -398,7 +398,7 @@ convert_to_integer (type, expr)
4ac4fd
 	  error ("can't convert between vector values of different size");
4ac4fd
 	  return error_mark_node;
4ac4fd
 	}
4ac4fd
-      return build1 (NOP_EXPR, type, expr);
4ac4fd
+      return build1 (VIEW_CONVERT_EXPR, type, expr);
4ac4fd
 
4ac4fd
     default:
4ac4fd
       error ("aggregate value used where an integer was expected");
4ac4fd
@@ -478,7 +478,7 @@ convert_to_vector (type, expr)
4ac4fd
 	  error ("can't convert between vector values of different size");
4ac4fd
 	  return error_mark_node;
4ac4fd
 	}
4ac4fd
-      return build1 (NOP_EXPR, type, expr);
4ac4fd
+      return build1 (VIEW_CONVERT_EXPR, type, expr);
4ac4fd
 
4ac4fd
     default:
4ac4fd
       error ("can't convert value to a vector");
4ac4fd
--- gcc/expr.c.orig	2006-02-22 15:50:38.000000000 -0300
4ac4fd
+++ gcc/expr.c	2006-02-24 04:49:59.000000000 -0300
4ac4fd
@@ -7641,16 +7641,28 @@ expand_expr (exp, target, tmode, modifie
4ac4fd
     case VIEW_CONVERT_EXPR:
4ac4fd
       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
4ac4fd
 
4ac4fd
-      /* If the input and output modes are both the same, we are done.
4ac4fd
-	 Otherwise, if neither mode is BLKmode and both are within a word, we
4ac4fd
-	 can use gen_lowpart.  If neither is true, make sure the operand is
4ac4fd
-	 in memory and convert the MEM to the new mode.  */
4ac4fd
+      /* If the input and output modes are both the same, we are done.  */
4ac4fd
       if (TYPE_MODE (type) == GET_MODE (op0))
4ac4fd
 	;
4ac4fd
+      /* If neither mode is BLKmode, and both modes are the same size
4ac4fd
+	 then we can use gen_lowpart.  */
4ac4fd
       else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
4ac4fd
-	       && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
4ac4fd
-	       && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
4ac4fd
-	op0 = gen_lowpart (TYPE_MODE (type), op0);
4ac4fd
+	       && GET_MODE_SIZE (TYPE_MODE (type))
4ac4fd
+	          == GET_MODE_SIZE (GET_MODE (op0)))
4ac4fd
+	{
4ac4fd
+	  if (GET_CODE (op0) == SUBREG)
4ac4fd
+	    op0 = force_reg (GET_MODE (op0), op0);
4ac4fd
+	  op0 = gen_lowpart (TYPE_MODE (type), op0);
4ac4fd
+	}
4ac4fd
+      /* If both modes are integral, then we can convert from one to the
4ac4fd
+	 other.  */
4ac4fd
+      else if (SCALAR_INT_MODE_P (GET_MODE (op0))
4ac4fd
+	       && SCALAR_INT_MODE_P (TYPE_MODE (type)))
4ac4fd
+	op0 = convert_modes (TYPE_MODE (type), GET_MODE (op0), op0,
4ac4fd
+			     TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp,
4ac4fd
+								     0))));
4ac4fd
+      /* As a last resort, spill op0 to memory, and reload it in a
4ac4fd
+	 different mode.  */
4ac4fd
       else if (GET_CODE (op0) != MEM)
4ac4fd
 	{
4ac4fd
 	  /* If the operand is not a MEM, force it into memory.  Since we
4ac4fd
--- gcc/machmode.h.orig	2002-02-19 07:13:31.000000000 -0300
4ac4fd
+++ gcc/machmode.h	2006-02-24 04:20:47.000000000 -0300
4ac4fd
@@ -75,6 +75,11 @@ extern const enum mode_class mode_class[
4ac4fd
   (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT	\
4ac4fd
    || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
4ac4fd
 
4ac4fd
+/* Nonzero if MODE is a scalar integral mode.  */
4ac4fd
+#define SCALAR_INT_MODE_P(MODE)			\
4ac4fd
+  (GET_MODE_CLASS (MODE) == MODE_INT		\
4ac4fd
+   || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
4ac4fd
+
4ac4fd
 /* Get the size in bytes of an object of mode MODE.  */
4ac4fd
 
4ac4fd
 extern const unsigned char mode_size[NUM_MACHINE_MODES];
4ac4fd
--- gcc/testsuite/gcc.dg/i386-mmx-3.c	1970-01-01 00:00:00.000000000 +0000
4ac4fd
+++ gcc/testsuite/gcc.dg/i386-mmx-3.c	2006-02-23 02:06:15.000000000 -0300
4ac4fd
@@ -0,0 +1,20 @@
4ac4fd
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
4ac4fd
+/* { dg-options "-O -mmmx" } */
4ac4fd
+
4ac4fd
+#include <stdint.h>
4ac4fd
+#include <mmintrin.h>
4ac4fd
+
4ac4fd
+void x(uint64_t *p_buffer)
4ac4fd
+{
4ac4fd
+    __m64 mm0, mm1;
4ac4fd
+
4ac4fd
+    mm0 = (__m64)(uint64_t)0;
4ac4fd
+
4ac4fd
+    /* This makes no sense whatsoever, it's just the result of
4ac4fd
+       minimization of a large testcase.  */
4ac4fd
+    mm1 = _mm_srli_pi16(mm0, 0);
4ac4fd
+    mm1 = _mm_slli_pi16(mm1, 1);
4ac4fd
+    mm0 = _mm_adds_pi16(mm0, mm1);
4ac4fd
+
4ac4fd
+    *p_buffer = (uint64_t)mm0;
4ac4fd
+}