#### 17.19.2 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 (see 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 nonzero 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 nonzero 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.

`(match_test c-expr)`

  The test is true if C expression c-expr is true. In non-constant attributes, c-expr has access to the following variables:

  insn

    The rtl instruction under test.

  which_alternative

    The `define_insn` alternative that insn matches. See Output Statement.

  operands

    An array of insn’s rtl operands.

  c-expr behaves like the condition in a C `if` statement, so there is no need to explicitly convert the expression into a boolean 0 or 1 value. For example, the following two tests are equivalent:

      (match_test "x & 2")
      (match_test "(x & 2) != 0")

`(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 (see 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` (see 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.

  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.

  `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.