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