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]

Another patch to prevent invalid subreg generation




This is a similar patch to the one that Geoff Keating applied
to extract_bit_field. It prevents the generation of
invalid SUBREGs in some cases.

Bootstrapped on i686 and ppc without any regressions.

2001-11-30 Alan Matsuoka <alanm@redhat.com>

	* expmed.c (store_bit_field): Don't create invalid SUBREGs.

Index: gcc/expmed.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/expmed.c,v
retrieving revision 1.163
diff -d -c -p -r1.163 expmed.c
*** expmed.c	2001/11/26 01:12:24	1.163
--- expmed.c	2001/12/11 14:47:43
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 299,304 ****
--- 299,305 ----
    unsigned HOST_WIDE_INT offset = bitnum / unit;
    unsigned HOST_WIDE_INT bitpos = bitnum % unit;
    rtx op0 = str_rtx;
+   int byte_offset;
  
    enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
  
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 332,338 ****
       If the target is memory, storing any naturally aligned field can be
       done with a simple store.  For targets that support fast unaligned
       memory, any naturally sized, unit aligned field can be done directly.  */
!      
    if (bitpos == 0
        && bitsize == GET_MODE_BITSIZE (fieldmode)
        && (GET_CODE (op0) != MEM
--- 333,342 ----
       If the target is memory, storing any naturally aligned field can be
       done with a simple store.  For targets that support fast unaligned
       memory, any naturally sized, unit aligned field can be done directly.  */
! 
!   byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
!               + (offset * UNITS_PER_WORD);
! 
    if (bitpos == 0
        && bitsize == GET_MODE_BITSIZE (fieldmode)
        && (GET_CODE (op0) != MEM
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 342,371 ****
  	     || (offset * BITS_PER_UNIT % bitsize == 0
  		 && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
      {
!       if (GET_MODE (op0) != fieldmode)
! 	{
! 	  if (GET_CODE (op0) == SUBREG)
! 	    {
! 	      if (GET_MODE (SUBREG_REG (op0)) == fieldmode
! 		  || GET_MODE_CLASS (fieldmode) == MODE_INT
! 		  || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
! 		op0 = SUBREG_REG (op0);
! 	      else
! 		/* Else we've got some float mode source being extracted into
! 		   a different float mode destination -- this combination of
! 		   subregs results in Severe Tire Damage.  */
! 		abort ();
  	    }
! 	  if (GET_CODE (op0) == REG)
! 	    op0 = gen_rtx_SUBREG (fieldmode, op0,
! 				  (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
! 				  + (offset * UNITS_PER_WORD));
! 	  else
! 	    op0 = adjust_address (op0, fieldmode, offset);
! 	}
!       emit_move_insn (op0, value);
!       return value;
!     }
  
    /* Make sure we are playing with integral modes.  Pun with subregs
       if we aren't.  This must come after the entire register case above,
--- 346,376 ----
  	     || (offset * BITS_PER_UNIT % bitsize == 0
  		 && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
      {
!       if (byte_offset % GET_MODE_SIZE (fieldmode) == 0)
!         {
!           if (GET_MODE (op0) != fieldmode)
!             {
! 	      if (GET_CODE (op0) == SUBREG)
! 	        {
! 	          if (GET_MODE (SUBREG_REG (op0)) == fieldmode
! 	           || GET_MODE_CLASS (fieldmode) == MODE_INT
! 	           || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
! 	            op0 = SUBREG_REG (op0);
! 	          else
! 	           /* Else we've got some float mode source being extracted into
! 	              a different float mode destination -- this combination of
! 	              subregs results in Severe Tire Damage.  */
! 	            abort ();
! 	        }
! 	        if (GET_CODE (op0) == REG)
! 	          op0 = gen_rtx_SUBREG (fieldmode, op0, byte_offset);
! 	        else
! 	          op0 = adjust_address (op0, fieldmode, offset);
  	    }
!           emit_move_insn (op0, value);
!           return value;
!        }
!   }
  
    /* Make sure we are playing with integral modes.  Pun with subregs
       if we aren't.  This must come after the entire register case above,

Alan Matsuoka
GCC Engineering
Red Hat Canada, Ltd
mailto:alanm@redhat.com Tel: (416) 482-2661 x250 / Fax: (416) 482-6299


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