This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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