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: [trunk] Addition to subreg section of rtl.text.


Jeff, DJ and Richard,

Richard Sandiford and I have taken on the task of trying to fully explain subregs in the gcc docs. This is an area where that traditionally has been very confusing to outsiders and even insiders who were not rtl maintainers. As the community of active developers has evolved, the complexity of this area is problematic to people new to the community.

We have attached a draft of the new section, however, there are many issues that we still do not understand. Could you please review the draft and take a few moments to answer the remaining questions? Also, if there are other subtleties that we have missed, please feel free to point us in the proper direction.

Of course, we also invite anyone in the community with experience here to comment. All help is appreciated.

1) Is it possible to have a MODE_PARTIAL_INT inner register that is bigger than a word? If so, what restrictions (if any) apply to subregs that access the partial word? Is the inner register implicitly extended so that it is a whole number of words? If not, are we effectively allowing non-contiguous byte ranges when WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN?

E.g., suppose we have a 16-bit WORDS_BIG_ENDIAN, !BYTES_BIG_ENDIAN target in which PSImode is a 24-bit value. Is the layout of 0x543210 "45..0123"?

2) Is it possible for the outer register in a normal subreg to be a superword MODE_PARTIAL_INT? (Our rules say "no".)

3) What about things like 80-bit FP modes on a 32-bit or 64-bit target? Is it valid to refer to pieces of an 80-bit FP pseudo? If so, are the rules we've got here right?

4) Do stores to subregs of hardreg invalidate just the registers mentioned in the outer mode or do they invalidate the entire set of registers mentioned in the inner mode? (our rules say only the outer mode).

Thanks in advance,

Kenny
@findex subreg
@item (subreg:@var{m1} @var{reg:m2} @var{bytenum})

@code{subreg} expressions are used to refer to a register in a machine
mode other than its natural one, or to refer to one register of
a multi-part @code{reg} that actually refers to several registers.

Each pseudo-register has a natural mode.  If it is necessary to
operate on it in a different mode, the pseudo-register must be
enclosed in a @code{subreg}.  It is seldom necessary to wrap
hard registers in @code{subreg}s; such registers would normally
reduce to a single @code{reg} rtx.

Subregs come in two distinct flavors, each having its own distinct
usage and rules:

@table
@item Paradoxical subregs
When @var{m1} is strictly wider than the
@var{m2}, the @code{subreg} expressions is called @dfn{paradoxical}.
The canonical test for this class of subreg is 

  @smallexample{GET_MODE_SIZE (m1) > GET_MODE_SIZE (m2)}.

Paradoxical subregs are used in cases where we want to refer to an
object in a wider mode but do not care what value the additional high
order bits have.  @var{Reg} is mapped into the low order bits.
Paradoxical subregs can be used as both lvalues and rvalues.   When
used as an lvalue, the high order bits are discarded.   @var{bytenum}
is always zero for a paradoxical register, even for big-endian targets.

@item Normal subregs 

When @var{m1} is at least as narrow as @var{m2} the @code{subreg}
expressions is called @dfn{normal}.

Normal subregs restrict consideration to certain bits of @var{reg}.
There are two cases.  If @var{m1} is smaller than a word, the
@code{subreg} refers to the least-significant part (or @dfn{lowpart})
of one word of @var{reg}.  If @var{m1} is word-sized or greater, the
@code{subreg} refers to one or more complete words.

When @var{m2} is larger than a word, the subreg is a @dfn{multi-word
outer subreg}.  When used as an lvalue, @code{subreg} is a word-based
accessor.  Storing to a @code{subreg} modifies all the words of
@var{reg} that overlap the @code{subreg}, but it leaves the other
words of @var{reg} alone.

When storing to a normal @code{subreg} that is smaller than a word,
the other bits of the referenced word are usually left in an undefined
state.  This laxity makes it easier to generate efficient code for
such instructions.  To represent an instruction that preserves all the
bits outside of those in the @code{subreg}, use @code{strict_low_part}
or @code{zero_extract} around the @code{subreg}.

If @var{reg} is a hard register, the @code{subreg} must also represent
the lowpart of a particular hard register, or represent one or more
complete hard registers.

@var{Bytenum} must identify the the offset of the first byte of the
@code{subreg} from the start of @var{reg}, assuming that @var{reg} is
laid out in memory order as defined by:

@cindex @code{WORDS_BIG_ENDIAN}, effect on @code{subreg}
The compilation parameter @code{WORDS_BIG_ENDIAN}, if set to 1, says
that byte number zero is part of the most significant word; otherwise,
it is part of the least significant word.

@cindex @code{BYTES_BIG_ENDIAN}, effect on @code{subreg}
The compilation parameter @code{BYTES_BIG_ENDIAN}, if set to 1, says
that byte number zero is the most significant byte within a word;
otherwise, it is the least significant byte within a word.

@cindex @code{FLOAT_WORDS_BIG_ENDIAN}, (lack of) effect on
@code{subreg} On a few targets, @code{FLOAT_WORDS_BIG_ENDIAN}
disagrees with @code{WORDS_BIG_ENDIAN}.  However, most parts of the
compiler treat floating point values as if they had the same
endianness as integer values.  This works because they handle them
solely as a collection of integer values, with no particular numerical
value.  Only real.c and the runtime libraries care about
@code{FLOAT_WORDS_BIG_ENDIAN}.

Thus, 

@smallexample{(subreg:HI (reg:SI X) 2)} 

on a @code{BYTES_BIG_ENDIAN} 32-bit target is the same as

@smallexample{(subreg:HI (reg:SI X) 0)} 

on a little endian 32-bit target.  Both of these access the low order
two bytes in the word.

@end table

@findex SUBREG_REG
@findex SUBREG_BYTE
The first operand of a @code{subreg} expression is customarily accessed
with the @code{SUBREG_REG} macro and the second operand is customarily
accessed with the @code{SUBREG_BYTE} macro.


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