gccint: Define Subst Example

1 
1 17.21.1 'define_subst' Example
1 ------------------------------
1 
1 To illustrate how 'define_subst' works, let us examine a simple template
1 transformation.
1 
1  Suppose there are two kinds of instructions: one that touches flags and
1 the other that does not.  The instructions of the second type could be
1 generated with the following 'define_subst':
1 
1      (define_subst "add_clobber_subst"
1        [(set (match_operand:SI 0 "" "")
1              (match_operand:SI 1 "" ""))]
1        ""
1        [(set (match_dup 0)
1              (match_dup 1))
1         (clobber (reg:CC FLAGS_REG))]
1 
1  This 'define_subst' can be applied to any RTL pattern containing 'set'
1 of mode SI and generates a copy with clobber when it is applied.
1 
1  Assume there is an RTL template for a 'max' instruction to be used in
1 'define_subst' mentioned above:
1 
1      (define_insn "maxsi"
1        [(set (match_operand:SI 0 "register_operand" "=r")
1              (max:SI
1                (match_operand:SI 1 "register_operand" "r")
1                (match_operand:SI 2 "register_operand" "r")))]
1        ""
1        "max\t{%2, %1, %0|%0, %1, %2}"
1       [...])
1 
1  To mark the RTL template for 'define_subst' application,
1 subst-attributes are used.  They should be declared in advance:
1 
1      (define_subst_attr "add_clobber_name" "add_clobber_subst" "_noclobber" "_clobber")
1 
1  Here 'add_clobber_name' is the attribute name, 'add_clobber_subst' is
1 the name of the corresponding 'define_subst', the third argument
1 ('_noclobber') is the attribute value that would be substituted into the
1 unchanged version of the source RTL template, and the last argument
1 ('_clobber') is the value that would be substituted into the second,
1 transformed, version of the RTL template.
1 
1  Once the subst-attribute has been defined, it should be used in RTL
1 templates which need to be processed by the 'define_subst'.  So, the
1 original RTL template should be changed:
1 
1      (define_insn "maxsi<add_clobber_name>"
1        [(set (match_operand:SI 0 "register_operand" "=r")
1              (max:SI
1                (match_operand:SI 1 "register_operand" "r")
1                (match_operand:SI 2 "register_operand" "r")))]
1        ""
1        "max\t{%2, %1, %0|%0, %1, %2}"
1       [...])
1 
1  The result of the 'define_subst' usage would look like the following:
1 
1      (define_insn "maxsi_noclobber"
1        [(set (match_operand:SI 0 "register_operand" "=r")
1              (max:SI
1                (match_operand:SI 1 "register_operand" "r")
1                (match_operand:SI 2 "register_operand" "r")))]
1        ""
1        "max\t{%2, %1, %0|%0, %1, %2}"
1       [...])
1      (define_insn "maxsi_clobber"
1        [(set (match_operand:SI 0 "register_operand" "=r")
1              (max:SI
1                (match_operand:SI 1 "register_operand" "r")
1                (match_operand:SI 2 "register_operand" "r")))
1         (clobber (reg:CC FLAGS_REG))]
1        ""
1        "max\t{%2, %1, %0|%0, %1, %2}"
1       [...])
1