The RTL template is used to define which insns match the particular pattern and how to find their operands. For named patterns, the RTL template also says how to construct an insn from specified operands.
Construction involves substituting specified operands into a copy of the template. Matching involves determining the values that serve as the operands in the insn being matched. Both of these activities are controlled by special expression types that direct matching and substitution of the operands.
(match_operand:m n predicate constraint)
Operand numbers must be chosen consecutively counting from zero in each instruction pattern. There may be only one match_operand
expression in the pattern for each operand number. Usually operands are numbered in the order of appearance in match_operand
expressions.
predicate is a string that is the name of a C function that accepts two arguments, an expression and a machine mode. During matching, the function will be called with the putative operand as the expression and m as the mode argument (if m is not specified, VOIDmode
will be used, which normally causes predicate to accept any mode). If it returns zero, this instruction pattern fails to match. predicate may be an empty string; then it means no test is to be done on the operand, so anything which occurs in this position is valid.
Most of the time, predicate will reject modes other than m---but not always. For example, the predicate address_operand
uses m as the mode of memory ref that the address should be valid for. Many predicates accept const_int
nodes even though their mode is VOIDmode
.
constraint controls reloading and the choice of the best register class to use for a value, as explained later (see Constraints).
People are often unclear on the difference between the constraint and the predicate. The predicate helps decide whether a given insn matches the pattern. The constraint plays no role in this decision; instead, it controls various decisions in the case of an insn which does match.
On CISC machines, the most common predicate is "general_operand"
. This function checks that the putative operand is either a constant, a register or a memory reference, and that it is valid for mode m.
For an operand that must be a register, predicate should be "register_operand"
. Using "general_operand"
would be valid, since the reload pass would copy any non-register operands through registers, but this would make GNU CC do extra work, it would prevent invariant operands (such as constant) from being removed from loops, and it would prevent the register allocator from doing the best possible job. On RISC machines, it is usually most efficient to allow predicate to accept only objects that the constraints allow.
For an operand that must be a constant, you must be sure to either use "immediate_operand"
for predicate, or make the instruction pattern's extra condition require a constant, or both. You cannot expect the constraints to do this work! If the constraints allow only constants, but the predicate allows something else, the compiler will crash when that case arises.
(match_scratch:m n constraint)
scratch
or reg
expression. When matching patterns, this is equivalent to
(match_operand:m n "scratch_operand" pred)
but, when generating RTL, it produces a (scratch
:m) expression.
If the last few expressions in a parallel
are clobber
expressions whose operands are either a hard register or match_scratch
, the combiner can add or delete them when necessary. See Side Effects.
(match_dup n)
In construction, match_dup
acts just like match_operand
: the operand is substituted into the insn being constructed. But in matching, match_dup
behaves differently. It assumes that operand number n has already been determined by a match_operand
appearing earlier in the recognition template, and it matches only an identical-looking expression.
(match_operator:m n predicate [operands...])
When constructing an insn, it stands for an RTL expression whose expression code is taken from that of operand n, and whose operands are constructed from the patterns operands.
When matching an expression, it matches an expression if the function predicate returns nonzero on that expression and the patterns operands match the operands of the expression.
Suppose that the function commutative_operator
is defined as follows, to match any expression whose operator is one of the commutative arithmetic operators of RTL and whose mode is mode:
int commutative_operator (x, mode) rtx x; enum machine_mode mode; { enum rtx_code code = GET_CODE (x); if (GET_MODE (x) != mode) return 0; return (GET_RTX_CLASS (code) == 'c' || code == EQ || code == NE); }
Then the following pattern will match any RTL expression consisting of a commutative operator applied to two general operands:
(match_operator:SI 3 "commutative_operator" [(match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")])
Here the vector [operands...]
contains two patterns because the expressions to be matched all contain two operands.
When this pattern does match, the two operands of the commutative operator are recorded as operands 1 and 2 of the insn. (This is done by the two instances of match_operand
.) Operand 3 of the insn will be the entire commutative expression: use GET_CODE (operands[3])
to see which commutative operator was used.
The machine mode m of match_operator
works like that of match_operand
: it is passed as the second argument to the predicate function, and that function is solely responsible for deciding whether the expression to be matched ``has'' that mode.
When constructing an insn, argument 3 of the gen-function will specify the operation (i.e. the expression code) for the expression to be made. It should be an RTL expression, whose expression code is copied into a new expression whose operands are arguments 1 and 2 of the gen-function. The subexpressions of argument 3 are not used; only its expression code matters.
When match_operator
is used in a pattern for matching an insn, it usually best if the operand number of the match_operator
is higher than that of the actual operands of the insn. This improves register allocation because the register allocator often looks at operands 1 and 2 of insns to see if it can do register tying.
There is no way to specify constraints in match_operator
. The operand of the insn which corresponds to the match_operator
never has any constraints because it is never reloaded as a whole. However, if parts of its operands are matched by match_operand
patterns, those parts may have constraints of their own.
(match_op_dup:m n[operands...])
match_dup
, except that it applies to operators instead of operands. When constructing an insn, operand number n will be substituted at this point. But in matching, match_op_dup
behaves differently. It assumes that operand number n has already been determined by a match_operator
appearing earlier in the recognition template, and it matches only an identical-looking expression.
(match_parallel n predicate [subpat...])
parallel
expression with a variable number of elements. This expression should only appear at the top level of an insn pattern.
When constructing an insn, operand number n will be substituted at this point. When matching an insn, it matches if the body of the insn is a parallel
expression with at least as many elements as the vector of subpat expressions in the match_parallel
, if each subpat matches the corresponding element of the parallel
, and the function predicate returns nonzero on the parallel
that is the body of the insn. It is the responsibility of the predicate to validate elements of the parallel
beyond those listed in the match_parallel
.
A typical use of match_parallel
is to match load and store multiple expressions, which can contain a variable number of elements in a parallel
. For example,
(define_insn "" [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 1 "gpc_reg_operand" "=r") (match_operand:SI 2 "memory_operand" "m")) (use (reg:SI 179)) (clobber (reg:SI 179))])] "" "loadm 0,0,%1,%2")
This example comes from `a29k.md'. The function load_multiple_operations
is defined in `a29k.c' and checks that subsequent elements in the parallel
are the same as the set
in the pattern, except that they are referencing subsequent registers and memory locations.
An insn that matches this pattern might look like:
(parallel [(set (reg:SI 20) (mem:SI (reg:SI 100))) (use (reg:SI 179)) (clobber (reg:SI 179)) (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 100) (const_int 4)))) (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 100) (const_int 8))))])
(match_par_dup n [subpat...])
match_op_dup
, but for match_parallel
instead of match_operator
.
(address (match_operand:m n "address_operand" ""))
address
expressions never appear in RTL code, only in machine descriptions. And they are used only in machine descriptions that do not use the operand constraint feature. When operand constraints are in use, the letter `p' in the constraint serves this purpose.
m is the machine mode of the memory location being addressed, not the machine mode of the address itself. That mode is always the same on a given target machine (it is Pmode
, which normally is SImode
), so there is no point in mentioning it; thus, no machine mode is written in the address
expression. If some day support is added for machines in which addresses of different kinds of objects appear differently or are used differently (such as the PDP-10), different formats would perhaps need different machine modes and these modes might be written in the address
expression.