Re: [PATCH] RFC: New compact syntax for insn and insn_split in Machine Descriptions

2023-05-16 Thread Richard Earnshaw (lists) via Gcc-patches

On 24/04/2023 09:33, Richard Sandiford via Gcc-patches wrote:

Richard Sandiford  writes:

Tamar Christina  writes:

Hi All,

This patch adds support for a compact syntax for specifying constraints in
instruction patterns. Credit for the idea goes to Richard Earnshaw.

I am sending up this RFC to get feedback for it's inclusion in GCC 14.
With this new syntax we want a clean break from the current limitations to make
something that is hopefully easier to use and maintain.

The idea behind this compact syntax is that often times it's quite hard to
correlate the entries in the constrains list, attributes and instruction lists.

One has to count and this often is tedious.  Additionally when changing a single
line in the insn multiple lines in a diff change, making it harder to see what's
going on.

This new syntax takes into account many of the common things that are done in MD
files.   It's also worth saying that this version is intended to deal with the
common case of a string based alternatives.   For C chunks we have some ideas
but those are not intended to be addressed here.

It's easiest to explain with an example:

normal syntax:

(define_insn_and_split "*movsi_aarch64"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m,  r,  
r,  r, w,r,w, w")
(match_operand:SI 1 "aarch64_mov_operand"  " 
r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
   "(register_operand (operands[0], SImode)
 || aarch64_reg_or_zero (operands[1], SImode))"
   "@
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]);
ldr\\t%w0, %1
ldr\\t%s0, %1
str\\t%w1, %0
str\\t%s1, %0
adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
adr\\t%x0, %c1
adrp\\t%x0, %A1
fmov\\t%s0, %w1
fmov\\t%w0, %s1
fmov\\t%s0, %s1
* return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode);"
   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
SImode)
 && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
[(const_int 0)]
"{
aarch64_expand_mov_immediate (operands[0], operands[1]);
DONE;
 }"
   ;; The "mov_imm" type for CNT is just a placeholder.
   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,

load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
(set_attr "arch"   "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
(set_attr "length" "4,4,4,4,*,  4,4, 4,4, 4,8,4,4, 4, 4, 4,   4")
]
)

New syntax:

(define_insn_and_split "*movsi_aarch64"
   [(set (match_operand:SI 0 "nonimmediate_operand")
(match_operand:SI 1 "aarch64_mov_operand"))]
   "(register_operand (operands[0], SImode)
 || aarch64_reg_or_zero (operands[1], SImode))"
   "@@ (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]);
[r , m  ; load_4   , *   , 4] ldr\t%w0, %1
[w , m  ; load_4   , fp  , 4] ldr\t%s0, %1
[m , rZ ; store_4  , *   , 4] str\t%w1, %0
[m , w  ; store_4  , fp  , 4] str\t%s1, %0
[r , Usw; load_4   , *   , 8] adrp\t%x0, %A1;ldr\t%w0, [%x0, %L1]
[r , Usa; adr  , *   , 4] adr\t%x0, %c1
[r , Ush; adr  , *   , 4] adrp\t%x0, %A1
[w , rZ ; f_mcr, fp  , 4] fmov\t%s0, %w1
[r , w  ; f_mrc, fp  , 4] fmov\t%w0, %s1
[w , w  ; fmov , fp  , 4] fmov\t%s0, %s1
[w , Ds ; neon_move, simd, 4] << aarch64_output_scalar_simd_mov_immediate 
(operands[1], SImode);"
   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
SImode)
 && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
   [(const_int 0)]
   {
 aarch64_expand_mov_immediate (operands[0], operands[1]);
 DONE;
   }
   ;; The "mov_imm" type for CNT is just a placeholder.
)

The patch contains some more rewritten examples for both Arm and AArch64.  I
have included them for examples in this RFC but the final version posted in
GCC 14 will have these split out.

The main syntax rules are as follows (See docs for full rules):
   - Template must start with "@@" to use the new syntax.
   - "@@" is followed by a layout in parentheses which is "cons:" followed by
 a list of match_operand/match_scratch IDs, then a semicolon, then the
 same for attributes ("attrs:"). 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.
   - Following the closing ']' is any amount of whit

Re: [PATCH] RFC: New compact syntax for insn and insn_split in Machine Descriptions

2023-04-24 Thread Richard Sandiford via Gcc-patches
Tamar Christina  writes:
>> -Original Message-
>> From: Richard Sandiford 
>> Sent: Friday, April 21, 2023 6:19 PM
>> To: Tamar Christina 
>> Cc: gcc-patches@gcc.gnu.org; nd ; Richard Earnshaw
>> 
>> Subject: Re: [PATCH] RFC: New compact syntax for insn and insn_split in
>> Machine Descriptions
>> 
>> Tamar Christina  writes:
>> > Hi All,
>> >
>> > This patch adds support for a compact syntax for specifying
>> > constraints in instruction patterns. Credit for the idea goes to Richard
>> Earnshaw.
>> >
>> > I am sending up this RFC to get feedback for it's inclusion in GCC 14.
>> > With this new syntax we want a clean break from the current
>> > limitations to make something that is hopefully easier to use and maintain.
>> >
>> > The idea behind this compact syntax is that often times it's quite
>> > hard to correlate the entries in the constrains list, attributes and 
>> > instruction
>> lists.
>> >
>> > One has to count and this often is tedious.  Additionally when
>> > changing a single line in the insn multiple lines in a diff change,
>> > making it harder to see what's going on.
>> >
>> > This new syntax takes into account many of the common things that are
>> done in MD
>> > files.   It's also worth saying that this version is intended to deal with 
>> > the
>> > common case of a string based alternatives.   For C chunks we have some
>> ideas
>> > but those are not intended to be addressed here.
>> >
>> > It's easiest to explain with an example:
>> >
>> > normal syntax:
>> >
>> > (define_insn_and_split "*movsi_aarch64"
>> >   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, 
>> > m,
>> r,  r,  r, w,r,w, w")
>> >(match_operand:SI 1 "aarch64_mov_operand"  "
>> r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
>> >   "(register_operand (operands[0], SImode)
>> > || aarch64_reg_or_zero (operands[1], SImode))"
>> >   "@
>> >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]);
>> >ldr\\t%w0, %1
>> >ldr\\t%s0, %1
>> >str\\t%w1, %0
>> >str\\t%s1, %0
>> >adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
>> >adr\\t%x0, %c1
>> >adrp\\t%x0, %A1
>> >fmov\\t%s0, %w1
>> >fmov\\t%w0, %s1
>> >fmov\\t%s0, %s1
>> >* return aarch64_output_scalar_simd_mov_immediate (operands[1],
>> SImode);"
>> >   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL
>> (operands[1]), SImode)
>> > && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
>> >[(const_int 0)]
>> >"{
>> >aarch64_expand_mov_immediate (operands[0], operands[1]);
>> >DONE;
>> > }"
>> >   ;; The "mov_imm" type for CNT is just a placeholder.
>> >   [(set_attr "type"
>> "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
>> >
>> load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
>> >(set_attr "arch"   "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
>> >(set_attr "length" "4,4,4,4,*,  4,4, 4,4, 4,8,4,4, 4, 4, 4,   4")
>> > ]
>> > )
>> >
>> > New syntax:
>> >
>> > (define_insn_and_split "*movsi_aarch64"
>> >   [(set (match_operand:SI 0 "nonimmediate_operand")
>> >(match_operand:SI 1 "aarch64_mov_operand"))]
>> >   "(register_operand (operands[0], SImode)
>> > || aarch64_reg_or_zero (operands[1], SImode))"
>> >   "@@ (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]);
>> >[r , m  ; load_4   , *   , 4] ldr\t%w0, %1
>> >   

RE: [PATCH] RFC: New compact syntax for insn and insn_split in Machine Descriptions

2023-04-24 Thread Tamar Christina via Gcc-patches


> -Original Message-
> From: Richard Sandiford 
> Sent: Friday, April 21, 2023 6:19 PM
> To: Tamar Christina 
> Cc: gcc-patches@gcc.gnu.org; nd ; Richard Earnshaw
> 
> Subject: Re: [PATCH] RFC: New compact syntax for insn and insn_split in
> Machine Descriptions
> 
> Tamar Christina  writes:
> > Hi All,
> >
> > This patch adds support for a compact syntax for specifying
> > constraints in instruction patterns. Credit for the idea goes to Richard
> Earnshaw.
> >
> > I am sending up this RFC to get feedback for it's inclusion in GCC 14.
> > With this new syntax we want a clean break from the current
> > limitations to make something that is hopefully easier to use and maintain.
> >
> > The idea behind this compact syntax is that often times it's quite
> > hard to correlate the entries in the constrains list, attributes and 
> > instruction
> lists.
> >
> > One has to count and this often is tedious.  Additionally when
> > changing a single line in the insn multiple lines in a diff change,
> > making it harder to see what's going on.
> >
> > This new syntax takes into account many of the common things that are
> done in MD
> > files.   It's also worth saying that this version is intended to deal with 
> > the
> > common case of a string based alternatives.   For C chunks we have some
> ideas
> > but those are not intended to be addressed here.
> >
> > It's easiest to explain with an example:
> >
> > normal syntax:
> >
> > (define_insn_and_split "*movsi_aarch64"
> >   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m,
> r,  r,  r, w,r,w, w")
> > (match_operand:SI 1 "aarch64_mov_operand"  "
> r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
> >   "(register_operand (operands[0], SImode)
> > || aarch64_reg_or_zero (operands[1], SImode))"
> >   "@
> >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]);
> >ldr\\t%w0, %1
> >ldr\\t%s0, %1
> >str\\t%w1, %0
> >str\\t%s1, %0
> >adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
> >adr\\t%x0, %c1
> >adrp\\t%x0, %A1
> >fmov\\t%s0, %w1
> >fmov\\t%w0, %s1
> >fmov\\t%s0, %s1
> >* return aarch64_output_scalar_simd_mov_immediate (operands[1],
> SImode);"
> >   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL
> (operands[1]), SImode)
> > && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
> >[(const_int 0)]
> >"{
> >aarch64_expand_mov_immediate (operands[0], operands[1]);
> >DONE;
> > }"
> >   ;; The "mov_imm" type for CNT is just a placeholder.
> >   [(set_attr "type"
> "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
> >
> load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
> >(set_attr "arch"   "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
> >(set_attr "length" "4,4,4,4,*,  4,4, 4,4, 4,8,4,4, 4, 4, 4,   4")
> > ]
> > )
> >
> > New syntax:
> >
> > (define_insn_and_split "*movsi_aarch64"
> >   [(set (match_operand:SI 0 "nonimmediate_operand")
> > (match_operand:SI 1 "aarch64_mov_operand"))]
> >   "(register_operand (operands[0], SImode)
> > || aarch64_reg_or_zero (operands[1], SImode))"
> >   "@@ (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]);
> >[r , m  ; load_4   , *   , 4] ldr\t%w0, %1
> >[w , m  ; load_4   , fp  , 4] ldr\t%s0, %1
> >[m , rZ ; store_4  , *   , 4] str\t%w1, %0
> >[m , w  ; store_4  , fp  , 4] str\t%s1, %0
> >[r , Usw; load_4   , *   , 8] adrp\t%x0, %A1;ldr\t%w0, [%x0, %L1]
> >[r , Usa; adr  , *   , 4] adr\t%x0, %c1
> >[r , Ush; adr  , *   , 4] adrp\t%x0, %A1
> >[w , rZ ; f_mcr, fp  , 4] fmov\t%s0, %w1
> >[r , w  ; f_mrc, fp  , 4] fmov\t%w0, 

Re: [PATCH] RFC: New compact syntax for insn and insn_split in Machine Descriptions

2023-04-24 Thread Richard Sandiford via Gcc-patches
Richard Sandiford  writes:
> Tamar Christina  writes:
>> Hi All,
>>
>> This patch adds support for a compact syntax for specifying constraints in
>> instruction patterns. Credit for the idea goes to Richard Earnshaw.
>>
>> I am sending up this RFC to get feedback for it's inclusion in GCC 14.
>> With this new syntax we want a clean break from the current limitations to 
>> make
>> something that is hopefully easier to use and maintain.
>>
>> The idea behind this compact syntax is that often times it's quite hard to
>> correlate the entries in the constrains list, attributes and instruction 
>> lists.
>>
>> One has to count and this often is tedious.  Additionally when changing a 
>> single
>> line in the insn multiple lines in a diff change, making it harder to see 
>> what's
>> going on.
>>
>> This new syntax takes into account many of the common things that are done 
>> in MD
>> files.   It's also worth saying that this version is intended to deal with 
>> the
>> common case of a string based alternatives.   For C chunks we have some ideas
>> but those are not intended to be addressed here.
>>
>> It's easiest to explain with an example:
>>
>> normal syntax:
>>
>> (define_insn_and_split "*movsi_aarch64"
>>   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m, 
>>  r,  r,  r, w,r,w, w")
>>  (match_operand:SI 1 "aarch64_mov_operand"  " 
>> r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
>>   "(register_operand (operands[0], SImode)
>> || aarch64_reg_or_zero (operands[1], SImode))"
>>   "@
>>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]);
>>ldr\\t%w0, %1
>>ldr\\t%s0, %1
>>str\\t%w1, %0
>>str\\t%s1, %0
>>adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
>>adr\\t%x0, %c1
>>adrp\\t%x0, %A1
>>fmov\\t%s0, %w1
>>fmov\\t%w0, %s1
>>fmov\\t%s0, %s1
>>* return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode);"
>>   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
>> SImode)
>> && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
>>[(const_int 0)]
>>"{
>>aarch64_expand_mov_immediate (operands[0], operands[1]);
>>DONE;
>> }"
>>   ;; The "mov_imm" type for CNT is just a placeholder.
>>   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
>>  
>> load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
>>(set_attr "arch"   "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
>>(set_attr "length" "4,4,4,4,*,  4,4, 4,4, 4,8,4,4, 4, 4, 4,   4")
>> ]
>> )
>>
>> New syntax:
>>
>> (define_insn_and_split "*movsi_aarch64"
>>   [(set (match_operand:SI 0 "nonimmediate_operand")
>>  (match_operand:SI 1 "aarch64_mov_operand"))]
>>   "(register_operand (operands[0], SImode)
>> || aarch64_reg_or_zero (operands[1], SImode))"
>>   "@@ (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]);
>>[r , m  ; load_4   , *   , 4] ldr\t%w0, %1
>>[w , m  ; load_4   , fp  , 4] ldr\t%s0, %1
>>[m , rZ ; store_4  , *   , 4] str\t%w1, %0
>>[m , w  ; store_4  , fp  , 4] str\t%s1, %0
>>[r , Usw; load_4   , *   , 8] adrp\t%x0, %A1;ldr\t%w0, [%x0, %L1]
>>[r , Usa; adr  , *   , 4] adr\t%x0, %c1
>>[r , Ush; adr  , *   , 4] adrp\t%x0, %A1
>>[w , rZ ; f_mcr, fp  , 4] fmov\t%s0, %w1
>>[r , w  ; f_mrc, fp  , 4] fmov\t%w0, %s1
>>[w , w  ; fmov , fp  , 4] fmov\t%s0, %s1
>>[w , Ds ; neon_move, simd, 4] << aarch64_output_scalar_simd_mov_immediate 
>> (operands[1], SImode);"
>>   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
>> SImode)
>> && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
>>   [(const_int 0)]
>>   {
>> aarch64_expand_mov_immediate (operands[0], operands[1]);
>> DONE;
>>   }
>>   ;; The "mov_imm" type for CNT is just a placeholder.
>> )
>>
>> The patch contains some more rewritten examples for both Arm and AArch64.  I
>> have included them for examples in this RFC but the final version posted in
>> GCC 14 will have these split out.
>>
>> The main syntax rules are as follows (See docs for full rules):
>>   - Template must start with "@@" to use the new syntax.
>>   - "@@" is followed by a layout in parentheses which is "cons:" followed by
>> a list of match_operand/match_scratch IDs, then a semicolon, then the
>> same for attributes ("attrs:"). 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

Re: [PATCH] RFC: New compact syntax for insn and insn_split in Machine Descriptions

2023-04-21 Thread Richard Sandiford via Gcc-patches
Tamar Christina  writes:
> Hi All,
>
> This patch adds support for a compact syntax for specifying constraints in
> instruction patterns. Credit for the idea goes to Richard Earnshaw.
>
> I am sending up this RFC to get feedback for it's inclusion in GCC 14.
> With this new syntax we want a clean break from the current limitations to 
> make
> something that is hopefully easier to use and maintain.
>
> The idea behind this compact syntax is that often times it's quite hard to
> correlate the entries in the constrains list, attributes and instruction 
> lists.
>
> One has to count and this often is tedious.  Additionally when changing a 
> single
> line in the insn multiple lines in a diff change, making it harder to see 
> what's
> going on.
>
> This new syntax takes into account many of the common things that are done in 
> MD
> files.   It's also worth saying that this version is intended to deal with the
> common case of a string based alternatives.   For C chunks we have some ideas
> but those are not intended to be addressed here.
>
> It's easiest to explain with an example:
>
> normal syntax:
>
> (define_insn_and_split "*movsi_aarch64"
>   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m,  
> r,  r,  r, w,r,w, w")
>   (match_operand:SI 1 "aarch64_mov_operand"  " 
> r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
>   "(register_operand (operands[0], SImode)
> || aarch64_reg_or_zero (operands[1], SImode))"
>   "@
>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]);
>ldr\\t%w0, %1
>ldr\\t%s0, %1
>str\\t%w1, %0
>str\\t%s1, %0
>adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
>adr\\t%x0, %c1
>adrp\\t%x0, %A1
>fmov\\t%s0, %w1
>fmov\\t%w0, %s1
>fmov\\t%s0, %s1
>* return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode);"
>   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
> SImode)
> && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
>[(const_int 0)]
>"{
>aarch64_expand_mov_immediate (operands[0], operands[1]);
>DONE;
> }"
>   ;; The "mov_imm" type for CNT is just a placeholder.
>   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
>   
> load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
>(set_attr "arch"   "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
>(set_attr "length" "4,4,4,4,*,  4,4, 4,4, 4,8,4,4, 4, 4, 4,   4")
> ]
> )
>
> New syntax:
>
> (define_insn_and_split "*movsi_aarch64"
>   [(set (match_operand:SI 0 "nonimmediate_operand")
>   (match_operand:SI 1 "aarch64_mov_operand"))]
>   "(register_operand (operands[0], SImode)
> || aarch64_reg_or_zero (operands[1], SImode))"
>   "@@ (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]);
>[r , m  ; load_4   , *   , 4] ldr\t%w0, %1
>[w , m  ; load_4   , fp  , 4] ldr\t%s0, %1
>[m , rZ ; store_4  , *   , 4] str\t%w1, %0
>[m , w  ; store_4  , fp  , 4] str\t%s1, %0
>[r , Usw; load_4   , *   , 8] adrp\t%x0, %A1;ldr\t%w0, [%x0, %L1]
>[r , Usa; adr  , *   , 4] adr\t%x0, %c1
>[r , Ush; adr  , *   , 4] adrp\t%x0, %A1
>[w , rZ ; f_mcr, fp  , 4] fmov\t%s0, %w1
>[r , w  ; f_mrc, fp  , 4] fmov\t%w0, %s1
>[w , w  ; fmov , fp  , 4] fmov\t%s0, %s1
>[w , Ds ; neon_move, simd, 4] << aarch64_output_scalar_simd_mov_immediate 
> (operands[1], SImode);"
>   "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), 
> SImode)
> && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
>   [(const_int 0)]
>   {
> aarch64_expand_mov_immediate (operands[0], operands[1]);
> DONE;
>   }
>   ;; The "mov_imm" type for CNT is just a placeholder.
> )
>
> The patch contains some more rewritten examples for both Arm and AArch64.  I
> have included them for examples in this RFC but the final version posted in
> GCC 14 will have these split out.
>
> The main syntax rules are as follows (See docs for full rules):
>   - Template must start with "@@" to use the new syntax.
>   - "@@" is followed by a layout in parentheses which is "cons:" followed by
> a list of match_operand/match_scratch IDs, then a semicolon, then the
> same for attributes ("attrs:"). 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 separa