1// Auto-generated file. Do not edit!
2//   Template: src/qs8-gemm/4x8-aarch32-neon-mlal-lane-cortex-a53.S.in
3//   Generator: tools/xngen
4//
5// Copyright 2021 Google LLC
6//
7// This source code is licensed under the BSD-style license found in the
8// LICENSE file in the root directory of this source tree.
9
10
11#include <xnnpack/assembly.h>
12
13.syntax unified
14
15// void xnn_qu8_gemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a53(
16//     size_t mr,                            r0
17//     size_t nc,                            r1
18//     size_t kc,                            (r2) -> sp + 56 -> r5
19//     const uint8_t*restrict a,              r3
20//     size_t a_stride,           sp + 96 -> (r7)
21//     const void*restrict w,     sp + 100 -> r9
22//     uint8_t*restrict c,         sp + 104 -> r11
23//     size_t cm_stride,          sp + 108 -> (r6)
24//     size_t cn_stride,          sp + 112 -> r7
25//     xnn_qs8_conv_minmax_params params)  sp + 116 -> (r5)
26
27// d8-d15, r4-r11,r14(lr) need to be preserved if used. r13(sp),r15(pc) are reserved.
28
29// Register usage
30// A0   r3  d0-d1 q0
31// A1  r12  d2-d3 q1
32// A2  r10  d4-d5 q2
33// A3   r0  d6-d7 q3
34
35// B    r9  d8-d9 q4 q5
36
37// C0  r11 d16-d17  q8  d18-d19  q9
38// C1   r4 d20-d21 q10  d22-d23 q11
39// C2   r8 d24-d25 q12  d26-d27 q13
40// C3   r6 d28-d29 q14  d30-d31 q15
41
42// r2,r14 A53 gpr temporary loads
43// Unused d15
44
45# params structure is 20 bytes
46#  struct {
47#    uint8_t kernel_zero_point[4];  d14
48#    int32_t right_pre_shift;       d12[0]
49#    int32_t multiplier;            d12[1]
50#    int32_t right_post_shift;      d13[0]
51#    int16_t output_zero_point;     d13[2]
52#    uint8_t output_min;            d13[6]
53#    uint8_t output_max;            d13[7]
54#  } rndnu_neon;
55
56BEGIN_FUNCTION xnn_qu8_gemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a53
57        # Push 96 bytes
58        PUSH    {r2, r4, r5, r6, r7, r8, r9, r10, r11, lr}  // 40
59        VPUSH   {d8-d14}                            // +56 = 96
60
61        LDR     r7, [sp, 96]            // a_stride
62        LDR     r11, [sp, 104]          // c
63        LDR     r6, [sp, 108]           // cm_stride
64        LDR     r9, [sp, 100]           // w
65        LDR     r5, [sp, 116]           // params
66
67        # Clamp A and C pointers
68        CMP     r0, 2                   // if mr >= 2
69        ADD     r12, r3, r7             //   a1 = a0 + a_stride
70        ADD     r4, r11, r6             //   c1 = c0 + cm_stride
71        MOVLO   r12, r3                 // a1
72        MOVLO   r4, r11                 // c1
73                                        // if mr > 2
74        ADD     r10, r12, r7            //   a2 = a1 + a_stride
75        ADD     r8, r4, r6              //   c2 = c1 + cm_stride
76        MOVLS   r10, r12                // a2
77        MOVLS   r8, r4                  // c2
78
79        CMP     r0, 4                   // if mr >=4
80        ADD     r0, r10, r7             //   a3 = a2 + a_stride
81        ADD     r6, r8, r6              //   c3 = c2 + cm_stride
82        MOVLO   r0, r10                 // a3
83        MOVLO   r6, r8                  // c3
84
85        # Load params values
86        VLD1.32 {d14[]}, [r5]!          // QU8 kernel_zero_point
87        VLDM    r5, {d12-d13}           // RNDNU params
88        LDR     r7, [sp, 112]            // cn_stride
89
90        PLD     [r9,  64]               // Prefetch B
91        PLD     [r9, 128]
92        PLD     [r9, 192]
93        PLD     [r9, 256]
94        PLD     [r9, 320]
95        PLD     [r9, 384]
96
97        .p2align 3
980:
99        # Load initial bias from w into accumulators
100        VLDM    r9!, {d16-d19}          // Bias
101        SUBS    r5, r2, 8               // k = kc - 8
102
103        VMOV    q10, q8
104        PLD     [r3,  64]               // Prefetch A
105        VMOV    q11, q9
106        PLD     [r12, 64]
107        VMOV    q12, q8
108        PLD     [r10, 64]
109        VMOV    q13, q9
110        PLD     [r0,  64]
111        VMOV    q14, q8
112        VMOV    q15, q9
113        BLO     4f                      // less than 8 channels?
114
115        // Prologue - load 4A's and B0
116        VLD1.8  {d0},  [r3]!            // A0
117        VLD1.8  {d2}, [r12]!            // A1
118        VLD1.8  {d4}, [r10]!            // A2
119        VLD1.8  {d6},  [r0]!            // A3
120        VLD1.8  {d8},  [r9]!            // B0
121
122        SUBS    r5, r5, 8               // k = k - 8
123        BLO     2f                      // less than 8 channels?
124
125        // Main loop - 8 bytes
126        // 64 bytes for weights.
127        // 5 VMOVL = 4 A and 1 B = 5 cycles
128        // 7 blocks with VLD B, VMOVL, 8 VMLA = 10 cycles
129        // 1 blocks with VLD B, VMLA = 9 cycles
130        // total = 84 cycles
131        .p2align 3
1321:
133        // Extend - 5 cycles
134        VMOVL.U8 q0, d0
135        PLD     [r3, 128]
136        VSUBL.U8 q4, d8, d14
137        PLD     [r9, 448]
138        VMOVL.U8 q1, d2
139        PLD     [r12, 128]
140        VMOVL.U8 q2, d4
141        PLD     [r0, 128]
142        VMOVL.U8 q3, d6
143        PLD     [r10, 128]
144
145        // BLOCK 0 - 10 cycles
146        VLD1.8  {d10},  [r9]!           // B1
147        VMLAL.S16 q8, d8, d0[0]
148        VMLAL.S16 q9, d9, d0[0]
149        VMLAL.S16 q10, d8, d2[0]
150        VMLAL.S16 q11, d9, d2[0]
151        VSUBL.U8 q5, d10, d14
152        VMLAL.S16 q12, d8, d4[0]
153        VMLAL.S16 q13, d9, d4[0]
154        VMLAL.S16 q14, d8, d6[0]
155        VMLAL.S16 q15, d9, d6[0]
156
157        // BLOCK 1 - 10 cycles
158        VLD1.8  {d8},  [r9]!            // B2
159        VMLAL.S16 q8, d10, d0[1]
160        VMLAL.S16 q9, d11, d0[1]
161        VMLAL.S16 q10, d10, d2[1]
162        VMLAL.S16 q11, d11, d2[1]
163        VSUBL.U8 q4, d8, d14
164        VMLAL.S16 q12, d10, d4[1]
165        VMLAL.S16 q13, d11, d4[1]
166        VMLAL.S16 q14, d10, d6[1]
167        VMLAL.S16 q15, d11, d6[1]
168
169        // BLOCK 2 - 10 cycles
170        VLD1.8  {d10},  [r9]!           // B3
171        VMLAL.S16 q8, d8, d0[2]
172        VMLAL.S16 q9, d9, d0[2]
173        VMLAL.S16 q10, d8, d2[2]
174        VMLAL.S16 q11, d9, d2[2]
175        VSUBL.U8 q5, d10, d14
176        VMLAL.S16 q12, d8, d4[2]
177        VMLAL.S16 q13, d9, d4[2]
178        VMLAL.S16 q14, d8, d6[2]
179        VMLAL.S16 q15, d9, d6[2]
180
181        // BLOCK 3 - 10 cycles
182        VLD1.8  {d8},  [r9]!            // B4
183        VMLAL.S16 q8, d10, d0[3]
184        VMLAL.S16 q9, d11, d0[3]
185        VMLAL.S16 q10, d10, d2[3]
186        VMLAL.S16 q11, d11, d2[3]
187        VSUBL.U8 q4, d8, d14
188        VMLAL.S16 q12, d10, d4[3]
189        LDR     r2, [r3]                // A0 low
190        VMLAL.S16 q13, d11, d4[3]
191        LDR     r14, [r3, 4]            // A0 high
192        VMLAL.S16 q14, d10, d6[3]
193        ADD     r3, r3, 8
194        VMLAL.S16 q15, d11, d6[3]
195
196        // BLOCK 4 - 10 cycles
197        VLD1.8  {d10},  [r9]!           // B5
198        VMOV    d0, r2, r14             // A0 VMOV
199        VMLAL.S16 q8, d8, d1[0]
200        VMLAL.S16 q9, d9, d1[0]
201        VMLAL.S16 q10, d8, d3[0]
202        VMLAL.S16 q11, d9, d3[0]
203        VSUBL.U8 q5, d10, d14
204        VMLAL.S16 q12, d8, d5[0]
205        LDR     r2, [r12]               // A1 low
206        VMLAL.S16 q13, d9, d5[0]
207        LDR     r14, [r12, 4]           // A1 high
208        VMLAL.S16 q14, d8, d7[0]
209        ADD     r12, r12, 8
210        VMLAL.S16 q15, d9, d7[0]
211
212        // BLOCK 5 - 10 cycles
213        VLD1.8  {d8},  [r9]!            // B6
214        VMOV    d2, r2, r14             // A1 VMOV
215        VMLAL.S16 q8, d10, d1[1]
216        VMLAL.S16 q9, d11, d1[1]
217        VMLAL.S16 q10, d10, d3[1]
218        VMLAL.S16 q11, d11, d3[1]
219        VSUBL.U8 q4, d8, d14
220        VMLAL.S16 q12, d10, d5[1]
221        LDR     r2, [r10]               // A2 low
222        VMLAL.S16 q13, d11, d5[1]
223        LDR     r14, [r10, 4]           // A2 high
224        VMLAL.S16 q14, d10, d7[1]
225        ADD     r10, r10, 8
226        VMLAL.S16 q15, d11, d7[1]
227
228        // BLOCK 6 - 10 cycles
229        VLD1.8  {d10},  [r9]!           // B7
230        VMOV    d4, r2, r14             // A2 VMOV
231        VMLAL.S16 q8, d8, d1[2]
232        VMLAL.S16 q9, d9, d1[2]
233        VMLAL.S16 q10, d8, d3[2]
234        VMLAL.S16 q11, d9, d3[2]
235        VSUBL.U8 q5, d10, d14
236        VMLAL.S16 q12, d8, d5[2]
237        LDR     r2, [r0]                // A3 low
238        VMLAL.S16 q13, d9, d5[2]
239        LDR     r14, [r0, 4]            // A3 high
240        VMLAL.S16 q14, d8, d7[2]
241        ADD     r0, r0, 8
242        VMLAL.S16 q15, d9, d7[2]
243
244        // BLOCK 7 - 9 cycles
245        VLD1.8  {d8},  [r9]!            // B0
246        VMOV    d6, r2, r14             // A3 VMOV
247        VMLAL.S16 q8, d10, d1[3]
248        VMLAL.S16 q9, d11, d1[3]
249        VMLAL.S16 q10, d10, d3[3]
250        VMLAL.S16 q11, d11, d3[3]
251        VMLAL.S16 q12, d10, d5[3]
252        VMLAL.S16 q13, d11, d5[3]
253        SUBS    r5, r5, 8
254        VMLAL.S16 q14, d10, d7[3]
255        VMLAL.S16 q15, d11, d7[3]
256        BHS     1b
257
258        // Epilogue
259
260        .p2align 3
2612:
262        VMOVL.U8 q0, d0
263        VSUBL.U8 q4, d8, d14
264        VMOVL.U8 q1, d2
265        VMOVL.U8 q2, d4
266        VMOVL.U8 q3, d6
267
268        VLD1.8  {d10},  [r9]!           // B1
269        VMLAL.S16 q8, d8, d0[0]
270        VMLAL.S16 q9, d9, d0[0]
271        VMLAL.S16 q10, d8, d2[0]
272        VMLAL.S16 q11, d9, d2[0]
273        VSUBL.U8 q5, d10, d14
274        VMLAL.S16 q12, d8, d4[0]
275        VMLAL.S16 q13, d9, d4[0]
276        VMLAL.S16 q14, d8, d6[0]
277        VMLAL.S16 q15, d9, d6[0]
278
279        VLD1.8  {d8},  [r9]!            // B2
280        VMLAL.S16 q8, d10, d0[1]
281        VMLAL.S16 q9, d11, d0[1]
282        VMLAL.S16 q10, d10, d2[1]
283        VMLAL.S16 q11, d11, d2[1]
284        VSUBL.U8 q4, d8, d14
285        VMLAL.S16 q12, d10, d4[1]
286        VMLAL.S16 q13, d11, d4[1]
287        VMLAL.S16 q14, d10, d6[1]
288        VMLAL.S16 q15, d11, d6[1]
289
290        VLD1.8  {d10},  [r9]!           // B3
291        VMLAL.S16 q8, d8, d0[2]
292        VMLAL.S16 q9, d9, d0[2]
293        VMLAL.S16 q10, d8, d2[2]
294        VMLAL.S16 q11, d9, d2[2]
295        VSUBL.U8 q5, d10, d14
296        VMLAL.S16 q12, d8, d4[2]
297        VMLAL.S16 q13, d9, d4[2]
298        VMLAL.S16 q14, d8, d6[2]
299        VMLAL.S16 q15, d9, d6[2]
300
301        VLD1.8  {d8},  [r9]!            // B4
302        VMLAL.S16 q8, d10, d0[3]
303        VMLAL.S16 q9, d11, d0[3]
304        VMLAL.S16 q10, d10, d2[3]
305        VMLAL.S16 q11, d11, d2[3]
306        VSUBL.U8 q4, d8, d14
307        VMLAL.S16 q12, d10, d4[3]
308        VMLAL.S16 q13, d11, d4[3]
309        VMLAL.S16 q14, d10, d6[3]
310        VMLAL.S16 q15, d11, d6[3]
311
312        VLD1.8  {d10},  [r9]!           // B5
313        VMLAL.S16 q8, d8, d1[0]
314        VMLAL.S16 q9, d9, d1[0]
315        VMLAL.S16 q10, d8, d3[0]
316        VMLAL.S16 q11, d9, d3[0]
317        VSUBL.U8 q5, d10, d14
318        VMLAL.S16 q12, d8, d5[0]
319        VMLAL.S16 q13, d9, d5[0]
320        VMLAL.S16 q14, d8, d7[0]
321        VMLAL.S16 q15, d9, d7[0]
322
323        VLD1.8  {d8},  [r9]!            // B6
324        VMLAL.S16 q8, d10, d1[1]
325        VMLAL.S16 q9, d11, d1[1]
326        VMLAL.S16 q10, d10, d3[1]
327        VMLAL.S16 q11, d11, d3[1]
328        VSUBL.U8 q4, d8, d14
329        VMLAL.S16 q12, d10, d5[1]
330        VMLAL.S16 q13, d11, d5[1]
331        VMLAL.S16 q14, d10, d7[1]
332        VMLAL.S16 q15, d11, d7[1]
333
334        VLD1.8  {d10},  [r9]!           // B7
335        VMLAL.S16 q8, d8, d1[2]
336        VMLAL.S16 q9, d9, d1[2]
337        VMLAL.S16 q10, d8, d3[2]
338        VMLAL.S16 q11, d9, d3[2]
339        VSUBL.U8 q5, d10, d14
340        VMLAL.S16 q12, d8, d5[2]
341        VMLAL.S16 q13, d9, d5[2]
342        VMLAL.S16 q14, d8, d7[2]
343        VMLAL.S16 q15, d9, d7[2]
344
345        VMLAL.S16 q8, d10, d1[3]
346        VMLAL.S16 q9, d11, d1[3]
347        VMLAL.S16 q10, d10, d3[3]
348        VMLAL.S16 q11, d11, d3[3]
349        VMLAL.S16 q12, d10, d5[3]
350        VMLAL.S16 q13, d11, d5[3]
351        ADDS    r5, r5, 8
352        VMLAL.S16 q14, d10, d7[3]
353        VMLAL.S16 q15, d11, d7[3]
354
355        # Is there a remainder?- 1-7 bytes of A
356        BNE     4f
357
3583:
359        # RNDNU quantization
360        VDUP.32 q0, d12[0]              // right_pre_shift
361
362        VQSHL.S32 q8,  q8, q0
363        VQSHL.S32 q9,  q9, q0
364        VQSHL.S32 q10, q10, q0
365        VQSHL.S32 q11, q11, q0
366        VQSHL.S32 q12, q12, q0
367        VQSHL.S32 q13, q13, q0
368        VQSHL.S32 q14, q14, q0
369        VQSHL.S32 q15, q15, q0
370
371        VDUP.32 q2, d13[0]              // right_post_shift
372
373        VQDMULH.S32 q8,  q8, d12[1]     // multiplier
374        VQDMULH.S32 q9,  q9, d12[1]
375        VQDMULH.S32 q10, q10, d12[1]
376        VQDMULH.S32 q11, q11, d12[1]
377        VQDMULH.S32 q12, q12, d12[1]
378        VQDMULH.S32 q13, q13, d12[1]
379        VQDMULH.S32 q14, q14, d12[1]
380        VQDMULH.S32 q15, q15, d12[1]
381
382        VRSHL.S32 q8,  q8, q2
383        VRSHL.S32 q9,  q9, q2
384        VRSHL.S32 q10, q10, q2
385        VRSHL.S32 q11, q11, q2
386        VRSHL.S32 q12, q12, q2
387        VRSHL.S32 q13, q13, q2
388        VRSHL.S32 q14, q14, q2
389        VRSHL.S32 q15, q15, q2
390
391        VDUP.16 q0, d13[2]              // output_zero_point
392
393        VQMOVN.S32 d16, q8
394        VQMOVN.S32 d17, q9
395        VQMOVN.S32 d18, q10
396        VQMOVN.S32 d19, q11
397        VQMOVN.S32 d20, q12
398        VQMOVN.S32 d21, q13
399        VQMOVN.S32 d22, q14
400        VQMOVN.S32 d23, q15
401
402        VQADD.S16 q8,  q8, q0
403        VQADD.S16 q9,  q9, q0
404        VQADD.S16 q10, q10, q0
405        VQADD.S16 q11, q11, q0
406
407        VDUP.8  q12, d13[6]             // output_min
408
409        VQMOVUN.S16 d0,  q8
410        VQMOVUN.S16 d1,  q9
411        VQMOVUN.S16 d2, q10
412        VQMOVUN.S16 d3, q11
413
414        VDUP.8  q13, d13[7]             // output_max
415
416        VMAX.U8 q0, q0, q12
417        VMAX.U8 q1, q1, q12
418
419        LDR     r2, [sp, 56]            // kc
420        SUBS    r1, r1, 8
421
422        VMIN.U8 q0, q0, q13
423        VMIN.U8 q1, q1, q13
424
425        # Store full 4 x 8
426        BLO     5f
427        VST1.8  {d0}, [r11], r7
428        SUB     r3, r3, r2
429        VST1.8  {d1}, [r4], r7
430        SUB     r12, r12, r2
431        VST1.8  {d2}, [r8], r7
432        SUB     r10, r10, r2
433        VST1.8  {d3}, [r6], r7
434        SUB     r0, r0, r2
435        BHI     0b
436
437        VPOP    {d8-d14}
438        ADD     sp, sp, 4               // skip r2
439        POP     {r4, r5, r6, r7, r8, r9, r10, r11, pc}
440
441        # Remainder- 1 to 7 bytes of A
442        .p2align 3
4434:
444        AND     r5, r5, 7               // kc remainder 1 to 7
445
446        VLD1.8  {d0},  [r3], r5
447        VLD1.8  {d8},  [r9]!
448        VLD1.8  {d2}, [r12], r5
449        VLD1.8  {d4}, [r10], r5
450        VLD1.8  {d6},  [r0], r5
451
452        VMOVL.U8 q0, d0
453        VSUBL.U8 q4, d8, d14
454        VMOVL.U8 q1, d2
455        VMOVL.U8 q2, d4
456        VMOVL.U8 q3, d6
457        VMLAL.S16 q8, d8, d0[0]
458        VMLAL.S16 q9, d9, d0[0]
459        VMLAL.S16 q10, d8, d2[0]
460        VMLAL.S16 q11, d9, d2[0]
461        VMLAL.S16 q12, d8, d4[0]
462        VMLAL.S16 q13, d9, d4[0]
463        VMLAL.S16 q14, d8, d6[0]
464        VMLAL.S16 q15, d9, d6[0]
465        CMP     r5, 2
466        BLO     3b
467
468        VLD1.8  {d8},  [r9]!
469        VSUBL.U8 q4, d8, d14
470        VMLAL.S16 q8, d8, d0[1]
471        VMLAL.S16 q9, d9, d0[1]
472        VMLAL.S16 q10, d8, d2[1]
473        VMLAL.S16 q11, d9, d2[1]
474        VMLAL.S16 q12, d8, d4[1]
475        VMLAL.S16 q13, d9, d4[1]
476        VMLAL.S16 q14, d8, d6[1]
477        VMLAL.S16 q15, d9, d6[1]
478        BEQ     3b
479
480        VLD1.8  {d8},  [r9]!
481        VSUBL.U8 q4, d8, d14
482        VMLAL.S16 q8, d8, d0[2]
483        VMLAL.S16 q9, d9, d0[2]
484        VMLAL.S16 q10, d8, d2[2]
485        VMLAL.S16 q11, d9, d2[2]
486        VMLAL.S16 q12, d8, d4[2]
487        VMLAL.S16 q13, d9, d4[2]
488        VMLAL.S16 q14, d8, d6[2]
489        VMLAL.S16 q15, d9, d6[2]
490        CMP     r5, 4
491        BLO     3b
492
493        VLD1.8  {d8},  [r9]!
494        VSUBL.U8 q4, d8, d14
495        VMLAL.S16 q8, d8, d0[3]
496        VMLAL.S16 q9, d9, d0[3]
497        VMLAL.S16 q10, d8, d2[3]
498        VMLAL.S16 q11, d9, d2[3]
499        VMLAL.S16 q12, d8, d4[3]
500        VMLAL.S16 q13, d9, d4[3]
501        VMLAL.S16 q14, d8, d6[3]
502        VMLAL.S16 q15, d9, d6[3]
503        BEQ     3b
504
505        VLD1.8  {d8},  [r9]!
506        VSUBL.U8 q4, d8, d14
507        VMLAL.S16 q8, d8, d1[0]
508        VMLAL.S16 q9, d9, d1[0]
509        VMLAL.S16 q10, d8, d3[0]
510        VMLAL.S16 q11, d9, d3[0]
511        VMLAL.S16 q12, d8, d5[0]
512        VMLAL.S16 q13, d9, d5[0]
513        VMLAL.S16 q14, d8, d7[0]
514        VMLAL.S16 q15, d9, d7[0]
515        CMP     r5, 6
516        BLO     3b
517
518        VLD1.8  {d8},  [r9]!
519        VSUBL.U8 q4, d8, d14
520        VMLAL.S16 q8, d8, d1[1]
521        VMLAL.S16 q9, d9, d1[1]
522        VMLAL.S16 q10, d8, d3[1]
523        VMLAL.S16 q11, d9, d3[1]
524        VMLAL.S16 q12, d8, d5[1]
525        VMLAL.S16 q13, d9, d5[1]
526        VMLAL.S16 q14, d8, d7[1]
527        VMLAL.S16 q15, d9, d7[1]
528        BEQ     3b
529
530        VLD1.8  {d8},  [r9]!
531        VSUBL.U8 q4, d8, d14
532        VMLAL.S16 q8, d8, d1[2]
533        VMLAL.S16 q9, d9, d1[2]
534        VMLAL.S16 q10, d8, d3[2]
535        VMLAL.S16 q11, d9, d3[2]
536        VMLAL.S16 q12, d8, d5[2]
537        VMLAL.S16 q13, d9, d5[2]
538        VMLAL.S16 q14, d8, d7[2]
539        VMLAL.S16 q15, d9, d7[2]
540        B       3b
541
542        # Store odd width
543        .p2align 3
5445:
545        TST     r1, 4
546        BEQ     6f
547        VST1.32 {d0[0]}, [r11]!
548        VST1.32 {d1[0]}, [r4]!
549        VST1.32 {d2[0]}, [r8]!
550        VST1.32 {d3[0]}, [r6]!
551        VEXT.8  q0, q0, q0, 4
552        VEXT.8  q1, q1, q1, 4
5536:
554        TST     r1, 2
555        BEQ     7f
556        VST1.16 {d0[0]}, [r11]!
557        VST1.16 {d1[0]}, [r4]!
558        VST1.16 {d2[0]}, [r8]!
559        VST1.16 {d3[0]}, [r6]!
560        VEXT.8  q0, q0, q0, 2
561        VEXT.8  q1, q1, q1, 2
562
5637:
564        TST     r1, 1
565        BEQ     8f
566        VST1.8  {d0[0]}, [r11]
567        VST1.8  {d1[0]}, [r4]
568        VST1.8  {d2[0]}, [r8]
569        VST1.8  {d3[0]}, [r6]
570
5718:
572        VPOP    {d8-d14}
573        ADD     sp, sp, 4               // skip r2
574        POP     {r4, r5, r6, r7, r8, r9, r10, r11, pc}
575
576
577END_FUNCTION xnn_qu8_gemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a53
578
579#ifdef __ELF__
580.section ".note.GNU-stack","",%progbits
581#endif
582
583