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]

combine/rotate tweek


Hi
For some purpose kernel defines swapping of endianity for short as:

#define ___swab16(x) \
	((__u16)( \
		(((__u16)(x) & (__u16)0x00ffU) << 8) | \
		(((__u16)(x) & (__u16)0xff00U) >> 8) ))

That gets recognized as rotate by combine (the recognized in fold-const is
blocked by the redundant ands).  Problem is that when parameters is SUBREGed
integer, it goes crazy, since the subreg is propagated over one shift and over
the other.

After seeing this number of times in the kernel compilation I've got irritated
enought to teach combine.c to do it (and fix the kernel header).

The code matches few extra times during gcc compilation, so probably kernel
developers are not only getting inovative ideas about encoding rotates.

I am just in the middle of bootstrap and will run the regression testing over
night and let you know in the case of problems.

Honza

Wed Nov  8 23:25:48 MET 2000  Jan Hubicka  <jh@suse.cz>
	* combine.c (simbplify_logical): Recognize rotates of SUBREGs.
Index: gcc/gcc/combine.c
===================================================================
RCS file: /home/cvs/Repository/gcc/gcc/combine.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 combine.c
*** gcc/gcc/combine.c	2000/11/06 14:30:16	1.3
--- gcc/gcc/combine.c	2000/11/08 22:24:39
*************** simplify_logical (x, last)
*** 5434,5449 ****
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
  	 mode size to (rotate A CX).  */
  
!       if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
! 	   || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT))
! 	  && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
! 	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
! 	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
! 	  && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1))
! 	      == GET_MODE_BITSIZE (mode)))
! 	return gen_rtx_ROTATE (mode, XEXP (op0, 0),
! 			       (GET_CODE (op0) == ASHIFT
! 				? XEXP (op0, 1) : XEXP (op1, 1)));
  
        /* If OP0 is (ashiftrt (plus ...) C), it might actually be
  	 a (sign_extend (plus ...)).  If so, OP1 is a CONST_INT, and the PLUS
--- 5434,5477 ----
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
  	 mode size to (rotate A CX).  */
  
!       {
! 	/* In case original register was subregged, we get something like:
! 	   (ior (lshift (subreg (reg) 0))
! 		(subreg (ashift (reg)) 0))
! 	   Match even this case.  */
! 	rtx rop0, rop1, srop1, srop0;
! 
! 	/* Get ASHIFT first.  */
! 	if (GET_CODE (op0) == LSHIFTRT)
! 	  rop0 = op0, rop1 = op1;
! 	else
! 	  rop0 = op1, rop1 = op0;
! 
! 	/* Skip posssible SUBREG for LSHIFT.  */
! 	if (GET_CODE (rop1) == SUBREG && SUBREG_WORD (rop1) == 0
! 	    && (GET_MODE_SIZE (mode)
! 	        <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (rop1)))))
! 	  srop1 = SUBREG_REG (rop1);
! 	else
! 	  srop1 = rop1;
! 
! 	if (GET_CODE (rop0) == LSHIFTRT && GET_CODE (srop1) == ASHIFT
! 	    && GET_CODE (XEXP (rop0, 1)) == CONST_INT
! 	    && GET_CODE (XEXP (srop1, 1)) == CONST_INT
! 	    && (INTVAL (XEXP (rop0, 1)) + INTVAL (XEXP (srop1, 1))
! 		== GET_MODE_BITSIZE (mode))
! 	    /* In case we skipped SUBREG, verify that there is an matching
! 	       SUBREG on the oposite side.  */
! 	    && (srop1 == rop1
! 	        || (GET_CODE (XEXP (rop0, 0)) == SUBREG
! 		    && SUBREG_WORD (XEXP (rop0, 0)) == 0
! 		    && (GET_MODE_SIZE (mode)
! 		        <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (rop0, 0)))))))
! 	    && rtx_equal_p (srop1 == rop1
! 			    ? XEXP (rop0, 0) : SUBREG_REG (XEXP (rop0, 0)),
! 			    XEXP (srop1, 0)))
! 	  return gen_rtx_ROTATE (mode, XEXP (srop1, 0), XEXP (srop1, 1));
! 	}
  
        /* If OP0 is (ashiftrt (plus ...) C), it might actually be
  	 a (sign_extend (plus ...)).  If so, OP1 is a CONST_INT, and the PLUS

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