Many machines have requirements for their operands that cannot be
expressed precisely using the generic predicates. You can define
additional predicates using define_predicate
and
define_special_predicate
expressions. These expressions have
three operands:
match_operand
or match_operator
expressions.
MATCH_OPERAND
MATCH_OPERAND
expression evaluates to true if the predicate it names would allow
op. The operand number and constraint are ignored. Due to
limitations in genrecog, you can only refer to generic
predicates and predicates that have already been defined.
MATCH_CODE
The first operand of this expression is a string constant containing a
comma-separated list of RTX code names (in lower case). These are the
codes for which the MATCH_CODE
will be true.
The second operand is a string constant which indicates what
subexpression of op to examine. If it is absent or the empty
string, op itself is examined. Otherwise, the string constant
must be a sequence of digits and/or lowercase letters. Each character
indicates a subexpression to extract from the current expression; for
the first character this is op, for the second and subsequent
characters it is the result of the previous character. A digit
n extracts ‘XEXP (e, n)’; a letter l
extracts ‘XVECEXP (e, 0, n)’ where n is the
alphabetic ordinal of l (0 for `a', 1 for 'b', and so on). The
MATCH_CODE
then examines the RTX code of the subexpression
extracted by the complete string. It is not possible to extract
components of an rtvec
that is not at position 0 within its RTX
object.
MATCH_TEST
MATCH_TEST
evaluates to true if the C expression evaluates to a nonzero value.
MATCH_TEST
expressions must not have side effects.
AND
IOR
NOT
IF_THEN_ELSE
AND
or IOR
expression an
arbitrary number of arguments; this has exactly the same effect as
writing a chain of two-argument AND
or IOR
expressions.
If a code block is present in a predicate definition, then the RTL expression must evaluate to true and the code block must execute ‘return true’ for the predicate to allow the operand. The RTL expression is evaluated first; do not re-check anything in the code block that was checked in the RTL expression.
The program genrecog scans define_predicate
and
define_special_predicate
expressions to determine which RTX
codes are possibly allowed. You should always make this explicit in
the RTL predicate expression, using MATCH_OPERAND
and
MATCH_CODE
.
Here is an example of a simple predicate definition, from the IA64 machine description:
;; True if op is a SYMBOL_REF
which refers to the sdata section.
(define_predicate "small_addr_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_SMALL_ADDR_P (op)")))
And here is another, showing the use of the C block.
;; True if op is a register operand that is (or could be) a GR reg. (define_predicate "gr_register_operand" (match_operand 0 "register_operand") { unsigned int regno; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); regno = REGNO (op); return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno)); })
Predicates written with define_predicate
automatically include
a test that mode is VOIDmode
, or op has the same
mode as mode, or op is a CONST_INT
or
CONST_DOUBLE
. They do not check specifically for
integer CONST_DOUBLE
, nor do they test that the value of either
kind of constant fits in the requested mode. This is because
target-specific predicates that take constants usually have to do more
stringent value checks anyway. If you need the exact same treatment
of CONST_INT
or CONST_DOUBLE
that the generic predicates
provide, use a MATCH_OPERAND
subexpression to call
const_int_operand
, const_double_operand
, or
immediate_operand
.
Predicates written with define_special_predicate
do not get any
automatic mode checks, and are treated as having special mode handling
by genrecog.
The program genpreds is responsible for generating code to test predicates. It also writes a header file containing function declarations for all machine-specific predicates. It is not necessary to declare these predicates in cpu-protos.h.