Previous: Subst Iterators, Up: Iterators [Contents][Index]

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

Previous: Subst Iterators, Up: Iterators [Contents][Index]