xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/SMEInstrFormats.td (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
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
17class 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
39class 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
46class 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
52class 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
77class 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
85class 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
92class 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
114multiclass sme_bf16_outer_product<bit S, string mnemonic> {
115  def : sme_outer_product_widening_inst<0b0, S, mnemonic>;
116}
117
118multiclass 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
126class 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
145class 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
152class 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
162class 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
183class 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
192multiclass 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
205multiclass 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
224multiclass sme_mem_ld_ss_aliases<string inst, bit is_col> {
225  defm NAME : sme_mem_ss_aliases<"ld1", inst, is_col, "/z">;
226}
227
228multiclass 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
269multiclass 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
278class 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
300class 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
309multiclass sme_mem_st_ss_aliases<string inst, bit is_col> {
310  defm NAME : sme_mem_ss_aliases<"st1", inst, is_col>;
311}
312
313multiclass 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
354multiclass 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
363class 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
383multiclass 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
391multiclass 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
399multiclass 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
411class 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
428class 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
435multiclass 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
442multiclass 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
503multiclass 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
508class 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
525class 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
532multiclass 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
539multiclass 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
594multiclass 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
603class 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
611multiclass 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
635class 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
654class 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
675multiclass 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
682class 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
702multiclass 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}
727