Disable Insn Alternatives - GNU Compiler Collection (GCC) Internals
Description: GNU Compiler Collection (GCC) Internals

Next: Machine Constraints, Previous: Modifiers, Up: Constraints

#### 16.8.6 Disable insn alternatives using the `enabled` attribute

The `enabled` insn attribute may be used to disable certain insn alternatives for machine-specific reasons. This is useful when adding new instructions to an existing pattern which are only available for certain cpu architecture levels as specified with the `-march=` option.

If an insn alternative is disabled, then it will never be used. The compiler treats the constraints for the disabled alternative as unsatisfiable.

In order to make use of the `enabled` attribute a back end has to add in the machine description files:

1. A definition of the `enabled` insn attribute. The attribute is defined as usual using the `define_attr` command. This definition should be based on other insn attributes and/or target flags. The `enabled` attribute is a numeric attribute and should evaluate to `(const_int 1)` for an enabled alternative and to `(const_int 0)` otherwise.
2. A definition of another insn attribute used to describe for what reason an insn alternative might be available or not. E.g. `cpu_facility` as in the example below.
3. An assignment for the second attribute to each insn definition combining instructions which are not all available under the same circumstances. (Note: It obviously only makes sense for definitions with more than one alternative. Otherwise the insn pattern should be disabled or enabled using the insn condition.)

E.g. the following two patterns could easily be merged using the `enabled` attribute:

         (define_insn "*movdi_old"
           [(set (match_operand:DI 0 "register_operand" "=d")
                 (match_operand:DI 1 "register_operand" " d"))]
           "!TARGET_NEW"
           "lgr %0,%1")

         (define_insn "*movdi_new"
           [(set (match_operand:DI 0 "register_operand" "=d,f,d")
                 (match_operand:DI 1 "register_operand" " d,d,f"))]
           "TARGET_NEW"
           "@
            lgr  %0,%1
            ldgr %0,%1
            lgdr %0,%1")

to:

         (define_insn "*movdi_combined"
           [(set (match_operand:DI 0 "register_operand" "=d,f,d")
                 (match_operand:DI 1 "register_operand" " d,d,f"))]
           ""
           "@
            lgr  %0,%1
            ldgr %0,%1
            lgdr %0,%1"
           [(set_attr "cpu_facility" "*,new,new")])

with the `enabled` attribute defined like this:

         (define_attr "cpu_facility" "standard,new" (const_string "standard"))

         (define_attr "enabled" ""
           (cond [(eq_attr "cpu_facility" "standard") (const_int 1)
                  (and (eq_attr "cpu_facility" "new")
                       (ne (symbol_ref "TARGET_NEW") (const_int 0)))
                  (const_int 1)]
                 (const_int 0)))