The expression codes described so far represent values, not actions. But machine instructions never produce values; they are meaningful only for their side effects on the state of the machine. Special expression codes are used to represent side effects.
The body of an instruction is always one of these side effect codes; the codes described above, which represent values, appear only as the operands of these.
(set lval x)
cc0. If lval is a
mem, it has a machine mode; then x must be valid for that mode. If lval is a
regwhose machine mode is less than the full width of the register, then it means that the part of the register specified by the machine mode is given the specified value and the rest of the register receives an undefined value. Likewise, if lval is a
subregwhose machine mode is narrower than the mode of the register, the rest of the register can be changed in an undefined way. If lval is a
subreg, then the part of the register specified by the machine mode of the
subregis given the value x and the rest of the register is not changed. If lval is
(cc0), it has no machine mode, and x may be either a
compareexpression or a value that may have any mode. The latter case represents a "test" instruction. The expression
(set (cc0) (reg:m n))is equivalent to
(set (cc0) (compare (reg:m n) (const_int 0))). Use the former expression to save space during the compilation. If lval is
(pc), we have a jump instruction, and the possibilities for x are very limited. It may be a
label_refexpression (unconditional jump). It may be an
if_then_else(conditional jump), in which case either the second or the third operand must be
(pc)(for the case which does not jump) and the other of the two must be a
label_ref(for the case which does jump). x may also be a
(plus:SI (pc) y), where y may be a
mem; these unusual patterns are used to represent jumps through branch tables. If lval is neither
(pc), the mode of lval must not be
VOIDmodeand the mode of x must be valid for the mode of lval. lval is customarily accessed with the
SET_DESTmacro and x with the
returnexpression code is never used. Inside an
if_then_elseexpression, represents the value to be placed in
pcto return to the caller. Note that an insn pattern of
(return)is logically equivalent to
(set (pc) (return)), but the latter form is never used.
(call function nargs)
memexpression whose address is the address of the function to be called. nargs is an expression which can be used for two purposes: on some machines it represents the number of bytes of stack argument; on others, it represents the number of argument registers. Each machine has a standard machine mode which function must have. The machine description defines macro
FUNCTION_MODEto expand into the requisite mode name. The purpose of this mode is to specify what kind of addressing is allowed, on machines where the allowed kinds of addressing depend on the machine mode being addressed.
memexpression. One place this is used is in string instructions that store standard values into particular hard registers. It may not be worth the trouble to describe the values that are stored, but it is essential to inform the compiler that the registers will be altered, lest it attempt to keep data in them across the string instruction. If x is
(mem:BLK (const_int 0)), it means that all memory locations must be presumed clobbered. Note that the machine description classifies certain hard registers as "call-clobbered". All function call instructions are assumed by default to clobber these registers, so there is no need to use
clobberexpressions to indicate this fact. Also, each function call is assumed to have the potential to alter any memory location, unless the function is declared
const. If the last group of expressions in a
parallelare each a
clobberexpression whose arguments are
match_scratch(see section RTL Template) expressions, the combiner phase can add the appropriate
clobberexpressions to an insn it has constructed when doing so will cause a pattern to be matched. This feature can be used, for example, on a machine that whose multiply and add instructions don't use an MQ register but which has an add-accumulate instruction that does clobber the MQ register. Similarly, a combined instruction might require a temporary register while the constituent instructions might not. When a
clobberexpression for a register appears inside a
parallelwith other side effects, the register allocator guarantees that the register is unoccupied both before and after that insn. However, the reload phase may allocate a register used for one of the inputs unless the `&' constraint is specified for the selected alternative (see section Constraint Modifier Characters). You can clobber either a specific hard register, a pseudo register, or a
scratchexpression; in the latter two cases, GNU CC will allocate a hard register that is available there for use as a temporary. For instructions that require a temporary register, you should use
scratchinstead of a pseudo-register because this will allow the combiner phase to add the
clobberwhen required. You do this by coding (
match_scratch...)). If you do clobber a pseudo register, use one which appears nowhere else--generate a new one each time. Otherwise, you may confuse CSE. There is one other known use for clobbering a pseudo register in a
parallel: when one of the input operands of the insn is also clobbered by the insn. In this case, using the same pseudo register in the clobber and elsewhere in the insn produces the expected results.
regexpression. During the reload phase, an insn that has a
useas pattern can carry a reg_equal note. These
useinsns will be deleted before the reload phase exits. During the delayed branch scheduling phase, x may be an insn. This indicates that x previously was located at this place in the code and its data dependencies need to be taken into account. These
useinsns will be deleted before the delayed branch scheduling phase exits.
(parallel [x0 x1 ...])
parallelis a vector of expressions. x0, x1 and so on are individual side effect expressions--expressions of code
use. "In parallel" means that first all the values used in the individual side-effects are computed, and second all the actual side-effects are performed. For example,
(parallel [(set (reg:SI 1) (mem:SI (reg:SI 1))) (set (mem:SI (reg:SI 1)) (reg:SI 1))])says unambiguously that the values of hard register 1 and the memory location addressed by it are interchanged. In both places where
(reg:SI 1)appears as a memory address it refers to the value in register 1 before the execution of the insn. It follows that it is incorrect to use
paralleland expect the result of one
setto be available for the next one. For example, people sometimes attempt to represent a jump-if-zero instruction this way:
(parallel [(set (cc0) (reg:SI 34)) (set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref ...) (pc)))])But this is incorrect, because it says that the jump condition depends on the condition code value before this instruction, not on the new value that is set by this instruction. Peephole optimization, which takes place together with final assembly code output, can produce insns whose patterns consist of a
parallelwhose elements are the operands needed to output the resulting assembler code--often
memor constant expressions. This would not be well-formed RTL at any other stage in compilation, but it is ok then because no further optimization remains to be done. However, the definition of the macro
NOTICE_UPDATE_CC, if any, must deal with such insns if you define any peephole optimizations.
(sequence [insns ...])
sequenceRTX is never placed in an actual insn during RTL generation. It represents the sequence of insns that result from a
define_expandbefore those insns are passed to
emit_insnto insert them in the chain of insns. When actually inserted, the individual sub-insns are separated out and the
sequenceis forgotten. After delay-slot scheduling is completed, an insn and all the insns that reside in its delay slots are grouped together into a
sequence. The insn requiring the delay slot is the first insn in the vector; subsequent insns are to be placed in the delay slot.
INSN_ANNULLED_BRANCH_Pis set on an insn in a delay slot to indicate that a branch insn should be used that will conditionally annul the effect of the insns in the delay slots. In such a case,
INSN_FROM_TARGET_Pindicates that the insn is from the target of the branch and should be executed only if the branch is taken; otherwise the insn should be executed only if the branch is not taken. See section Delay Slot Scheduling.
These expression codes appear in place of a side effect, as the body of an insn, though strictly speaking they do not always describe side effects as such:
(unspec [operands ...] index)
(unspec_volatile [operands ...] index)
unspec_volatileis used for volatile operations and operations that may trap;
unspecis used for other operations. These codes may appear inside a
patternof an insn, inside a
parallel, or inside an expression.
(addr_vec:m [lr0 lr1 ...])
label_refexpressions. The mode m specifies how much space is given to each address; normally m would be
(addr_diff_vec:m base [lr0 lr1 ...] min max flags)
label_refexpressions and so is base. The mode m specifies how much space is given to each address-difference. min and max are set up by branch shortening and hold a label with a minimum and a maximum address, respectively. flags indicates the relative position of base, min and max to the cointaining insn and of min and max to base. See rtl.def for details.