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 Mon, Oct 05, 1998 at 10:12:44PM -0700, David S. Miller wrote:
> Look at what purge_addressof_1 looks at when this is compiled.  It
> look at something resembling:
> 
> (insn 18 15 19 (set (reg:QI 110)
>         (mem:QI (addressof:SI (reg:SF 108) 107) 0)) -1 (nil)
>     (nil))
> 
> And this is the source of the problem cases on big endian.

This is a red herring, since if big-endian were really the issue,
you'd have the same problem with (reg:SI 108).

Oddly, and much more significantly, is that when I'd looked at
some of these things on the Alpha, I saw that a wrapping

	(subreg:SI (reg:SF) 0) 

had been added for me, and so assumed the bit operations knew
how to handle all of this.  Seems I was wrong.

Consider the following.  Note that I'll still want to do a check
in purge_addressof_1 to make sure we're not XFmode or some nonsense
like that.  Note that the abort for pun == BLKmode could be 
changed to allocate a bit of stack.

Assuming you've no problems with this scheme in general, I'll
clean up those loose ends.


r~


	* expmed.c (store_bit_field): Pun non-integral storage modes.
	(extract_bit_field): Likewise.

Index: expmed.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expmed.c,v
retrieving revision 1.20
diff -c -p -d -r1.20 expmed.c
*** expmed.c	1998/09/23 16:24:09	1.20
--- expmed.c	1998/10/06 07:30:53
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 261,266 ****
--- 261,295 ----
        op0 = SUBREG_REG (op0);
      }
  
+   switch (GET_MODE_CLASS (GET_MODE (op0)))
+     {
+     case MODE_INT:
+     case MODE_PARTIAL_INT:
+       break;
+ 
+     case MODE_COMPLEX_INT:
+     case MODE_COMPLEX_FLOAT:
+     case MODE_FLOAT:
+       {
+ 	enum machine_mode pun;
+ 	pun = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op0)), MODE_INT, 0);
+ 	if (GET_CODE (op0) == MEM)
+ 	  op0 = change_address (op0, pun, NULL_RTX);
+ 	else if (pun != BLKmode)
+ 	  op0 = gen_lowpart (pun, op0);
+ 	else
+ 	  abort ();
+ 	break;
+       }
+ 
+     case MODE_RANDOM:
+       if (GET_MODE (op0) == BLKmode)
+ 	break;
+     case MODE_CC:
+     default:
+       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.  */
*************** extract_bit_field (str_rtx, bitsize, bit
*** 955,960 ****
--- 984,1018 ----
        op0 = SUBREG_REG (op0);
      }
  
+   switch (GET_MODE_CLASS (GET_MODE (op0)))
+     {
+     case MODE_INT:
+     case MODE_PARTIAL_INT:
+       break;
+ 
+     case MODE_COMPLEX_INT:
+     case MODE_COMPLEX_FLOAT:
+     case MODE_FLOAT:
+       {
+ 	enum machine_mode pun;
+ 	pun = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op0)), MODE_INT, 0);
+ 	if (GET_CODE (op0) == MEM)
+ 	  op0 = change_address (op0, pun, NULL_RTX);
+ 	else if (pun != BLKmode)
+ 	  op0 = gen_lowpart (pun, op0);
+ 	else
+ 	  abort ();
+ 	break;
+       }
+ 
+     case MODE_RANDOM:
+       if (GET_MODE (op0) == BLKmode)
+ 	break;
+     case MODE_CC:
+     default:
+       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
--- 1031,1037 ----
       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,1002 ****
  
        if (mode1 != GET_MODE (op0))
  	{
! 	  if (GET_CODE (op0) == REG)
  	    op0 = gen_rtx_SUBREG (mode1, op0, offset);
  	  else
  	    op0 = change_address (op0, mode1,
--- 1054,1060 ----
  
        if (mode1 != GET_MODE (op0))
  	{
! 	  if (GET_CODE (op0) != MEM)
  	    op0 = gen_rtx_SUBREG (mode1, op0, offset);
  	  else
  	    op0 = change_address (op0, mode1,
*************** 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
--- 1146,1157 ----
    /* 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]