xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/SMEInstrFormats.td (revision 69ade1e033e478ec426cafc0ec2104d672de294a)
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_BHSD<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        0b0, 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
192class sme_mem_ld_ss_inst_Q<string mnemonic, MatrixTileVectorOperand tile_ty,
193                           bit is_col>
194    : sme_mem_ld_ss_base<
195        0b1, is_col, 0b11, (outs tile_ty:$ZAt),
196        (ins MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg, GPR64sp:$Rn,
197             GPR64shifted128:$Rm),
198        mnemonic, "\t\\{$ZAt[$Rv]\\}, $Pg/z, [$Rn, $Rm]">;
199
200multiclass sme_mem_ss_aliases_BHSD<string mnemonic, Instruction inst,
201                                   MatrixTileVectorOperand tile_ty, Operand imm_ty,
202                                   RegisterOperand gpr_ty,
203                                   string pg_suffix=""> {
204  def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn, $Rm]",
205                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, gpr_ty:$Rm), 0>;
206  // Default XZR offset aliases
207  def : InstAlias<mnemonic # "\t\\{$ZAt[$Rv, $imm]\\}, $Pg" # pg_suffix # ", [$Rn]",
208                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
209  def : InstAlias<mnemonic # "\t$ZAt[$Rv, $imm], $Pg" # pg_suffix # ", [$Rn]",
210                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
211}
212
213multiclass sme_mem_ss_aliases_Q<string mnemonic, Instruction inst,
214                                MatrixTileVectorOperand tile_ty,
215                                string pg_suffix=""> {
216  def : InstAlias<mnemonic # "\t$ZAt[$Rv], $Pg" # pg_suffix # ", [$Rn, $Rm]",
217                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg, GPR64sp:$Rn, GPR64shifted128:$Rm), 0>;
218  // Default XZR offset aliases
219  def : InstAlias<mnemonic # "\t\\{$ZAt[$Rv]\\}, $Pg" # pg_suffix # ", [$Rn]",
220                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 2>;
221  def : InstAlias<mnemonic # "\t$ZAt[$Rv], $Pg" # pg_suffix # ", [$Rn]",
222                  (inst tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
223}
224
225multiclass sme_mem_ss_aliases<string mnemonic, string inst, bit is_col,
226                              string pg_suffix=""> {
227  defm : sme_mem_ss_aliases_BHSD<mnemonic # "b", !cast<Instruction>(inst # _B),
228                                 !if(is_col, TileVectorOpV8, TileVectorOpH8),
229                                 imm0_15, GPR64shifted8, pg_suffix>;
230  defm : sme_mem_ss_aliases_BHSD<mnemonic # "h", !cast<Instruction>(inst # _H),
231                                 !if(is_col, TileVectorOpV16, TileVectorOpH16),
232                                 imm0_7, GPR64shifted16, pg_suffix>;
233  defm : sme_mem_ss_aliases_BHSD<mnemonic # "w", !cast<Instruction>(inst # _S),
234                                 !if(is_col, TileVectorOpV32, TileVectorOpH32),
235                                 imm0_3, GPR64shifted32, pg_suffix>;
236  defm : sme_mem_ss_aliases_BHSD<mnemonic # "d", !cast<Instruction>(inst # _D),
237                                 !if(is_col, TileVectorOpV64, TileVectorOpH64),
238                                 imm0_1, GPR64shifted64, pg_suffix>;
239  defm : sme_mem_ss_aliases_Q   <mnemonic # "q", !cast<Instruction>(inst # _Q),
240                                 !if(is_col, TileVectorOpV128, TileVectorOpH128),
241                                 pg_suffix>;
242}
243
244multiclass sme_mem_ld_ss_aliases<string inst, bit is_col> {
245  defm NAME : sme_mem_ss_aliases<"ld1", inst, is_col, "/z">;
246}
247
248multiclass sme_mem_ld_v_ss<string mnemonic, bit is_col> {
249  def _B : sme_mem_ld_ss_inst_BHSD<0b00, mnemonic # "b",
250                                   !if(is_col, TileVectorOpV8,
251                                               TileVectorOpH8),
252                                   is_col, imm0_15, GPR64shifted8> {
253    bits<4> imm;
254    let Inst{3-0} = imm;
255  }
256  def _H : sme_mem_ld_ss_inst_BHSD<0b01, mnemonic # "h",
257                                   !if(is_col, TileVectorOpV16,
258                                               TileVectorOpH16),
259                                   is_col, imm0_7, GPR64shifted16> {
260    bits<1> ZAt;
261    bits<3> imm;
262    let Inst{3}   = ZAt;
263    let Inst{2-0} = imm;
264  }
265  def _S : sme_mem_ld_ss_inst_BHSD<0b10, mnemonic # "w",
266                                   !if(is_col, TileVectorOpV32,
267                                               TileVectorOpH32),
268                                   is_col, imm0_3, GPR64shifted32> {
269    bits<2> ZAt;
270    bits<2> imm;
271    let Inst{3-2} = ZAt;
272    let Inst{1-0} = imm;
273  }
274  def _D : sme_mem_ld_ss_inst_BHSD<0b11, mnemonic # "d",
275                                   !if(is_col, TileVectorOpV64,
276                                               TileVectorOpH64),
277                                   is_col, imm0_1, GPR64shifted64> {
278    bits<3> ZAt;
279    bits<1> imm;
280    let Inst{3-1} = ZAt;
281    let Inst{0}   = imm;
282  }
283  def _Q : sme_mem_ld_ss_inst_Q<mnemonic # "q",
284                                !if(is_col, TileVectorOpV128,
285                                            TileVectorOpH128),
286                                is_col> {
287    bits<4> ZAt;
288    let Inst{3-0} = ZAt;
289  }
290
291  defm : sme_mem_ld_ss_aliases<NAME, is_col>;
292}
293
294multiclass sme_mem_ld_ss<string mnemonic> {
295  defm _H : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b0>;
296  defm _V : sme_mem_ld_v_ss<mnemonic, /*is_col=*/0b1>;
297}
298
299//===----------------------------------------------------------------------===//
300// SME Contiguous Stores
301//===----------------------------------------------------------------------===//
302
303class sme_mem_st_ss_base<bit Q, bit V, bits<2> msz, dag ins,
304                         string mnemonic, string argstr>
305    : I<(outs), ins, mnemonic, argstr, "", []>, Sched<[]> {
306  bits<5> Rm;
307  bits<2> Rv;
308  bits<3> Pg;
309  bits<5> Rn;
310  let Inst{31-25} = 0b1110000;
311  let Inst{24}    = Q;
312  let Inst{23-22} = msz;
313  let Inst{21}    = 0b1;
314  let Inst{20-16} = Rm;
315  let Inst{15}    = V;
316  let Inst{14-13} = Rv;
317  let Inst{12-10} = Pg;
318  let Inst{9-5}   = Rn;
319  let Inst{4}     = 0b0;
320
321  let mayStore = 1;
322  let hasSideEffects = 1;
323}
324
325class sme_mem_st_ss_inst_BHSD<bits<2> msz, string mnemonic,
326                              MatrixTileVectorOperand tile_ty, bit is_col,
327                              Operand imm_ty, RegisterOperand gpr_ty>
328    : sme_mem_st_ss_base<
329        0b0, is_col, msz,
330        (ins tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg,
331             GPR64sp:$Rn, gpr_ty:$Rm),
332        mnemonic, "\t\\{$ZAt[$Rv, $imm]\\}, $Pg, [$Rn, $Rm]">;
333
334class sme_mem_st_ss_inst_Q<string mnemonic, MatrixTileVectorOperand tile_ty,
335                           bit is_col>
336    : sme_mem_st_ss_base<
337        0b1, is_col, 0b11,
338        (ins tile_ty:$ZAt, MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg,
339             GPR64sp:$Rn, GPR64shifted128:$Rm),
340        mnemonic, "\t\\{$ZAt[$Rv]\\}, $Pg, [$Rn, $Rm]">;
341
342multiclass sme_mem_st_ss_aliases<string inst, bit is_col> {
343  defm NAME : sme_mem_ss_aliases<"st1", inst, is_col>;
344}
345
346multiclass sme_mem_st_v_ss<string mnemonic, bit is_col> {
347  def _B : sme_mem_st_ss_inst_BHSD<0b00, mnemonic # "b",
348                                   !if(is_col, TileVectorOpV8,
349                                               TileVectorOpH8),
350                                   is_col, imm0_15, GPR64shifted8> {
351    bits<4> imm;
352    let Inst{3-0} = imm;
353  }
354  def _H : sme_mem_st_ss_inst_BHSD<0b01, mnemonic # "h",
355                                   !if(is_col, TileVectorOpV16,
356                                               TileVectorOpH16),
357                                   is_col, imm0_7, GPR64shifted16> {
358    bits<1> ZAt;
359    bits<3> imm;
360    let Inst{3}   = ZAt;
361    let Inst{2-0} = imm;
362  }
363  def _S : sme_mem_st_ss_inst_BHSD<0b10, mnemonic # "w",
364                                   !if(is_col, TileVectorOpV32,
365                                               TileVectorOpH32),
366                                   is_col, imm0_3, GPR64shifted32> {
367    bits<2> ZAt;
368    bits<2> imm;
369    let Inst{3-2} = ZAt;
370    let Inst{1-0} = imm;
371  }
372  def _D : sme_mem_st_ss_inst_BHSD<0b11, mnemonic # "d",
373                                   !if(is_col, TileVectorOpV64,
374                                               TileVectorOpH64),
375                                   is_col, imm0_1, GPR64shifted64> {
376    bits<3> ZAt;
377    bits<1> imm;
378    let Inst{3-1} = ZAt;
379    let Inst{0}   = imm;
380  }
381  def _Q : sme_mem_st_ss_inst_Q<mnemonic # "q",
382                                !if(is_col, TileVectorOpV128,
383                                            TileVectorOpH128),
384                                is_col> {
385    bits<4> ZAt;
386    let Inst{3-0} = ZAt;
387  }
388
389  defm : sme_mem_st_ss_aliases<NAME, is_col>;
390}
391
392multiclass sme_mem_st_ss<string mnemonic> {
393  defm _H : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b0>;
394  defm _V : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b1>;
395}
396
397//===----------------------------------------------------------------------===//
398// SME Save and Restore Array
399//===----------------------------------------------------------------------===//
400
401class sme_spill_fill_inst<bit isStore, dag outs, dag ins, string opcodestr>
402    : I<outs, ins, opcodestr, "\t$ZAt[$Rv, $imm4], [$Rn, $offset, mul vl]", "",
403        []>,
404      Sched<[]> {
405  bits<2> Rv;
406  bits<5> Rn;
407  bits<4> imm4;
408  let Inst{31-22} = 0b1110000100;
409  let Inst{21}    = isStore;
410  let Inst{20-15} = 0b000000;
411  let Inst{14-13} = Rv;
412  let Inst{12-10} = 0b000;
413  let Inst{9-5}   = Rn;
414  let Inst{4}     = 0b0;
415  let Inst{3-0}   = imm4;
416
417  let mayLoad = !not(isStore);
418  let mayStore = isStore;
419}
420
421multiclass sme_spill_fill<bit isStore, dag outs, dag ins, string opcodestr> {
422  def NAME : sme_spill_fill_inst<isStore, outs, ins, opcodestr>;
423
424  def : InstAlias<opcodestr # "\t$ZAt[$Rv, $imm4], [$Rn]",
425                  (!cast<Instruction>(NAME) MatrixOp:$ZAt,
426                   MatrixIndexGPR32Op12_15:$Rv, imm0_15:$imm4, GPR64sp:$Rn, 0), 1>;
427}
428
429multiclass sme_spill<string opcodestr> {
430  defm NAME : sme_spill_fill<0b1, (outs),
431                             (ins MatrixOp:$ZAt, MatrixIndexGPR32Op12_15:$Rv,
432                                  imm0_15:$imm4, GPR64sp:$Rn,
433                                  imm0_15:$offset),
434                             opcodestr>;
435}
436
437multiclass sme_fill<string opcodestr> {
438  defm NAME : sme_spill_fill<0b0, (outs MatrixOp:$ZAt),
439                             (ins MatrixIndexGPR32Op12_15:$Rv,
440                                  imm0_15:$imm4, GPR64sp:$Rn,
441                                  imm0_15:$offset),
442                             opcodestr>;
443}
444
445//===----------------------------------------------------------------------===//
446// Move instructions
447//===----------------------------------------------------------------------===//
448
449class sme_vector_to_tile_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
450                              string mnemonic, string argstr>
451    : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
452  bits<2> Rv;
453  bits<3> Pg;
454  bits<5> Zn;
455  let Inst{31-24} = 0b11000000;
456  let Inst{23-22} = sz;
457  let Inst{21-17} = 0b00000;
458  let Inst{16}    = Q;
459  let Inst{15}    = V;
460  let Inst{14-13} = Rv;
461  let Inst{12-10} = Pg;
462  let Inst{9-5}   = Zn;
463  let Inst{4}     = 0b0;
464}
465
466class sme_vector_to_tile_inst<bits<2> sz, MatrixTileVectorOperand tile_ty,
467                              bit is_col, Operand imm_ty, ZPRRegOp zpr_ty,
468                              string mnemonic>
469    : sme_vector_to_tile_base<0b0, is_col, sz, (outs tile_ty:$ZAd),
470        (ins MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn),
471        mnemonic, "\t$ZAd[$Rv, $imm], $Pg/m, $Zn">;
472
473class sme_vector_to_tile_inst_Q<MatrixTileVectorOperand tile_ty,
474                                bit is_col, string mnemonic>
475    : sme_vector_to_tile_base<0b1, is_col, 0b11, (outs tile_ty:$ZAd),
476        (ins MatrixIndexGPR32Op12_15:$Rv, PPR3bAny:$Pg, ZPR128:$Zn),
477        mnemonic, "\t$ZAd[$Rv], $Pg/m, $Zn">;
478
479multiclass sme_vector_to_tile_aliases<Instruction inst,
480                                      MatrixTileVectorOperand tile_ty,
481                                      ZPRRegOp zpr_ty, Operand imm_ty> {
482  def : InstAlias<"mov\t$ZAd[$Rv, $imm], $Pg/m, $Zn",
483                  (inst tile_ty:$ZAd, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm, PPR3bAny:$Pg, zpr_ty:$Zn), 1>;
484}
485
486multiclass sme_vector_v_to_tile<string mnemonic, bit is_col> {
487  def _B : sme_vector_to_tile_inst<0b00, !if(is_col, TileVectorOpV8,
488                                                     TileVectorOpH8),
489                                   is_col, imm0_15, ZPR8, mnemonic> {
490    bits<4> imm;
491    let Inst{3-0} = imm;
492  }
493  def _H : sme_vector_to_tile_inst<0b01, !if(is_col, TileVectorOpV16,
494                                                     TileVectorOpH16),
495                                   is_col, imm0_7, ZPR16, mnemonic> {
496    bits<1> ZAd;
497    bits<3> imm;
498    let Inst{3}   = ZAd;
499    let Inst{2-0} = imm;
500  }
501  def _S : sme_vector_to_tile_inst<0b10, !if(is_col, TileVectorOpV32,
502                                                     TileVectorOpH32),
503                                   is_col, imm0_3, ZPR32, mnemonic> {
504    bits<2> ZAd;
505    bits<2> imm;
506    let Inst{3-2} = ZAd;
507    let Inst{1-0} = imm;
508  }
509  def _D : sme_vector_to_tile_inst<0b11, !if(is_col, TileVectorOpV64,
510                                                     TileVectorOpH64),
511                                   is_col, imm0_1, ZPR64, mnemonic> {
512    bits<3> ZAd;
513    bits<1> imm;
514    let Inst{3-1} = ZAd;
515    let Inst{0}   = imm;
516  }
517  def _Q : sme_vector_to_tile_inst_Q<!if(is_col, TileVectorOpV128,
518                                                 TileVectorOpH128),
519                                     is_col, mnemonic> {
520    bits<4> ZAd;
521    bits<1> imm;
522    let Inst{3-0} = ZAd;
523  }
524
525  defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _B),
526                                    !if(is_col, TileVectorOpV8,
527                                                TileVectorOpH8),
528                                    ZPR8, imm0_15>;
529  defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _H),
530                                    !if(is_col, TileVectorOpV16,
531                                                TileVectorOpH16),
532                                    ZPR16, imm0_7>;
533  defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _S),
534                                    !if(is_col, TileVectorOpV32,
535                                                TileVectorOpH32),
536                                    ZPR32, imm0_3>;
537  defm : sme_vector_to_tile_aliases<!cast<Instruction>(NAME # _D),
538                                    !if(is_col, TileVectorOpV64,
539                                                TileVectorOpH64),
540                                    ZPR64, imm0_1>;
541
542  def : InstAlias<"mov\t$ZAd[$Rv], $Pg/m, $Zn",
543                  (!cast<Instruction>(NAME # _Q) !if(is_col,
544                                                      TileVectorOpV128,
545                                                      TileVectorOpH128):$ZAd,
546                                                 MatrixIndexGPR32Op12_15:$Rv,
547                                                 PPR3bAny:$Pg, ZPR128:$Zn), 1>;
548}
549
550multiclass sme_vector_to_tile<string mnemonic> {
551  defm _H : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b0>;
552  defm _V : sme_vector_v_to_tile<mnemonic, /*is_col=*/0b1>;
553}
554
555class sme_tile_to_vector_base<bit Q, bit V, bits<2> sz, dag outs, dag ins,
556                              string mnemonic, string argstr>
557    : I<outs, ins, mnemonic, argstr, "", []>, Sched<[]> {
558  bits<2> Rv;
559  bits<3> Pg;
560  bits<5> Zd;
561  let Inst{31-24} = 0b11000000;
562  let Inst{23-22} = sz;
563  let Inst{21-17} = 0b00001;
564  let Inst{16}    = Q;
565  let Inst{15}    = V;
566  let Inst{14-13} = Rv;
567  let Inst{12-10} = Pg;
568  let Inst{9}     = 0b0;
569  let Inst{4-0}   = Zd;
570}
571
572class sme_tile_to_vector_inst<bits<2> sz, ZPRRegOp zpr_ty,
573                              MatrixTileVectorOperand tile_ty,
574                              bit is_col, Operand imm_ty, string mnemonic>
575    : sme_tile_to_vector_base<0b0, is_col, sz, (outs zpr_ty:$Zd),
576        (ins PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm),
577        mnemonic, "\t$Zd, $Pg/m, $ZAn[$Rv, $imm]">;
578
579class sme_tile_to_vector_inst_Q<MatrixTileVectorOperand tile_ty,
580                                bit is_col, string mnemonic>
581    : sme_tile_to_vector_base<0b1, is_col, 0b11, (outs ZPR128:$Zd),
582        (ins PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv),
583        mnemonic, "\t$Zd, $Pg/m, $ZAn[$Rv]">;
584
585multiclass sme_tile_to_vector_aliases<Instruction inst, ZPRRegOp zpr_ty,
586                                      MatrixTileVectorOperand tile_ty,
587                                      Operand imm_ty > {
588  def : InstAlias<"mov\t$Zd, $Pg/m, $ZAn[$Rv, $imm]",
589                  (inst zpr_ty:$Zd, PPR3bAny:$Pg, tile_ty:$ZAn, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm), 1>;
590}
591
592multiclass sme_tile_to_vector_v<string mnemonic, bit is_col> {
593  def _B : sme_tile_to_vector_inst<0b00, ZPR8, !if(is_col, TileVectorOpV8,
594                                                           TileVectorOpH8),
595                                   is_col, imm0_15, mnemonic> {
596    bits<4> imm;
597    let Inst{8-5} = imm;
598  }
599  def _H : sme_tile_to_vector_inst<0b01, ZPR16, !if(is_col, TileVectorOpV16,
600                                                            TileVectorOpH16),
601                                   is_col, imm0_7, mnemonic> {
602    bits<1> ZAn;
603    bits<3> imm;
604    let Inst{8}   = ZAn;
605    let Inst{7-5} = imm;
606  }
607  def _S : sme_tile_to_vector_inst<0b10, ZPR32, !if(is_col, TileVectorOpV32,
608                                                            TileVectorOpH32),
609                                   is_col, imm0_3, mnemonic> {
610    bits<2> ZAn;
611    bits<2> imm;
612    let Inst{8-7} = ZAn;
613    let Inst{6-5} = imm;
614  }
615  def _D : sme_tile_to_vector_inst<0b11, ZPR64, !if(is_col, TileVectorOpV64,
616                                                            TileVectorOpH64),
617                                   is_col, imm0_1, mnemonic> {
618    bits<3> ZAn;
619    bits<1> imm;
620    let Inst{8-6} = ZAn;
621    let Inst{5}   = imm;
622  }
623  def _Q : sme_tile_to_vector_inst_Q<!if(is_col, TileVectorOpV128,
624                                                 TileVectorOpH128),
625                                     is_col, mnemonic> {
626    bits<4> ZAn;
627    let Inst{8-5} = ZAn;
628  }
629
630  defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _B), ZPR8,
631                                    !if(is_col, TileVectorOpV8,
632                                                TileVectorOpH8), imm0_15>;
633  defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _H), ZPR16,
634                                    !if(is_col, TileVectorOpV16,
635                                                TileVectorOpH16), imm0_7>;
636  defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _S), ZPR32,
637                                    !if(is_col, TileVectorOpV32,
638                                                TileVectorOpH32), imm0_3>;
639  defm : sme_tile_to_vector_aliases<!cast<Instruction>(NAME # _D), ZPR64,
640                                    !if(is_col, TileVectorOpV64,
641                                                TileVectorOpH64), imm0_1>;
642
643  def : InstAlias<"mov\t$Zd, $Pg/m, $ZAn[$Rv]",
644                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, PPR3bAny:$Pg,
645                                                 !if(is_col,
646                                                      TileVectorOpV128,
647                                                      TileVectorOpH128):$ZAn,
648                                                 MatrixIndexGPR32Op12_15:$Rv), 1>;
649}
650
651multiclass sme_tile_to_vector<string mnemonic> {
652  defm _H : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b0>;
653  defm _V : sme_tile_to_vector_v<mnemonic, /*is_col=*/0b1>;
654}
655
656//===----------------------------------------------------------------------===//
657// SME Zero
658//===----------------------------------------------------------------------===//
659
660class sme_zero_inst<string mnemonic>
661    : I<(outs MatrixTileList:$imm), (ins),
662        mnemonic, "\t$imm", "", []>, Sched<[]> {
663  bits<8> imm;
664  let Inst{31-8} = 0b110000000000100000000000;
665  let Inst{7-0}  = imm;
666}
667
668multiclass sme_zero<string mnemonic> {
669  def NAME : sme_zero_inst<mnemonic>;
670
671  def : InstAlias<"zero\t\\{za\\}", (!cast<Instruction>(NAME) 0b11111111), 1>;
672  def : InstAlias<"zero\t\\{za0.h\\}", (!cast<Instruction>(NAME) 0b01010101), 1>;
673  def : InstAlias<"zero\t\\{za1.h\\}", (!cast<Instruction>(NAME) 0b10101010), 1>;
674  def : InstAlias<"zero\t\\{za0.s\\}", (!cast<Instruction>(NAME) 0b00010001), 1>;
675  def : InstAlias<"zero\t\\{za1.s\\}", (!cast<Instruction>(NAME) 0b00100010), 1>;
676  def : InstAlias<"zero\t\\{za2.s\\}", (!cast<Instruction>(NAME) 0b01000100), 1>;
677  def : InstAlias<"zero\t\\{za3.s\\}", (!cast<Instruction>(NAME) 0b10001000), 1>;
678  def : InstAlias<"zero\t\\{za0.s,za1.s\\}", (!cast<Instruction>(NAME) 0b00110011), 1>;
679  def : InstAlias<"zero\t\\{za0.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10011001), 1>;
680  def : InstAlias<"zero\t\\{za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01100110), 1>;
681  def : InstAlias<"zero\t\\{za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11001100), 1>;
682  def : InstAlias<"zero\t\\{za0.s,za1.s,za2.s\\}", (!cast<Instruction>(NAME) 0b01110111), 1>;
683  def : InstAlias<"zero\t\\{za0.s,za1.s,za3.s\\}", (!cast<Instruction>(NAME) 0b10111011), 1>;
684  def : InstAlias<"zero\t\\{za0.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11011101), 1>;
685  def : InstAlias<"zero\t\\{za1.s,za2.s,za3.s\\}", (!cast<Instruction>(NAME) 0b11101110), 1>;
686}
687
688//===----------------------------------------------------------------------===//
689// SVE2 Instructions
690//===----------------------------------------------------------------------===//
691
692class sve2_int_perm_revd<string asm>
693    : I<(outs ZPR128:$Zd), (ins ZPR128:$_Zd, PPR3bAny:$Pg, ZPR128:$Zn),
694        asm, "\t$Zd, $Pg/m, $Zn", "", []>,
695      Sched<[]> {
696  bits<5> Zd;
697  bits<3> Pg;
698  bits<5> Zn;
699  let Inst{31-24} = 0b00000101;
700  let Inst{23-22} = 0b00; // size
701  let Inst{21-13} = 0b101110100;
702  let Inst{12-10} = Pg;
703  let Inst{9-5}   = Zn;
704  let Inst{4-0}   = Zd;
705
706  let Constraints = "$Zd = $_Zd";
707  let DestructiveInstType = DestructiveUnary;
708  let ElementSize = ZPR128.ElementSize;
709}
710
711class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
712    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$Zn, zpr_ty:$Zm, zpr_ty:$_Zd),
713        asm, "\t$Zd, $Zn, $Zm", "", []>,
714      Sched<[]> {
715  bits<5> Zm;
716  bits<5> Zn;
717  bits<5> Zd;
718  let Inst{31-24} = 0b01000100;
719  let Inst{23-22} = sz;
720  let Inst{21}    = 0b0;
721  let Inst{20-16} = Zm;
722  let Inst{15-11} = 0b11000;
723  let Inst{10}    = U;
724  let Inst{9-5}   = Zn;
725  let Inst{4-0}   = Zd;
726
727  let Constraints = "$Zd = $_Zd";
728  let DestructiveInstType = DestructiveOther;
729  let ElementSize = zpr_ty.ElementSize;
730}
731
732multiclass sve2_clamp<string asm, bit U> {
733  def _B : sve2_clamp<asm, 0b00, U, ZPR8>;
734  def _H : sve2_clamp<asm, 0b01, U, ZPR16>;
735  def _S : sve2_clamp<asm, 0b10, U, ZPR32>;
736  def _D : sve2_clamp<asm, 0b11, U, ZPR64>;
737}
738
739class sve2_int_perm_dup_p<string asm, PPRRegOp ppr_ty, Operand imm_ty>
740    : I<(outs ppr_ty:$Pd), (ins PPRAny:$Pg, ppr_ty:$Pn,
741                                MatrixIndexGPR32Op12_15:$Rm, imm_ty:$imm),
742        asm, "\t$Pd, $Pg/z, $Pn[$Rm, $imm]", "", []>,
743      Sched<[]> {
744  bits<2> Rm;
745  bits<4> Pg;
746  bits<4> Pn;
747  bits<4> Pd;
748  let Inst{31-24} = 0b00100101;
749  let Inst{21}    = 0b1;
750  let Inst{17-16} = Rm;
751  let Inst{15-14} = 0b01;
752  let Inst{13-10} = Pg;
753  let Inst{9}     = 0b0;
754  let Inst{8-5}   = Pn;
755  let Inst{4}     = 0b0;
756  let Inst{3-0}   = Pd;
757}
758
759multiclass sve2_int_perm_dup_p<string asm> {
760  def _B : sve2_int_perm_dup_p<asm, PPR8, imm0_15> {
761    bits<4> imm;
762    let Inst{23-22} = imm{3-2};
763    let Inst{20-19} = imm{1-0};
764    let Inst{18}    = 0b1;
765  }
766  def _H : sve2_int_perm_dup_p<asm, PPR16, imm0_7> {
767    bits<3> imm;
768    let Inst{23-22} = imm{2-1};
769    let Inst{20}    = imm{0};
770    let Inst{19-18} = 0b10;
771  }
772  def _S : sve2_int_perm_dup_p<asm, PPR32, imm0_3> {
773    bits<2> imm;
774    let Inst{23-22} = imm{1-0};
775    let Inst{20-18} = 0b100;
776  }
777  def _D : sve2_int_perm_dup_p<asm, PPR64, imm0_1> {
778    bits<1> imm;
779    let Inst{23}    = imm;
780    let Inst{22}    = 0b1;
781    let Inst{20-18} = 0b000;
782  }
783
784  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
785                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, PPRAny:$Pg, PPR8:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
786  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
787                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, PPRAny:$Pg, PPR16:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
788  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
789                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, PPRAny:$Pg, PPR32:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
790  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
791                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, PPRAny:$Pg, PPR64:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
792}
793