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, 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


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