1//=- AArch64SMEInstrInfo.td -  AArch64 SME Instructions -*- 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 definitions.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// Add vector elements horizontally or vertically to ZA tile.
15//===----------------------------------------------------------------------===//
16
17def SDT_AArch64RDSVL  : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
18def AArch64rdsvl : SDNode<"AArch64ISD::RDSVL", SDT_AArch64RDSVL>;
19
20let Predicates = [HasSME] in {
21def RDSVLI_XI  : sve_int_read_vl_a<0b0, 0b11111, "rdsvl", /*streaming_sve=*/0b1>;
22def ADDSPL_XXI : sve_int_arith_vl<0b1, "addspl", /*streaming_sve=*/0b1>;
23def ADDSVL_XXI : sve_int_arith_vl<0b0, "addsvl", /*streaming_sve=*/0b1>;
24
25def ADDHA_MPPZ_S : sme_add_vector_to_tile_u32<0b0, "addha">;
26def ADDVA_MPPZ_S : sme_add_vector_to_tile_u32<0b1, "addva">;
27
28def : Pat<(AArch64rdsvl (i32 simm6_32b:$imm)), (RDSVLI_XI simm6_32b:$imm)>;
29}
30
31let Predicates = [HasSMEI64] in {
32def ADDHA_MPPZ_D : sme_add_vector_to_tile_u64<0b0, "addha">;
33def ADDVA_MPPZ_D : sme_add_vector_to_tile_u64<0b1, "addva">;
34}
35
36let Predicates = [HasSME] in {
37//===----------------------------------------------------------------------===//
38// Outer products
39//===----------------------------------------------------------------------===//
40
41defm BFMOPA_MPPZZ  : sme_bf16_outer_product<0b0, "bfmopa", int_aarch64_sme_mopa_wide>;
42defm BFMOPS_MPPZZ  : sme_bf16_outer_product<0b1, "bfmops", int_aarch64_sme_mops_wide>;
43
44defm FMOPA_MPPZZ_S : sme_outer_product_fp32<0b0, "fmopa", int_aarch64_sme_mopa>;
45defm FMOPS_MPPZZ_S : sme_outer_product_fp32<0b1, "fmops", int_aarch64_sme_mops>;
46}
47
48let Predicates = [HasSMEF64] in {
49defm FMOPA_MPPZZ_D : sme_outer_product_fp64<0b0, "fmopa", int_aarch64_sme_mopa>;
50defm FMOPS_MPPZZ_D : sme_outer_product_fp64<0b1, "fmops", int_aarch64_sme_mops>;
51}
52
53let Predicates = [HasSME] in {
54defm FMOPAL_MPPZZ  : sme_f16_outer_product<0b0, "fmopa", int_aarch64_sme_mopa_wide>;
55defm FMOPSL_MPPZZ  : sme_f16_outer_product<0b1, "fmops", int_aarch64_sme_mops_wide>;
56
57defm SMOPA_MPPZZ_S  : sme_int_outer_product_i32<0b000, "smopa",  int_aarch64_sme_smopa_wide>;
58defm SMOPS_MPPZZ_S  : sme_int_outer_product_i32<0b001, "smops",  int_aarch64_sme_smops_wide>;
59defm UMOPA_MPPZZ_S  : sme_int_outer_product_i32<0b110, "umopa",  int_aarch64_sme_umopa_wide>;
60defm UMOPS_MPPZZ_S  : sme_int_outer_product_i32<0b111, "umops",  int_aarch64_sme_umops_wide>;
61defm SUMOPA_MPPZZ_S : sme_int_outer_product_i32<0b010, "sumopa", int_aarch64_sme_sumopa_wide>;
62defm SUMOPS_MPPZZ_S : sme_int_outer_product_i32<0b011, "sumops", int_aarch64_sme_sumops_wide>;
63defm USMOPA_MPPZZ_S : sme_int_outer_product_i32<0b100, "usmopa", int_aarch64_sme_usmopa_wide>;
64defm USMOPS_MPPZZ_S : sme_int_outer_product_i32<0b101, "usmops", int_aarch64_sme_usmops_wide>;
65}
66
67let Predicates = [HasSMEI64] in {
68defm SMOPA_MPPZZ_D  : sme_int_outer_product_i64<0b000, "smopa",  int_aarch64_sme_smopa_wide>;
69defm SMOPS_MPPZZ_D  : sme_int_outer_product_i64<0b001, "smops",  int_aarch64_sme_smops_wide>;
70defm UMOPA_MPPZZ_D  : sme_int_outer_product_i64<0b110, "umopa",  int_aarch64_sme_umopa_wide>;
71defm UMOPS_MPPZZ_D  : sme_int_outer_product_i64<0b111, "umops",  int_aarch64_sme_umops_wide>;
72defm SUMOPA_MPPZZ_D : sme_int_outer_product_i64<0b010, "sumopa", int_aarch64_sme_sumopa_wide>;
73defm SUMOPS_MPPZZ_D : sme_int_outer_product_i64<0b011, "sumops", int_aarch64_sme_sumops_wide>;
74defm USMOPA_MPPZZ_D : sme_int_outer_product_i64<0b100, "usmopa", int_aarch64_sme_usmopa_wide>;
75defm USMOPS_MPPZZ_D : sme_int_outer_product_i64<0b101, "usmops", int_aarch64_sme_usmops_wide>;
76}
77
78let Predicates = [HasSME] in {
79//===----------------------------------------------------------------------===//
80// Loads and stores
81//===----------------------------------------------------------------------===//
82
83defm LD1_MXIPXX : sme_mem_ld_ss<"ld1">;
84defm ST1_MXIPXX : sme_mem_st_ss<"st1">;
85
86//===----------------------------------------------------------------------===//
87// Spill + fill
88//===----------------------------------------------------------------------===//
89
90defm LDR_ZA : sme_fill<"ldr">;
91defm STR_ZA : sme_spill<"str">;
92
93//===----------------------------------------------------------------------===//
94// Move instructions
95//===----------------------------------------------------------------------===//
96
97defm INSERT_MXIPZ  : sme_vector_to_tile<"mova">;
98defm EXTRACT_ZPMXI : sme_tile_to_vector<"mova">;
99
100//===----------------------------------------------------------------------===//
101// Zero instruction
102//===----------------------------------------------------------------------===//
103
104defm ZERO_M : sme_zero<"zero">;
105
106//===----------------------------------------------------------------------===//
107// Mode selection and state access instructions
108//===----------------------------------------------------------------------===//
109
110// SME defines three pstate fields to set or clear PSTATE.SM, PSTATE.ZA, or
111// both fields:
112//
113//   MSR SVCRSM, #<imm1>
114//   MSR SVCRZA, #<imm1>
115//   MSR SVCRSMZA, #<imm1>
116//
117// It's tricky to using the existing pstate operand defined in
118// AArch64SystemOperands.td since it only encodes 5 bits including op1;op2,
119// when these fields are also encoded in CRm[3:1].
120class MSRpstatesvcrImm0_1
121  : PstateWriteSimple<(ins svcr_op:$pstatefield, imm0_1:$imm), "msr",
122                      "\t$pstatefield, $imm">,
123    Sched<[WriteSys]> {
124  bits<3> pstatefield;
125  bit imm;
126  let Inst{18-16} = 0b011; // op1
127  let Inst{11-9} = pstatefield;
128  let Inst{8} = imm;
129  let Inst{7-5} = 0b011; // op2
130}
131
132def MSRpstatesvcrImm1 : MSRpstatesvcrImm0_1;
133def : InstAlias<"smstart",    (MSRpstatesvcrImm1 0b011, 0b1)>;
134def : InstAlias<"smstart sm", (MSRpstatesvcrImm1 0b001, 0b1)>;
135def : InstAlias<"smstart za", (MSRpstatesvcrImm1 0b010, 0b1)>;
136
137def : InstAlias<"smstop",     (MSRpstatesvcrImm1 0b011, 0b0)>;
138def : InstAlias<"smstop sm",  (MSRpstatesvcrImm1 0b001, 0b0)>;
139def : InstAlias<"smstop za",  (MSRpstatesvcrImm1 0b010, 0b0)>;
140
141// Read and write TPIDR2_EL0
142def : Pat<(int_aarch64_sme_set_tpidr2 i64:$val),
143          (MSR 0xde85, GPR64:$val)>;
144def : Pat<(i64 (int_aarch64_sme_get_tpidr2)),
145          (MRS 0xde85)>;
146
147//===----------------------------------------------------------------------===//
148// SVE2 instructions
149//===----------------------------------------------------------------------===//
150
151defm REVD_ZPmZ : sve2_int_perm_revd<"revd", AArch64revd_mt>;
152
153defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0, int_aarch64_sve_sclamp>;
154defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1, int_aarch64_sve_uclamp>;
155
156defm PSEL_PPPRI : sve2_int_perm_sel_p<"psel", int_aarch64_sve_psel>;
157
158} // End let Predicates = [HasSME]
159