gccint: Regs and Memory
1
1 14.8 Registers and Memory
1 =========================
1
1 Here are the RTL expression types for describing access to machine
1 registers and to main memory.
1
1 '(reg:M N)'
1 For small values of the integer N (those that are less than
1 'FIRST_PSEUDO_REGISTER'), this stands for a reference to machine
1 register number N: a "hard register". For larger values of N, it
1 stands for a temporary value or "pseudo register". The compiler's
1 strategy is to generate code assuming an unlimited number of such
1 pseudo registers, and later convert them into hard registers or
1 into memory references.
1
1 M is the machine mode of the reference. It is necessary because
1 machines can generally refer to each register in more than one
1 mode. For example, a register may contain a full word but there
1 may be instructions to refer to it as a half word or as a single
1 byte, as well as instructions to refer to it as a floating point
1 number of various precisions.
1
1 Even for a register that the machine can access in only one mode,
1 the mode must always be specified.
1
1 The symbol 'FIRST_PSEUDO_REGISTER' is defined by the machine
1 description, since the number of hard registers on the machine is
1 an invariant characteristic of the machine. Note, however, that
1 not all of the machine registers must be general registers. All
1 the machine registers that can be used for storage of data are
1 given hard register numbers, even those that can be used only in
1 certain instructions or can hold only certain types of data.
1
1 A hard register may be accessed in various modes throughout one
1 function, but each pseudo register is given a natural mode and is
1 accessed only in that mode. When it is necessary to describe an
1 access to a pseudo register using a nonnatural mode, a 'subreg'
1 expression is used.
1
1 A 'reg' expression with a machine mode that specifies more than one
1 word of data may actually stand for several consecutive registers.
1 If in addition the register number specifies a hardware register,
1 then it actually represents several consecutive hardware registers
1 starting with the specified one.
1
1 Each pseudo register number used in a function's RTL code is
1 represented by a unique 'reg' expression.
1
1 Some pseudo register numbers, those within the range of
1 'FIRST_VIRTUAL_REGISTER' to 'LAST_VIRTUAL_REGISTER' only appear
1 during the RTL generation phase and are eliminated before the
1 optimization phases. These represent locations in the stack frame
1 that cannot be determined until RTL generation for the function has
1 been completed. The following virtual register numbers are
1 defined:
1
1 'VIRTUAL_INCOMING_ARGS_REGNUM'
1 This points to the first word of the incoming arguments passed
1 on the stack. Normally these arguments are placed there by
1 the caller, but the callee may have pushed some arguments that
1 were previously passed in registers.
1
1 When RTL generation is complete, this virtual register is
1 replaced by the sum of the register given by
1 'ARG_POINTER_REGNUM' and the value of 'FIRST_PARM_OFFSET'.
1
1 'VIRTUAL_STACK_VARS_REGNUM'
1 If 'FRAME_GROWS_DOWNWARD' is defined to a nonzero value, this
1 points to immediately above the first variable on the stack.
1 Otherwise, it points to the first variable on the stack.
1
1 'VIRTUAL_STACK_VARS_REGNUM' is replaced with the sum of the
1 register given by 'FRAME_POINTER_REGNUM' and the value
1 'TARGET_STARTING_FRAME_OFFSET'.
1
1 'VIRTUAL_STACK_DYNAMIC_REGNUM'
1 This points to the location of dynamically allocated memory on
1 the stack immediately after the stack pointer has been
1 adjusted by the amount of memory desired.
1
1 This virtual register is replaced by the sum of the register
1 given by 'STACK_POINTER_REGNUM' and the value
1 'STACK_DYNAMIC_OFFSET'.
1
1 'VIRTUAL_OUTGOING_ARGS_REGNUM'
1 This points to the location in the stack at which outgoing
1 arguments should be written when the stack is pre-pushed
1 (arguments pushed using push insns should always use
1 'STACK_POINTER_REGNUM').
1
1 This virtual register is replaced by the sum of the register
1 given by 'STACK_POINTER_REGNUM' and the value
1 'STACK_POINTER_OFFSET'.
1
1 '(subreg:M1 REG:M2 BYTENUM)'
1
1 'subreg' expressions are used to refer to a register in a machine
1 mode other than its natural one, or to refer to one register of a
1 multi-part 'reg' that actually refers to several registers.
1
1 Each pseudo register has a natural mode. If it is necessary to
1 operate on it in a different mode, the register must be enclosed in
1 a 'subreg'.
1
1 There are currently three supported types for the first operand of
1 a 'subreg':
1 * pseudo registers This is the most common case. Most 'subreg's
1 have pseudo 'reg's as their first operand.
1
1 * mem 'subreg's of 'mem' were common in earlier versions of GCC
1 and are still supported. During the reload pass these are
1 replaced by plain 'mem's. On machines that do not do
1 instruction scheduling, use of 'subreg's of 'mem' are still
1 used, but this is no longer recommended. Such 'subreg's are
1 considered to be 'register_operand's rather than
1 'memory_operand's before and during reload. Because of this,
1 the scheduling passes cannot properly schedule instructions
1 with 'subreg's of 'mem', so for machines that do scheduling,
1 'subreg's of 'mem' should never be used. To support this, the
1 combine and recog passes have explicit code to inhibit the
1 creation of 'subreg's of 'mem' when 'INSN_SCHEDULING' is
1 defined.
1
1 The use of 'subreg's of 'mem' after the reload pass is an area
1 that is not well understood and should be avoided. There is
1 still some code in the compiler to support this, but this code
1 has possibly rotted. This use of 'subreg's is discouraged and
1 will most likely not be supported in the future.
1
1 * hard registers It is seldom necessary to wrap hard registers
1 in 'subreg's; such registers would normally reduce to a single
1 'reg' rtx. This use of 'subreg's is discouraged and may not
1 be supported in the future.
1
1 'subreg's of 'subreg's are not supported. Using
1 'simplify_gen_subreg' is the recommended way to avoid this problem.
1
1 'subreg's come in two distinct flavors, each having its own usage
1 and rules:
1
1 Paradoxical subregs
1 When M1 is strictly wider than M2, the 'subreg' expression is
1 called "paradoxical". The canonical test for this class of
1 'subreg' is:
1
1 paradoxical_subreg_p (M1, M2)
1
1 Paradoxical 'subreg's can be used as both lvalues and rvalues.
1 When used as an lvalue, the low-order bits of the source value
1 are stored in REG and the high-order bits are discarded. When
1 used as an rvalue, the low-order bits of the 'subreg' are
1 taken from REG while the high-order bits may or may not be
1 defined.
1
1 The high-order bits of rvalues are defined in the following
1 circumstances:
1
1 * 'subreg's of 'mem' When M2 is smaller than a word, the
1 macro 'LOAD_EXTEND_OP', can control how the high-order
1 bits are defined.
1
1 * 'subreg' of 'reg's The upper bits are defined when
1 'SUBREG_PROMOTED_VAR_P' is true.
1 'SUBREG_PROMOTED_UNSIGNED_P' describes what the upper
1 bits hold. Such subregs usually represent local
1 variables, register variables and parameter pseudo
1 variables that have been promoted to a wider mode.
1
1 BYTENUM is always zero for a paradoxical 'subreg', even on
1 big-endian targets.
1
1 For example, the paradoxical 'subreg':
1
1 (set (subreg:SI (reg:HI X) 0) Y)
1
1 stores the lower 2 bytes of Y in X and discards the upper 2
1 bytes. A subsequent:
1
1 (set Z (subreg:SI (reg:HI X) 0))
1
1 would set the lower two bytes of Z to Y and set the upper two
1 bytes to an unknown value assuming 'SUBREG_PROMOTED_VAR_P' is
1 false.
1
1 Normal subregs
1 When M1 is at least as narrow as M2 the 'subreg' expression is
1 called "normal".
1
1 Normal 'subreg's restrict consideration to certain bits of
1 REG. For this purpose, REG is divided into
1 individually-addressable blocks in which each block has:
1
1 REGMODE_NATURAL_SIZE (M2)
1
1 bytes. Usually the value is 'UNITS_PER_WORD'; that is, most
1 targets usually treat each word of a register as being
1 independently addressable.
1
1 There are two types of normal 'subreg'. If M1 is known to be
1 no bigger than a block, the 'subreg' refers to the
1 least-significant part (or "lowpart") of one block of REG. If
1 M1 is known to be larger than a block, the 'subreg' refers to
1 two or more complete blocks.
1
1 When used as an lvalue, 'subreg' is a block-based accessor.
1 Storing to a 'subreg' modifies all the blocks of REG that
1 overlap the 'subreg', but it leaves the other blocks of REG
1 alone.
1
1 When storing to a normal 'subreg' that is smaller than a
1 block, the other bits of the referenced block are usually left
1 in an undefined state. This laxity makes it easier to
1 generate efficient code for such instructions. To represent
1 an instruction that preserves all the bits outside of those in
1 the 'subreg', use 'strict_low_part' or 'zero_extract' around
1 the 'subreg'.
1
1 BYTENUM must identify the offset of the first byte of the
1 'subreg' from the start of REG, assuming that REG is laid out
1 in memory order. The memory order of bytes is defined by two
1 target macros, 'WORDS_BIG_ENDIAN' and 'BYTES_BIG_ENDIAN':
1
1 * 'WORDS_BIG_ENDIAN', if set to 1, says that byte number
1 zero is part of the most significant word; otherwise, it
1 is part of the least significant word.
1
1 * 'BYTES_BIG_ENDIAN', if set to 1, says that byte number
1 zero is the most significant byte within a word;
1 otherwise, it is the least significant byte within a
1 word.
1
1 On a few targets, 'FLOAT_WORDS_BIG_ENDIAN' disagrees with
1 'WORDS_BIG_ENDIAN'. However, most parts of the compiler treat
1 floating point values as if they had the same endianness as
1 integer values. This works because they handle them solely as
1 a collection of integer values, with no particular numerical
1 value. Only real.c and the runtime libraries care about
1 'FLOAT_WORDS_BIG_ENDIAN'.
1
1 Thus,
1
1 (subreg:HI (reg:SI X) 2)
1
1 on a 'BYTES_BIG_ENDIAN', 'UNITS_PER_WORD == 4' target is the
1 same as
1
1 (subreg:HI (reg:SI X) 0)
1
1 on a little-endian, 'UNITS_PER_WORD == 4' target. Both
1 'subreg's access the lower two bytes of register X.
1
1 Note that the byte offset is a polynomial integer; it may not
1 be a compile-time constant on targets with variable-sized
1 modes. However, the restrictions above mean that there are
1 only a certain set of acceptable offsets for a given
1 combination of M1 and M2. The compiler can always tell which
1 blocks a valid subreg occupies, and whether the subreg is a
1 lowpart of a block.
1
1 A 'MODE_PARTIAL_INT' mode behaves as if it were as wide as the
1 corresponding 'MODE_INT' mode, except that it has an unknown number
1 of undefined bits. For example:
1
1 (subreg:PSI (reg:SI 0) 0)
1
1 accesses the whole of '(reg:SI 0)', but the exact relationship
1 between the 'PSImode' value and the 'SImode' value is not defined.
1 If we assume 'REGMODE_NATURAL_SIZE (DImode) <= 4', then the
1 following two 'subreg's:
1
1 (subreg:PSI (reg:DI 0) 0)
1 (subreg:PSI (reg:DI 0) 4)
1
1 represent independent 4-byte accesses to the two halves of '(reg:DI
1 0)'. Both 'subreg's have an unknown number of undefined bits.
1
1 If 'REGMODE_NATURAL_SIZE (PSImode) <= 2' then these two 'subreg's:
1
1 (subreg:HI (reg:PSI 0) 0)
1 (subreg:HI (reg:PSI 0) 2)
1
1 represent independent 2-byte accesses that together span the whole
1 of '(reg:PSI 0)'. Storing to the first 'subreg' does not affect
1 the value of the second, and vice versa. '(reg:PSI 0)' has an
1 unknown number of undefined bits, so the assignment:
1
1 (set (subreg:HI (reg:PSI 0) 0) (reg:HI 4))
1
1 does not guarantee that '(subreg:HI (reg:PSI 0) 0)' has the value
1 '(reg:HI 4)'.
1
1 The rules above apply to both pseudo REGs and hard REGs. If the
1 semantics are not correct for particular combinations of M1, M2 and
1 hard REG, the target-specific code must ensure that those
1 combinations are never used. For example:
1
1 TARGET_CAN_CHANGE_MODE_CLASS (M2, M1, CLASS)
1
1 must be false for every class CLASS that includes REG.
1
1 GCC must be able to determine at compile time whether a subreg is
1 paradoxical, whether it occupies a whole number of blocks, or
1 whether it is a lowpart of a block. This means that certain
1 combinations of variable-sized mode are not permitted. For
1 example, if M2 holds N 'SI' values, where N is greater than zero,
1 it is not possible to form a 'DI' 'subreg' of it; such a 'subreg'
1 would be paradoxical when N is 1 but not when N is greater than 1.
1
1 The first operand of a 'subreg' expression is customarily accessed
1 with the 'SUBREG_REG' macro and the second operand is customarily
1 accessed with the 'SUBREG_BYTE' macro.
1
1 It has been several years since a platform in which
1 'BYTES_BIG_ENDIAN' not equal to 'WORDS_BIG_ENDIAN' has been tested.
1 Anyone wishing to support such a platform in the future may be
1 confronted with code rot.
1
1 '(scratch:M)'
1 This represents a scratch register that will be required for the
1 execution of a single instruction and not used subsequently. It is
1 converted into a 'reg' by either the local register allocator or
1 the reload pass.
1
11 'scratch' is usually present inside a 'clobber' operation (⇒
Side Effects).
1
1 '(cc0)'
1 This refers to the machine's condition code register. It has no
1 operands and may not have a machine mode. There are two ways to
1 use it:
1
1 * To stand for a complete set of condition code flags. This is
1 best on most machines, where each comparison sets the entire
1 series of flags.
1
1 With this technique, '(cc0)' may be validly used in only two
1 contexts: as the destination of an assignment (in test and
1 compare instructions) and in comparison operators comparing
1 against zero ('const_int' with value zero; that is to say,
1 'const0_rtx').
1
1 * To stand for a single flag that is the result of a single
1 condition. This is useful on machines that have only a single
1 flag bit, and in which comparison instructions must specify
1 the condition to test.
1
1 With this technique, '(cc0)' may be validly used in only two
1 contexts: as the destination of an assignment (in test and
1 compare instructions) where the source is a comparison
1 operator, and as the first operand of 'if_then_else' (in a
1 conditional branch).
1
1 There is only one expression object of code 'cc0'; it is the value
1 of the variable 'cc0_rtx'. Any attempt to create an expression of
1 code 'cc0' will return 'cc0_rtx'.
1
1 Instructions can set the condition code implicitly. On many
1 machines, nearly all instructions set the condition code based on
1 the value that they compute or store. It is not necessary to
1 record these actions explicitly in the RTL because the machine
1 description includes a prescription for recognizing the
1 instructions that do so (by means of the macro 'NOTICE_UPDATE_CC').
1 ⇒Condition Code. Only instructions whose sole purpose is to
1 set the condition code, and instructions that use the condition
1 code, need mention '(cc0)'.
1
1 On some machines, the condition code register is given a register
1 number and a 'reg' is used instead of '(cc0)'. This is usually the
1 preferable approach if only a small subset of instructions modify
1 the condition code. Other machines store condition codes in
1 general registers; in such cases a pseudo register should be used.
1
1 Some machines, such as the SPARC and RS/6000, have two sets of
1 arithmetic instructions, one that sets and one that does not set
1 the condition code. This is best handled by normally generating
1 the instruction that does not set the condition code, and making a
1 pattern that both performs the arithmetic and sets the condition
1 code register (which would not be '(cc0)' in this case). For
1 examples, search for 'addcc' and 'andcc' in 'sparc.md'.
1
1 '(pc)'
1 This represents the machine's program counter. It has no operands
1 and may not have a machine mode. '(pc)' may be validly used only
1 in certain specific contexts in jump instructions.
1
1 There is only one expression object of code 'pc'; it is the value
1 of the variable 'pc_rtx'. Any attempt to create an expression of
1 code 'pc' will return 'pc_rtx'.
1
1 All instructions that do not jump alter the program counter
1 implicitly by incrementing it, but there is no need to mention this
1 in the RTL.
1
1 '(mem:M ADDR ALIAS)'
1 This RTX represents a reference to main memory at an address
1 represented by the expression ADDR. M specifies how large a unit
1 of memory is accessed. ALIAS specifies an alias set for the
1 reference. In general two items are in different alias sets if
1 they cannot reference the same memory address.
1
1 The construct '(mem:BLK (scratch))' is considered to alias all
1 other memories. Thus it may be used as a memory barrier in
1 epilogue stack deallocation patterns.
1
1 '(concatM RTX RTX)'
1 This RTX represents the concatenation of two other RTXs. This is
1 used for complex values. It should only appear in the RTL attached
1 to declarations and during RTL generation. It should not appear in
1 the ordinary insn chain.
1
1 '(concatnM [RTX ...])'
1 This RTX represents the concatenation of all the RTX to make a
1 single value. Like 'concat', this should only appear in
1 declarations, and not in the insn chain.
1