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]

fix for USE/SET problem on ppc-elf



This fixes the parts of the rs6000 backend that are used by ELF,
and improves the message on failure a bit.

Bootstrapped & passes make check on powerpc-linux.

Note that it fixes only about one third of the patterns that could
cause the error.  The rest are only used by AIX, for which a patch
will follow.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-singleset.patch=============
2000-09-30  Geoff Keating  <geoffk@cygnus.com>

	* config/rs6000/rs6000.md (movsi_to_cr): Remove the USE.  Calculate
	the mask value from the individual SET operations.
	(return_internal_si): Move the USE after the RETURN.
	(return_internal_di): Likewise.
	(return_and_restore_fpregs_si): Likewise.
	(return_and_restore_fpregs_di): Likewise.
	(return_eh_si): Likewise.
	(return_eh_di): Likewise.
	* config/rs6000/rs6000.c (mtcrf_operation): Don't look for,
	or check, the USE.
	(rs6000_emit_prologue): Don't emit the USE for movsi_to_cr.
	Don't generate a PARALLEL around a single operation movsi_to_cr.
	Generate the RETURN first in any PARALLELs.

	* rtlanal.c (single_set_1): Use fatal_insn to display the
	invalid insn.  Check for more cases when a USE or CLOBBER occurs
	before a SET.
	* Makefile.in: Update dependencies for rtlanal.o.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.516
diff -p -u -u -p -r1.516 Makefile.in
--- Makefile.in	2000/09/25 22:34:53	1.516
+++ Makefile.in	2000/10/01 05:19:38
@@ -1253,7 +1253,7 @@ rtl.o : rtl.c $(CONFIG_H) system.h $(RTL
 
 print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h \
     $(BASIC_BLOCK_H)
-rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H)
+rtlanal.o : rtlanal.c $(CONFIG_H) system.h toplev.h $(RTL_H)
 errors.o : errors.c $(CONFIG_H) system.h errors.h
 
 varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.70
diff -p -u -u -p -r1.70 rtlanal.c
--- rtlanal.c	2000/09/29 11:24:12	1.70
+++ rtlanal.c	2000/10/01 05:19:39
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "toplev.h"
 #include "rtl.h"
 
 static int rtx_addr_can_trap_p	PARAMS ((rtx));
@@ -878,7 +879,7 @@ single_set_1 (insn)
 	    /* Instruction should not consist only from USEs and CLOBBERS,
 	       since then gcc is allowed to remove it entirely.  In case
 	       something else is present, it should be first in the pattern.  */
-	    abort();
+	    fatal_insn ("USE or CLOBBER before SET:", insn);
 #endif
 	  case SET:
 	    break;
@@ -895,34 +896,41 @@ single_set_1 (insn)
 	  for (i = XVECLEN (pat, 0) - 1; i > 1; i--)
 	    if (GET_CODE (XVECEXP (pat, 0, i)) != USE
 		&& GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
-	      abort();
+	      fatal_insn ("USE or CLOBBER before SET:", insn);
 #endif
 	    return set;
 	case SET:
-	  /* Multiple set insns - we are off the critical path now.  */
-	  for (i = XVECLEN (pat, 0) - 1; i > 0; i--)
-	    {
-	      sub = XVECEXP (pat, 0, i);
-	      switch GET_CODE (sub)
-		{
-		case USE:
-		case CLOBBER:
-		  break;
-
-		case SET:
-		  if (!set
-		      || (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
-			  && side_effects_p (set)))
-		    set = sub;
-		  else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
-			   || side_effects_p (sub))
-		    return NULL_RTX;
-		  break;
+	  {
+	    int seen_clobber = 0;
 
-		default:
-		  return NULL_RTX;
-		}
-	    }
+	    /* Multiple set insns - we are off the critical path now.  */
+	    for (i = 1; i < XVECLEN (pat, 0); i++)
+	      {
+		sub = XVECEXP (pat, 0, i);
+		switch GET_CODE (sub)
+		  {
+		  case USE:
+		  case CLOBBER:
+		    seen_clobber = 1;
+		    break;
+		    
+		  case SET:
+		    if (seen_clobber)
+		      fatal_insn ("USE or CLOBBER before SET:", insn);
+		    if (!set
+			|| (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
+			    && side_effects_p (set)))
+		      set = sub;
+		    else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
+			     || side_effects_p (sub))
+		      return NULL_RTX;
+		    break;
+		    
+		  default:
+		    return NULL_RTX;
+		  }
+	      }
+	  }
 	  return set;
 	default:
 	  return NULL_RTX;
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.149
diff -p -u -u -p -r1.149 rs6000.c
--- rs6000.c	2000/09/11 06:00:52	1.149
+++ rs6000.c	2000/10/01 05:19:44
@@ -3006,25 +3006,22 @@ mtcrf_operation (op, mode)
 {
   int count = XVECLEN (op, 0);
   int i;
-  int bitmap = 0;
   rtx src_reg;
 
   /* Perform a quick check so we don't blow up below.  */
-  if (count < 2
-      || GET_CODE (XVECEXP (op, 0, 0)) != USE
-      || GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) != CONST_INT
-      || GET_CODE (XVECEXP (op, 0, 1)) != SET
-      || GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != UNSPEC
-      || XVECLEN (SET_SRC (XVECEXP (op, 0, 1)), 0) != 2)
+  if (count < 1
+      || GET_CODE (XVECEXP (op, 0, 0)) != SET
+      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
+      || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
     return 0;
-  src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 1)), 0, 0);
+  src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
   
   if (GET_CODE (src_reg) != REG
       || GET_MODE (src_reg) != SImode
       || ! INT_REGNO_P (REGNO (src_reg)))
     return 0;
 
-  for (i = 1; i < count; i++)
+  for (i = 0; i < count; i++)
     {
       rtx exp = XVECEXP (op, 0, i);
       rtx unspec;
@@ -3037,7 +3034,6 @@ mtcrf_operation (op, mode)
 	return 0;
       unspec = SET_SRC (exp);
       maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
-      bitmap |= maskval;
       
       if (GET_CODE (unspec) != UNSPEC
 	  || XINT (unspec, 1) != 20
@@ -3047,7 +3043,7 @@ mtcrf_operation (op, mode)
 	  || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
 	return 0;
     }
-  return INTVAL (XEXP (XVECEXP (op, 0, 0), 0)) == bitmap;
+  return 1;
 }
 
 /* Return 1 for an PARALLEL suitable for lmw. */
@@ -5974,38 +5970,39 @@ rs6000_emit_epilogue(sibcall)
   if (info->cr_save_p)
     {
       rtx r12_rtx = gen_rtx_REG (SImode, 12);
+      int count = 0;
       
       if (using_mfcr_multiple)
 	{
-	  rtvec p;
-	  int mask = 0;
-	  int count = 0;
-
 	  for (i = 0; i < 8; i++)
 	    if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
-	      {
-		mask |= 1 << (7-i);
-		count++;
-	      }
+	      count++;
 	  if (count == 0)
-	    abort();
+	    abort ();
+	}
+
+      if (using_mfcr_multiple && count > 1)
+	{
+	  rtvec p;
+	  int ndx;
 	  
-	  p = rtvec_alloc (count + 1);
+	  p = rtvec_alloc (count);
 
-	  RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, GEN_INT (mask));
-	  count = 1;
+	  ndx = 0;
 	  for (i = 0; i < 8; i++)
 	    if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
 	      {
 		rtvec r = rtvec_alloc (2);
 		RTVEC_ELT (r, 0) = r12_rtx;
 		RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
-		RTVEC_ELT (p, count) =
+		RTVEC_ELT (p, ndx) =
 		  gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), 
 			       gen_rtx_UNSPEC (CCmode, r, 20));
-		count++;
+		ndx++;
 	      }
 	  emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+	  if (ndx != count)
+	    abort ();
 	}
       else
 	for (i = 0; i < 8; i++)
@@ -6050,10 +6047,10 @@ rs6000_emit_epilogue(sibcall)
       else
 	p = rtvec_alloc (2);
 
-      RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, 
+      RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+      RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, 
 				      gen_rtx_REG (Pmode, 
 						   LINK_REGISTER_REGNUM));
-      RTVEC_ELT (p, 1) = gen_rtx_RETURN (VOIDmode);
 
       /* If we have to restore more than two FP registers, branch to the
 	 restore function.  It will return to our caller.  */
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.101
diff -p -u -u -p -r1.101 rs6000.md
--- rs6000.md	2000/09/11 06:00:52	1.101
+++ rs6000.md	2000/10/01 05:19:47
@@ -13295,13 +13295,20 @@ operands[2] = GEN_INT (INTVAL (operands[
 
 (define_insn "*movsi_to_cr"
  [(match_parallel 0 "mtcrf_operation"
-                  [(use (match_operand 1 "immediate_operand" "n"))
-		   (set (match_operand:CC 2 "cc_reg_operand" "=y")
-       			(unspec:CC [(match_operand:SI 3 "gpc_reg_operand" "r")
-		   		    (match_operand 4 "immediate_operand" "n")]
+                  [(set (match_operand:CC 1 "cc_reg_operand" "=y")
+       			(unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
+		   		    (match_operand 3 "immediate_operand" "n")]
 			 20))])]
  ""
- "mtcrf %1,%3")
+ "*
+{
+  int mask = 0;
+  int i;
+  for (i = 0; i < XVECLEN (operands[0], 0); i++)
+    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
+  operands[4] = GEN_INT (mask);
+  return \"mtcrf %4,%2\";
+}")
 
 (define_insn ""
  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
@@ -13325,15 +13332,15 @@ operands[2] = GEN_INT (INTVAL (operands[
  "{lm|lmw} %1,%2")
  
 (define_insn "*return_internal_si"
-  [(use (match_operand:SI 0 "register_operand" "lc"))
-   (return)]
+  [(return)
+   (use (match_operand:SI 0 "register_operand" "lc"))]
   "TARGET_32BIT"
   "b%T0"
   [(set_attr "type" "jmpreg")])
 
 (define_insn "*return_internal_di"
-  [(use (match_operand:DI 0 "register_operand" "lc"))
-   (return)]
+  [(return)
+   (use (match_operand:DI 0 "register_operand" "lc"))]
   "TARGET_64BIT"
   "b%T0"
   [(set_attr "type" "jmpreg")])
@@ -13343,8 +13350,8 @@ operands[2] = GEN_INT (INTVAL (operands[
 
 (define_insn "*return_and_restore_fpregs_si"
  [(match_parallel 0 "any_operand"
-                  [(use (match_operand:SI 1 "register_operand" "l"))
-		   (return)
+                  [(return)
+		   (use (match_operand:SI 1 "register_operand" "l"))
 		   (use (match_operand:SI 2 "call_operand" "s"))
 		   (set (match_operand:DF 3 "gpc_reg_operand" "=f")
 			(match_operand:DF 4 "memory_operand" "m"))])]
@@ -13353,8 +13360,8 @@ operands[2] = GEN_INT (INTVAL (operands[
 
 (define_insn "*return_and_restore_fpregs_di"
  [(match_parallel 0 "any_operand"
-                  [(use (match_operand:DI 1 "register_operand" "l"))
-		   (return)
+                  [(return)
+		   (use (match_operand:DI 1 "register_operand" "l"))
 		   (use (match_operand:DI 2 "call_operand" "s"))
 		   (set (match_operand:DF 3 "gpc_reg_operand" "=f")
 			(match_operand:DF 4 "memory_operand" "m"))])]
@@ -13460,8 +13467,8 @@ operands[2] = GEN_INT (INTVAL (operands[
 
 
 (define_insn "return_eh_si"
-  [(use (match_operand:SI 0 "register_operand" "lc"))
-   (return)
+  [(return)
+   (use (match_operand:SI 0 "register_operand" "lc"))
    (use (reg:SI 2))
    (use (reg:SI 3))]
   "TARGET_32BIT"
@@ -13469,8 +13476,8 @@ operands[2] = GEN_INT (INTVAL (operands[
   [(set_attr "type" "jmpreg")])
 
 (define_insn "return_eh_di"
-  [(use (match_operand:DI 0 "register_operand" "lc"))
-   (return)
+  [(return)
+   (use (match_operand:DI 0 "register_operand" "lc"))
    (use (reg:DI 2))
    (use (reg:DI 3))]
   "TARGET_64BIT"
============================================================

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