]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AArch64/SMEInstrFormats.td
zfs: merge openzfs/zfs@92e0d9d18 (zfs-2.1-release) into stable/13
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AArch64 / SMEInstrFormats.td
1 //=-- SMEInstrFormats.td -  AArch64 SME Instruction classes -*- tablegen -*--=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // AArch64 Scalable Matrix Extension (SME) Instruction Class Definitions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 //===----------------------------------------------------------------------===//
14 // SME Outer Products
15 //===----------------------------------------------------------------------===//
16
17 class sme_fp_outer_product_inst<bit S, bit sz, MatrixTileOperand za_ty,
18                                 ZPRRegOp zpr_ty, string mnemonic>
19     : I<(outs za_ty:$ZAda),
20         (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn, zpr_ty:$Zm),
21         mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
22         "", []>,
23       Sched<[]> {
24   bits<5> Zm;
25   bits<3> Pm;
26   bits<3> Pn;
27   bits<5> Zn;
28   let Inst{31-23} = 0b100000001;
29   let Inst{22}    = sz;
30   let Inst{21}    = 0b0;
31   let Inst{20-16} = Zm;
32   let Inst{15-13} = Pm;
33   let Inst{12-10} = Pn;
34   let Inst{9-5}   = Zn;
35   let Inst{4}     = S;
36   let Inst{3}     = 0b0;
37 }
38
39 class sme_outer_product_fp32<bit S, string mnemonic>
40     : sme_fp_outer_product_inst<S, 0b0, TileOp32, ZPR32, mnemonic> {
41   bits<2> ZAda;
42   let Inst{1-0} = ZAda;
43   let Inst{2}   = 0b0;
44 }
45
46 class sme_outer_product_fp64<bit S, string mnemonic>
47     : sme_fp_outer_product_inst<S, 0b1, TileOp64, ZPR64, mnemonic> {
48   bits<3> ZAda;
49   let Inst{2-0} = ZAda;
50 }
51
52 class sme_int_outer_product_inst<bit u0, bit u1, bit S, bit sz,
53                                  MatrixTileOperand za_ty, ZPRRegOp zpr_ty,
54                                  string mnemonic>
55     : I<(outs za_ty:$ZAda),
56         (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn, zpr_ty:$Zm),
57         mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
58         "", []>,
59       Sched<[]> {
60   bits<5> Zm;
61   bits<3> Pm;
62   bits<3> Pn;
63   bits<5> Zn;
64   let Inst{31-25} = 0b1010000;
65   let Inst{24}    = u0;
66   let Inst{23}    = 0b1;
67   let Inst{22}    = sz;
68   let Inst{21}    = u1;
69   let Inst{20-16} = Zm;
70   let Inst{15-13} = Pm;
71   let Inst{12-10} = Pn;
72   let Inst{9-5}   = Zn;
73   let Inst{4}     = S;
74   let Inst{3}     = 0b0;
75 }
76
77 class sme_int_outer_product_i32<bits<3> opc, string mnemonic>
78     : sme_int_outer_product_inst<opc{2}, opc{1}, opc{0}, 0b0, TileOp32, ZPR8,
79                                  mnemonic> {
80   bits<2> ZAda;
81   let Inst{1-0} = ZAda;
82   let Inst{2}   = 0b0;
83 }
84
85 class sme_int_outer_product_i64<bits<3> opc, string mnemonic>
86     : sme_int_outer_product_inst<opc{2}, opc{1}, opc{0}, 0b1, TileOp64, ZPR16,
87                                  mnemonic> {
88   bits<3> ZAda;
89   let Inst{2-0} = ZAda;
90 }
91
92 class sme_outer_product_widening_inst<bit op, bit S, string mnemonic>
93     : I<(outs TileOp32:$ZAda),
94         (ins PPR3bAny:$Pn, PPR3bAny:$Pm, ZPR16:$Zn, ZPR16:$Zm),
95         mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn, $Zm",
96         "", []>,
97       Sched<[]> {
98   bits<5> Zm;
99   bits<3> Pm;
100   bits<3> Pn;
101   bits<5> Zn;
102   bits<2> ZAda;
103   let Inst{31-22} = 0b1000000110;
104   let Inst{21}    = op;
105   let Inst{20-16} = Zm;
106   let Inst{15-13} = Pm;
107   let Inst{12-10} = Pn;
108   let Inst{9-5}   = Zn;
109   let Inst{4}     = S;
110   let Inst{3-2}   = 0b00;
111   let Inst{1-0}   = ZAda;
112 }
113
114 multiclass sme_bf16_outer_product<bit S, string mnemonic> {
115   def : sme_outer_product_widening_inst<0b0, S, mnemonic>;
116 }
117
118 multiclass sme_f16_outer_product<bit S, string mnemonic> {
119   def : sme_outer_product_widening_inst<0b1, S, mnemonic>;
120 }
121
122 //===----------------------------------------------------------------------===//
123 // SME Add Vector to Tile
124 //===----------------------------------------------------------------------===//
125
126 class sme_add_vector_to_tile_inst<bit op, bit V, MatrixTileOperand tile_ty,
127                                   ZPRRegOp zpr_ty, string mnemonic>
128     : I<(outs tile_ty:$ZAda),
129         (ins PPR3bAny:$Pn, PPR3bAny:$Pm, zpr_ty:$Zn),
130         mnemonic, "\t$ZAda, $Pn/m, $Pm/m, $Zn",
131         "", []>, Sched<[]> {
132   bits<3> Pm;
133   bits<3> Pn;
134   bits<5> Zn;
135   let Inst{31-23} = 0b110000001;
136   let Inst{22}    = op;
137   let Inst{21-17} = 0b01000;
138   let Inst{16}    = V;
139   let Inst{15-13} = Pm;
140   let Inst{12-10} = Pn;
141   let Inst{9-5}   = Zn;
142   let Inst{4-3}   = 0b00;
143 }
144
145 class sme_add_vector_to_tile_u32<bit V, string mnemonic>
146     : sme_add_vector_to_tile_inst<0b0, V, TileOp32, ZPR32, mnemonic> {
147   bits<2> ZAda;
148   let Inst{2}   = 0b0;
149   let Inst{1-0} = ZAda;
150 }
151
152 class sme_add_vector_to_tile_u64<bit V, string mnemonic>
153     : sme_add_vector_to_tile_inst<0b1, V, TileOp64, ZPR64, mnemonic> {
154   bits<3> ZAda;
155   let Inst{2-0} = ZAda;
156 }
157
158 //===----------------------------------------------------------------------===//
159 // SME Contiguous Loads
160 //===----------------------------------------------------------------------===//
161
162 class sme_mem_ld_ss_base<bit Q, bit V, bits<2> msz, dag outs, dag ins,
163                          string mnemonic, string argstr>
164     : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
165   bits<5> Rm;
166   bits<2> Rv;
167   bits<3> Pg;
168   bits<5> Rn;
169   let Inst{31-25} = 0b1110000;
170   let Inst{24}    = Q;
171   let Inst{23-22} = msz;
172   let Inst{21}    = 0b0;
173   let Inst{20-16} = Rm;
174   let Inst{15}    = V;
175   let Inst{14-13} = Rv;
176   let Inst{12-10} = Pg;
177   let Inst{9-5}   = Rn;
178   let Inst{4}     = 0b0;
179
180   let mayLoad = 1;
181 }
182
183 class sme_mem_ld_ss_inst<bit Q, bits<2> msz, string mnemonic,
184                          MatrixTileVectorOperand tile_ty, bit is_col,
185                          Operand imm_ty, RegisterOperand gpr_ty>
186     : sme_mem_ld_ss_base<
187         Q, is_col, msz, (outs tile_ty:$ZAt),
188         (ins MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn,
189              gpr_ty:$Rm),
190         mnemonic, "\t\\{$ZAt[$Rv, $imm]\\}, $Pg/z, [$Rn, $Rm]">;
191
192 multiclass sme_mem_ss_aliases_base<string mnemonic, Instruction inst,
193                                    MatrixTileVectorOperand tile_ty,
194                                    Operand imm_ty, RegisterOperand gpr_ty,
195                                    string pg_suffix=""> {
196   def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn, $Rm]",
197                   (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, gpr_ty:$Rm), 0>;
198   // Default XZR offset aliases
199   def : InstAlias<mnemonic # "\t\\{$ZAt[$Rv, $imm]\\}, $Pg" # pg_suffix # ", [$Rn]",
200                   (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
201   def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn]",
202                   (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
203 }
204
205 multiclass sme_mem_ss_aliases<string mnemonic, string inst, bit is_col,
206                               string pg_suffix=""> {
207   defm : sme_mem_ss_aliases_base<mnemonic # "b", !cast<Instruction>(inst # _B),
208                                  !if(is_col, TileVectorOpV8, TileVectorOpH8),
209                                  sme_elm_idx0_15, GPR64shifted8, pg_suffix>;
210   defm : sme_mem_ss_aliases_base<mnemonic # "h", !cast<Instruction>(inst # _H),
211                                  !if(is_col, TileVectorOpV16, TileVectorOpH16),
212                                  sme_elm_idx0_7, GPR64shifted16, pg_suffix>;
213   defm : sme_mem_ss_aliases_base<mnemonic # "w", !cast<Instruction>(inst # _S),
214                                  !if(is_col, TileVectorOpV32, TileVectorOpH32),
215                                  sme_elm_idx0_3, GPR64shifted32, pg_suffix>;
216   defm : sme_mem_ss_aliases_base<mnemonic # "d", !cast<Instruction>(inst # _D),
217                                  !if(is_col, TileVectorOpV64, TileVectorOpH64),
218                                  sme_elm_idx0_1, GPR64shifted64, pg_suffix>;
219   defm : sme_mem_ss_aliases_base<mnemonic # "q", !cast<Instruction>(inst # _Q),
220                                  !if(is_col, TileVectorOpV128, TileVectorOpH128),
221                                  sme_elm_idx0_0, GPR64shifted128, pg_suffix>;
222 }
223
224 multiclass sme_mem_ld_ss_aliases<string inst, bit is_col> {
225   defm NAME : sme_mem_ss_aliases<"ld1", inst, is_col, "/z">;
226 }
227
228 multiclass sme_mem_ld_v_ss<string mnemonic, bit is_col> {
229   def _B : sme_mem_ld_ss_inst<0b0, 0b00, mnemonic # "b",
230                               !if(is_col, TileVectorOpV8, TileVectorOpH8),
231                               is_col, sme_elm_idx0_15, GPR64shifted8> {
232     bits<4> imm;
233     let Inst{3-0} = imm;
234   }
235   def _H : sme_mem_ld_ss_inst<0b0, 0b01, mnemonic # "h",
236                               !if(is_col, TileVectorOpV16, TileVectorOpH16),
237                               is_col, sme_elm_idx0_7, GPR64shifted16> {
238     bits<1> ZAt;
239     bits<3> imm;
240     let Inst{3}   = ZAt;
241     let Inst{2-0} = imm;
242   }
243   def _S : sme_mem_ld_ss_inst<0b0, 0b10, mnemonic # "w",
244                               !if(is_col, TileVectorOpV32, TileVectorOpH32),
245                               is_col, sme_elm_idx0_3, GPR64shifted32> {
246     bits<2> ZAt;
247     bits<2> imm;
248     let Inst{3-2} = ZAt;
249     let Inst{1-0} = imm;
250   }
251   def _D : sme_mem_ld_ss_inst<0b0, 0b11, mnemonic # "d",
252                               !if(is_col, TileVectorOpV64, TileVectorOpH64),
253                               is_col, sme_elm_idx0_1, GPR64shifted64> {
254     bits<3> ZAt;
255     bits<1> imm;
256     let Inst{3-1} = ZAt;
257     let Inst{0}   = imm;
258   }
259   def _Q : sme_mem_ld_ss_inst<0b1, 0b11, mnemonic # "q",
260                               !if(is_col, TileVectorOpV128, TileVectorOpH128),
261                               is_col, sme_elm_idx0_0, GPR64shifted128> {
262     bits<4> ZAt;
263     let Inst{3-0} = ZAt;
264   }
265
266   defm : sme_mem_ld_ss_aliases<NAME, is_col>;
267 }
268
269 multiclass sme_mem_ld_ss<string mnemonic> {
270   defm _H : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b0>;
271   defm _V : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b1>;
272 }
273
274 //===----------------------------------------------------------------------===//
275 // SME Contiguous Stores
276 //===----------------------------------------------------------------------===//
277
278 class sme_mem_st_ss_base<bit Q, bit V, bits<2> msz, dag ins,
279                          string mnemonic, string argstr>
280     : I<(outs), ins, mnemonic, argstr, "", []>, Sched<[]> {
281   bits<5> Rm;
282   bits<2> Rv;
283   bits<3> Pg;
284   bits<5> Rn;
285   let Inst{31-25} = 0b1110000;
286   let Inst{24}    = Q;
287   let Inst{23-22} = msz;
288   let Inst{21}    = 0b1;
289   let Inst{20-16} = Rm;
290   let Inst{15}    = V;
291   let Inst{14-13} = Rv;
292   let Inst{12-10} = Pg;
293   let Inst{9-5}   = Rn;
294   let Inst{4}     = 0b0;
295
296   let mayStore = 1;
297   let hasSideEffects = 1;
298 }
299
300 class sme_mem_st_ss_inst<bit Q, bits<2> msz, string mnemonic,
301                          MatrixTileVectorOperand tile_ty, bit is_col,
302                          Operand imm_ty, RegisterOperand gpr_ty>
303     : sme_mem_st_ss_base<
304         Q, is_col, msz,
305         (ins tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg,
306              GPR64sp:$Rn, gpr_ty:$Rm),
307         mnemonic, "\t\\{$ZAt[$Rv, $imm]\\}, $Pg, [$Rn, $Rm]">;
308
309 multiclass sme_mem_st_ss_aliases<string inst, bit is_col> {
310   defm NAME : sme_mem_ss_aliases<"st1", inst, is_col>;
311 }
312
313 multiclass sme_mem_st_v_ss<string mnemonic, bit is_col> {
314   def _B : sme_mem_st_ss_inst<0b0, 0b00, mnemonic # "b",
315                               !if(is_col, TileVectorOpV8, TileVectorOpH8),
316                               is_col, sme_elm_idx0_15, GPR64shifted8> {
317     bits<4> imm;
318     let Inst{3-0} = imm;
319   }
320   def _H : sme_mem_st_ss_inst<0b0, 0b01, mnemonic # "h",
321                               !if(is_col, TileVectorOpV16, TileVectorOpH16),
322                               is_col, sme_elm_idx0_7, GPR64shifted16> {
323     bits<1> ZAt;
324     bits<3> imm;
325     let Inst{3}   = ZAt;
326     let Inst{2-0} = imm;
327   }
328   def _S : sme_mem_st_ss_inst<0b0, 0b10, mnemonic # "w",
329                               !if(is_col, TileVectorOpV32, TileVectorOpH32),
330                               is_col, sme_elm_idx0_3, GPR64shifted32> {
331     bits<2> ZAt;
332     bits<2> imm;
333     let Inst{3-2} = ZAt;
334     let Inst{1-0} = imm;
335   }
336   def _D : sme_mem_st_ss_inst<0b0, 0b11, mnemonic # "d",
337                               !if(is_col, TileVectorOpV64, TileVectorOpH64),
338                               is_col, sme_elm_idx0_1, GPR64shifted64> {
339     bits<3> ZAt;
340     bits<1> imm;
341     let Inst{3-1} = ZAt;
342     let Inst{0}   = imm;
343   }
344   def _Q : sme_mem_st_ss_inst<0b1, 0b11, mnemonic # "q",
345                               !if(is_col, TileVectorOpV128, TileVectorOpH128),
346                               is_col, sme_elm_idx0_0, GPR64shifted128> {
347     bits<4> ZAt;
348     let Inst{3-0} = ZAt;
349   }
350
351   defm : sme_mem_st_ss_aliases<NAME, is_col>;
352 }
353
354 multiclass sme_mem_st_ss<string mnemonic> {
355   defm _H : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b0>;
356   defm _V : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b1>;
357 }
358
359 //===----------------------------------------------------------------------===//
360 // SME Save and Restore Array
361 //===----------------------------------------------------------------------===//
362
363 class sme_spill_fill_inst<bit isStore, dag outs, dag ins, string opcodestr>
364     : I<outs, ins, opcodestr, "\t$ZAt[$Rv, $imm4], [$Rn, $offset, mul vl]", "",
365         []>,
366       Sched<[]> {
367   bits<2> Rv;
368   bits<5> Rn;
369   bits<4> imm4;
370   let Inst{31-22} = 0b1110000100;
371   let Inst{21}    = isStore;
372   let Inst{20-15} = 0b000000;
373   let Inst{14-13} = Rv;
374   let Inst{12-10} = 0b000;
375   let Inst{9-5}   = Rn;
376   let Inst{4}     = 0b0;
377   let Inst{3-0}   = imm4;
378
379   let mayLoad = !not(isStore);
380   let mayStore = isStore;
381 }
382
383 multiclass sme_spill_fill<bit isStore, dag outs, dag ins, string opcodestr> {
384   def NAME : sme_spill_fill_inst<isStore, outs, ins, opcodestr>;
385
386   def : InstAlias<opcodestr # "\t$ZAt[$Rv, $imm4], [$Rn]",
387                   (!cast<Instruction>(NAME) MatrixOp:$ZAt,
388                    MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_15:$imm4, GPR64sp:$Rn, 0), 1>;
389 }
390
391 multiclass sme_spill<string opcodestr> {
392   defm NAME : sme_spill_fill<0b1, (outs),
393                              (ins MatrixOp:$ZAt, MatrixIndexGPR32Op12_15:$Rv,
394                                   sme_elm_idx0_15:$imm4, GPR64sp:$Rn,
395                                   imm0_15:$offset),
396                              opcodestr>;
397 }
398
399 multiclass sme_fill<string opcodestr> {
400   defm NAME : sme_spill_fill<0b0, (outs MatrixOp:$ZAt),
401                              (ins MatrixIndexGPR32Op12_15:$Rv,
402                                   sme_elm_idx0_15:$imm4, GPR64sp:$Rn,
403                                   imm0_15:$offset),
404                              opcodestr>;
405 }
406
407 //===----------------------------------------------------------------------===//
408 // Move instructions
409 //===----------------------------------------------------------------------===//
410
411 class sme_vector_to_tile_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
412                               string mnemonic, string argstr>
413     : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
414   bits<2> Rv;
415   bits<3> Pg;
416   bits<5> Zn;
417   let Inst{31-24} = 0b11000000;
418   let Inst{23-22} = sz;
419   let Inst{21-17} = 0b00000;
420   let Inst{16}    = Q;
421   let Inst{15}    = V;
422   let Inst{14-13} = Rv;
423   let Inst{12-10} = Pg;
424   let Inst{9-5}   = Zn;
425   let Inst{4}     = 0b0;
426 }
427
428 class sme_vector_to_tile_inst<bit Q, bits<2> sz, MatrixTileVectorOperand tile_ty,
429                               bit is_col, Operand imm_ty, ZPRRegOp zpr_ty,
430                               string mnemonic>
431     : sme_vector_to_tile_base<Q, is_col, sz, (outs tile_ty:$ZAd),
432         (ins MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn),
433         mnemonic, "\t$ZAd[$Rv, $imm], $Pg/m, $Zn">;
434
435 multiclass sme_vector_to_tile_aliases<Instruction inst,
436                                       MatrixTileVectorOperand tile_ty,
437                                       ZPRRegOp zpr_ty, Operand imm_ty> {
438   def : InstAlias<"mov\t$ZAd[$Rv, $imm], $Pg/m, $Zn",
439                   (inst tile_ty:$ZAd, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn), 1>;
440 }
441
442 multiclass sme_vector_v_to_tile<string mnemonic, bit is_col> {
443   def _B : sme_vector_to_tile_inst<0b0, 0b00, !if(is_col, TileVectorOpV8,
444                                                           TileVectorOpH8),
445                                    is_col, sme_elm_idx0_15, ZPR8, mnemonic> {
446     bits<4> imm;
447     let Inst{3-0} = imm;
448   }
449   def _H : sme_vector_to_tile_inst<0b0, 0b01, !if(is_col, TileVectorOpV16,
450                                                           TileVectorOpH16),
451                                    is_col, sme_elm_idx0_7, ZPR16, mnemonic> {
452     bits<1> ZAd;
453     bits<3> imm;
454     let Inst{3}   = ZAd;
455     let Inst{2-0} = imm;
456   }
457   def _S : sme_vector_to_tile_inst<0b0, 0b10, !if(is_col, TileVectorOpV32,
458                                                           TileVectorOpH32),
459                                    is_col, sme_elm_idx0_3, ZPR32, mnemonic> {
460     bits<2> ZAd;
461     bits<2> imm;
462     let Inst{3-2} = ZAd;
463     let Inst{1-0} = imm;
464   }
465   def _D : sme_vector_to_tile_inst<0b0, 0b11, !if(is_col, TileVectorOpV64,
466                                                           TileVectorOpH64),
467                                    is_col, sme_elm_idx0_1, ZPR64, mnemonic> {
468     bits<3> ZAd;
469     bits<1> imm;
470     let Inst{3-1} = ZAd;
471     let Inst{0}   = imm;
472   }
473   def _Q : sme_vector_to_tile_inst<0b1, 0b11, !if(is_col, TileVectorOpV128,
474                                                           TileVectorOpH128),
475                                    is_col, sme_elm_idx0_0, ZPR128, mnemonic> {
476     bits<4> ZAd;
477     bits<1> imm;
478     let Inst{3-0} = ZAd;
479   }
480
481   defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _B),
482                                     !if(is_col, TileVectorOpV8,
483                                                 TileVectorOpH8),
484                                     ZPR8, sme_elm_idx0_15>;
485   defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _H),
486                                     !if(is_col, TileVectorOpV16,
487                                                 TileVectorOpH16),
488                                     ZPR16, sme_elm_idx0_7>;
489   defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _S),
490                                     !if(is_col, TileVectorOpV32,
491                                                 TileVectorOpH32),
492                                     ZPR32, sme_elm_idx0_3>;
493   defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _D),
494                                     !if(is_col, TileVectorOpV64,
495                                                 TileVectorOpH64),
496                                     ZPR64, sme_elm_idx0_1>;
497   defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _Q),
498                                     !if(is_col, TileVectorOpV128,
499                                                 TileVectorOpH128),
500                                     ZPR128, sme_elm_idx0_0>;
501 }
502
503 multiclass sme_vector_to_tile<string mnemonic> {
504   defm _H : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b0>;
505   defm _V : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b1>;
506 }
507
508 class sme_tile_to_vector_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
509                               string mnemonic, string argstr>
510     : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
511   bits<2> Rv;
512   bits<3> Pg;
513   bits<5> Zd;
514   let Inst{31-24} = 0b11000000;
515   let Inst{23-22} = sz;
516   let Inst{21-17} = 0b00001;
517   let Inst{16}    = Q;
518   let Inst{15}    = V;
519   let Inst{14-13} = Rv;
520   let Inst{12-10} = Pg;
521   let Inst{9}     = 0b0;
522   let Inst{4-0}   = Zd;
523 }
524
525 class sme_tile_to_vector_inst<bit Q, bits<2> sz, ZPRRegOp zpr_ty,
526                               MatrixTileVectorOperand tile_ty,
527                               bit is_col, Operand imm_ty, string mnemonic>
528     : sme_tile_to_vector_base<Q, is_col, sz, (outs zpr_ty:$Zd),
529         (ins PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm),
530         mnemonic, "\t$Zd, $Pg/m, $ZAn[$Rv, $imm]">;
531
532 multiclass sme_tile_to_vector_aliases<Instruction inst, ZPRRegOp zpr_ty,
533                                       MatrixTileVectorOperand tile_ty,
534                                       Operand imm_ty > {
535   def : InstAlias<"mov\t$Zd, $Pg/m, $ZAn[$Rv, $imm]",
536                   (inst zpr_ty:$Zd, PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm), 1>;
537 }
538
539 multiclass sme_tile_to_vector_v<string mnemonic, bit is_col> {
540   def _B : sme_tile_to_vector_inst<0b0, 0b00, ZPR8, !if(is_col, TileVectorOpV8,
541                                                                 TileVectorOpH8),
542                                    is_col, sme_elm_idx0_15, mnemonic> {
543     bits<4> imm;
544     let Inst{8-5} = imm;
545   }
546   def _H : sme_tile_to_vector_inst<0b0, 0b01, ZPR16, !if(is_col, TileVectorOpV16,
547                                                                  TileVectorOpH16),
548                                    is_col, sme_elm_idx0_7, mnemonic> {
549     bits<1> ZAn;
550     bits<3> imm;
551     let Inst{8}   = ZAn;
552     let Inst{7-5} = imm;
553   }
554   def _S : sme_tile_to_vector_inst<0b0, 0b10, ZPR32, !if(is_col, TileVectorOpV32,
555                                                                  TileVectorOpH32),
556                                    is_col, sme_elm_idx0_3, mnemonic> {
557     bits<2> ZAn;
558     bits<2> imm;
559     let Inst{8-7} = ZAn;
560     let Inst{6-5} = imm;
561   }
562   def _D : sme_tile_to_vector_inst<0b0, 0b11, ZPR64, !if(is_col, TileVectorOpV64,
563                                                                  TileVectorOpH64),
564                                    is_col, sme_elm_idx0_1, mnemonic> {
565     bits<3> ZAn;
566     bits<1> imm;
567     let Inst{8-6} = ZAn;
568     let Inst{5}   = imm;
569   }
570   def _Q : sme_tile_to_vector_inst<0b1, 0b11, ZPR128, !if(is_col, TileVectorOpV128,
571                                                                   TileVectorOpH128),
572                                    is_col, sme_elm_idx0_0, mnemonic> {
573     bits<4> ZAn;
574     let Inst{8-5} = ZAn;
575   }
576
577   defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _B), ZPR8,
578                                     !if(is_col, TileVectorOpV8,
579                                                 TileVectorOpH8), sme_elm_idx0_15>;
580   defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _H), ZPR16,
581                                     !if(is_col, TileVectorOpV16,
582                                                 TileVectorOpH16), sme_elm_idx0_7>;
583   defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _S), ZPR32,
584                                     !if(is_col, TileVectorOpV32,
585                                                 TileVectorOpH32), sme_elm_idx0_3>;
586   defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _D), ZPR64,
587                                     !if(is_col, TileVectorOpV64,
588                                                 TileVectorOpH64), sme_elm_idx0_1>;
589   defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _Q), ZPR128,
590                                     !if(is_col, TileVectorOpV128,
591                                                 TileVectorOpH128), sme_elm_idx0_0>;
592 }
593
594 multiclass sme_tile_to_vector<string mnemonic> {
595   defm _H : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b0>;
596   defm _V : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b1>;
597 }
598
599 //===----------------------------------------------------------------------===//
600 // SME Zero
601 //===----------------------------------------------------------------------===//
602
603 class sme_zero_inst<string mnemonic>
604     : I<(outs MatrixTileList:$imm), (ins),
605         mnemonic, "\t$imm", "", []>, Sched<[]> {
606   bits<8> imm;
607   let Inst{31-8} = 0b110000000000100000000000;
608   let Inst{7-0}  = imm;
609 }
610
611 multiclass sme_zero<string mnemonic> {
612   def NAME : sme_zero_inst<mnemonic>;
613
614   def : InstAlias<"zero\t\\{za\\}", (!cast<Instruction>(NAME) 0b11111111), 1>;
615   def : InstAlias<"zero\t\\{za0.h\\}", (!cast<Instruction>(NAME) 0b01010101), 1>;
616   def : InstAlias<"zero\t\\{za1.h\\}", (!cast<Instruction>(NAME) 0b10101010), 1>;
617   def : InstAlias<"zero\t\\{za0.s\\}", (!cast<Instruction>(NAME) 0b00010001), 1>;
618   def : InstAlias<"zero\t\\{za1.s\\}", (!cast<Instruction>(NAME) 0b00100010), 1>;
619   def : InstAlias<"zero\t\\{za2.s\\}", (!cast<Instruction>(NAME) 0b01000100), 1>;
620   def : InstAlias<"zero\t\\{za3.s\\}", (!cast<Instruction>(NAME) 0b10001000), 1>;
621   def : InstAlias<"zero\t\\{za0.s,za1.s\\}", (!cast<Instruction>(NAME) 0b00110011), 1>;
622   def : InstAlias<"zero\t\\{za0.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10011001), 1>;
623   def : InstAlias<"zero\t\\{za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01100110), 1>;
624   def : InstAlias<"zero\t\\{za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11001100), 1>;
625   def : InstAlias<"zero\t\\{za0.s,za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01110111), 1>;
626   def : InstAlias<"zero\t\\{za0.s,za1.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10111011), 1>;
627   def : InstAlias<"zero\t\\{za0.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11011101), 1>;
628   def : InstAlias<"zero\t\\{za1.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11101110), 1>;
629 }
630
631 //===----------------------------------------------------------------------===//
632 // SVE2 Instructions
633 //===----------------------------------------------------------------------===//
634
635 class sve2_int_perm_revd<string asm>
636     : I<(outs ZPR128:$Zd), (ins ZPR128:$_Zd, PPR3bAny:$Pg, ZPR128:$Zn),
637         asm, "\t$Zd, $Pg/m, $Zn", "", []>,
638       Sched<[]> {
639   bits<5> Zd;
640   bits<3> Pg;
641   bits<5> Zn;
642   let Inst{31-24} = 0b00000101;
643   let Inst{23-22} = 0b00; // size
644   let Inst{21-13} = 0b101110100;
645   let Inst{12-10} = Pg;
646   let Inst{9-5}   = Zn;
647   let Inst{4-0}   = Zd;
648
649   let Constraints = "$Zd = $_Zd";
650   let DestructiveInstType = DestructiveUnary;
651   let ElementSize = ZPR128.ElementSize;
652 }
653
654 class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
655     : I<(outs zpr_ty:$Zd), (ins zpr_ty:$Zn, zpr_ty:$Zm, zpr_ty:$_Zd),
656         asm, "\t$Zd, $Zn, $Zm", "", []>,
657       Sched<[]> {
658   bits<5> Zm;
659   bits<5> Zn;
660   bits<5> Zd;
661   let Inst{31-24} = 0b01000100;
662   let Inst{23-22} = sz;
663   let Inst{21}    = 0b0;
664   let Inst{20-16} = Zm;
665   let Inst{15-11} = 0b11000;
666   let Inst{10}    = U;
667   let Inst{9-5}   = Zn;
668   let Inst{4-0}   = Zd;
669
670   let Constraints = "$Zd = $_Zd";
671   let DestructiveInstType = DestructiveOther;
672   let ElementSize = zpr_ty.ElementSize;
673 }
674
675 multiclass sve2_clamp<string asm, bit U> {
676   def _B : sve2_clamp<asm, 0b00, U, ZPR8>;
677   def _H : sve2_clamp<asm, 0b01, U, ZPR16>;
678   def _S : sve2_clamp<asm, 0b10, U, ZPR32>;
679   def _D : sve2_clamp<asm, 0b11, U, ZPR64>;
680 }
681
682 class sve2_int_perm_sel_p<string asm, PPRRegOp ppr_ty, Operand imm_ty>
683     : I<(outs PPRAny:$Pd), (ins PPRAny:$Pn, ppr_ty:$Pm,
684                             MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm),
685         asm, "\t$Pd, $Pn, $Pm[$Rv, $imm]", "", []>,
686       Sched<[]> {
687   bits<2> Rv;
688   bits<4> Pn;
689   bits<4> Pm;
690   bits<4> Pd;
691   let Inst{31-24} = 0b00100101;
692   let Inst{21}    = 0b1;
693   let Inst{17-16} = Rv;
694   let Inst{15-14} = 0b01;
695   let Inst{13-10} = Pn;
696   let Inst{9}     = 0b0;
697   let Inst{8-5}   = Pm;
698   let Inst{4}     = 0b0;
699   let Inst{3-0}   = Pd;
700 }
701
702 multiclass sve2_int_perm_sel_p<string asm> {
703   def _B : sve2_int_perm_sel_p<asm, PPR8, sme_elm_idx0_15> {
704     bits<4> imm;
705     let Inst{23-22} = imm{3-2};
706     let Inst{20-19} = imm{1-0};
707     let Inst{18}    = 0b1;
708   }
709   def _H : sve2_int_perm_sel_p<asm, PPR16, sme_elm_idx0_7> {
710     bits<3> imm;
711     let Inst{23-22} = imm{2-1};
712     let Inst{20}    = imm{0};
713     let Inst{19-18} = 0b10;
714   }
715   def _S : sve2_int_perm_sel_p<asm, PPR32, sme_elm_idx0_3> {
716     bits<2> imm;
717     let Inst{23-22} = imm{1-0};
718     let Inst{20-18} = 0b100;
719   }
720   def _D : sve2_int_perm_sel_p<asm, PPR64, sme_elm_idx0_1> {
721     bits<1> imm;
722     let Inst{23}    = imm;
723     let Inst{22}    = 0b1;
724     let Inst{20-18} = 0b000;
725   }
726 }