xref: /aosp_15_r20/external/ComputeLibrary/src/cpu/kernels/activation/generic/sve/lut.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2022 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include "arm_compute/core/Helpers.h"
26 
27 #include <arm_neon.h>
28 #include <cstdint>
29 
30 namespace arm_compute
31 {
32 namespace cpu
33 {
34 namespace
35 {
36 #ifdef __aarch64__
substitute_bytes_sve(const uint8_t * table,size_t num_strings,size_t string_length,const uint8_t * const * input,uint8_t * const * output)37 void substitute_bytes_sve(
38     const uint8_t        *table,
39     size_t                num_strings,
40     size_t                string_length,
41     const uint8_t *const *input,
42     uint8_t *const       *output)
43 {
44     __asm__ __volatile__(
45         "ptrue p0.b\n"
46         "cntd x24\n"
47         "addvl %x[table], %x[table], #8\n"
48         "ld1b { z16.b }, p0/Z, [%x[table], #-8, MUL VL]\n"
49         "tbnz x24, #5, 1f\n"
50         "ld1b { z17.b }, p0/Z, [%x[table], #-7, MUL VL]\n"
51         "tbnz x24, #4, 1f\n"
52         "ld1b { z18.b }, p0/Z, [%x[table], #-6, MUL VL]\n"
53         "ld1b { z19.b }, p0/Z, [%x[table], #-5, MUL VL]\n"
54         "tbnz x24, #3, 1f\n"
55         "ld1b { z20.b }, p0/Z, [%x[table], #-4, MUL VL]\n"
56         "ld1b { z21.b }, p0/Z, [%x[table], #-3, MUL VL]\n"
57         "ld1b { z22.b }, p0/Z, [%x[table], #-2, MUL VL]\n"
58         "ld1b { z23.b }, p0/Z, [%x[table], #-1, MUL VL]\n"
59         "tbnz x24, #2, 1f\n"
60         "ld1b { z24.b }, p0/Z, [%x[table]]\n"
61         "ld1b { z25.b }, p0/Z, [%x[table], #1, MUL VL]\n"
62         "ld1b { z26.b }, p0/Z, [%x[table], #2, MUL VL]\n"
63         "ld1b { z27.b }, p0/Z, [%x[table], #3, MUL VL]\n"
64         "ld1b { z28.b }, p0/Z, [%x[table], #4, MUL VL]\n"
65         "ld1b { z29.b }, p0/Z, [%x[table], #5, MUL VL]\n"
66         "ld1b { z30.b }, p0/Z, [%x[table], #6, MUL VL]\n"
67         "ld1b { z31.b }, p0/Z, [%x[table], #7, MUL VL]\n"
68         "1:" // Table load done
69         "mov x23, #0x0\n"
70         "2:" // string loop
71         "ldr x22, [%x[input], x23, LSL #0x3]\n"
72         "ldr x21, [%x[output], x23, LSL #0x3]\n"
73         "tbnz x24, #5, 14f\n"
74         "tbnz x24, #4, 11f\n"
75         "tbnz x24, #3, 8f\n"
76         "tbnz x24, #2, 5f\n"
77         "mov z12.b, #0x10\n"
78         "mov x20, %x[string_length]\n"
79         "ptrue p5.b\n"
80         "ptrue p4.b\n"
81         "ptrue p3.b\n"
82         "ptrue p2.b\n"
83         "ptrue p1.b\n"
84         "ptrue p0.b\n"
85         "3:" // 16 rounds: width loop
86         "addvl x19, x20, #-6\n"
87         "cmp x19, XZR\n"
88         "bge 4f\n"
89         "mov x19, #0x0\n"
90         "addvl x19, x19, #1\n"
91         "whilelt p5.b, XZR, x20\n"
92         "whilelt p4.b, x19, x20\n"
93         "addvl x19, x19, #1\n"
94         "whilelt p3.b, x19, x20\n"
95         "addvl x19, x19, #1\n"
96         "whilelt p2.b, x19, x20\n"
97         "addvl x19, x19, #1\n"
98         "whilelt p1.b, x19, x20\n"
99         "addvl x19, x19, #1\n"
100         "whilelt p0.b, x19, x20\n"
101         "4:" // 16 rounds: predicate OK
102         "ld1b { z11.b }, p5/Z, [x22]\n"
103         "ld1b { z10.b }, p4/Z, [x22, #1, MUL VL]\n"
104         "tbl z9.b, { z16.b }, z11.b\n"
105         "ld1b { z8.b }, p3/Z, [x22, #2, MUL VL]\n"
106         "ld1b { z7.b }, p2/Z, [x22, #3, MUL VL]\n"
107         "sub z11.b, z11.b, z12.b\n"
108         "ld1b { z6.b }, p1/Z, [x22, #4, MUL VL]\n"
109         "ld1b { z5.b }, p0/Z, [x22, #5, MUL VL]\n"
110         "tbl z4.b, { z16.b }, z10.b\n"
111         "sub z10.b, z10.b, z12.b\n"
112         "tbl z3.b, { z16.b }, z8.b\n"
113         "sub z8.b, z8.b, z12.b\n"
114         "tbl z2.b, { z16.b }, z7.b\n"
115         "sub z7.b, z7.b, z12.b\n"
116         "tbl z1.b, { z16.b }, z6.b\n"
117         "sub z6.b, z6.b, z12.b\n"
118         "tbl z0.b, { z16.b }, z5.b\n"
119         "sub z5.b, z5.b, z12.b\n"
120         ".inst 0x052b2e29 // tbx z9.b, z17.b, z11.b\n"
121         "sub z11.b, z11.b, z12.b\n"
122         ".inst 0x052a2e24 // tbx z4.b, z17.b, z10.b\n"
123         "sub z10.b, z10.b, z12.b\n"
124         ".inst 0x05282e23 // tbx z3.b, z17.b, z8.b\n"
125         "sub z8.b, z8.b, z12.b\n"
126         ".inst 0x05272e22 // tbx z2.b, z17.b, z7.b\n"
127         "sub z7.b, z7.b, z12.b\n"
128         ".inst 0x05262e21 // tbx z1.b, z17.b, z6.b\n"
129         "sub z6.b, z6.b, z12.b\n"
130         ".inst 0x05252e20 // tbx z0.b, z17.b, z5.b\n"
131         "sub z5.b, z5.b, z12.b\n"
132         ".inst 0x052b2e49 // tbx z9.b, z18.b, z11.b\n"
133         "sub z11.b, z11.b, z12.b\n"
134         ".inst 0x052a2e44 // tbx z4.b, z18.b, z10.b\n"
135         "sub z10.b, z10.b, z12.b\n"
136         ".inst 0x05282e43 // tbx z3.b, z18.b, z8.b\n"
137         "sub z8.b, z8.b, z12.b\n"
138         ".inst 0x05272e42 // tbx z2.b, z18.b, z7.b\n"
139         "sub z7.b, z7.b, z12.b\n"
140         ".inst 0x05262e41 // tbx z1.b, z18.b, z6.b\n"
141         "sub z6.b, z6.b, z12.b\n"
142         ".inst 0x05252e40 // tbx z0.b, z18.b, z5.b\n"
143         "sub z5.b, z5.b, z12.b\n"
144         ".inst 0x052b2e69 // tbx z9.b, z19.b, z11.b\n"
145         "sub z11.b, z11.b, z12.b\n"
146         ".inst 0x052a2e64 // tbx z4.b, z19.b, z10.b\n"
147         "sub z10.b, z10.b, z12.b\n"
148         ".inst 0x05282e63 // tbx z3.b, z19.b, z8.b\n"
149         "sub z8.b, z8.b, z12.b\n"
150         ".inst 0x05272e62 // tbx z2.b, z19.b, z7.b\n"
151         "sub z7.b, z7.b, z12.b\n"
152         ".inst 0x05262e61 // tbx z1.b, z19.b, z6.b\n"
153         "sub z6.b, z6.b, z12.b\n"
154         ".inst 0x05252e60 // tbx z0.b, z19.b, z5.b\n"
155         "sub z5.b, z5.b, z12.b\n"
156         ".inst 0x052b2e89 // tbx z9.b, z20.b, z11.b\n"
157         "sub z11.b, z11.b, z12.b\n"
158         ".inst 0x052a2e84 // tbx z4.b, z20.b, z10.b\n"
159         "sub z10.b, z10.b, z12.b\n"
160         ".inst 0x05282e83 // tbx z3.b, z20.b, z8.b\n"
161         "sub z8.b, z8.b, z12.b\n"
162         ".inst 0x05272e82 // tbx z2.b, z20.b, z7.b\n"
163         "sub z7.b, z7.b, z12.b\n"
164         ".inst 0x05262e81 // tbx z1.b, z20.b, z6.b\n"
165         "sub z6.b, z6.b, z12.b\n"
166         ".inst 0x05252e80 // tbx z0.b, z20.b, z5.b\n"
167         "sub z5.b, z5.b, z12.b\n"
168         ".inst 0x052b2ea9 // tbx z9.b, z21.b, z11.b\n"
169         "sub z11.b, z11.b, z12.b\n"
170         ".inst 0x052a2ea4 // tbx z4.b, z21.b, z10.b\n"
171         "sub z10.b, z10.b, z12.b\n"
172         ".inst 0x05282ea3 // tbx z3.b, z21.b, z8.b\n"
173         "sub z8.b, z8.b, z12.b\n"
174         ".inst 0x05272ea2 // tbx z2.b, z21.b, z7.b\n"
175         "sub z7.b, z7.b, z12.b\n"
176         ".inst 0x05262ea1 // tbx z1.b, z21.b, z6.b\n"
177         "sub z6.b, z6.b, z12.b\n"
178         ".inst 0x05252ea0 // tbx z0.b, z21.b, z5.b\n"
179         "sub z5.b, z5.b, z12.b\n"
180         ".inst 0x052b2ec9 // tbx z9.b, z22.b, z11.b\n"
181         "sub z11.b, z11.b, z12.b\n"
182         ".inst 0x052a2ec4 // tbx z4.b, z22.b, z10.b\n"
183         "sub z10.b, z10.b, z12.b\n"
184         ".inst 0x05282ec3 // tbx z3.b, z22.b, z8.b\n"
185         "sub z8.b, z8.b, z12.b\n"
186         ".inst 0x05272ec2 // tbx z2.b, z22.b, z7.b\n"
187         "sub z7.b, z7.b, z12.b\n"
188         ".inst 0x05262ec1 // tbx z1.b, z22.b, z6.b\n"
189         "sub z6.b, z6.b, z12.b\n"
190         ".inst 0x05252ec0 // tbx z0.b, z22.b, z5.b\n"
191         "sub z5.b, z5.b, z12.b\n"
192         ".inst 0x052b2ee9 // tbx z9.b, z23.b, z11.b\n"
193         "sub z11.b, z11.b, z12.b\n"
194         ".inst 0x052a2ee4 // tbx z4.b, z23.b, z10.b\n"
195         "sub z10.b, z10.b, z12.b\n"
196         ".inst 0x05282ee3 // tbx z3.b, z23.b, z8.b\n"
197         "sub z8.b, z8.b, z12.b\n"
198         ".inst 0x05272ee2 // tbx z2.b, z23.b, z7.b\n"
199         "sub z7.b, z7.b, z12.b\n"
200         ".inst 0x05262ee1 // tbx z1.b, z23.b, z6.b\n"
201         "sub z6.b, z6.b, z12.b\n"
202         ".inst 0x05252ee0 // tbx z0.b, z23.b, z5.b\n"
203         "sub z5.b, z5.b, z12.b\n"
204         ".inst 0x052b2f09 // tbx z9.b, z24.b, z11.b\n"
205         "sub z11.b, z11.b, z12.b\n"
206         ".inst 0x052a2f04 // tbx z4.b, z24.b, z10.b\n"
207         "sub z10.b, z10.b, z12.b\n"
208         ".inst 0x05282f03 // tbx z3.b, z24.b, z8.b\n"
209         "sub z8.b, z8.b, z12.b\n"
210         ".inst 0x05272f02 // tbx z2.b, z24.b, z7.b\n"
211         "sub z7.b, z7.b, z12.b\n"
212         ".inst 0x05262f01 // tbx z1.b, z24.b, z6.b\n"
213         "sub z6.b, z6.b, z12.b\n"
214         ".inst 0x05252f00 // tbx z0.b, z24.b, z5.b\n"
215         "sub z5.b, z5.b, z12.b\n"
216         ".inst 0x052b2f29 // tbx z9.b, z25.b, z11.b\n"
217         "sub z11.b, z11.b, z12.b\n"
218         ".inst 0x052a2f24 // tbx z4.b, z25.b, z10.b\n"
219         "sub z10.b, z10.b, z12.b\n"
220         ".inst 0x05282f23 // tbx z3.b, z25.b, z8.b\n"
221         "sub z8.b, z8.b, z12.b\n"
222         ".inst 0x05272f22 // tbx z2.b, z25.b, z7.b\n"
223         "sub z7.b, z7.b, z12.b\n"
224         ".inst 0x05262f21 // tbx z1.b, z25.b, z6.b\n"
225         "sub z6.b, z6.b, z12.b\n"
226         ".inst 0x05252f20 // tbx z0.b, z25.b, z5.b\n"
227         "sub z5.b, z5.b, z12.b\n"
228         ".inst 0x052b2f49 // tbx z9.b, z26.b, z11.b\n"
229         "sub z11.b, z11.b, z12.b\n"
230         ".inst 0x052a2f44 // tbx z4.b, z26.b, z10.b\n"
231         "sub z10.b, z10.b, z12.b\n"
232         ".inst 0x05282f43 // tbx z3.b, z26.b, z8.b\n"
233         "sub z8.b, z8.b, z12.b\n"
234         ".inst 0x05272f42 // tbx z2.b, z26.b, z7.b\n"
235         "sub z7.b, z7.b, z12.b\n"
236         ".inst 0x05262f41 // tbx z1.b, z26.b, z6.b\n"
237         "sub z6.b, z6.b, z12.b\n"
238         ".inst 0x05252f40 // tbx z0.b, z26.b, z5.b\n"
239         "sub z5.b, z5.b, z12.b\n"
240         ".inst 0x052b2f69 // tbx z9.b, z27.b, z11.b\n"
241         "sub z11.b, z11.b, z12.b\n"
242         ".inst 0x052a2f64 // tbx z4.b, z27.b, z10.b\n"
243         "sub z10.b, z10.b, z12.b\n"
244         ".inst 0x05282f63 // tbx z3.b, z27.b, z8.b\n"
245         "sub z8.b, z8.b, z12.b\n"
246         ".inst 0x05272f62 // tbx z2.b, z27.b, z7.b\n"
247         "sub z7.b, z7.b, z12.b\n"
248         ".inst 0x05262f61 // tbx z1.b, z27.b, z6.b\n"
249         "sub z6.b, z6.b, z12.b\n"
250         ".inst 0x05252f60 // tbx z0.b, z27.b, z5.b\n"
251         "sub z5.b, z5.b, z12.b\n"
252         ".inst 0x052b2f89 // tbx z9.b, z28.b, z11.b\n"
253         "sub z11.b, z11.b, z12.b\n"
254         ".inst 0x052a2f84 // tbx z4.b, z28.b, z10.b\n"
255         "sub z10.b, z10.b, z12.b\n"
256         ".inst 0x05282f83 // tbx z3.b, z28.b, z8.b\n"
257         "sub z8.b, z8.b, z12.b\n"
258         ".inst 0x05272f82 // tbx z2.b, z28.b, z7.b\n"
259         "sub z7.b, z7.b, z12.b\n"
260         ".inst 0x05262f81 // tbx z1.b, z28.b, z6.b\n"
261         "sub z6.b, z6.b, z12.b\n"
262         ".inst 0x05252f80 // tbx z0.b, z28.b, z5.b\n"
263         "sub z5.b, z5.b, z12.b\n"
264         ".inst 0x052b2fa9 // tbx z9.b, z29.b, z11.b\n"
265         "sub z11.b, z11.b, z12.b\n"
266         ".inst 0x052a2fa4 // tbx z4.b, z29.b, z10.b\n"
267         "sub z10.b, z10.b, z12.b\n"
268         ".inst 0x05282fa3 // tbx z3.b, z29.b, z8.b\n"
269         "sub z8.b, z8.b, z12.b\n"
270         ".inst 0x05272fa2 // tbx z2.b, z29.b, z7.b\n"
271         "sub z7.b, z7.b, z12.b\n"
272         ".inst 0x05262fa1 // tbx z1.b, z29.b, z6.b\n"
273         "sub z6.b, z6.b, z12.b\n"
274         ".inst 0x05252fa0 // tbx z0.b, z29.b, z5.b\n"
275         "sub z5.b, z5.b, z12.b\n"
276         "addvl x20, x20, #-6\n"
277         ".inst 0x052b2fc9 // tbx z9.b, z30.b, z11.b\n"
278         "sub z11.b, z11.b, z12.b\n"
279         ".inst 0x052a2fc4 // tbx z4.b, z30.b, z10.b\n"
280         "sub z10.b, z10.b, z12.b\n"
281         ".inst 0x05282fc3 // tbx z3.b, z30.b, z8.b\n"
282         "sub z8.b, z8.b, z12.b\n"
283         ".inst 0x05272fc2 // tbx z2.b, z30.b, z7.b\n"
284         "sub z7.b, z7.b, z12.b\n"
285         ".inst 0x05262fc1 // tbx z1.b, z30.b, z6.b\n"
286         "sub z6.b, z6.b, z12.b\n"
287         ".inst 0x05252fc0 // tbx z0.b, z30.b, z5.b\n"
288         "sub z5.b, z5.b, z12.b\n"
289         "cmp x20, XZR\n"
290         ".inst 0x052b2fe9 // tbx z9.b, z31.b, z11.b\n"
291         ".inst 0x052a2fe4 // tbx z4.b, z31.b, z10.b\n"
292         ".inst 0x05282fe3 // tbx z3.b, z31.b, z8.b\n"
293         "st1b { z9.b }, p5, [x21]\n"
294         ".inst 0x05272fe2 // tbx z2.b, z31.b, z7.b\n"
295         ".inst 0x05262fe1 // tbx z1.b, z31.b, z6.b\n"
296         "st1b { z4.b }, p4, [x21, #1, MUL VL]\n"
297         ".inst 0x05252fe0 // tbx z0.b, z31.b, z5.b\n"
298         "st1b { z3.b }, p3, [x21, #2, MUL VL]\n"
299         "addvl x22, x22, #6\n"
300         "st1b { z2.b }, p2, [x21, #3, MUL VL]\n"
301         "st1b { z1.b }, p1, [x21, #4, MUL VL]\n"
302         "st1b { z0.b }, p0, [x21, #5, MUL VL]\n"
303         "addvl x21, x21, #6\n"
304         "bgt 3b\n"
305         "b 17f\n"
306         "5:" // 256 bits
307         "mov z12.b, #0x20\n"
308         "mov x20, %x[string_length]\n"
309         "ptrue p5.b\n"
310         "ptrue p4.b\n"
311         "ptrue p3.b\n"
312         "ptrue p2.b\n"
313         "ptrue p1.b\n"
314         "ptrue p0.b\n"
315         "6:" // 8 rounds: width loop
316         "addvl x19, x20, #-6\n"
317         "cmp x19, XZR\n"
318         "bge 7f\n"
319         "mov x19, #0x0\n"
320         "addvl x19, x19, #1\n"
321         "whilelt p5.b, XZR, x20\n"
322         "whilelt p4.b, x19, x20\n"
323         "addvl x19, x19, #1\n"
324         "whilelt p3.b, x19, x20\n"
325         "addvl x19, x19, #1\n"
326         "whilelt p2.b, x19, x20\n"
327         "addvl x19, x19, #1\n"
328         "whilelt p1.b, x19, x20\n"
329         "addvl x19, x19, #1\n"
330         "whilelt p0.b, x19, x20\n"
331         "7:" // 8 rounds: predicate OK
332         "ld1b { z11.b }, p5/Z, [x22]\n"
333         "ld1b { z10.b }, p4/Z, [x22, #1, MUL VL]\n"
334         "tbl z9.b, { z16.b }, z11.b\n"
335         "ld1b { z8.b }, p3/Z, [x22, #2, MUL VL]\n"
336         "ld1b { z7.b }, p2/Z, [x22, #3, MUL VL]\n"
337         "sub z11.b, z11.b, z12.b\n"
338         "ld1b { z6.b }, p1/Z, [x22, #4, MUL VL]\n"
339         "ld1b { z5.b }, p0/Z, [x22, #5, MUL VL]\n"
340         "tbl z4.b, { z16.b }, z10.b\n"
341         "sub z10.b, z10.b, z12.b\n"
342         "tbl z3.b, { z16.b }, z8.b\n"
343         "sub z8.b, z8.b, z12.b\n"
344         "tbl z2.b, { z16.b }, z7.b\n"
345         "sub z7.b, z7.b, z12.b\n"
346         "tbl z1.b, { z16.b }, z6.b\n"
347         "sub z6.b, z6.b, z12.b\n"
348         "tbl z0.b, { z16.b }, z5.b\n"
349         "sub z5.b, z5.b, z12.b\n"
350         ".inst 0x052b2e29 // tbx z9.b, z17.b, z11.b\n"
351         "sub z11.b, z11.b, z12.b\n"
352         ".inst 0x052a2e24 // tbx z4.b, z17.b, z10.b\n"
353         "sub z10.b, z10.b, z12.b\n"
354         ".inst 0x05282e23 // tbx z3.b, z17.b, z8.b\n"
355         "sub z8.b, z8.b, z12.b\n"
356         ".inst 0x05272e22 // tbx z2.b, z17.b, z7.b\n"
357         "sub z7.b, z7.b, z12.b\n"
358         ".inst 0x05262e21 // tbx z1.b, z17.b, z6.b\n"
359         "sub z6.b, z6.b, z12.b\n"
360         ".inst 0x05252e20 // tbx z0.b, z17.b, z5.b\n"
361         "sub z5.b, z5.b, z12.b\n"
362         ".inst 0x052b2e49 // tbx z9.b, z18.b, z11.b\n"
363         "sub z11.b, z11.b, z12.b\n"
364         ".inst 0x052a2e44 // tbx z4.b, z18.b, z10.b\n"
365         "sub z10.b, z10.b, z12.b\n"
366         ".inst 0x05282e43 // tbx z3.b, z18.b, z8.b\n"
367         "sub z8.b, z8.b, z12.b\n"
368         ".inst 0x05272e42 // tbx z2.b, z18.b, z7.b\n"
369         "sub z7.b, z7.b, z12.b\n"
370         ".inst 0x05262e41 // tbx z1.b, z18.b, z6.b\n"
371         "sub z6.b, z6.b, z12.b\n"
372         ".inst 0x05252e40 // tbx z0.b, z18.b, z5.b\n"
373         "sub z5.b, z5.b, z12.b\n"
374         ".inst 0x052b2e69 // tbx z9.b, z19.b, z11.b\n"
375         "sub z11.b, z11.b, z12.b\n"
376         ".inst 0x052a2e64 // tbx z4.b, z19.b, z10.b\n"
377         "sub z10.b, z10.b, z12.b\n"
378         ".inst 0x05282e63 // tbx z3.b, z19.b, z8.b\n"
379         "sub z8.b, z8.b, z12.b\n"
380         ".inst 0x05272e62 // tbx z2.b, z19.b, z7.b\n"
381         "sub z7.b, z7.b, z12.b\n"
382         ".inst 0x05262e61 // tbx z1.b, z19.b, z6.b\n"
383         "sub z6.b, z6.b, z12.b\n"
384         ".inst 0x05252e60 // tbx z0.b, z19.b, z5.b\n"
385         "sub z5.b, z5.b, z12.b\n"
386         ".inst 0x052b2e89 // tbx z9.b, z20.b, z11.b\n"
387         "sub z11.b, z11.b, z12.b\n"
388         ".inst 0x052a2e84 // tbx z4.b, z20.b, z10.b\n"
389         "sub z10.b, z10.b, z12.b\n"
390         ".inst 0x05282e83 // tbx z3.b, z20.b, z8.b\n"
391         "sub z8.b, z8.b, z12.b\n"
392         ".inst 0x05272e82 // tbx z2.b, z20.b, z7.b\n"
393         "sub z7.b, z7.b, z12.b\n"
394         ".inst 0x05262e81 // tbx z1.b, z20.b, z6.b\n"
395         "sub z6.b, z6.b, z12.b\n"
396         ".inst 0x05252e80 // tbx z0.b, z20.b, z5.b\n"
397         "sub z5.b, z5.b, z12.b\n"
398         ".inst 0x052b2ea9 // tbx z9.b, z21.b, z11.b\n"
399         "sub z11.b, z11.b, z12.b\n"
400         ".inst 0x052a2ea4 // tbx z4.b, z21.b, z10.b\n"
401         "sub z10.b, z10.b, z12.b\n"
402         ".inst 0x05282ea3 // tbx z3.b, z21.b, z8.b\n"
403         "sub z8.b, z8.b, z12.b\n"
404         ".inst 0x05272ea2 // tbx z2.b, z21.b, z7.b\n"
405         "sub z7.b, z7.b, z12.b\n"
406         ".inst 0x05262ea1 // tbx z1.b, z21.b, z6.b\n"
407         "sub z6.b, z6.b, z12.b\n"
408         ".inst 0x05252ea0 // tbx z0.b, z21.b, z5.b\n"
409         "sub z5.b, z5.b, z12.b\n"
410         "addvl x20, x20, #-6\n"
411         ".inst 0x052b2ec9 // tbx z9.b, z22.b, z11.b\n"
412         "sub z11.b, z11.b, z12.b\n"
413         ".inst 0x052a2ec4 // tbx z4.b, z22.b, z10.b\n"
414         "sub z10.b, z10.b, z12.b\n"
415         ".inst 0x05282ec3 // tbx z3.b, z22.b, z8.b\n"
416         "sub z8.b, z8.b, z12.b\n"
417         ".inst 0x05272ec2 // tbx z2.b, z22.b, z7.b\n"
418         "sub z7.b, z7.b, z12.b\n"
419         ".inst 0x05262ec1 // tbx z1.b, z22.b, z6.b\n"
420         "sub z6.b, z6.b, z12.b\n"
421         ".inst 0x05252ec0 // tbx z0.b, z22.b, z5.b\n"
422         "sub z5.b, z5.b, z12.b\n"
423         "cmp x20, XZR\n"
424         ".inst 0x052b2ee9 // tbx z9.b, z23.b, z11.b\n"
425         ".inst 0x052a2ee4 // tbx z4.b, z23.b, z10.b\n"
426         ".inst 0x05282ee3 // tbx z3.b, z23.b, z8.b\n"
427         "st1b { z9.b }, p5, [x21]\n"
428         ".inst 0x05272ee2 // tbx z2.b, z23.b, z7.b\n"
429         ".inst 0x05262ee1 // tbx z1.b, z23.b, z6.b\n"
430         "st1b { z4.b }, p4, [x21, #1, MUL VL]\n"
431         ".inst 0x05252ee0 // tbx z0.b, z23.b, z5.b\n"
432         "st1b { z3.b }, p3, [x21, #2, MUL VL]\n"
433         "addvl x22, x22, #6\n"
434         "st1b { z2.b }, p2, [x21, #3, MUL VL]\n"
435         "st1b { z1.b }, p1, [x21, #4, MUL VL]\n"
436         "st1b { z0.b }, p0, [x21, #5, MUL VL]\n"
437         "addvl x21, x21, #6\n"
438         "bgt 6b\n"
439         "b 17f\n"
440         "8:" // 512 bits
441         "mov z12.b, #0x40\n"
442         "mov x20, %x[string_length]\n"
443         "ptrue p5.b\n"
444         "ptrue p4.b\n"
445         "ptrue p3.b\n"
446         "ptrue p2.b\n"
447         "ptrue p1.b\n"
448         "ptrue p0.b\n"
449         "9:" // 4 rounds: width loop
450         "addvl x19, x20, #-6\n"
451         "cmp x19, XZR\n"
452         "bge 10f\n"
453         "mov x19, #0x0\n"
454         "addvl x19, x19, #1\n"
455         "whilelt p5.b, XZR, x20\n"
456         "whilelt p4.b, x19, x20\n"
457         "addvl x19, x19, #1\n"
458         "whilelt p3.b, x19, x20\n"
459         "addvl x19, x19, #1\n"
460         "whilelt p2.b, x19, x20\n"
461         "addvl x19, x19, #1\n"
462         "whilelt p1.b, x19, x20\n"
463         "addvl x19, x19, #1\n"
464         "whilelt p0.b, x19, x20\n"
465         "10:" // 4 rounds: predicate OK
466         "ld1b { z11.b }, p5/Z, [x22]\n"
467         "ld1b { z10.b }, p4/Z, [x22, #1, MUL VL]\n"
468         "tbl z9.b, { z16.b }, z11.b\n"
469         "ld1b { z8.b }, p3/Z, [x22, #2, MUL VL]\n"
470         "ld1b { z7.b }, p2/Z, [x22, #3, MUL VL]\n"
471         "sub z11.b, z11.b, z12.b\n"
472         "ld1b { z6.b }, p1/Z, [x22, #4, MUL VL]\n"
473         "ld1b { z5.b }, p0/Z, [x22, #5, MUL VL]\n"
474         "tbl z4.b, { z16.b }, z10.b\n"
475         "sub z10.b, z10.b, z12.b\n"
476         "tbl z3.b, { z16.b }, z8.b\n"
477         "sub z8.b, z8.b, z12.b\n"
478         "tbl z2.b, { z16.b }, z7.b\n"
479         "sub z7.b, z7.b, z12.b\n"
480         "tbl z1.b, { z16.b }, z6.b\n"
481         "sub z6.b, z6.b, z12.b\n"
482         "tbl z0.b, { z16.b }, z5.b\n"
483         "sub z5.b, z5.b, z12.b\n"
484         ".inst 0x052b2e29 // tbx z9.b, z17.b, z11.b\n"
485         "sub z11.b, z11.b, z12.b\n"
486         ".inst 0x052a2e24 // tbx z4.b, z17.b, z10.b\n"
487         "sub z10.b, z10.b, z12.b\n"
488         ".inst 0x05282e23 // tbx z3.b, z17.b, z8.b\n"
489         "sub z8.b, z8.b, z12.b\n"
490         ".inst 0x05272e22 // tbx z2.b, z17.b, z7.b\n"
491         "sub z7.b, z7.b, z12.b\n"
492         ".inst 0x05262e21 // tbx z1.b, z17.b, z6.b\n"
493         "sub z6.b, z6.b, z12.b\n"
494         ".inst 0x05252e20 // tbx z0.b, z17.b, z5.b\n"
495         "sub z5.b, z5.b, z12.b\n"
496         "addvl x20, x20, #-6\n"
497         ".inst 0x052b2e49 // tbx z9.b, z18.b, z11.b\n"
498         "sub z11.b, z11.b, z12.b\n"
499         ".inst 0x052a2e44 // tbx z4.b, z18.b, z10.b\n"
500         "sub z10.b, z10.b, z12.b\n"
501         ".inst 0x05282e43 // tbx z3.b, z18.b, z8.b\n"
502         "sub z8.b, z8.b, z12.b\n"
503         ".inst 0x05272e42 // tbx z2.b, z18.b, z7.b\n"
504         "sub z7.b, z7.b, z12.b\n"
505         ".inst 0x05262e41 // tbx z1.b, z18.b, z6.b\n"
506         "sub z6.b, z6.b, z12.b\n"
507         ".inst 0x05252e40 // tbx z0.b, z18.b, z5.b\n"
508         "sub z5.b, z5.b, z12.b\n"
509         "cmp x20, XZR\n"
510         ".inst 0x052b2e69 // tbx z9.b, z19.b, z11.b\n"
511         ".inst 0x052a2e64 // tbx z4.b, z19.b, z10.b\n"
512         ".inst 0x05282e63 // tbx z3.b, z19.b, z8.b\n"
513         "st1b { z9.b }, p5, [x21]\n"
514         ".inst 0x05272e62 // tbx z2.b, z19.b, z7.b\n"
515         ".inst 0x05262e61 // tbx z1.b, z19.b, z6.b\n"
516         "st1b { z4.b }, p4, [x21, #1, MUL VL]\n"
517         ".inst 0x05252e60 // tbx z0.b, z19.b, z5.b\n"
518         "st1b { z3.b }, p3, [x21, #2, MUL VL]\n"
519         "addvl x22, x22, #6\n"
520         "st1b { z2.b }, p2, [x21, #3, MUL VL]\n"
521         "st1b { z1.b }, p1, [x21, #4, MUL VL]\n"
522         "st1b { z0.b }, p0, [x21, #5, MUL VL]\n"
523         "addvl x21, x21, #6\n"
524         "bgt 9b\n"
525         "b 17f\n"
526         "11:" // 1024 bits
527         "mov z12.b, #0x80\n"
528         "mov x20, %x[string_length]\n"
529         "ptrue p5.b\n"
530         "ptrue p4.b\n"
531         "ptrue p3.b\n"
532         "ptrue p2.b\n"
533         "ptrue p1.b\n"
534         "ptrue p0.b\n"
535         "12:" // 2 rounds: width loop
536         "addvl x19, x20, #-6\n"
537         "cmp x19, XZR\n"
538         "bge 13f\n"
539         "mov x19, #0x0\n"
540         "addvl x19, x19, #1\n"
541         "whilelt p5.b, XZR, x20\n"
542         "whilelt p4.b, x19, x20\n"
543         "addvl x19, x19, #1\n"
544         "whilelt p3.b, x19, x20\n"
545         "addvl x19, x19, #1\n"
546         "whilelt p2.b, x19, x20\n"
547         "addvl x19, x19, #1\n"
548         "whilelt p1.b, x19, x20\n"
549         "addvl x19, x19, #1\n"
550         "whilelt p0.b, x19, x20\n"
551         "13:" // 2 rounds: predicate OK
552         "ld1b { z11.b }, p5/Z, [x22]\n"
553         "ld1b { z10.b }, p4/Z, [x22, #1, MUL VL]\n"
554         "addvl x20, x20, #-6\n"
555         "ld1b { z8.b }, p3/Z, [x22, #2, MUL VL]\n"
556         "ld1b { z7.b }, p2/Z, [x22, #3, MUL VL]\n"
557         "tbl z9.b, { z16.b }, z11.b\n"
558         "ld1b { z6.b }, p1/Z, [x22, #4, MUL VL]\n"
559         "ld1b { z5.b }, p0/Z, [x22, #5, MUL VL]\n"
560         "sub z11.b, z11.b, z12.b\n"
561         "tbl z4.b, { z16.b }, z10.b\n"
562         "sub z10.b, z10.b, z12.b\n"
563         "tbl z3.b, { z16.b }, z8.b\n"
564         "sub z8.b, z8.b, z12.b\n"
565         "tbl z2.b, { z16.b }, z7.b\n"
566         "sub z7.b, z7.b, z12.b\n"
567         "tbl z1.b, { z16.b }, z6.b\n"
568         "sub z6.b, z6.b, z12.b\n"
569         "tbl z0.b, { z16.b }, z5.b\n"
570         "sub z5.b, z5.b, z12.b\n"
571         "cmp x20, XZR\n"
572         ".inst 0x052b2e29 // tbx z9.b, z17.b, z11.b\n"
573         ".inst 0x052a2e24 // tbx z4.b, z17.b, z10.b\n"
574         ".inst 0x05282e23 // tbx z3.b, z17.b, z8.b\n"
575         "st1b { z9.b }, p5, [x21]\n"
576         ".inst 0x05272e22 // tbx z2.b, z17.b, z7.b\n"
577         ".inst 0x05262e21 // tbx z1.b, z17.b, z6.b\n"
578         "st1b { z4.b }, p4, [x21, #1, MUL VL]\n"
579         ".inst 0x05252e20 // tbx z0.b, z17.b, z5.b\n"
580         "st1b { z3.b }, p3, [x21, #2, MUL VL]\n"
581         "addvl x22, x22, #6\n"
582         "st1b { z2.b }, p2, [x21, #3, MUL VL]\n"
583         "st1b { z1.b }, p1, [x21, #4, MUL VL]\n"
584         "st1b { z0.b }, p0, [x21, #5, MUL VL]\n"
585         "addvl x21, x21, #6\n"
586         "bgt 12b\n"
587         "b 17f\n"
588         "14:" // 2048 bits
589         "mov x20, %x[string_length]\n"
590         "ptrue p5.b\n"
591         "ptrue p4.b\n"
592         "ptrue p3.b\n"
593         "ptrue p2.b\n"
594         "ptrue p1.b\n"
595         "ptrue p0.b\n"
596         "15:" // 1 rounds: width loop
597         "addvl x19, x20, #-6\n"
598         "cmp x19, XZR\n"
599         "bge 16f\n"
600         "mov x19, #0x0\n"
601         "addvl x19, x19, #1\n"
602         "whilelt p5.b, XZR, x20\n"
603         "whilelt p4.b, x19, x20\n"
604         "addvl x19, x19, #1\n"
605         "whilelt p3.b, x19, x20\n"
606         "addvl x19, x19, #1\n"
607         "whilelt p2.b, x19, x20\n"
608         "addvl x19, x19, #1\n"
609         "whilelt p1.b, x19, x20\n"
610         "addvl x19, x19, #1\n"
611         "whilelt p0.b, x19, x20\n"
612         "16:" // 1 rounds: predicate OK
613         "addvl x20, x20, #-6\n"
614         "ld1b { z11.b }, p5/Z, [x22]\n"
615         "ld1b { z10.b }, p4/Z, [x22, #1, MUL VL]\n"
616         "ld1b { z8.b }, p3/Z, [x22, #2, MUL VL]\n"
617         "ld1b { z7.b }, p2/Z, [x22, #3, MUL VL]\n"
618         "cmp x20, XZR\n"
619         "ld1b { z6.b }, p1/Z, [x22, #4, MUL VL]\n"
620         "ld1b { z5.b }, p0/Z, [x22, #5, MUL VL]\n"
621         "tbl z9.b, { z16.b }, z11.b\n"
622         "tbl z4.b, { z16.b }, z10.b\n"
623         "tbl z3.b, { z16.b }, z8.b\n"
624         "st1b { z9.b }, p5, [x21]\n"
625         "tbl z2.b, { z16.b }, z7.b\n"
626         "tbl z1.b, { z16.b }, z6.b\n"
627         "st1b { z4.b }, p4, [x21, #1, MUL VL]\n"
628         "tbl z0.b, { z16.b }, z5.b\n"
629         "st1b { z3.b }, p3, [x21, #2, MUL VL]\n"
630         "addvl x22, x22, #6\n"
631         "st1b { z2.b }, p2, [x21, #3, MUL VL]\n"
632         "st1b { z1.b }, p1, [x21, #4, MUL VL]\n"
633         "st1b { z0.b }, p0, [x21, #5, MUL VL]\n"
634         "addvl x21, x21, #6\n"
635         "bgt 15b\n"
636         "17:" // SVE body done
637         "add x23, x23, #0x1\n"
638         "cmp x23, %x[num_strings]\n"
639         "bne 2b\n"
640         : [table] "+&r"(table)
641         : [input] "r"(input), [num_strings] "r"(num_strings), [output] "r"(output), [string_length] "r"(string_length)
642         : "cc", "memory", "p0", "p1", "p2", "p3", "p4", "p5", "x19", "x20", "x21", "x22", "x23", "x24", "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", "z11", "z12", "z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
643 }
644 #endif // __aarch64__
645 } // namespace
646 
647 #ifdef __aarch64__
sve_q8_activation_lut(const ITensor * src,ITensor * dst,const ActivationLayerInfo & act_info,const Window & window)648 void sve_q8_activation_lut(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
649 {
650     ARM_COMPUTE_ERROR_ON(!ActivationLayerInfo::is_lut_supported(act_info.activation(), src->info()->data_type()));
651     const auto window_end_x  = window.x().end();
652     Window     win_collapsed = window.collapse_if_possible(window, Window::DimZ);
653     win_collapsed.set(Window::DimX, Window::Dimension(0, 1, 1));
654     Iterator input(src, win_collapsed);
655     Iterator output(dst, win_collapsed);
656     execute_window_loop(win_collapsed, [&](const Coordinates &)
657     {
658         const auto input_ptr  = input.ptr();
659         auto       output_ptr = output.ptr();
660         substitute_bytes_sve(act_info.lut().data(), 1u, window_end_x, &input_ptr, &output_ptr);
661     },
662     input, output);
663 }
664 #endif // __aarch64__
665 } // namespace cpu
666 } // namespace arm_compute
667