Thanks again to everyone who commented.  In sumnmary:

  - There was disagreement about whether subregs of hard registers
    should be phased out.  However, we still have some code to handle
    them, and they are still used today (at least by SPE).

  - A MODE_PARTIAL_INT mode behaves like the corresponding MODE_INT mode.

Does the updated documentation below look OK?

Richard


@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.

@code{subreg}s come in two distinct flavors, each having its own
usage and rules:

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

@smallexample
GET_MODE_SIZE (@var{m1}) > GET_MODE_SIZE (@var{m2})
@end smallexample

Paradoxical @code{subreg}s can be used as both lvalues and rvalues.
When used as an rvalue, the low-order bits of the @code{subreg} are
taken from @var{reg} while the high-order bits are left undefined.
When used as an lvalue, the low-order bits of the source value are
stored in @var{reg} and the high-order bits are discarded.

@var{bytenum} is always zero for a paradoxical @code{subreg}, even on
big-endian targets.

For example, the paradoxical @code{subreg}:

@smallexample
(set (subreg:SI (reg:HI @var{x}) 0) @var{y})
@end smallexample

stores the lower 2 bytes of @var{y} in @var{x} and discards the upper
2 bytes.  A subsequent:

@smallexample
(set @var{z} (subreg:SI (reg:HI @var{x}) 0))
@end smallexample

would set the lower two bytes of @var{z} to @var{y} and set the upper two
bytes to an unknown value.

@item Normal subregs 
When @var{m1} is at least as narrow as @var{m2} the @code{subreg}
expression is called @dfn{normal}.

Normal @code{subreg}s 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 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}.

@var{bytenum} must identify 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.  The memory order of bytes is defined by
two target macros, @code{WORDS_BIG_ENDIAN} and @code{BYTES_BIG_ENDIAN}:

@itemize
@item
@cindex @code{WORDS_BIG_ENDIAN}, effect on @code{subreg}
@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.

@item
@cindex @code{BYTES_BIG_ENDIAN}, effect on @code{subreg}
@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.
@end itemize

@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 @var{x}) 2)
@end smallexample

on a @code{BYTES_BIG_ENDIAN}, @samp{UNITS_PER_WORD == 4} target is the same as

@smallexample
(subreg:HI (reg:SI @var{x}) 0)
@end smallexample

on a little-endian, @samp{UNITS_PER_WORD == 4} target.  Both
@code{subreg}s access the lower two bytes of register @var{x}.

@end table

A @code{MODE_PARTIAL_INT} mode behaves as if it were as wide as the
corresponding @code{MODE_INT} mode, except that it has an unknown
number of undefined bits.  For example:

@smallexample
(subreg:PSI (reg:SI 0) 0)
@end smallexample

accesses the whole of @samp{(reg:SI 0)}, but the exact relationship
between the @code{PSImode} value and the @code{SImode} value is not
defined.  If we assume @samp{UNITS_PER_WORD <= 4}, then the following
two @code{subreg}s:

@smallexample
(subreg:PSI (reg:DI 0) 0)
(subreg:PSI (reg:DI 0) 4)
@end smallexample

represent independent 4-byte accesses to the two halves of
@samp{(reg:DI 0)}.  Both @code{subreg}s have an unknown number
of undefined bits.

If @samp{UNITS_PER_WORD <= 2} then these two @code{subreg}s:

@smallexample
(subreg:HI (reg:PSI 0) 0)
(subreg:HI (reg:PSI 0) 2)
@end smallexample

represent independent 2-byte accesses that together span the whole
of @samp{(reg:PSI 0)}.  Storing to the first @code{subreg} does not
affect the value of the second, and vice versa.  @samp{(reg:PSI 0)}
has an unknown number of undefined bits, so the assignment:

@smallexample
(set (subreg:HI (reg:PSI 0) 0) (reg:HI 4))
@end smallexample

does not guarantee that @samp{(subreg:HI (reg:PSI 0) 0)} has the
value @samp{(reg:HI 4)}.

@cindex @code{CANNOT_CHANGE_MODE_CLASS} and subreg semantics
The rules above apply to both pseudo @var{reg}s and hard @var{reg}s.
If the semantics are not correct for particular combinations of
@var{m1}, @var{m2} and hard @var{reg}, the target-specific code
must ensure that those combinations are never used.  For example:

@smallexample
CANNOT_CHANGE_MODE_CLASS (@var{m2}, @var{m1}, @var{class})
@end smallexample

must be true for every class @var{class} that includes @var{reg}.

@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.

Reply via email to