1//===--- arm_sme.td - ARM SME compiler interface ------------------------===//
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//  This file defines the TableGen definitions from which the ARM SME header
10//  file will be generated.  See:
11//
12//      https://developer.arm.com/architectures/system-architectures/software-standards/acle
13//
14//===----------------------------------------------------------------------===//
15
16include "arm_sve_sme_incl.td"
17
18////////////////////////////////////////////////////////////////////////////////
19// Loads
20
21multiclass ZALoad<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
22  let TargetGuard = "sme" in {
23    def NAME # _H : MInst<"svld1_hor_" # n_suffix, "vimiPQ", t,
24                          [IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
25                          MemEltTyDefault, i_prefix # "_horiz", ch>;
26
27    def NAME # _H_VNUM : MInst<"svld1_hor_vnum_" # n_suffix, "vimiPQl", t,
28                               [IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
29                               MemEltTyDefault, i_prefix # "_horiz", ch>;
30
31    def NAME # _V : MInst<"svld1_ver_" # n_suffix, "vimiPQ", t,
32                          [IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
33                          MemEltTyDefault, i_prefix # "_vert", ch>;
34
35    def NAME # _V_VNUM : MInst<"svld1_ver_vnum_" # n_suffix, "vimiPQl", t,
36                               [IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
37                               MemEltTyDefault, i_prefix # "_vert", ch>;
38  }
39}
40
41defm SVLD1_ZA8 : ZALoad<"za8", "c", "aarch64_sme_ld1b", [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
42defm SVLD1_ZA16 : ZALoad<"za16", "s", "aarch64_sme_ld1h", [ImmCheck<0, ImmCheck0_1>, ImmCheck<2, ImmCheck0_7>]>;
43defm SVLD1_ZA32 : ZALoad<"za32", "i", "aarch64_sme_ld1w", [ImmCheck<0, ImmCheck0_3>, ImmCheck<2, ImmCheck0_3>]>;
44defm SVLD1_ZA64 : ZALoad<"za64", "l", "aarch64_sme_ld1d", [ImmCheck<0, ImmCheck0_7>, ImmCheck<2, ImmCheck0_1>]>;
45defm SVLD1_ZA128 : ZALoad<"za128", "q", "aarch64_sme_ld1q", [ImmCheck<0, ImmCheck0_15>, ImmCheck<2, ImmCheck0_0>]>;
46
47def SVLDR_VNUM_ZA : MInst<"svldr_vnum_za", "vmiQ", "",
48                          [IsOverloadNone, IsStreamingCompatible, IsSharedZA],
49                          MemEltTyDefault, "aarch64_sme_ldr",
50                          [ImmCheck<1, ImmCheck0_15>]>;
51
52////////////////////////////////////////////////////////////////////////////////
53// Stores
54
55multiclass ZAStore<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
56  let TargetGuard = "sme" in {
57    def NAME # _H : MInst<"svst1_hor_" # n_suffix, "vimiP%", t,
58                          [IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
59                          MemEltTyDefault, i_prefix # "_horiz", ch>;
60
61    def NAME # _H_VNUM : MInst<"svst1_hor_vnum_" # n_suffix, "vimiP%l", t,
62                               [IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
63                               MemEltTyDefault, i_prefix # "_horiz", ch>;
64
65    def NAME # _V : MInst<"svst1_ver_" # n_suffix, "vimiP%", t,
66                          [IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
67                          MemEltTyDefault, i_prefix # "_vert", ch>;
68
69    def NAME # _V_VNUM : MInst<"svst1_ver_vnum_" # n_suffix, "vimiP%l", t,
70                               [IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
71                               MemEltTyDefault, i_prefix # "_vert", ch>;
72  }
73}
74
75defm SVST1_ZA8 : ZAStore<"za8", "c", "aarch64_sme_st1b", [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
76defm SVST1_ZA16 : ZAStore<"za16", "s", "aarch64_sme_st1h", [ImmCheck<0, ImmCheck0_1>, ImmCheck<2, ImmCheck0_7>]>;
77defm SVST1_ZA32 : ZAStore<"za32", "i", "aarch64_sme_st1w", [ImmCheck<0, ImmCheck0_3>, ImmCheck<2, ImmCheck0_3>]>;
78defm SVST1_ZA64 : ZAStore<"za64", "l", "aarch64_sme_st1d", [ImmCheck<0, ImmCheck0_7>, ImmCheck<2, ImmCheck0_1>]>;
79defm SVST1_ZA128 : ZAStore<"za128", "q", "aarch64_sme_st1q", [ImmCheck<0, ImmCheck0_15>, ImmCheck<2, ImmCheck0_0>]>;
80
81def SVSTR_VNUM_ZA : MInst<"svstr_vnum_za", "vmi%", "",
82                          [IsOverloadNone, IsStreamingCompatible, IsSharedZA, IsPreservesZA],
83                          MemEltTyDefault, "aarch64_sme_str",
84                          [ImmCheck<1, ImmCheck0_15>]>;
85
86////////////////////////////////////////////////////////////////////////////////
87// Read horizontal/vertical ZA slices
88
89multiclass ZARead<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
90  let TargetGuard = "sme" in {
91    def NAME # _H : SInst<"svread_hor_" # n_suffix # "[_{d}]", "ddPimi", t,
92                          MergeOp1, i_prefix # "_horiz",
93                          [IsReadZA, IsStreaming, IsSharedZA, IsPreservesZA], ch>;
94
95    def NAME # _V : SInst<"svread_ver_" # n_suffix # "[_{d}]", "ddPimi", t,
96                          MergeOp1, i_prefix # "_vert",
97                          [IsReadZA, IsStreaming, IsSharedZA, IsPreservesZA], ch>;
98  }
99}
100
101defm SVREAD_ZA8 : ZARead<"za8", "cUc", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_0>, ImmCheck<4, ImmCheck0_15>]>;
102defm SVREAD_ZA16 : ZARead<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_1>, ImmCheck<4, ImmCheck0_7>]>;
103defm SVREAD_ZA32 : ZARead<"za32", "iUif", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_3>, ImmCheck<4, ImmCheck0_3>]>;
104defm SVREAD_ZA64 : ZARead<"za64", "lUld", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_7>, ImmCheck<4, ImmCheck0_1>]>;
105defm SVREAD_ZA128 : ZARead<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_readq", [ImmCheck<2, ImmCheck0_15>, ImmCheck<4, ImmCheck0_0>]>;
106
107////////////////////////////////////////////////////////////////////////////////
108// Write horizontal/vertical ZA slices
109
110multiclass ZAWrite<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
111  let TargetGuard = "sme" in {
112    def NAME # _H : SInst<"svwrite_hor_" # n_suffix # "[_{d}]", "vimiPd", t,
113                          MergeOp1, i_prefix # "_horiz",
114                          [IsWriteZA, IsStreaming, IsSharedZA], ch>;
115
116    def NAME # _V : SInst<"svwrite_ver_" # n_suffix # "[_{d}]", "vimiPd", t,
117                          MergeOp1, i_prefix # "_vert",
118                          [IsWriteZA, IsStreaming, IsSharedZA], ch>;
119  }
120}
121
122defm SVWRITE_ZA8 : ZAWrite<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
123defm SVWRITE_ZA16 : ZAWrite<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>, ImmCheck<2, ImmCheck0_7>]>;
124defm SVWRITE_ZA32 : ZAWrite<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>, ImmCheck<2, ImmCheck0_3>]>;
125defm SVWRITE_ZA64 : ZAWrite<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>, ImmCheck<2, ImmCheck0_1>]>;
126defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_writeq", [ImmCheck<0, ImmCheck0_15>, ImmCheck<2, ImmCheck0_0>]>;
127
128////////////////////////////////////////////////////////////////////////////////
129// SME - Zero
130
131let TargetGuard = "sme" in {
132  def SVZERO_MASK_ZA : SInst<"svzero_mask_za", "vi", "", MergeNone, "aarch64_sme_zero",
133                             [IsOverloadNone, IsStreamingCompatible, IsSharedZA],
134                             [ImmCheck<0, ImmCheck0_255>]>;
135  def SVZERO_ZA      : SInst<"svzero_za", "v", "", MergeNone, "aarch64_sme_zero",
136                             [IsOverloadNone, IsStreamingCompatible, IsSharedZA]>;
137}
138
139////////////////////////////////////////////////////////////////////////////////
140// SME - Counting elements in a streaming vector
141
142multiclass ZACount<string n_suffix> {
143  let TargetGuard = "sme" in {
144    def NAME : SInst<"sv" # n_suffix, "nv", "", MergeNone,
145                      "aarch64_sme_" # n_suffix,
146                      [IsOverloadNone, IsStreamingCompatible, IsPreservesZA]>;
147  }
148}
149
150defm SVCNTSB : ZACount<"cntsb">;
151defm SVCNTSH : ZACount<"cntsh">;
152defm SVCNTSW : ZACount<"cntsw">;
153defm SVCNTSD : ZACount<"cntsd">;
154
155////////////////////////////////////////////////////////////////////////////////
156// SME - ADDHA/ADDVA
157
158multiclass ZAAdd<string n_suffix> {
159  let TargetGuard = "sme" in {
160    def NAME # _ZA32: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPd", "iUi", MergeOp1,
161                      "aarch64_sme_" # n_suffix, [IsStreaming, IsSharedZA],
162                      [ImmCheck<0, ImmCheck0_3>]>;
163  }
164
165  let TargetGuard = "sme-i16i64" in {
166    def NAME # _ZA64: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPd", "lUl", MergeOp1,
167                     "aarch64_sme_" # n_suffix, [IsStreaming, IsSharedZA],
168                     [ImmCheck<0, ImmCheck0_7>]>;
169  }
170}
171
172defm SVADDHA : ZAAdd<"addha">;
173defm SVADDVA : ZAAdd<"addva">;
174
175////////////////////////////////////////////////////////////////////////////////
176// SME - SMOPA, SMOPS, UMOPA, UMOPS
177
178multiclass ZAIntOuterProd<string n_suffix1, string n_suffix2> {
179  let TargetGuard = "sme" in {
180    def NAME # _ZA32_B: SInst<"sv" # n_suffix2 # "_za32[_{d}]",
181                              "viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "c",
182                              MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
183                              [IsStreaming, IsSharedZA],
184                              [ImmCheck<0, ImmCheck0_3>]>;
185  }
186
187  let TargetGuard = "sme-i16i64" in {
188    def NAME # _ZA64_H: SInst<"sv" # n_suffix2 # "_za64[_{d}]",
189                              "viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "s",
190                              MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
191                              [IsStreaming, IsSharedZA],
192                              [ImmCheck<0, ImmCheck0_7>]>;
193  }
194}
195
196defm SVSMOPA : ZAIntOuterProd<"s", "mopa">;
197defm SVSMOPS : ZAIntOuterProd<"s", "mops">;
198defm SVUMOPA : ZAIntOuterProd<"u", "mopa">;
199defm SVUMOPS : ZAIntOuterProd<"u", "mops">;
200
201////////////////////////////////////////////////////////////////////////////////
202// SME - SUMOPA, SUMOPS, USMOPA, USMOPS
203
204multiclass ZAIntOuterProdMixedSigns<string n_suffix1, string n_suffix2> {
205  let TargetGuard = "sme" in {
206    def NAME # _ZA32_B: SInst<"sv" # n_suffix1 # n_suffix2 # "_za32[_{d}]",
207                              "viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
208                              !cond(!eq(n_suffix1, "su") : "", true: "U") # "c",
209                              MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
210                              [IsStreaming, IsSharedZA],
211                              [ImmCheck<0, ImmCheck0_3>]>;
212  }
213
214  let TargetGuard = "sme-i16i64" in {
215    def NAME # _ZA64_H: SInst<"sv" # n_suffix1 # n_suffix2 # "_za64[_{d}]",
216                              "viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
217                              !cond(!eq(n_suffix1, "su") : "", true: "U") # "s",
218                              MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
219                              [IsStreaming, IsSharedZA],
220                              [ImmCheck<0, ImmCheck0_7>]>;
221  }
222}
223
224defm SVSUMOPA : ZAIntOuterProdMixedSigns<"su", "mopa">;
225defm SVSUMOPS : ZAIntOuterProdMixedSigns<"su", "mops">;
226defm SVUSMOPA : ZAIntOuterProdMixedSigns<"us", "mopa">;
227defm SVUSMOPS : ZAIntOuterProdMixedSigns<"us", "mops">;
228
229////////////////////////////////////////////////////////////////////////////////
230// SME - FMOPA, FMOPS
231
232multiclass ZAFPOuterProd<string n_suffix> {
233  let TargetGuard = "sme" in {
234    def NAME # _ZA32_B: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "h",
235                              MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
236                              [IsStreaming, IsSharedZA],
237                              [ImmCheck<0, ImmCheck0_3>]>;
238
239    def NAME # _ZA32_H: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "b",
240                              MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
241                              [IsStreaming, IsSharedZA],
242                              [ImmCheck<0, ImmCheck0_3>]>;
243
244    def NAME # _ZA32_S: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "f",
245                              MergeOp1, "aarch64_sme_" # n_suffix,
246                              [IsStreaming, IsSharedZA],
247                              [ImmCheck<0, ImmCheck0_3>]>;
248  }
249
250  let TargetGuard = "sme-f64f64" in {
251    def NAME # _ZA64_D: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPdd", "d",
252                              MergeOp1, "aarch64_sme_" # n_suffix,
253                              [IsStreaming, IsSharedZA],
254                              [ImmCheck<0, ImmCheck0_3>]>;
255  }
256}
257
258defm SVMOPA : ZAFPOuterProd<"mopa">;
259defm SVMOPS : ZAFPOuterProd<"mops">;
260