Compact Syntax (GNU Compiler Collection (GCC) Internals)

### 18.7 Compact Syntax ¶

When a `define_insn` or `define_insn_and_split` has multiple alternatives it may be beneficial to use the compact syntax when specifying alternatives.

This syntax puts the constraints and attributes on the same horizontal line as the instruction assembly template.

As an example

    (define_insn_and_split ""
      [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r")
    	(match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,n,Usv"))]
      ""
      "@
       mov\\t%w0, %w1
       mov\\t%w0, %w1
       mov\\t%w0, %w1
       mov\\t%w0, %1
       #
       * return aarch64_output_sve_cnt_immediate ('cnt', '%x0', operands[1]);"
      "&& true"
       [(const_int 0)]
      {
         aarch64_expand_mov_immediate (operands[0], operands[1]);
         DONE;
      }
      [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm")
       (set_attr "arch"   "*,*,*,*,*,sve")
       (set_attr "length" "4,4,4,4,*,  4")
    ]
    )

can be better expressed as:

    (define_insn_and_split ""
      [(set (match_operand:SI 0 "nonimmediate_operand")
    	(match_operand:SI 1 "aarch64_mov_operand"))]
      ""
      {@ [cons: =0, 1; attrs: type, arch, length]
         [r , r  ; mov_reg  , *   , 4] mov\t%w0, %w1
         [k , r  ; mov_reg  , *   , 4] ^
         [r , k  ; mov_reg  , *   , 4] ^
         [r , M  ; mov_imm  , *   , 4] mov\t%w0, %1
         [r , n  ; mov_imm  , *   , *] #
         [r , Usv; mov_imm  , sve , 4] << aarch64_output_sve_cnt_immediate ("cnt", "%x0", operands[1]);
      }
      "&& true"
      [(const_int 0)]
      {
        aarch64_expand_mov_immediate (operands[0], operands[1]);
        DONE;
      }
    )

The syntax rules are as follows:

- Templates must start with ‘`{@`’ to use the new syntax.
- ‘`{@`’ is followed by a layout in square brackets which is ‘`cons:`’ followed by a comma-separated list of `match_operand`/`match_scratch` operand numbers, then a semicolon, followed by the same for attributes (‘`attrs:`’). Operand modifiers like `=` and `+` can be placed before an operand number. Both sections are optional (so you can use only ‘`cons`’, or only ‘`attrs`’, or both), and ‘`cons`’ must come before ‘`attrs`’ if present.
- Each alternative begins with any amount of whitespace.
- Following the whitespace is a comma-separated list of "constraints" and/or "attributes" within brackets `[]`, with sections separated by a semicolon.
- Should you want to copy the previous asm line, the symbol `^` can be used. This allows less copy pasting between alternative and reduces the number of lines to update on changes.
- When using C functions for output, the idiom ‘`* return function;`’ can be replaced with the shorthand ‘`<< function;`’.
- Following the closing ‘`]`’ is any amount of whitespace, and then the actual asm output.
- Spaces are allowed in the list (they will simply be removed).
- All constraint alternatives should be specified. For example, a list of of three blank alternatives should be written ‘`[,,]`’ rather than ‘`[]`’.
- All attribute alternatives should be non-empty, with ‘`*`’ representing the default attribute value. For example, a list of three default attribute values should be written ‘`[*,*,*]`’ rather than ‘`[]`’.
- Within an ‘`{@`’ block both multiline and singleline C comments are allowed, but when used outside of a C block they must be the only non-whitespace blocks on the line.
- Within an ‘`{@`’ block, any iterators that do not get expanded will result in an error. If for some reason it is required to have `<` or `>` in the output then these must be escaped using ‘`\`’.
- It is possible to use the ‘`attrs`’ list to specify some attributes and to use the normal `set_attr` syntax to specify other attributes. There must not be any overlap between the two lists.

  In other words, the following is valid:

      (define_insn_and_split ""
        [(set (match_operand:SI 0 "nonimmediate_operand")
      	(match_operand:SI 1 "aarch64_mov_operand"))]
        ""
        {@ [cons: 0, 1; attrs: type, arch, length]}
        ...
        [(set_attr "foo" "mov_imm")]
      )

  but this is not valid:

      (define_insn_and_split ""
        [(set (match_operand:SI 0 "nonimmediate_operand")
      	(match_operand:SI 1 "aarch64_mov_operand"))]
        ""
        {@ [cons: 0, 1; attrs: type, arch, length]}
        ...
        [(set_attr "arch" "bar")
         (set_attr "foo" "mov_imm")]
      )

  because it specifies `arch` twice.