Attribute Expressions
---------------------
RTL expressions used to define attributes use the codes described
above plus a few specific to attribute definitions, to be discussed
below. Attribute value expressions must have one of the following
forms:
`(const_int I)'
The integer I specifies the value of a numeric attribute. I must
be non-negative.
The value of a numeric attribute can be specified either with a
`const_int', or as an integer represented as a string in
`const_string', `eq_attr' (see below), `attr', `symbol_ref',
simple arithmetic expressions, and `set_attr' overrides on
specific instructions (Note:Tagging Insns.).
`(const_string VALUE)'
The string VALUE specifies a constant attribute value. If VALUE
is specified as `"*"', it means that the default value of the
attribute is to be used for the insn containing this expression.
`"*"' obviously cannot be used in the DEFAULT expression of a
`define_attr'.
If the attribute whose value is being specified is numeric, VALUE
must be a string containing a non-negative integer (normally
`const_int' would be used in this case). Otherwise, it must
contain one of the valid values for the attribute.
`(if_then_else TEST TRUE-VALUE FALSE-VALUE)'
TEST specifies an attribute test, whose format is defined below.
The value of this expression is TRUE-VALUE if TEST is true,
otherwise it is FALSE-VALUE.
`(cond [TEST1 VALUE1 ...] DEFAULT)'
The first operand of this expression is a vector containing an even
number of expressions and consisting of pairs of TEST and VALUE
expressions. The value of the `cond' expression is that of the
VALUE corresponding to the first true TEST expression. If none of
the TEST expressions are true, the value of the `cond' expression
is that of the DEFAULT expression.
TEST expressions can have one of the following forms:
`(const_int I)'
This test is true if I is non-zero and false otherwise.
`(not TEST)'
`(ior TEST1 TEST2)'
`(and TEST1 TEST2)'
These tests are true if the indicated logical function is true.
`(match_operand:M N PRED CONSTRAINTS)'
This test is true if operand N of the insn whose attribute value
is being determined has mode M (this part of the test is ignored
if M is `VOIDmode') and the function specified by the string PRED
returns a non-zero value when passed operand N and mode M (this
part of the test is ignored if PRED is the null string).
The CONSTRAINTS operand is ignored and should be the null string.
`(le ARITH1 ARITH2)'
`(leu ARITH1 ARITH2)'
`(lt ARITH1 ARITH2)'
`(ltu ARITH1 ARITH2)'
`(gt ARITH1 ARITH2)'
`(gtu ARITH1 ARITH2)'
`(ge ARITH1 ARITH2)'
`(geu ARITH1 ARITH2)'
`(ne ARITH1 ARITH2)'
`(eq ARITH1 ARITH2)'
These tests are true if the indicated comparison of the two
arithmetic expressions is true. Arithmetic expressions are formed
with `plus', `minus', `mult', `div', `mod', `abs', `neg', `and',
`ior', `xor', `not', `ashift', `lshiftrt', and `ashiftrt'
expressions.
`const_int' and `symbol_ref' are always valid terms (Note:Insn
Lengths.,for additional forms). `symbol_ref' is a string
denoting a C expression that yields an `int' when evaluated by the
`get_attr_...' routine. It should normally be a global variable.
`(eq_attr NAME VALUE)'
NAME is a string specifying the name of an attribute.
VALUE is a string that is either a valid value for attribute NAME,
a comma-separated list of values, or `!' followed by a value or
list. If VALUE does not begin with a `!', this test is true if
the value of the NAME attribute of the current insn is in the list
specified by VALUE. If VALUE begins with a `!', this test is true
if the attribute's value is *not* in the specified list.
For example,
(eq_attr "type" "load,store")
is equivalent to
(ior (eq_attr "type" "load") (eq_attr "type" "store"))
If NAME specifies an attribute of `alternative', it refers to the
value of the compiler variable `which_alternative' (Note:Output
Statement.) and the values must be small integers. For example,
(eq_attr "alternative" "2,3")
is equivalent to
(ior (eq (symbol_ref "which_alternative") (const_int 2))
(eq (symbol_ref "which_alternative") (const_int 3)))
Note that, for most attributes, an `eq_attr' test is simplified in
cases where the value of the attribute being tested is known for
all insns matching a particular pattern. This is by far the most
common case.
`(attr_flag NAME)'
The value of an `attr_flag' expression is true if the flag
specified by NAME is true for the `insn' currently being scheduled.
NAME is a string specifying one of a fixed set of flags to test.
Test the flags `forward' and `backward' to determine the direction
of a conditional branch. Test the flags `very_likely', `likely',
`very_unlikely', and `unlikely' to determine if a conditional
branch is expected to be taken.
If the `very_likely' flag is true, then the `likely' flag is also
true. Likewise for the `very_unlikely' and `unlikely' flags.
This example describes a conditional branch delay slot which can
be nullified for forward branches that are taken (annul-true) or
for backward branches which are not taken (annul-false).
(define_delay (eq_attr "type" "cbranch")
[(eq_attr "in_branch_delay" "true")
(and (eq_attr "in_branch_delay" "true")
(attr_flag "forward"))
(and (eq_attr "in_branch_delay" "true")
(attr_flag "backward"))])
The `forward' and `backward' flags are false if the current `insn'
being scheduled is not a conditional branch.
The `very_likely' and `likely' flags are true if the `insn' being
scheduled is not a conditional branch. The `very_unlikely' and
`unlikely' flags are false if the `insn' being scheduled is not a
conditional branch.
`attr_flag' is only used during delay slot scheduling and has no
meaning to other passes of the compiler.
`(attr NAME)'
The value of another attribute is returned. This is most useful
for numeric attributes, as `eq_attr' and `attr_flag' produce more
efficient code for non-numeric attributes.