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]

[PATCH] store_bit_field: Handle paradoxical subregs properly


Hi,

store_bit_field in expmed.c doesn't handle paradoxical subregs properly.
It should use the same logic simplify_subreg is using.

I don't have a testcase because the problem only occurred when using another
patch on top.

Bootstrapped on s390 and s390x with gcc 4.2 and gcc 4.1.
No testsuite regressions.

I will bootstrap and test this on i686 as well.

This patch is needed for another patch (I will post soon) fixing a gcc 4.1 
regression. So please consider approving this for mainline and 4.1.

Bye,

-Andreas-


2006-03-31  Andreas Krebbel  <krebbel1@de.ibm.com>

	* expmed.c (store_bit_field): Add special handling for paradoxical 
	subregs on big endian machines.


Index: gcc/expmed.c
===================================================================
*** gcc/expmed.c.orig	2006-03-13 09:29:23.000000000 +0100
--- gcc/expmed.c	2006-03-30 17:25:51.000000000 +0200
*************** store_bit_field (rtx str_rtx, unsigned H
*** 363,369 ****
  	 meaningful at a much higher level; when structures are copied
  	 between memory and regs, the higher-numbered regs
  	 always get higher addresses.  */
!       bitnum += SUBREG_BYTE (op0) * BITS_PER_UNIT;
        op0 = SUBREG_REG (op0);
      }
  
--- 363,387 ----
  	 meaningful at a much higher level; when structures are copied
  	 between memory and regs, the higher-numbered regs
  	 always get higher addresses.  */
!       int inner_mode_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)));
!       int outer_mode_size = GET_MODE_SIZE (GET_MODE (op0));
!       
!       byte_offset = 0;
! 
!       /* Paradoxical subregs need special handling on big endian machines.  */
!       if (SUBREG_BYTE (op0) == 0 && inner_mode_size < outer_mode_size)
! 	{
! 	  int difference = inner_mode_size - outer_mode_size;
! 
! 	  if (WORDS_BIG_ENDIAN)
! 	    byte_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
! 	  if (BYTES_BIG_ENDIAN)
! 	    byte_offset += difference % UNITS_PER_WORD;
! 	}
!       else
! 	byte_offset = SUBREG_BYTE (op0);
! 
!       bitnum += byte_offset * BITS_PER_UNIT;
        op0 = SUBREG_REG (op0);
      }
  


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