This is the mail archive of the gcc@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]

Re: SUBREG_BYTE question


On Tue, Feb 26, 2002 at 04:25:42PM +0000, Bernd Schmidt wrote:
> On Tue, 26 Feb 2002, Jakub Jelinek wrote:
> 
> > On Tue, Feb 26, 2002 at 01:35:35PM +0000, Bernd Schmidt wrote:
> > > I need to know the exact meaning of the SUBREG_BYTE field of a SUBREG.
> > > 
> > > Suppose I have a big-endian target, an SImode (which is the word size)
> > > register, and I want to use the part of the register in a narrower mode.
> > > Should SUBREG_BYTE be zero, or should it be equal to the offset that
> > > would be used if the value were in memory?
> > > 
> > > The problem I have is that I've got two testcases, and in one of these I
> > > get (subreg:HI (reg:SI xyz) 0) for the lowpart, and in the other I get
> > > (subreg:QI (reg:SI abc) 3).  Fixing one breaks the other.  Which one is
> > > correct?
> > 
> > (subreg:QI (reg:SI abc) 3) is correct.
> > On big-endian, (subreg:HI (reg:SI xyz) 0) means upper 16 bits of
> > 32 bit register xyz.
> 
> I got the (subreg:HI (reg:SI xyz) 0) straight out of gen_lowpart_common.  This
> happens on arm with -mbig-endian.
> 
> subreg_lowpart_offset doesn't agree with your statement:
> 
> /* Return offset in bytes to get OUTERMODE low part
>    of the value in mode INNERMODE stored in memory in target format.  */
> 
> unsigned int
> subreg_lowpart_offset (outermode, innermode)
>      enum machine_mode outermode, innermode;
> {
>   unsigned int offset = 0;
>   int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
> 
>   if (difference > 0)
>     {
>       if (WORDS_BIG_ENDIAN)
>         offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
>     }
> 
>   return offset;
> }

subreg_lowpart_offset contains also:
      if (BYTES_BIG_ENDIAN)
        offset += difference % UNITS_PER_WORD;

in the if above.
If you have a true big-endian (ie. WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN == 1),
then subreg_lowpart_offset (QImode, SImode) == 3.
For true little-endian it is 0, for PDP-like endian (ie.
when WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN, this depends on what's word
on that machine).
SUBREG_BYTE is 0 for paradoxical subregs, otherwise it is memory offset
if you store the innermode register into memory and want to
locate outermode value.

	Jakub


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