rpms/gcc/devel gcc41-pr14024.patch, NONE, 1.1 gcc41-pr24823.patch, NONE, 1.1 gcc41-pr24975.patch, NONE, 1.1 gcc41-pr24982.patch, NONE, 1.1 gcc41-pr25180.patch, NONE, 1.1 gcc41-pr25268.patch, NONE, 1.1 gcc41-s390-atomic1.patch, NONE, 1.1 gcc41-s390-atomic2.patch, NONE, 1.1 gcc41-s390-atomic3.patch, NONE, 1.1 .cvsignore, 1.118, 1.119 gcc41.spec, 1.2, 1.3 sources, 1.120, 1.121 gcc41-gomp-nestedfn.patch, 1.1, NONE

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Dec 7 18:06:55 UTC 2005


Author: jakub

Update of /cvs/dist/rpms/gcc/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv15338

Modified Files:
	.cvsignore gcc41.spec sources 
Added Files:
	gcc41-pr14024.patch gcc41-pr24823.patch gcc41-pr24975.patch 
	gcc41-pr24982.patch gcc41-pr25180.patch gcc41-pr25268.patch 
	gcc41-s390-atomic1.patch gcc41-s390-atomic2.patch 
	gcc41-s390-atomic3.patch 
Removed Files:
	gcc41-gomp-nestedfn.patch 
Log Message:
4.1.0-0.5


gcc41-pr14024.patch:
 0 files changed

--- NEW FILE gcc41-pr14024.patch ---
2005-11-28  Richard Guenther  <rguenther at suse.de>

	* c-common.c (strict_aliasing_warning): Handle all
	component-ref like accesses.
testsuite/
	* gcc.dg/alias-9.c: New testcase.
	* g++.dg/warn/Wstrict-aliasing-7.C: Likewise.

2005-11-24  Richard Guenther  <rguenther at suse.de>
	Dirk Mueller <dmueller at suse.de>

	PR c++/14024
	* c-common.h (strict_aliasing_warning): Declare.
	* c-common.c (strict_aliasing_warning): New function,
	split out from ...
	* c-typeck.c (build_c_cast): ... here.
cp/
	* typeck.c (build_reinterpret_cast_1): Use
	strict_aliasing_warning.
testsuite/
	* g++.dg/warn/Wstrict-aliasing-1.C: New testcase.
	* g++.dg/warn/Wstrict-aliasing-2.C: Likewise.
	* g++.dg/warn/Wstrict-aliasing-3.C: Likewise.
	* g++.dg/warn/Wstrict-aliasing-4.C: Likewise.
	* g++.dg/warn/Wstrict-aliasing-5.C: Likewise.
	* g++.dg/warn/Wstrict-aliasing-6.C: Likewise.

--- gcc/cp/typeck.c	(revision 107458)
+++ gcc/cp/typeck.c	(revision 107459)
@@ -5011,6 +5011,8 @@
   else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
+      tree sexpr = expr;
+
       if (!c_cast_p)
 	check_for_casting_away_constness (intype, type, error,
 					  "reinterpret_cast");
@@ -5025,6 +5027,11 @@
 		 "target type",
 		 intype, type);
 
+      /* We need to strip nops here, because the frontend likes to
+	 create (int *)&a for array-to-pointer decay, instead of &a[0].  */
+      STRIP_NOPS (sexpr);
+      strict_aliasing_warning (intype, type, sexpr);
+
       return fold_if_not_in_template (build_nop (type, expr));
     }
   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
--- gcc/c-typeck.c	(revision 107458)
+++ gcc/c-typeck.c	(revision 107459)
@@ -3441,34 +3441,8 @@
 	warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
 		 "of different size");
 
-      if (flag_strict_aliasing && warn_strict_aliasing
-	  && TREE_CODE (type) == POINTER_TYPE
-	  && TREE_CODE (otype) == POINTER_TYPE
-	  && TREE_CODE (expr) == ADDR_EXPR
-	  && (DECL_P (TREE_OPERAND (expr, 0))
-	      || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)
-	  && !VOID_TYPE_P (TREE_TYPE (type)))
-	{
-	  /* Casting the address of an object to non void pointer. Warn
-	     if the cast breaks type based aliasing.  */
-	  if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
-	    warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
-		     "might break strict-aliasing rules");
-	  else
-	    {
-	      HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
-	      HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
+      strict_aliasing_warning (otype, type, expr);
 
-	      if (!alias_sets_conflict_p (set1, set2))
-		warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
-			 "pointer will break strict-aliasing rules");
-	      else if (warn_strict_aliasing > 1
-		       && !alias_sets_might_conflict_p (set1, set2))
-		warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
-			 "pointer might break strict-aliasing rules");
-	    }
-	}
-
       /* If pedantic, warn for conversions between function and object
 	 pointer types, except for converting a null pointer constant
 	 to function pointer type.  */
--- gcc/c-common.c	(revision 107458)
+++ gcc/c-common.c	(revision 107598)
@@ -954,6 +954,42 @@
     }
 }
 
+/* Print a warning about casts that might indicate violation
+   of strict aliasing rules if -Wstrict-aliasing is used and
+   strict aliasing mode is in effect. otype is the original
+   TREE_TYPE of expr, and type the type we're casting to. */
+
+void
+strict_aliasing_warning(tree otype, tree type, tree expr)
+{
+  if (flag_strict_aliasing && warn_strict_aliasing
+      && POINTER_TYPE_P (type) && POINTER_TYPE_P (otype)
+      && TREE_CODE (expr) == ADDR_EXPR
+      && (DECL_P (TREE_OPERAND (expr, 0))
+          || handled_component_p (TREE_OPERAND (expr, 0)))
+      && !VOID_TYPE_P (TREE_TYPE (type)))
+    {
+      /* Casting the address of an object to non void pointer. Warn
+         if the cast breaks type based aliasing.  */
+      if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
+        warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
+                 "might break strict-aliasing rules");
+      else
+        {
+          HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
+          HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
+
+          if (!alias_sets_conflict_p (set1, set2))
+            warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+                     "pointer will break strict-aliasing rules");
+          else if (warn_strict_aliasing > 1
+                  && !alias_sets_might_conflict_p (set1, set2))
+            warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+                     "pointer might break strict-aliasing rules");
+        }
+    }
+}
+
 /* Nonzero if constant C has a value that is permissible
    for type TYPE (an INTEGER_TYPE).  */
 
--- gcc/c-common.h	(revision 107458)
+++ gcc/c-common.h	(revision 107459)
@@ -649,6 +649,7 @@
 extern tree fix_string_type (tree);
 struct varray_head_tag;
 extern void constant_expression_warning (tree);
+extern void strict_aliasing_warning(tree, tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern void unsigned_conversion_warning (tree, tree);
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C	(revision 107459)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+int *foo(void)
+{
+  return (int *)&x; /* { dg-warning "strict-aliasing" } */
+}
+
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C	(revision 107459)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  return (T *)&x; /* { dg-warning "strict-aliasing" } */
+}
+
+template int *foo<int>(void); /* { dg-warning "instantiated from here" } */
+template char *foo<char>(void); /* { dg-bogus "instantiated from here" } */
+
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C	(revision 107459)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+float foo ()
+{
+  unsigned int MASK = 0x80000000;
+  return (float &) MASK; /* { dg-warning "strict-aliasing" } */
+}
+
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C	(revision 107459)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  return (T *)&x; /* { dg-bogus "strict-aliasing" } */
+}
+
+template double *foo<double>(void);
+
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C	(revision 107459)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  int a[2];
+  float *y = (float *)a; /* { dg-bogus "strict-aliasing" } */
+  return (T *)&x; /* { dg-bogus "strict-aliasing" } */
+}
+
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C	(revision 107459)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+int foo ()
+{
+  char buf[8];
+  return *((int *)buf); /* { dg-warning "strict-aliasing" } */
+}
+
--- gcc/testsuite/gcc.dg/alias-9.c	(revision 0)
+++ gcc/testsuite/gcc.dg/alias-9.c	(revision 107598)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing -O2" } */
+
+int a[2];
+
+double *foo1(void)
+{
+  return (double *)a; /* { dg-warning "strict-aliasing" } */
+}
+
+double *foo2(void)
+{
+  return (double *)&a[0]; /* { dg-warning "strict-aliasing" } */
+}
+
+_Complex x;
+int *bar(void)
+{
+  return (int *)&__imag x; /* { dg-warning "strict-aliasing" } */
+}
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-7.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-7.C	(revision 107598)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing -O2" } */
+
+int a[2];
+
+double *foo1(void)
+{
+  return (double *)a; /* { dg-warning "strict-aliasing" } */
+}
+
+double *foo2(void)
+{
+  return (double *)&a[0]; /* { dg-warning "strict-aliasing" } */
+}
+
+__complex__ double x;
+int *bar(void)
+{
+  return (int *)&__imag__ x; /* { dg-warning "strict-aliasing" } */
+}

gcc41-pr24823.patch:
 flow.c                          |  161 +++++++++++++++++++++++-----------------
 testsuite/gfortran.dg/pr24823.f |   78 +++++++++++++++++++
 2 files changed, 172 insertions(+), 67 deletions(-)

--- NEW FILE gcc41-pr24823.patch ---
2005-11-28  Andreas Krebbel  <krebbel1 at de.ibm.com>

	PR rtl-optimization/24823
	* gfortran.dg/pr24823.f: New test.

2005-11-25  Andreas Krebbel  <krebbel1 at de.ibm.com>

	PR rtl-optimization/24823
	* flow.c (mark_used_dest_regs): New function.
	(mark_used_regs): Call mark_used_dest_regs.

--- gcc/flow.c.jj	2005-12-07 14:27:46.000000000 +0100
+++ gcc/flow.c	2005-12-07 15:01:38.000000000 +0100
@@ -3857,6 +3857,89 @@ mark_used_reg (struct propagate_block_in
     }
 }
 
+/* Scan expression X for registers which have to be marked used in PBI.  
+   X is considered to be the SET_DEST rtx of SET.  TRUE is returned if
+   X could be handled by this function.  */
+
+static bool
+mark_used_dest_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
+{
+  int regno;
+  bool mark_dest = false;
+  rtx dest = x;
+  
+  /* On some platforms calls return values spread over several 
+     locations.  These locations are wrapped in a EXPR_LIST rtx
+     together with a CONST_INT offset.  */
+  if (GET_CODE (x) == EXPR_LIST
+      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+    x = XEXP (x, 0);
+  
+  /* If storing into MEM, don't show it as being used.  But do
+     show the address as being used.  */
+  if (MEM_P (x))
+    {
+#ifdef AUTO_INC_DEC
+      if (pbi->flags & PROP_AUTOINC)
+	find_auto_inc (pbi, x, insn);
+#endif
+      mark_used_regs (pbi, XEXP (x, 0), cond, insn);
+      return true;
+    }
+	    
+  /* Storing in STRICT_LOW_PART is like storing in a reg
+     in that this SET might be dead, so ignore it in TESTREG.
+     but in some other ways it is like using the reg.
+     
+     Storing in a SUBREG or a bit field is like storing the entire
+     register in that if the register's value is not used
+	       then this SET is not needed.  */
+  while (GET_CODE (x) == STRICT_LOW_PART
+	 || GET_CODE (x) == ZERO_EXTRACT
+	 || GET_CODE (x) == SUBREG)
+    {
+#ifdef CANNOT_CHANGE_MODE_CLASS
+      if ((pbi->flags & PROP_REG_INFO) && GET_CODE (x) == SUBREG)
+	record_subregs_of_mode (x);
+#endif
+      
+      /* Modifying a single register in an alternate mode
+	 does not use any of the old value.  But these other
+	 ways of storing in a register do use the old value.  */
+      if (GET_CODE (x) == SUBREG
+	  && !((REG_BYTES (SUBREG_REG (x))
+		+ UNITS_PER_WORD - 1) / UNITS_PER_WORD
+	       > (REG_BYTES (x)
+		  + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+	;
+      else
+	mark_dest = true;
+      
+      x = XEXP (x, 0);
+    }
+  
+  /* If this is a store into a register or group of registers,
+     recursively scan the value being stored.  */
+  if (REG_P (x)	&& 
+      (regno = REGNO (x),
+       !(regno == FRAME_POINTER_REGNUM
+	  && (!reload_completed || frame_pointer_needed)))
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+      && !(regno == HARD_FRAME_POINTER_REGNUM
+	    && (!reload_completed || frame_pointer_needed))
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+      && !(regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+#endif
+	  )
+    {
+      if (mark_dest)
+	mark_used_regs (pbi, dest, cond, insn);
+      return true;
+    }
+  return false;
+}
+
 /* Scan expression X and store a 1-bit in NEW_LIVE for each reg it uses.
    This is done assuming the registers needed from X are those that
    have 1-bits in PBI->REG_LIVE.
@@ -3868,7 +3951,6 @@ static void
 mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
 {
   RTX_CODE code;
-  int regno;
   int flags = pbi->flags;
 
  retry:
@@ -3969,73 +4051,18 @@ mark_used_regs (struct propagate_block_i
 
     case SET:
       {
-	rtx testreg = SET_DEST (x);
-	int mark_dest = 0;
-
-	/* If storing into MEM, don't show it as being used.  But do
-	   show the address as being used.  */
-	if (MEM_P (testreg))
-	  {
-#ifdef AUTO_INC_DEC
-	    if (flags & PROP_AUTOINC)
-	      find_auto_inc (pbi, testreg, insn);
-#endif
-	    mark_used_regs (pbi, XEXP (testreg, 0), cond, insn);
-	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
-	    return;
-	  }
-
-	/* Storing in STRICT_LOW_PART is like storing in a reg
-	   in that this SET might be dead, so ignore it in TESTREG.
-	   but in some other ways it is like using the reg.
-
-	   Storing in a SUBREG or a bit field is like storing the entire
-	   register in that if the register's value is not used
-	   then this SET is not needed.  */
-	while (GET_CODE (testreg) == STRICT_LOW_PART
-	       || GET_CODE (testreg) == ZERO_EXTRACT
-	       || GET_CODE (testreg) == SUBREG)
-	  {
-#ifdef CANNOT_CHANGE_MODE_CLASS
-	    if ((flags & PROP_REG_INFO) && GET_CODE (testreg) == SUBREG)
-	      record_subregs_of_mode (testreg);
-#endif
-
-	    /* Modifying a single register in an alternate mode
-	       does not use any of the old value.  But these other
-	       ways of storing in a register do use the old value.  */
-	    if (GET_CODE (testreg) == SUBREG
-		&& !((REG_BYTES (SUBREG_REG (testreg))
-		      + UNITS_PER_WORD - 1) / UNITS_PER_WORD
-		     > (REG_BYTES (testreg)
-			+ UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-	      ;
-	    else
-	      mark_dest = 1;
-
-	    testreg = XEXP (testreg, 0);
-	  }
-
-	/* If this is a store into a register or group of registers,
-	   recursively scan the value being stored.  */
-
-	if ((GET_CODE (testreg) == PARALLEL
-	     && GET_MODE (testreg) == BLKmode)
-	    || (REG_P (testreg)
-		&& (regno = REGNO (testreg),
-		    ! (regno == FRAME_POINTER_REGNUM
-		       && (! reload_completed || frame_pointer_needed)))
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-		&& ! (regno == HARD_FRAME_POINTER_REGNUM
-		      && (! reload_completed || frame_pointer_needed))
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-		&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
-#endif
-		))
+	rtx dest = SET_DEST (x);
+	int i;
+	bool ret = false;
+
+	if (GET_CODE (dest) == PARALLEL)
+	  for (i = 0; i < XVECLEN (dest, 0); i++)
+	    ret |= mark_used_dest_regs (pbi, XVECEXP (dest, 0 ,i), cond, insn);
+	else
+	  ret = mark_used_dest_regs (pbi, dest, cond, insn);
+	
+	if (ret)
 	  {
-	    if (mark_dest)
-	      mark_used_regs (pbi, SET_DEST (x), cond, insn);
 	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
 	    return;
 	  }
--- gcc/testsuite/gfortran.dg/pr24823.f.jj	2005-12-07 15:01:29.000000000 +0100
+++ gcc/testsuite/gfortran.dg/pr24823.f	2005-12-07 15:01:29.000000000 +0100
@@ -0,0 +1,78 @@
+!     { dg-do compile }
+!     { dg-options "-O2" }
+!     PR24823 Flow didn't handle a PARALLEL as destination of a SET properly.
+      SUBROUTINE ZLATMR( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
+     $     RSIGN, GRADE, DL, MODEL, CONDL, DR, MODER,
+     $     PACK, A, LDA, IWORK, INFO )
+      COMPLEX*16         A( LDA, * ), D( * ), DL( * ), DR( * )
+      LOGICAL            BADPVT, DZERO, FULBND
+      COMPLEX*16         ZLATM2, ZLATM3
+      IF( IGRADE.EQ.4 .AND. MODEL.EQ.0 ) THEN
+      END IF
+      IF( IPVTNG.GT.0 ) THEN
+      END IF
+      IF( M.LT.0 ) THEN
+      ELSE IF( IPACK.EQ.-1 .OR. ( ( IPACK.EQ.1 .OR. IPACK.EQ.2 .OR.
+     $        IPACK.EQ.5 .OR. IPACK.EQ.6 ) .AND. ISYM.EQ.1 ) .OR.
+     $        ( IPACK.EQ.3 .AND. ISYM.EQ.1 .AND. ( KL.NE.0 .OR. M.NE.
+     $        6 ) .AND. LDA.LT.KUU+1 ) .OR.
+     $        ( IPACK.EQ.7 .AND. LDA.LT.KLL+KUU+1 ) ) THEN
+         INFO = -26
+      END IF
+      IF( INFO.NE.0 ) THEN
+         RETURN
+      END IF
+      IF( KUU.EQ.N-1 .AND. KLL.EQ.M-1 )
+     $     FULBND = .TRUE.
+      IF( MODE.NE.0 .AND. MODE.NE.-6 .AND. MODE.NE.6 ) THEN
+         TEMP = ABS( D( 1 ) )
+         IF( TEMP.EQ.ZERO .AND. DMAX.NE.CZERO ) THEN
+            INFO = 2
+         END IF
+      END IF
+      IF( ISYM.EQ.0 ) THEN
+      END IF
+      IF( IGRADE.EQ.1 .OR. IGRADE.EQ.3 .OR. IGRADE.EQ.4 .OR. IGRADE.EQ.
+     $     5 .OR. IGRADE.EQ.6 ) THEN
+         IF( INFO.NE.0 ) THEN
+         END IF
+      END IF
+      IF( FULBND ) THEN
+         IF( IPACK.EQ.0 ) THEN
+            IF( ISYM.EQ.0 ) THEN
+               CTEMP = ZLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
+     $              IWORK, SPARSE )
+               DO 120 I = 1, M
+                  CTEMP = ZLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
+     $                 IWORK, SPARSE )
+ 120           CONTINUE
+            END IF
+            IF( I.LT.1 ) THEN
+               IF( ISYM.EQ.0 ) THEN
+                  A( J-I+1, I ) = DCONJG( ZLATM2( M, N, I, J, KL,
+     $                 DR, IPVTNG, IWORK, SPARSE ) )
+               ELSE
+                  A( J-I+1, I ) = ZLATM2( M, N, I, J, KL, KU,
+     $                 IPVTNG, IWORK, SPARSE )
+               END IF
+            END IF
+            IF( ISYM.NE.1 ) THEN
+               IF( I.GE.1 .AND. I.NE.J ) THEN
+                  IF( ISYM.EQ.0 ) THEN
+                  END IF
+               END IF
+               A( I-J+KUU+1, J ) = ZLATM2( M, N, I, J, KL, KU,
+     $              DR, IPVTNG, IWORK, SPARSE )
+            END IF
+         END IF
+      END IF
+      IF( IPACK.EQ.0 ) THEN
+         ONORM = ZLANGB( 'M', N, KLL, KUU, A, LDA, TEMPA )
+      END IF
+      IF( ANORM.GE.ZERO ) THEN
+         IF( ANORM.GT.ZERO .AND. ONORM.EQ.ZERO ) THEN
+            IF( IPACK.LE.2 ) THEN
+            END IF
+         END IF
+      END IF
+      END

gcc41-pr24975.patch:
 0 files changed

--- NEW FILE gcc41-pr24975.patch ---
2005-11-23  Paolo Carlini  <pcarlini at suse.de>

	PR libstdc++/24975 (basic_string)
	* include/bits/basic_string.h (_Rep::_S_empty_rep): Avoid
	strict-aliasing warnings.

--- libstdc++-v3/include/bits/basic_string.h	(revision 107446)
+++ libstdc++-v3/include/bits/basic_string.h	(revision 107447)
@@ -177,7 +177,13 @@
 
         static _Rep&
         _S_empty_rep()
-        { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
+        { 
+	  // NB: Mild hack to avoid strict-aliasing warnings.  Note that
+	  // _S_empty_rep_storage is never modified and the punning should
+	  // be reasonably safe in this case.
+	  void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
+	  return *reinterpret_cast<_Rep*>(__p);
+	}
 
         bool
 	_M_is_leaked() const

gcc41-pr24982.patch:
 reload.c |    3 ++-
 reload.h |    1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

--- NEW FILE gcc41-pr24982.patch ---
2005-11-22  Kaz Kojima  <kkojima at gcc.gnu.org>

	PR target/24982
	* reload.c (refers_to_regno_for_reload_p): Take
	reg_equiv_invariant and reg_equiv_init into account.
	* reload.h (reg_equiv_invariant): Declare.

--- gcc/reload.c	2005-11-20 09:23:39.000000000 +0900
+++ gcc/reload.c	2005-11-22 20:43:05.000000000 +0900
@@ -6278,7 +6278,8 @@ refers_to_regno_for_reload_p (unsigned i
 						 reg_equiv_memory_loc[r],
 						 (rtx*) 0);
 
-	  gcc_assert (reg_equiv_constant[r]);
+	  gcc_assert (reg_equiv_constant[r]
+		      || (reg_equiv_invariant[r] && reg_equiv_init[r]));
 	  return 0;
 	}
 
--- gcc/reload.h	2005-10-29 06:52:10.000000000 +0900
+++ gcc/reload.h	2005-11-22 20:46:51.000000000 +0900
@@ -166,6 +166,7 @@ extern int n_reloads;
 
 extern GTY (()) struct varray_head_tag *reg_equiv_memory_loc_varray;
 extern rtx *reg_equiv_constant;
+extern rtx *reg_equiv_invariant;
 extern rtx *reg_equiv_memory_loc;
 extern rtx *reg_equiv_address;
 extern rtx *reg_equiv_mem;


gcc41-pr25180.patch:
 0 files changed

--- NEW FILE gcc41-pr25180.patch ---
2005-12-05  Paolo Bonzini  <bonzini at gnu.org>

	* config/rs6000/predicates.md (logical_const_operand): Split
	out of logical_operand.
	(logical_operand): Use it.
	* config/rs6000/rs6000.md (cmp -> xor peephole2): Use
	logical_const_operand.

--- gcc/config/rs6000/predicates.md	(revision 108064)
+++ gcc/config/rs6000/predicates.md	(revision 108065)
@@ -407,16 +407,13 @@
        (match_test "!CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
 		    && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')")))
 
-;; Return 1 if the operand is a non-special register or a constant that
-;; can be used as the operand of an OR or XOR.
-(define_predicate "logical_operand"
-  (match_code "reg,subreg,const_int,const_double")
+;; Return 1 if the operand is a constant that can be used as the operand
+;; of an OR or XOR.
+(define_predicate "logical_const_operand"
+  (match_code "const_int,const_double")
 {
   HOST_WIDE_INT opl, oph;
 
-  if (gpc_reg_operand (op, mode))
-    return 1;
-
   if (GET_CODE (op) == CONST_INT)
     {
       opl = INTVAL (op) & GET_MODE_MASK (mode);
@@ -441,6 +438,12 @@
 	  || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
 })
 
+;; Return 1 if the operand is a non-special register or a constant that
+;; can be used as the operand of an OR or XOR.
+(define_predicate "logical_operand"
+  (ior (match_operand 0 "gpc_reg_operand")
+       (match_operand 0 "logical_const_operand")))
+
 ;; Return 1 if op is a constant that is not a logical operand, but could
 ;; be split into one.
 (define_predicate "non_logical_cint_operand"
--- gcc/config/rs6000/rs6000.md	(revision 108064)
+++ gcc/config/rs6000/rs6000.md	(revision 108065)
@@ -11283,10 +11283,10 @@
 
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand")
-        (match_operand:SI 1 "logical_operand" ""))
+        (match_operand:SI 1 "logical_const_operand" ""))
    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
 		       [(match_dup 0)
-			(match_operand:SI 2 "logical_operand" "")]))
+			(match_operand:SI 2 "logical_const_operand" "")]))
    (set (match_operand:CC 4 "cc_reg_operand" "")
         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
                     (match_dup 0)))

gcc41-pr25268.patch:
 config/s390/predicates.md                    |   34 ----
 config/s390/s390-protos.h                    |    2 
 config/s390/s390.c                           |   21 --
 config/s390/s390.md                          |  203 ++++++++++++++++++++++++---
 testsuite/gcc.c-torture/compile/20051207-1.c |    7 
 5 files changed, 201 insertions(+), 66 deletions(-)

--- NEW FILE gcc41-pr25268.patch ---
2005-12-07  Andreas Krebbel  <krebbel1 at de.ibm.com>

	PR target/25268
	* config/s390/s390.c (s390_decompose_shift_count): Remove BITS
	argument.  Don't drop outer ANDs.
	(s390_extra_constraint_str, print_shift_count_operand): Adjust callers.
	* config/s390/s390-protos.h (s390_decompose_shift_count): Adjust
	prototype.
	* config/s390/predicates.md (setmem_operand): Remove.
	(shift_count_operand): Rename to...
	(shift_count_or_setmem_operand): ... this.  Adjust
	s390_decompose_shift_count caller.
	* config/s390/s390.md (<shift>di3_31_and, <shift>di3_64_and,
	ashrdi3_cc_31_and, ashrdi3_cconly_31_and, ashrdi3_31_and,
	ashrdi3_cc_64_and, ashrdi3_cconly_64_and, ashrdi3_64_and,
	<shift>si3_and, ashrsi3_cc_and, ashrsi3_cconly_and, ashrsi3_and,
	rotl<mode>3_and, setmem_long_and): New insns.
	(<shift>di3_31, <shift>di3_64, ashrdi3_cc_31, ashrdi3_cconly_31,
	ashrdi3_31, ashrdi3_cc_64, ashrdi3_cconly_64, ashrdi3_64,
	<shift>si3, ashrsi3_cc, ashrsi3_cconly, ashrsi3, rotl<mode>3,
	<shift>di3, ashrdi3): Use shift_count_or_setmem_operand instead
	of shift_count_operand.
	(setmem_long): Use shift_count_or_setmem_operand instead of
	setmem_operand.

	* gcc.c-torture/compile/20051207-1.c: New test.

--- gcc/config/s390/s390.c.jj	2005-11-24 13:24:35.000000000 +0100
+++ gcc/config/s390/s390.c	2005-12-07 17:28:52.000000000 +0100
@@ -1729,28 +1729,13 @@ s390_decompose_address (rtx addr, struct
 /* Decompose a RTL expression OP for a shift count into its components,
    and return the base register in BASE and the offset in OFFSET.
 
-   If BITS is non-zero, the expression is used in a context where only
-   that number to low-order bits is significant.  We then allow OP to
-   contain and outer AND that does not affect significant bits.  If BITS
-   is zero, we allow OP to contain any outer AND with a constant.
-
    Return true if OP is a valid shift count, false if not.  */
 
 bool
-s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset, int bits)
+s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
 {
   HOST_WIDE_INT off = 0;
 
-  /* Drop outer ANDs.  */
-  if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT)
-    {
-      HOST_WIDE_INT mask = ((HOST_WIDE_INT)1 << bits) - 1;
-      if ((INTVAL (XEXP (op, 1)) & mask) != mask)
-	return false;
-
-      op = XEXP (op, 0);
-    }
-
   /* We can have an integer constant, an address register,
      or a sum of the two.  */
   if (GET_CODE (op) == CONST_INT)
@@ -1910,7 +1895,7 @@ s390_extra_constraint_str (rtx op, int c
     case 'Y':
       /* Simply check for the basic form of a shift count.  Reload will
 	 take care of making sure we have a proper base register.  */
-      if (!s390_decompose_shift_count (op, NULL, NULL, 0))
+      if (!s390_decompose_shift_count (op, NULL, NULL))
 	return 0;
       break;
 
@@ -4043,7 +4028,7 @@ print_shift_count_operand (FILE *file, r
   rtx base;
 
   /* Extract base register and offset.  */
-  if (!s390_decompose_shift_count (op, &base, &offset, 0))
+  if (!s390_decompose_shift_count (op, &base, &offset))
     gcc_unreachable ();
 
   /* Sanity check.  */
--- gcc/config/s390/s390-protos.h.jj	2005-11-24 13:24:35.000000000 +0100
+++ gcc/config/s390/s390-protos.h	2005-12-07 17:28:52.000000000 +0100
@@ -97,7 +97,7 @@ extern rtx s390_load_got (void);
 extern rtx s390_get_thread_pointer (void);
 extern void s390_emit_tpf_eh_return (rtx);
 extern bool s390_legitimate_address_without_index_p (rtx);
-extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *, int);
+extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
 extern int s390_branch_condition_mask (rtx);
 
 #endif /* RTX_CODE */
--- gcc/config/s390/predicates.md.jj	2005-11-24 13:24:35.000000000 +0100
+++ gcc/config/s390/predicates.md	2005-12-07 17:28:52.000000000 +0100
@@ -75,42 +75,16 @@
        (and (match_test "mode == Pmode")
 	    (match_test "!legitimate_la_operand_p (op)"))))
 
-;; Return true if OP is a valid operand for setmem.
+;; Return true if OP is a valid operand as shift count or setmem.
 
-(define_predicate "setmem_operand"
+(define_predicate "shift_count_or_setmem_operand"
   (match_code "reg, subreg, plus, const_int")
 {
   HOST_WIDE_INT offset;
   rtx base;
 
-  /* Extract base register and offset.  Use 8 significant bits.  */
-  if (!s390_decompose_shift_count (op, &base, &offset, 8))
-    return false;
-
-  /* Don't allow any non-base hard registers.  Doing so without
-     confusing reload and/or regrename would be tricky, and doesn't
-     buy us much anyway.  */
-  if (base && REGNO (base) < FIRST_PSEUDO_REGISTER && !ADDR_REG_P (base))
-    return false;
-
-  /* Unfortunately we have to reject constants that are invalid
-     for an address, or else reload will get confused.  */
-  if (!DISP_IN_RANGE (offset))
-    return false;
-
-  return true;
-})
-
-;; Return true if OP is a valid shift count operand.
-
-(define_predicate "shift_count_operand"
-  (match_code "reg, subreg, plus, const_int, and")
-{
-  HOST_WIDE_INT offset;
-  rtx base;
-
-  /* Extract base register and offset.  Use 6 significant bits.  */
-  if (!s390_decompose_shift_count (op, &base, &offset, 6))
+  /* Extract base register and offset.  */
+  if (!s390_decompose_shift_count (op, &base, &offset))
     return false;
 
   /* Don't allow any non-base hard registers.  Doing so without
--- gcc/config/s390/s390.md.jj	2005-11-24 13:24:35.000000000 +0100
+++ gcc/config/s390/s390.md	2005-12-07 17:28:52.000000000 +0100
@@ -2217,7 +2217,7 @@
   [(parallel
     [(clobber (match_dup 1))
      (set (match_operand:BLK 0 "memory_operand" "")
-          (match_operand 2 "setmem_operand" ""))
+          (match_operand 2 "shift_count_or_setmem_operand" ""))
      (use (match_operand 1 "general_operand" ""))
      (use (match_dup 3))
      (clobber (reg:CC CC_REGNUM))])]
@@ -2243,7 +2243,7 @@
 (define_insn "*setmem_long"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (match_operand 2 "setmem_operand" "Y"))
+        (match_operand 2 "shift_count_or_setmem_operand" "Y"))
    (use (match_dup 3))
    (use (match_operand:<DBL> 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
@@ -2252,6 +2252,18 @@
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
+(define_insn "*setmem_long_and"
+  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
+   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
+        (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
+	     (match_operand 4 "const_int_operand"             "n")))
+   (use (match_dup 3))
+   (use (match_operand:<DBL> 1 "register_operand" "d"))
+   (clobber (reg:CC CC_REGNUM))]
+  "(INTVAL (operands[4]) & 255) == 255"
+  "mvcle\t%0,%1,%Y2\;jo\t.-4"
+  [(set_attr "length" "8")
+   (set_attr "type" "vs")])
 ;
 ; cmpmemM instruction pattern(s).
 ;
@@ -6258,12 +6270,22 @@
 (define_insn "rotl<mode>3"
   [(set (match_operand:GPR 0 "register_operand" "=d")
 	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (match_operand:SI 2 "shift_count_operand" "Y")))]
+		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
   "TARGET_CPU_ZARCH"
   "rll<g>\t%0,%1,%Y2"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")])
 
+(define_insn "*rotl<mode>3_and"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			    (match_operand:SI 3 "const_int_operand"   "n"))))]
+  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
+  "rll<g>\t%0,%1,%Y2"
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
 
 ;;
 ;;- Shift instructions.
@@ -6276,14 +6298,14 @@
 (define_expand "<shift>di3"
   [(set (match_operand:DI 0 "register_operand" "")
         (SHIFT:DI (match_operand:DI 1 "register_operand" "")
-                  (match_operand:SI 2 "shift_count_operand" "")))]
+                  (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
   ""
   "")
 
 (define_insn "*<shift>di3_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
-                  (match_operand:SI 2 "shift_count_operand" "Y")))]
+                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
   "!TARGET_64BIT"
   "s<lr>dl\t%0,%Y2"
   [(set_attr "op_type"  "RS")
@@ -6292,12 +6314,32 @@
 (define_insn "*<shift>di3_64"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (SHIFT:DI (match_operand:DI 1 "register_operand" "d")
-                  (match_operand:SI 2 "shift_count_operand" "Y")))]
+                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
   "TARGET_64BIT"
   "s<lr>lg\t%0,%1,%Y2"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")])
 
+(define_insn "*<shift>di3_31_and"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
+                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			  (match_operand:SI 3 "const_int_operand"   "n"))))]
+  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+  "s<lr>dl\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*<shift>di3_64_and"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (SHIFT:DI (match_operand:DI 1 "register_operand" "d")
+                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			  (match_operand:SI 3 "const_int_operand"   "n"))))]
+  "TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+  "s<lr>lg\t%0,%1,%Y2"
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
 ;
 ; ashrdi3 instruction pattern(s).
 ;
@@ -6306,7 +6348,7 @@
   [(parallel
     [(set (match_operand:DI 0 "register_operand" "")
           (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
-                       (match_operand:SI 2 "shift_count_operand" "")))
+                       (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
      (clobber (reg:CC CC_REGNUM))])]
   ""
   "")
@@ -6314,7 +6356,7 @@
 (define_insn "*ashrdi3_cc_31"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d")
         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -6326,7 +6368,7 @@
 (define_insn "*ashrdi3_cconly_31"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (clobber (match_scratch:DI 0 "=d"))]
   "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
@@ -6337,7 +6379,7 @@
 (define_insn "*ashrdi3_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                     (match_operand:SI 2 "shift_count_operand" "Y")))
+                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_64BIT"
   "srda\t%0,%Y2"
@@ -6347,7 +6389,7 @@
 (define_insn "*ashrdi3_cc_64"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d")
         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -6359,7 +6401,7 @@
 (define_insn "*ashrdi3_cconly_64"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (clobber (match_scratch:DI 0 "=d"))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
@@ -6370,7 +6412,7 @@
 (define_insn "*ashrdi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
-                     (match_operand:SI 2 "shift_count_operand" "Y")))
+                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_64BIT"
   "srag\t%0,%1,%Y2"
@@ -6378,6 +6420,84 @@
    (set_attr "atype"    "reg")])
 
 
+; shift pattern with implicit ANDs
+
+(define_insn "*ashrdi3_cc_31_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+		 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d")
+        (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+   && (INTVAL (operands[3]) & 63) == 63"
+  "srda\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrdi3_cconly_31_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d"))]
+  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+   && (INTVAL (operands[3]) & 63) == 63"
+  "srda\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrdi3_31_and"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			     (match_operand:SI 3 "const_int_operand"   "n"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+  "srda\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrdi3_cc_64_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+		 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d")
+        (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+  "TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+   && (INTVAL (operands[3]) & 63) == 63"
+  "srag\t%0,%1,%Y2"
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrdi3_cconly_64_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d"))]
+  "TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+   && (INTVAL (operands[3]) & 63) == 63"
+  "srag\t%0,%1,%Y2"
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrdi3_64_and"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			     (match_operand:SI 3 "const_int_operand"   "n"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+  "srag\t%0,%1,%Y2"
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
 ;
 ; (ashl|lshr)si3 instruction pattern(s).
 ;
@@ -6385,12 +6505,22 @@
 (define_insn "<shift>si3"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (SHIFT:SI (match_operand:SI 1 "register_operand" "0")
-                  (match_operand:SI 2 "shift_count_operand" "Y")))]
+                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
   ""
   "s<lr>l\t%0,%Y2"
   [(set_attr "op_type"  "RS")
    (set_attr "atype"    "reg")])
 
+(define_insn "*<shift>si3_and"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (SHIFT:SI (match_operand:SI 1 "register_operand" "0")
+                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			  (match_operand:SI 3 "const_int_operand"   "n"))))]
+  "(INTVAL (operands[3]) & 63) == 63"
+  "s<lr>l\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
 ;
 ; ashrsi3 instruction pattern(s).
 ;
@@ -6398,7 +6528,7 @@
 (define_insn "*ashrsi3_cc"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d")
         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -6411,7 +6541,7 @@
 (define_insn "*ashrsi3_cconly"
   [(set (reg CC_REGNUM)
         (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_operand" "Y"))
+                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
                  (const_int 0)))
    (clobber (match_scratch:SI 0 "=d"))]
   "s390_match_ccmode(insn, CCSmode)"
@@ -6422,13 +6552,52 @@
 (define_insn "ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
-                     (match_operand:SI 2 "shift_count_operand" "Y")))
+                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
    (clobber (reg:CC CC_REGNUM))]
   ""
   "sra\t%0,%Y2"
   [(set_attr "op_type"  "RS")
    (set_attr "atype"    "reg")])
 
+; with implicit ANDs
+
+(define_insn "*ashrsi3_cc_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+                 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (ashiftrt:SI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
+  "sra\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+
+(define_insn "*ashrsi3_cconly_and"
+  [(set (reg CC_REGNUM)
+        (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+				      (match_operand:SI 3 "const_int_operand"   "n")))
+                 (const_int 0)))
+   (clobber (match_scratch:SI 0 "=d"))]
+  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
+  "sra\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
+(define_insn "*ashrsi3_and"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+			     (match_operand:SI 3 "const_int_operand"   "n"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "(INTVAL (operands[3]) & 63) == 63"
+  "sra\t%0,%Y2"
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
 
 ;;
 ;; Branch instruction patterns.
--- gcc/testsuite/gcc.c-torture/compile/20051207-1.c.jj	2005-12-02 15:07:13.880680000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/20051207-1.c	2005-12-07 17:37:00.000000000 +0100
@@ -0,0 +1,7 @@
+/* PR target/25268 */
+
+long long
+foo (long long x, int y)
+{
+  return x << ((y + 1) & 63);
+}

gcc41-s390-atomic1.patch:
 builtins.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

--- NEW FILE gcc41-s390-atomic1.patch ---
2005-12-06  Adrian Straetling  <straetling at de.ibm.com>

	* gcc/builtins.c: (expand_builtin_sync_operation,
	expand_builtin_compare_and_swap,expand_builtin_lock_test_and_set,
	expand_builtin_lock_release): Copy alignment to memory rtx.

--- gcc/builtins.c.orig	2005-11-22 13:45:07.000000000 +0100
+++ gcc/builtins.c	2005-11-22 17:00:13.480637006 +0100
@@ -5418,9 +5418,10 @@ expand_builtin_sync_operation (enum mach
 			       rtx target, bool ignore)
 {
   rtx addr, val, mem;
+  tree loc = TREE_VALUE (arglist);
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
+  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
@@ -5429,6 +5430,7 @@ expand_builtin_sync_operation (enum mach
      memory, so that we kill all other live memories.  Otherwise we don't
      satisfy the full barrier semantics of the intrinsic.  */
   mem = validize_mem (gen_rtx_MEM (mode, addr));
+  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
   MEM_VOLATILE_P (mem) = 1;
 
   if (ignore)
@@ -5447,9 +5449,10 @@ expand_builtin_compare_and_swap (enum ma
 				 bool is_bool, rtx target)
 {
   rtx addr, old_val, new_val, mem;
+  tree loc = TREE_VALUE (arglist);
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
+  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
 
   arglist = TREE_CHAIN (arglist);
   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
@@ -5461,6 +5464,7 @@ expand_builtin_compare_and_swap (enum ma
      memory, so that we kill all other live memories.  Otherwise we don't
      satisfy the full barrier semantics of the intrinsic.  */
   mem = validize_mem (gen_rtx_MEM (mode, addr));
+  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
   MEM_VOLATILE_P (mem) = 1;
 
   if (is_bool)
@@ -5480,9 +5484,10 @@ expand_builtin_lock_test_and_set (enum m
 				  rtx target)
 {
   rtx addr, val, mem;
+  tree loc = TREE_VALUE (arglist);
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
+  addr = expand_expr (loc, NULL, Pmode, EXPAND_NORMAL);
 
   arglist = TREE_CHAIN (arglist);
   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
@@ -5491,6 +5496,7 @@ expand_builtin_lock_test_and_set (enum m
      memory, so that we kill all other live memories.  Otherwise we don't
      satisfy the barrier semantics of the intrinsic.  */
   mem = validize_mem (gen_rtx_MEM (mode, addr));
+  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
   MEM_VOLATILE_P (mem) = 1;
 
   return expand_sync_lock_test_and_set (mem, val, target);
@@ -5528,14 +5534,16 @@ expand_builtin_lock_release (enum machin
   enum insn_code icode;
   rtx addr, mem, insn;
   rtx val = const0_rtx;
+  tree loc = TREE_VALUE (arglist);
 
   /* Expand the operands.  */
-  addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
+  addr = expand_expr (loc, NULL, Pmode, EXPAND_NORMAL);
 
   /* Note that we explicitly do not want any alias information for this
      memory, so that we kill all other live memories.  Otherwise we don't
      satisfy the barrier semantics of the intrinsic.  */
   mem = validize_mem (gen_rtx_MEM (mode, addr));
+  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
   MEM_VOLATILE_P (mem) = 1;
 
   /* If there is an explicit operation in the md file, use it.  */


gcc41-s390-atomic2.patch:
 config/s390/s390-protos.h         |    1 
 config/s390/s390.c                |  150 ++++++++++++++++++++++++++++++++++++++
 config/s390/s390.md               |   16 ++++
 testsuite/lib/target-supports.exp |    1 
 4 files changed, 168 insertions(+)

--- NEW FILE gcc41-s390-atomic2.patch ---
2005-12-06  Adrian Straetling  <straetling at de.ibm.com>

	* config/s390/s390.c (s390_expand_mask_and_shift, 
	struct alignment_context, init_alignment_context, 
	s390_expand_cs_hqi): New.
	* config/s390/s390-protos.h (s390_expand_cs_hqi): Declare.
	* config/s390/s390.md ("sync_compare_and_swaphi",
	"sync_compare_and_swapqi"): New pattern.
	* testsuite/lib/target-supports.exp
	(check_effective_target_sync_char_short): Add s390*.

--- gcc/config/s390/s390.md.jj	2005-12-07 17:28:52.000000000 +0100
+++ gcc/config/s390/s390.md	2005-12-07 18:45:42.000000000 +0100
@@ -7439,6 +7439,22 @@
 	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
   "")
 
+(define_expand "sync_compare_and_swap<mode>"
+  [(parallel
+    [(set (match_operand:HQI 0 "register_operand" "")
+	  (match_operand:HQI 1 "memory_operand" ""))
+     (set (match_dup 1)
+	  (unspec_volatile:HQI
+	    [(match_dup 1)
+	     (match_operand:HQI 2 "general_operand" "")
+	     (match_operand:HQI 3 "general_operand" "")]
+	    UNSPECV_CAS))
+     (set (reg:CCZ1 CC_REGNUM)
+	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
+  ""
+  "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], 
+		       operands[2], operands[3]); DONE;")
+
 (define_expand "sync_compare_and_swap_cc<mode>"
   [(parallel
     [(set (match_operand:TDSI 0 "register_operand" "")
--- gcc/config/s390/s390.c.jj	2005-12-07 17:28:52.000000000 +0100
+++ gcc/config/s390/s390.c	2005-12-07 18:45:42.000000000 +0100
@@ -3957,6 +3957,156 @@ s390_expand_insv (rtx dest, rtx op1, rtx
   return false;
 }
 
+/* A subroutine of s390_expand_cs_hqi which returns a register which holds VAL
+   of mode MODE shifted by COUNT bits.  */
+
+static inline rtx
+s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
+{
+  val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
+			     NULL_RTX, 1, OPTAB_DIRECT);
+  return expand_simple_binop (SImode, ASHIFT, val, count, 
+			      NULL_RTX, 1, OPTAB_DIRECT);
+}
+
+/* Structure to hold the initial parameters for a compare_and_swap operation
+   in HImode and QImode.  */ 
+
+struct alignment_context
+{
+  rtx memsi;	  /* SI aligned memory location.  */ 
+  rtx shift;	  /* Bit offset with regard to lsb.  */
+  rtx modemask;	  /* Mask of the HQImode shifted by SHIFT bits.  */
+  rtx modemaski;  /* ~modemask */
+  bool aligned;	  /* True if memory is aliged, false else.  */
+};
+
+/* A subroutine of s390_expand_cs_hqi to initialize the structure AC for
+   transparent simplifying, if the memory alignment is known to be at least
+   32bit.  MEM is the memory location for the actual operation and MODE its
+   mode.  */
+
+static void
+init_alignment_context (struct alignment_context *ac, rtx mem,
+			enum machine_mode mode)
+{
+  ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
+  ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
+
+  if (ac->aligned)
+    ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned.  */
+  else
+    {
+      /* Alignment is unknown.  */
+      rtx byteoffset, addr, align;
+
+      /* Force the address into a register.  */
+      addr = force_reg (Pmode, XEXP (mem, 0));
+
+      /* Align it to SImode.  */
+      align = expand_simple_binop (Pmode, AND, addr,
+				   GEN_INT (-GET_MODE_SIZE (SImode)),
+				   NULL_RTX, 1, OPTAB_DIRECT);
+      /* Generate MEM.  */
+      ac->memsi = gen_rtx_MEM (SImode, align);
+      MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
+      set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
+
+      /* Calculate shiftcount.  */
+      byteoffset = expand_simple_binop (Pmode, AND, addr,
+					GEN_INT (GET_MODE_SIZE (SImode) - 1),
+					NULL_RTX, 1, OPTAB_DIRECT);
+      /* As we already have some offset, evaluate the remaining distance.  */
+      ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
+				      NULL_RTX, 1, OPTAB_DIRECT);
+
+    }
+  /* Shift is the byte count, but we need the bitcount.  */
+  ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
+				  NULL_RTX, 1, OPTAB_DIRECT);
+  /* Calculate masks.  */
+  ac->modemask = expand_simple_binop (SImode, ASHIFT, 
+				     GEN_INT (GET_MODE_MASK (mode)), ac->shift,
+				     NULL_RTX, 1, OPTAB_DIRECT);
+  ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
+}
+
+/* Expand an atomic compare and swap operation for HImode and QImode.  MEM is
+   the memory location, CMP the old value to compare MEM with and NEW the value
+   to set if CMP == MEM.
+   CMP is never in memory for compare_and_swap_cc because
+   expand_bool_compare_and_swap puts it into a register for later compare.  */
+
+void
+s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx new)
+{
+  struct alignment_context ac;
+  rtx cmpv, newv, val, resv, cc;
+  rtx res = gen_reg_rtx (SImode);
+  rtx csloop = gen_label_rtx ();
+  rtx csend = gen_label_rtx ();
+
+  gcc_assert (register_operand (target, VOIDmode));
+  gcc_assert (MEM_P (mem));
+
+  init_alignment_context (&ac, mem, mode);
+
+  /* Shift the values to the correct bit positions.  */
+  if (!(ac.aligned && MEM_P (cmp)))
+    cmp = s390_expand_mask_and_shift (cmp, mode, ac.shift);
+  if (!(ac.aligned && MEM_P (new)))
+    new = s390_expand_mask_and_shift (new, mode, ac.shift);
+
+  /* Load full word.  Subsequent loads are performed by CS.  */
+  val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
+			     NULL_RTX, 1, OPTAB_DIRECT);
+
+  /* Start CS loop.  */
+  emit_label (csloop);
+  /* val = "<mem>00..0<mem>" 
+   * cmp = "00..0<cmp>00..0"
+   * new = "00..0<new>00..0" 
+   */
+
+  /* Patch cmp and new with val at correct position.  */
+  if (ac.aligned && MEM_P (cmp))
+    {
+      cmpv = force_reg (SImode, val);
+      store_bit_field (cmpv, GET_MODE_BITSIZE (mode), 0, SImode, cmp);
+    }
+  else
+    cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
+						   NULL_RTX, 1, OPTAB_DIRECT));
+  if (ac.aligned && MEM_P (new))
+    {
+      newv = force_reg (SImode, val);
+      store_bit_field (newv, GET_MODE_BITSIZE (mode), 0, SImode, new);
+    }
+  else
+    newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new, val,
+						   NULL_RTX, 1, OPTAB_DIRECT));
+
+  /* Emit compare_and_swap pattern.  */
+  emit_insn (gen_sync_compare_and_swap_ccsi (res, ac.memsi, cmpv, newv));
+      
+  /* Jump to end if we're done (likely?).  */
+  s390_emit_jump (csend, s390_emit_compare (EQ, cmpv, ac.memsi));
+
+  /* Check for changes outside mode.  */
+  resv = expand_simple_binop (SImode, AND, res, ac.modemaski, 
+			      NULL_RTX, 1, OPTAB_DIRECT);
+  cc = s390_emit_compare (NE, resv, val); 
+  emit_move_insn (val, resv);
+  /* Loop internal if so.  */
+  s390_emit_jump (csloop, cc);
+
+  emit_label (csend);
+  
+  /* Return the correct part of the bitfield.  */
+  convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift, 
+					     NULL_RTX, 1, OPTAB_DIRECT), 1);
+}
+
 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
    We need to emit DTP-relative relocations.  */
 
--- gcc/config/s390/s390-protos.h.jj	2005-12-07 17:28:52.000000000 +0100
+++ gcc/config/s390/s390-protos.h	2005-12-07 18:45:42.000000000 +0100
@@ -75,6 +75,7 @@ extern void s390_expand_setmem (rtx, rtx
 extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
 extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
 extern bool s390_expand_insv (rtx, rtx, rtx, rtx);
+extern void s390_expand_cs_hqi (enum machine_mode, rtx, rtx, rtx, rtx);
 extern rtx s390_return_addr_rtx (int, rtx);
 extern rtx s390_back_chain_rtx (void);
 extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
--- gcc/testsuite/lib/target-supports.exp.jj	2005-11-24 13:25:31.000000000 +0100
+++ gcc/testsuite/lib/target-supports.exp	2005-12-07 18:46:12.000000000 +0100
@@ -1338,6 +1338,7 @@ proc check_effective_target_sync_char_sh
 	     || [istarget x86_64-*-*]
 	     || [istarget alpha*-*-*] 
 	     || [istarget powerpc*-*-*]
+	     || [istarget s390*-*-*]
 	     || [istarget sparc64-*-*]
 	     || [istarget sparcv9-*-*] } {
            set et_sync_char_short_saved 1

gcc41-s390-atomic3.patch:
 s390-protos.h |    2 +
 s390.c        |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 s390.md       |   44 ++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 6 deletions(-)

--- NEW FILE gcc41-s390-atomic3.patch ---
2005-12-06  Adrian Straetling  <straetling at de.ibm.com>

	* config/s390/s390.c (s390_expand_atomic): New function.
	Adjust comment of helper functions.
	* config/s390/s390-protos.h (s390_expand_atomic): Declare.
	* config/s390/s390.md ("ATOMIC"): New code macro.
	("atomic"): Corresponding new code attribute.
	("sync_lock_test_and_set[hq]i", 
	"sync_{new_,old_,}{and,ior,xor,add,sub,nand}[hq]i"): New pattern.

--- gcc/config/s390/s390.c.jj	2005-12-07 18:45:42.000000000 +0100
+++ gcc/config/s390/s390.c	2005-12-07 18:53:39.000000000 +0100
@@ -3957,8 +3957,8 @@ s390_expand_insv (rtx dest, rtx op1, rtx
   return false;
 }
 
-/* A subroutine of s390_expand_cs_hqi which returns a register which holds VAL
-   of mode MODE shifted by COUNT bits.  */
+/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
+   register that holds VAL of mode MODE shifted by COUNT bits.  */
 
 static inline rtx
 s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
@@ -3981,10 +3981,10 @@ struct alignment_context
   bool aligned;	  /* True if memory is aliged, false else.  */
 };
 
-/* A subroutine of s390_expand_cs_hqi to initialize the structure AC for
-   transparent simplifying, if the memory alignment is known to be at least
-   32bit.  MEM is the memory location for the actual operation and MODE its
-   mode.  */
+/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
+   structure AC for transparent simplifying, if the memory alignment is known
+   to be at least 32bit.  MEM is the memory location for the actual operation
+   and MODE its mode.  */
 
 static void
 init_alignment_context (struct alignment_context *ac, rtx mem,
@@ -4107,6 +4107,97 @@ s390_expand_cs_hqi (enum machine_mode mo
 					     NULL_RTX, 1, OPTAB_DIRECT), 1);
 }
 
+/* Expand an atomic operation CODE of mode MODE.  MEM is the memory location
+   and VAL the value to play with.  If AFTER is true then store the the value
+   MEM holds after the operation, if AFTER is false then store the value MEM
+   holds before the operation.  If TARGET is zero then discard that value, else
+   store it to TARGET.  */
+
+void
+s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
+		    rtx target, rtx mem, rtx val, bool after)
+{
+  struct alignment_context ac;
+  rtx cmp;
+  rtx new = gen_reg_rtx (SImode);
+  rtx orig = gen_reg_rtx (SImode);
+  rtx csloop = gen_label_rtx ();
+
+  gcc_assert (!target || register_operand (target, VOIDmode));
+  gcc_assert (MEM_P (mem));
+
+  init_alignment_context (&ac, mem, mode);
+
+  /* Shift val to the correct bit positions.
+     Preserve "icm", but prevent "ex icm".  */
+  if (!(ac.aligned && code == SET && MEM_P (val)))
+    val = s390_expand_mask_and_shift (val, mode, ac.shift);
+
+  /* Further preparation insns.  */
+  if (code == PLUS || code == MINUS)
+    emit_move_insn (orig, val);
+  else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
+    val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
+			       NULL_RTX, 1, OPTAB_DIRECT);
+
+  /* Load full word.  Subsequent loads are performed by CS.  */
+  cmp = force_reg (SImode, ac.memsi);
+
+  /* Start CS loop.  */
+  emit_label (csloop);
+  emit_move_insn (new, cmp);
+
+  /* Patch new with val at correct position.  */
+  switch (code)
+    {
+    case PLUS:
+    case MINUS:
+      val = expand_simple_binop (SImode, code, new, orig,
+				 NULL_RTX, 1, OPTAB_DIRECT);
+      val = expand_simple_binop (SImode, AND, val, ac.modemask,
+				 NULL_RTX, 1, OPTAB_DIRECT);
+      /* FALLTHRU */
+    case SET: 
+      if (ac.aligned && MEM_P (val))
+	store_bit_field (new, GET_MODE_BITSIZE (mode), 0, SImode, val);
+      else
+	{
+	  new = expand_simple_binop (SImode, AND, new, ac.modemaski,
+				     NULL_RTX, 1, OPTAB_DIRECT);
+	  new = expand_simple_binop (SImode, IOR, new, val,
+				     NULL_RTX, 1, OPTAB_DIRECT);
+	}
+      break;
+    case AND:
+    case IOR:
+    case XOR:
+      new = expand_simple_binop (SImode, code, new, val,
+				 NULL_RTX, 1, OPTAB_DIRECT);
+      break;
+    case MULT: /* NAND */
+      new = expand_simple_binop (SImode, XOR, new, ac.modemask,
+				 NULL_RTX, 1, OPTAB_DIRECT);
+      new = expand_simple_binop (SImode, AND, new, val,
+				 NULL_RTX, 1, OPTAB_DIRECT);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  /* Emit compare_and_swap pattern.  */
+  emit_insn (gen_sync_compare_and_swap_ccsi (cmp, ac.memsi, cmp, new));
+
+  /* Loop until swapped (unlikely?).  */
+  s390_emit_jump (csloop, gen_rtx_fmt_ee (NE, CCZ1mode,
+					  gen_rtx_REG (CCZ1mode, CC_REGNUM),
+					  const0_rtx));
+
+  /* Return the correct part of the bitfield.  */
+  if (target)
+    convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
+					       after ? new : cmp, ac.shift,
+					       NULL_RTX, 1, OPTAB_DIRECT), 1);
+}
+
 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
    We need to emit DTP-relative relocations.  */
 
--- gcc/config/s390/s390.md.jj	2005-12-07 18:45:42.000000000 +0100
+++ gcc/config/s390/s390.md	2005-12-07 18:53:39.000000000 +0100
@@ -315,6 +315,11 @@
 ;; the same template.
 (define_code_macro SHIFT [ashift lshiftrt])
 
+;; These macros allow to combine most atomic operations.
+(define_code_macro ATOMIC [and ior xor plus minus mult])
+(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
+			  (plus "add") (minus "sub") (mult "nand")])
+
 
 ;; In FPR templates, a string like "lt<de>br" will expand to "ltdbr" in DFmode
 ;; and "ltebr" in SFmode.
@@ -7509,6 +7514,45 @@
    (set_attr "type"   "sem")])
 
 
+;
+; Other atomic instruction patterns.
+;
+
+(define_expand "sync_lock_test_and_set<mode>"
+  [(match_operand:HQI 0 "register_operand")
+   (match_operand:HQI 1 "memory_operand")
+   (match_operand:HQI 2 "general_operand")]
+  ""
+  "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], 
+		       operands[2], false); DONE;")
+
+(define_expand "sync_<atomic><mode>"
+  [(set (match_operand:HQI 0 "memory_operand")
+	(ATOMIC:HQI (match_dup 0)
+		    (match_operand:HQI 1 "general_operand")))]
+  ""
+  "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], 
+		       operands[1], false); DONE;")
+
+(define_expand "sync_old_<atomic><mode>"
+  [(set (match_operand:HQI 0 "register_operand")
+	(match_operand:HQI 1 "memory_operand"))
+   (set (match_dup 1)
+	(ATOMIC:HQI (match_dup 1)
+		    (match_operand:HQI 2 "general_operand")))]
+  ""
+  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
+		       operands[2], false); DONE;")
+
+(define_expand "sync_new_<atomic><mode>"
+  [(set (match_operand:HQI 0 "register_operand")
+	(ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
+		    (match_operand:HQI 2 "general_operand"))) 
+   (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
+  ""
+  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
+		       operands[2], true); DONE;")
+
 ;;
 ;;- Miscellaneous instructions.
 ;;
--- gcc/config/s390/s390-protos.h.jj	2005-12-07 18:45:42.000000000 +0100
+++ gcc/config/s390/s390-protos.h	2005-12-07 18:53:39.000000000 +0100
@@ -76,6 +76,8 @@ extern void s390_expand_cmpmem (rtx, rtx
 extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
 extern bool s390_expand_insv (rtx, rtx, rtx, rtx);
 extern void s390_expand_cs_hqi (enum machine_mode, rtx, rtx, rtx, rtx);
+extern void s390_expand_atomic (enum machine_mode, enum rtx_code, 
+				rtx, rtx, rtx, bool);
 extern rtx s390_return_addr_rtx (int, rtx);
 extern rtx s390_back_chain_rtx (void);
 extern rtx s390_emit_call (rtx, rtx, rtx, rtx);


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/.cvsignore,v
retrieving revision 1.118
retrieving revision 1.119
diff -u -r1.118 -r1.119
--- .cvsignore	1 Dec 2005 13:03:01 -0000	1.118
+++ .cvsignore	7 Dec 2005 18:06:53 -0000	1.119
@@ -1 +1 @@
-gcc-4.1.0-20051201.tar.bz2
+gcc-4.1.0-20051207.tar.bz2


Index: gcc41.spec
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/gcc41.spec,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gcc41.spec	1 Dec 2005 13:03:02 -0000	1.2
+++ gcc41.spec	7 Dec 2005 18:06:53 -0000	1.3
@@ -1,6 +1,6 @@
-%define DATE 20051201
+%define DATE 20051207
 %define gcc_version 4.1.0
-%define gcc_release 0.4
+%define gcc_release 0.5
 %define _unpackaged_files_terminate_build 0
 %define multilib_64_archs sparc64 ppc64 s390x x86_64
 %ifarch %{ix86} x86_64 ia64
@@ -100,7 +100,15 @@
 Patch19: gcc41-ppc64-sync.patch
 Patch20: gcc41-ppc32-retaddr.patch
 Patch21: gcc41-libgfortran-host_subdir.patch
-Patch22: gcc41-gomp-nestedfn.patch
+Patch22: gcc41-pr14024.patch
+Patch23: gcc41-pr24823.patch
+Patch24: gcc41-pr24975.patch
+Patch25: gcc41-pr24982.patch
+Patch26: gcc41-pr25180.patch
+Patch27: gcc41-pr25268.patch
+Patch28: gcc41-s390-atomic1.patch
+Patch29: gcc41-s390-atomic2.patch
+Patch30: gcc41-s390-atomic3.patch
 
 %define _gnu %{nil}
 %ifarch sparc
@@ -450,7 +458,15 @@
 %patch19 -p0 -b .ppc64-sync~
 %patch20 -p0 -b .ppc32-retaddr~
 %patch21 -p0 -b .libgfortran-host_subdir~
-%patch22 -p0 -b .gomp-nestedfn~
+%patch22 -p0 -b .pr14024~
+%patch23 -p0 -b .pr24823~
+%patch24 -p0 -b .pr24975~
+%patch25 -p0 -b .pr24982~
+%patch26 -p0 -b .pr25180~
+%patch27 -p0 -b .pr25268~
+%patch28 -p0 -b .s390-atomic1~
+%patch29 -p0 -b .s390-atomic2~
+%patch30 -p0 -b .s390-atomic3~
 
 sed -i -e 's/4\.1\.0/4.1.0/' gcc/BASE-VER gcc/version.c
 sed -i -e 's/" (Red Hat[^)]*)"/" (Red Hat %{version}-%{gcc_release})"/' gcc/version.c
@@ -1530,6 +1546,23 @@
 %endif
 
 %changelog
+* Wed Dec  7 2005 Jakub Jelinek <jakub at redhat.com> 4.1.0-0.5
+- update from gcc-4_1-branch (-r107810:108157)
+  - PRs bootstrap/25207, c++/24103, c++/24138, c++/24173, fortran/15809,
+	fortran/21302, fortran/23912, java/25283, libfortran/24919,
+	libgfortran/25149, middle-end/25176, other/13873, target/18580,
+	target/24108, target/24475, target/24934, target/25199,
+	testsuite/25247, tree-optimization/24963
+- update from gomp-20050608-branch (up to -r108105)
+- -Wstrict-aliasing C++ support (Richard Guenther, Dirk Mueller,
+  Paolo Carlini, PRs c++/14024, libstdc++/24975)
+- fix mark_used_regs regression (Andreas Krebbel, PR rtl-optimization/24823)
+- fix reload ICE (Kaz Kojima, PR target/24982)
+- fix PPC ICE on Linux kernel (Paolo Bonzini, PR target/24982)
+- fix s390{,x} shifts with shift count ANDed with constant mask
+  (Andreas Krebbel, PR target/25268)
+- s390{,x} atomic builtins enhancements (Adrian Straetling)
+
 * Thu Dec  1 2005 Jakub Jelinek <jakub at redhat.com> 4.1.0-0.4
 - update from gcc-4_1-branch (-r107618:107810)
   - PRs c++/21123, c++/21166, fortran/24223, fortran/24705, java/18278,


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/gcc/devel/sources,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -r1.120 -r1.121
--- sources	1 Dec 2005 13:03:02 -0000	1.120
+++ sources	7 Dec 2005 18:06:53 -0000	1.121
@@ -1 +1 @@
-4b43a8833f1b9dc552f94f367bab2a2e  gcc-4.1.0-20051201.tar.bz2
+34a34dd7995a147527dd921382dc020b  gcc-4.1.0-20051207.tar.bz2


--- gcc41-gomp-nestedfn.patch DELETED ---




More information about the fedora-cvs-commits mailing list