Next: , Up: Define Subst


16.21.1 define_subst Example

To illustrate how define_subst works, let us examine a simple template transformation.

Suppose there are two kinds of instructions: one that touches flags and the other that does not. The instructions of the second type could be generated with the following define_subst:

     (define_subst "add_clobber_subst"
       [(set (match_operand:SI 0 "" "")
             (match_operand:SI 1 "" ""))]
       ""
       [(set (match_dup 0)
             (match_dup 1))
        (clobber (reg:CC FLAGS_REG))]

This define_subst can be applied to any RTL pattern containing set of mode SI and generates a copy with clobber when it is applied.

Assume there is an RTL template for a max instruction to be used in define_subst mentioned above:

     (define_insn "maxsi"
       [(set (match_operand:SI 0 "register_operand" "=r")
             (max:SI
               (match_operand:SI 1 "register_operand" "r")
               (match_operand:SI 2 "register_operand" "r")))]
       ""
       "max\t{%2, %1, %0|%0, %1, %2}"
      [...])

To mark the RTL template for define_subst application, subst-attributes are used. They should be declared in advance:

     (define_subst_attr "add_clobber_name" "add_clobber_subst" "_noclobber" "_clobber")

Here ‘add_clobber_name’ is the attribute name, ‘add_clobber_subst’ is the name of the corresponding define_subst, the third argument (‘_noclobber’) is the attribute value that would be substituted into the unchanged version of the source RTL template, and the last argument (‘_clobber’) is the value that would be substituted into the second, transformed, version of the RTL template.

Once the subst-attribute has been defined, it should be used in RTL templates which need to be processed by the define_subst. So, the original RTL template should be changed:

     (define_insn "maxsi<add_clobber_name>"
       [(set (match_operand:SI 0 "register_operand" "=r")
             (max:SI
               (match_operand:SI 1 "register_operand" "r")
               (match_operand:SI 2 "register_operand" "r")))]
       ""
       "max\t{%2, %1, %0|%0, %1, %2}"
      [...])

The result of the define_subst usage would look like the following:

     (define_insn "maxsi_noclobber"
       [(set (match_operand:SI 0 "register_operand" "=r")
             (max:SI
               (match_operand:SI 1 "register_operand" "r")
               (match_operand:SI 2 "register_operand" "r")))]
       ""
       "max\t{%2, %1, %0|%0, %1, %2}"
      [...])
     (define_insn "maxsi_clobber"
       [(set (match_operand:SI 0 "register_operand" "=r")
             (max:SI
               (match_operand:SI 1 "register_operand" "r")
               (match_operand:SI 2 "register_operand" "r")))
        (clobber (reg:CC FLAGS_REG))]
       ""
       "max\t{%2, %1, %0|%0, %1, %2}"
      [...])