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:
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.
[]
, with sections separated by a semicolon.
^
can be used.
This allows less copy pasting between alternative and reduces the number of
lines to update on changes.
<
or >
in
the output then these must be escaped using ‘\’.
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.