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