Previous: Subst Iterators, Up: Iterators

#### 17.23.5 Parameterized Names

Ports sometimes need to apply iterators using C++ code, in order to get the code or RTL pattern for a specific instruction. For example, suppose we have the ``neon_vq<absneg><mode>`' pattern given above:

         (define_int_iterator QABSNEG [UNSPEC_VQABS UNSPEC_VQNEG])

         (define_int_attr absneg [(UNSPEC_VQABS "abs") (UNSPEC_VQNEG "neg")])

         (define_insn "neon_vq<absneg><mode>"
           [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
         	(unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
         		       (match_operand:SI 2 "immediate_operand" "i")]
         		      QABSNEG))]
           ...
         )

A port might need to generate this pattern for a variable ``QABSNEG`' value and a variable ``VDQIW`' mode. There are two ways of doing this. The first is to build the rtx for the pattern directly from C++ code; this is a valid technique and avoids any risk of combinatorial explosion. The second is to prefix the instruction name with the special character ``@`', which tells GCC to generate the four additional functions below. In each case, name is the name of the instruction without the leading ``@`' character, without the ``<...>`' placeholders, and with any underscore before a ``<...>`' placeholder removed if keeping it would lead to a double or trailing underscore.

``insn_code maybe_code_for_name (i1, i2, ...)`'
  See whether replacing the first ``<...>`' placeholder with iterator value i1, the second with iterator value i2, and so on, gives a valid instruction. Return its code if so, otherwise return `CODE_FOR_nothing`.
``insn_code code_for_name (i1, i2, ...)`'
  Same, but abort the compiler if the requested instruction does not exist.
``rtx maybe_gen_name (i1, i2, ..., op0, op1, ...)`'
  Check for a valid instruction in the same way as `maybe_code_for_`name. If the instruction exists, generate an instance of it using the operand values given by op0, op1, and so on, otherwise return null.
``rtx gen_name (i1, i2, ..., op0, op1, ...)`'
  Same, but abort the compiler if the requested instruction does not exist, or if the instruction generator invoked the `FAIL` macro.

For example, changing the pattern above to:

         (define_insn "@neon_vq<absneg><mode>"
           [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
         	(unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
         		       (match_operand:SI 2 "immediate_operand" "i")]
         		      QABSNEG))]
           ...
         )

would define the same patterns as before, but in addition would generate the four functions below:

         insn_code maybe_code_for_neon_vq (int, machine_mode);
         insn_code code_for_neon_vq (int, machine_mode);
         rtx maybe_gen_neon_vq (int, machine_mode, rtx, rtx, rtx);
         rtx gen_neon_vq (int, machine_mode, rtx, rtx, rtx);

Calling ``code_for_neon_vq (UNSPEC_VQABS, V8QImode)`' would then give `CODE_FOR_neon_vqabsv8qi`.

It is possible to have multiple ``@`' patterns with the same name and same types of iterator. For example:

         (define_insn "@some_arithmetic_op<mode>"
           [(set (match_operand:INTEGER_MODES 0 "register_operand") ...)]
           ...
         )

         (define_insn "@some_arithmetic_op<mode>"
           [(set (match_operand:FLOAT_MODES 0 "register_operand") ...)]
           ...
         )

would produce a single set of functions that handles both `INTEGER_MODES` and `FLOAT_MODES`.

It is also possible for these ``@`' patterns to have different numbers of operands from each other. For example, patterns with a binary rtl code might take three operands (one output and two inputs) while patterns with a ternary rtl code might take four operands (one output and three inputs). This combination would produce separate ``maybe_gen_name`' and ``gen_name`' functions for each operand count, but it would still produce a single ``maybe_code_for_name`' and a single ``code_for_name`'.