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]

Re: Your change to function.c


On Tue, Oct 06, 1998 at 05:13:52AM -0700, David S. Miller wrote:
> Nice, seems to work fine with my function.c change removed to punt on
> FLOAT stuff in purge_addressof_1.  You can revert that change of mine
> when you install these changes after your loose end cleanups...

FYI, here it is with loose end cleanups.  Assuming there are no
unexpected problems, or unexpected objections, after the currently
running make check finishes, I'll check it in.


r~


	* expmed.c (store_bit_field): Pun non-integral str_rtx modes.
	Take extra care for op0 now possibly being a subreg.
	(extract_bit_field): Likewise.
	* function.c (purge_addressof_1): Revert Oct 4 change.  Drop
	the reg to memory if there is no equal sized integral mode.
	* stor-layout.c (int_mode_for_mode): New function.
	* machmode.h: Prototype it.


Index: expmed.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expmed.c,v
retrieving revision 1.21
diff -c -p -d -r1.21 expmed.c
*** expmed.c	1998/10/05 00:08:56	1.21
--- expmed.c	1998/10/08 06:25:41
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 261,266 ****
--- 261,281 ----
        op0 = SUBREG_REG (op0);
      }
  
+   /* Make sure we are playing with integral modes.  Pun with subregs
+      if we aren't.  */
+   {
+     enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+     if (imode != GET_MODE (op0))
+       {
+ 	if (GET_CODE (op0) == MEM)
+ 	  op0 = change_address (op0, imode, NULL_RTX);
+ 	else if (imode != BLKmode)
+ 	  op0 = gen_lowpart (imode, op0);
+ 	else
+ 	  abort ();
+       }
+   }
+ 
    /* If OP0 is a register, BITPOS must count within a word.
       But as we have it, it counts within whatever size OP0 now has.
       On a bigendian machine, these are not the same, so convert.  */
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 287,292 ****
--- 302,319 ----
  	 can be done with just SUBREG.  */
        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, offset);
  	  else
*************** extract_bit_field (str_rtx, bitsize, bit
*** 955,960 ****
--- 982,1002 ----
        op0 = SUBREG_REG (op0);
      }
  
+   /* Make sure we are playing with integral modes.  Pun with subregs
+      if we aren't.  */
+   {
+     enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+     if (imode != GET_MODE (op0))
+       {
+ 	if (GET_CODE (op0) == MEM)
+ 	  op0 = change_address (op0, imode, NULL_RTX);
+ 	else if (imode != BLKmode)
+ 	  op0 = gen_lowpart (imode, op0);
+ 	else
+ 	  abort ();
+       }
+   }
+ 
    /* ??? We currently assume TARGET is at least as big as BITSIZE.
       If that's wrong, the solution is to test for it and set TARGET to 0
       if needed.  */
*************** extract_bit_field (str_rtx, bitsize, bit
*** 973,979 ****
       So too extracting a subword value in
       the least significant part of the register.  */
  
!   if (((GET_CODE (op0) == REG
  	&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
  				  GET_MODE_BITSIZE (GET_MODE (op0))))
         || (GET_CODE (op0) == MEM
--- 1015,1021 ----
       So too extracting a subword value in
       the least significant part of the register.  */
  
!   if (((GET_CODE (op0) != MEM
  	&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
  				  GET_MODE_BITSIZE (GET_MODE (op0))))
         || (GET_CODE (op0) == MEM
*************** extract_bit_field (str_rtx, bitsize, bit
*** 996,1001 ****
--- 1038,1055 ----
  
        if (mode1 != GET_MODE (op0))
  	{
+ 	  if (GET_CODE (op0) == SUBREG)
+ 	    {
+ 	      if (GET_MODE (SUBREG_REG (op0)) == mode1
+ 		  || GET_MODE_CLASS (mode1) == MODE_INT
+ 		  || GET_MODE_CLASS (mode1) == 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 (mode1, op0, offset);
  	  else
*************** extract_bit_field (str_rtx, bitsize, bit
*** 1088,1099 ****
    /* OFFSET is the number of words or bytes (UNIT says which)
       from STR_RTX to the first word or byte containing part of the field.  */
  
!   if (GET_CODE (op0) == REG)
      {
        if (offset != 0
  	  || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
! 	op0 = gen_rtx_SUBREG (TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
! 		       op0, offset);
        offset = 0;
      }
    else
--- 1142,1153 ----
    /* OFFSET is the number of words or bytes (UNIT says which)
       from STR_RTX to the first word or byte containing part of the field.  */
  
!   if (GET_CODE (op0) != MEM)
      {
        if (offset != 0
  	  || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
! 	op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0),
! 		              op0, offset);
        offset = 0;
      }
    else
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.47
diff -c -p -d -r1.47 function.c
*** function.c	1998/10/04 01:29:19	1.47
--- function.c	1998/10/08 06:25:41
*************** purge_addressof_1 (loc, insn, force, sto
*** 2874,2896 ****
  
  	  /* Don't even consider working with paradoxical subregs,
  	     or the moral equivalent seen here.  */
! 	  if (size_x < size_sub)
  	    {
  	      /* Do a bitfield insertion to mirror what would happen
  		 in memory.  */
  
  	      rtx val, seq;
- 
- 	      /* We cannot do this if we are trying to pick out
- 		 an integral piece, smaller than a word, of a
- 		 floating point value.  */
- 	      if (INTEGRAL_MODE_P (GET_MODE (x))
- 		  && GET_MODE_SIZE (GET_MODE (x)) < UNITS_PER_WORD
- 		  && FLOAT_MODE_P (GET_MODE (sub)))
- 		{
- 		  put_addressof_into_stack (XEXP (x, 0));
- 		  return;
- 		}
  
  	      if (store)
  		{
--- 2874,2886 ----
  
  	  /* Don't even consider working with paradoxical subregs,
  	     or the moral equivalent seen here.  */
! 	  if (size_x < size_sub
! 	      && int_mode_for_mode (GET_MODE (sub)) != BLKmode)
  	    {
  	      /* Do a bitfield insertion to mirror what would happen
  		 in memory.  */
  
  	      rtx val, seq;
  
  	      if (store)
  		{
Index: machmode.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/machmode.h,v
retrieving revision 1.5
diff -c -p -d -r1.5 machmode.h
*** machmode.h	1998/10/01 16:47:37	1.5
--- machmode.h	1998/10/08 06:25:42
*************** extern unsigned char mode_wider_mode[];
*** 211,216 ****
--- 211,221 ----
  
  extern enum machine_mode mode_for_size PROTO((unsigned int, enum mode_class, int));
  
+ /* Return an integer mode of the exact same size as the input mode,
+    or BLKmode on failure.  */
+ 
+ extern enum machine_mode int_mode_for_mode PROTO((enum machine_mode));
+ 
  /* Find the best mode to use to access a bit field.  */
  
  extern enum machine_mode get_best_mode PROTO((int, int, int, enum machine_mode, int));
Index: stor-layout.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stor-layout.c,v
retrieving revision 1.19
diff -c -p -d -r1.19 stor-layout.c
*** stor-layout.c	1998/08/20 10:29:22	1.19
--- stor-layout.c	1998/10/08 06:25:42
*************** smallest_mode_for_size (size, class)
*** 176,181 ****
--- 176,212 ----
    abort ();
  }
  
+ /* Find an integer mode of the exact same size, or BLKmode on failure.  */
+ 
+ enum machine_mode
+ int_mode_for_mode (mode)
+      enum machine_mode mode;
+ {
+   switch (GET_MODE_CLASS (mode))
+     {
+     case MODE_INT:
+     case MODE_PARTIAL_INT:
+       break;
+ 
+     case MODE_COMPLEX_INT:
+     case MODE_COMPLEX_FLOAT:
+     case MODE_FLOAT:
+       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+       break;
+ 
+     case MODE_RANDOM:
+       if (mode == BLKmode)
+         break;
+       /* FALLTHRU */
+ 
+     case MODE_CC:
+     default:
+       abort();
+     }
+ 
+   return mode;
+ }
+ 
  /* Return the value of VALUE, rounded up to a multiple of DIVISOR.  */
  
  tree


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