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.