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