This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: SUBREG_BYTE question
- From: Bernd Schmidt <bernds at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: <gcc at gcc dot gnu dot org>
- Date: Tue, 26 Feb 2002 16:25:42 +0000 (GMT)
- Subject: Re: SUBREG_BYTE question
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;
}
First of all, it doesn't do anything for BYTES_BIG_ENDIAN, and even if
WORDS_BIG_ENDIAN, the SUBREG_BYTE field only seems to indicate the word
offset.
Also, see the comment in rtl.def:
/* One word of a multi-word value.
The first operand is the complete value; the second says which word.
The WORDS_BIG_ENDIAN flag controls whether word number 0
(as numbered in a SUBREG) is the most or least significant word.
This is also used to refer to a value in a different machine mode.
For example, it can be used to refer to a SImode value as if it were
Qimode, or vice versa. Then the word number is always 0. */
DEF_RTL_EXPR(SUBREG, "subreg", "ei", 'x')
Some ports use 0 (rs6000 - I assume their rotate patterns want to use the
low part, not the high part), others use 3 (m68k) for QImode subregs of
SImode values.
My feeling is that now, with the SUBREG_BYTE patch, the SUBREG rtx no
longer has any kind of defined semantics.
Bernd