1// Auto-generated file. Do not edit!
2//   Template: src/qs8-igemm/4x8-aarch32-neon-mlal-lane-cortex-a7.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_a35(
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// Unused d15
45
46// params structure is 4 bytes
47//  struct {
48//    int16_t output_zero_point;  d13[2]
49//    int8_t output_min;          d13[6]
50//    int8_t output_max;          d13[7]
51//  } xnn_qs8_minmax_params.neonv8;
52
53BEGIN_FUNCTION xnn_qc8_igemm_minmax_fp32_ukernel_4x8__aarch32_neonv8_mlal_lane_cortex_a35
54        # Push 104 bytes
55        # r1, r2 will be reloaded in outer loop.  r3 is ks
56        PUSH    {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}   // +48
57        SUB     sp, sp, 8                           // +8
58        VPUSH   {d8-d13}                            // +48 = 104
59
60        LDR     r11, [sp, 112]          // c
61        LDR     r6, [sp, 116]           // cm_stride
62        LDR     r2, [sp, 104]           // a
63        LDR     r9, [sp, 108]           // w
64        LDR     r5, [sp, 132]           // params
65        MOV     r14, r3                 // p = ks
66
67        # Clamp C pointers
68        CMP     r0, 2                   // if mr >= 2
69        ADD     r4, r11, r6             //   c1 = c0 + cm_stride
70        MOVLO   r4, r11                 // c1
71                                        // if mr > 2
72        ADD     r8, r4, r6              //   c2 = c1 + cm_stride
73        MOVLS   r8, r4                  // c2
74        CMP     r0, 4                   // if mr >=4
75        ADD     r6, r8, r6              //   c3 = c2 + cm_stride
76        MOVLO   r6, r8                  // c3
77
78        # Load params values
79        VLD1.32 {d13[]}, [r5]           // QC8 neonv8 params
80
81
82        .p2align 3
830:
84        # Load initial bias from w into accumulators
85        VLDM    r9!, {d16-d19}          // Bias
86        VMOV    q10, q8
87        VMOV    q11, q9
88        STR     r1, [sp, 56]            // save nc
89        VMOV    q12, q8
90        VMOV    q13, q9
91        VMOV    q14, q8
92        VMOV    q15, q9
93
94        .p2align 3
951:
96        # Load next 4 A pointers
97        LDR     r3, [r2,  0]
98        LDR     r12, [r2,  4]
99        LDR     r10, [r2,  8]
100        LDR     r0, [r2, 12]
101
102        # Add a_offset
103        LDR     r5, [sp, 124]           // a_offset
104        LDR     r7, [sp, 128]           // zero
105        ADD     r2, r2, 16
106        CMP     r3,  r7                 // if a0 == zero
107        ADD     r3,  r3, r5             // a0 += a_offset
108        MOVEQ   r3,  r7                 //   a0 = zero, else += a0 + a_offset
109        CMP     r12,  r7                // if a1 == zero
110        ADD     r12, r12, r5            // a1 += a_offset
111        MOVEQ   r12,  r7                //   a1 = zero, else += a1 + a_offset
112        CMP     r10,  r7                // if a2 == zero
113        ADD     r10, r10, r5            // a2 += a_offset
114        MOVEQ   r10,  r7                //   a2 = zero, else += a2 + a_offset
115        CMP     r0,  r7                 // if a3 == zero
116        ADD     r0,  r0, r5             // a3 += a_offset
117        LDR     r5, [sp, 60]            // kc
118        MOVEQ   r0,  r7                 //   a3 = zero, else += a3 + a_offset
119        SUBS    r5, r5, 8               // kc - 8
120        BLO     5f                      // less than 8 channels?
121
122        // Prologue - load 4A's and B0
123        VLD1.8  {d0},  [r3]!            // A0
124        VLD1.8  {d8},  [r9]!            // B0
125        SUBS    r5, r5, 8               // k = k - 8
126        VLD1.8  {d2}, [r12]!            // A1
127        VLD1.8  {d4}, [r10]!            // A2
128        VLD1.8  {d6},  [r0]!            // A3
129
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        VLD1.8  {d0},  [r3]!            // A0
190        VMOVL.S8 q4, d8
191        VMLAL.S16 q12, d10, d4[3]
192        VMLAL.S16 q13, d11, d4[3]
193        VMLAL.S16 q14, d10, d6[3]
194        VMLAL.S16 q15, d11, d6[3]
195
196        // BLOCK 4 - 10 cycles
197        VLD1.8  {d10},  [r9]!           // B5
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        VLD1.8  {d2}, [r12]!            // A1
203        VMOVL.S8 q5, d10
204        VMLAL.S16 q12, d8, d5[0]
205        VMLAL.S16 q13, d9, d5[0]
206        VMLAL.S16 q14, d8, d7[0]
207        VMLAL.S16 q15, d9, d7[0]
208
209        // BLOCK 5 - 10 cycles
210        VLD1.8  {d8},  [r9]!            // B6
211        VMLAL.S16 q8, d10, d1[1]
212        VMLAL.S16 q9, d11, d1[1]
213        VMLAL.S16 q10, d10, d3[1]
214        VMLAL.S16 q11, d11, d3[1]
215        VLD1.8  {d4}, [r10]!            // A2
216        VMOVL.S8 q4, d8
217        VMLAL.S16 q12, d10, d5[1]
218        VMLAL.S16 q13, d11, d5[1]
219        VMLAL.S16 q14, d10, d7[1]
220        VMLAL.S16 q15, d11, d7[1]
221
222        // BLOCK 6 - 10 cycles
223        VLD1.8  {d10},  [r9]!           // B7
224        VMLAL.S16 q8, d8, d1[2]
225        VMLAL.S16 q9, d9, d1[2]
226        VMLAL.S16 q10, d8, d3[2]
227        VMLAL.S16 q11, d9, d3[2]
228        VLD1.8  {d6},  [r0]!            // A3
229        VMOVL.S8 q5, d10
230        VMLAL.S16 q12, d8, d5[2]
231        VMLAL.S16 q13, d9, d5[2]
232        VMLAL.S16 q14, d8, d7[2]
233        VMLAL.S16 q15, d9, d7[2]
234
235        // BLOCK 7 - 9 cycles
236        VLD1.8  {d8},  [r9]!            // B0
237        VMLAL.S16 q8, d10, d1[3]
238        VMLAL.S16 q9, d11, d1[3]
239        VMLAL.S16 q10, d10, d3[3]
240        VMLAL.S16 q11, d11, d3[3]
241        VMLAL.S16 q12, d10, d5[3]
242        VMLAL.S16 q13, d11, d5[3]
243        SUBS    r5, r5, 8
244        VMLAL.S16 q14, d10, d7[3]
245        VMLAL.S16 q15, d11, d7[3]
246        BHS     2b
247
248        // Epilogue
249
250        .p2align 3
2513:
252        VMOVL.S8 q0, d0
253        VMOVL.S8 q4, d8
254        VMOVL.S8 q1, d2
255        VMOVL.S8 q2, d4
256        VMOVL.S8 q3, d6
257
258        VLD1.8  {d10},  [r9]!           // B1
259        VMLAL.S16 q8, d8, d0[0]
260        VMLAL.S16 q9, d9, d0[0]
261        VMLAL.S16 q10, d8, d2[0]
262        VMLAL.S16 q11, d9, d2[0]
263        VMOVL.S8 q5, d10
264        VMLAL.S16 q12, d8, d4[0]
265        VMLAL.S16 q13, d9, d4[0]
266        VMLAL.S16 q14, d8, d6[0]
267        VMLAL.S16 q15, d9, d6[0]
268
269        VLD1.8  {d8},  [r9]!            // B2
270        VMLAL.S16 q8, d10, d0[1]
271        VMLAL.S16 q9, d11, d0[1]
272        VMLAL.S16 q10, d10, d2[1]
273        VMLAL.S16 q11, d11, d2[1]
274        VMOVL.S8 q4, d8
275        VMLAL.S16 q12, d10, d4[1]
276        VMLAL.S16 q13, d11, d4[1]
277        VMLAL.S16 q14, d10, d6[1]
278        VMLAL.S16 q15, d11, d6[1]
279
280        VLD1.8  {d10},  [r9]!           // B3
281        VMLAL.S16 q8, d8, d0[2]
282        VMLAL.S16 q9, d9, d0[2]
283        VMLAL.S16 q10, d8, d2[2]
284        VMLAL.S16 q11, d9, d2[2]
285        VMOVL.S8 q5, d10
286        VMLAL.S16 q12, d8, d4[2]
287        VMLAL.S16 q13, d9, d4[2]
288        VMLAL.S16 q14, d8, d6[2]
289        VMLAL.S16 q15, d9, d6[2]
290
291        VLD1.8  {d8},  [r9]!            // B4
292        VMLAL.S16 q8, d10, d0[3]
293        VMLAL.S16 q9, d11, d0[3]
294        VMLAL.S16 q10, d10, d2[3]
295        VMLAL.S16 q11, d11, d2[3]
296        VMOVL.S8 q4, d8
297        VMLAL.S16 q12, d10, d4[3]
298        VMLAL.S16 q13, d11, d4[3]
299        VMLAL.S16 q14, d10, d6[3]
300        VMLAL.S16 q15, d11, d6[3]
301
302        VLD1.8  {d10},  [r9]!           // B5
303        VMLAL.S16 q8, d8, d1[0]
304        VMLAL.S16 q9, d9, d1[0]
305        VMLAL.S16 q10, d8, d3[0]
306        VMLAL.S16 q11, d9, d3[0]
307        VMOVL.S8 q5, d10
308        VMLAL.S16 q12, d8, d5[0]
309        VMLAL.S16 q13, d9, d5[0]
310        VMLAL.S16 q14, d8, d7[0]
311        VMLAL.S16 q15, d9, d7[0]
312
313        VLD1.8  {d8},  [r9]!            // B6
314        VMLAL.S16 q8, d10, d1[1]
315        VMLAL.S16 q9, d11, d1[1]
316        VMLAL.S16 q10, d10, d3[1]
317        VMLAL.S16 q11, d11, d3[1]
318        VMOVL.S8 q4, d8
319        VMLAL.S16 q12, d10, d5[1]
320        VMLAL.S16 q13, d11, d5[1]
321        VMLAL.S16 q14, d10, d7[1]
322        VMLAL.S16 q15, d11, d7[1]
323
324        VLD1.8  {d10},  [r9]!           // B7
325        VMLAL.S16 q8, d8, d1[2]
326        VMLAL.S16 q9, d9, d1[2]
327        VMLAL.S16 q10, d8, d3[2]
328        VMLAL.S16 q11, d9, d3[2]
329        VMOVL.S8 q5, d10
330        VMLAL.S16 q12, d8, d5[2]
331        VMLAL.S16 q13, d9, d5[2]
332        VMLAL.S16 q14, d8, d7[2]
333        VMLAL.S16 q15, d9, d7[2]
334
335        VMLAL.S16 q8, d10, d1[3]
336        VMLAL.S16 q9, d11, d1[3]
337        VMLAL.S16 q10, d10, d3[3]
338        VMLAL.S16 q11, d11, d3[3]
339        VMLAL.S16 q12, d10, d5[3]
340        VMLAL.S16 q13, d11, d5[3]
341        ADDS    r5, r5, 8
342        VMLAL.S16 q14, d10, d7[3]
343        VMLAL.S16 q15, d11, d7[3]
344
345        # Is there a remainder?- 1-7 bytes of A
346        BNE     6f
347
3484:
349        # ks loop
350        SUBS    r14, r14, 16            // ks -= MR * sizeof(void*)
351        BHI     1b
352
353        LDR     r7, [sp, 120]           // cn_stride
354        LDR     r14, [sp, 64]           // p = ks
355
356        # QC8 FP32 quantization
357        VLD1.8  {q0-q1},  [r9]!
358
359        VCVT.F32.S32 q8,  q8
360        VCVT.F32.S32 q9,  q9
361        VCVT.F32.S32 q10, q10
362        VCVT.F32.S32 q11, q11
363        VCVT.F32.S32 q12, q12
364        VCVT.F32.S32 q13, q13
365        VCVT.F32.S32 q14, q14
366        VCVT.F32.S32 q15, q15
367
368        VMUL.F32 q8,  q8, q0            // multiplier
369        VMUL.F32 q9,  q9, q1
370        VMUL.F32 q10, q10, q0
371        VMUL.F32 q11, q11, q1
372        VMUL.F32 q12, q12, q0
373        VMUL.F32 q13, q13, q1
374        VMUL.F32 q14, q14, q0
375        VMUL.F32 q15, q15, q1
376
377        VCVTN.S32.F32 q8,  q8
378        VCVTN.S32.F32 q9,  q9
379        VCVTN.S32.F32 q10, q10
380        VCVTN.S32.F32 q11, q11
381        VCVTN.S32.F32 q12, q12
382        VCVTN.S32.F32 q13, q13
383        VCVTN.S32.F32 q14, q14
384        VCVTN.S32.F32 q15, q15
385
386        VDUP.16 q0, d13[2]              // output_zero_point
387
388        VQMOVN.S32 d16, q8
389        VQMOVN.S32 d17, q9
390        VQMOVN.S32 d18, q10
391        VQMOVN.S32 d19, q11
392        VQMOVN.S32 d20, q12
393        VQMOVN.S32 d21, q13
394        VQMOVN.S32 d22, q14
395        VQMOVN.S32 d23, q15
396
397        VQADD.S16 q8,  q8, q0
398        VQADD.S16 q9,  q9, q0
399        VQADD.S16 q10, q10, q0
400        VQADD.S16 q11, q11, q0
401
402        LDR     r1, [sp, 56]            // restore nc
403        VDUP.8  q12, d13[6]             // output_min
404
405        VQMOVN.S16 d0,  q8
406        VQMOVN.S16 d1,  q9
407        VQMOVN.S16 d2, q10
408        VQMOVN.S16 d3, q11
409
410        VDUP.8  q13, d13[7]             // output_max
411
412        VMAX.S8 q0, q0, q12
413        VMAX.S8 q1, q1, q12
414
415        SUBS    r1, r1, 8               // nc -= 8
416
417        VMIN.S8 q0, q0, q13
418        VMIN.S8 q1, q1, q13
419
420        # Store full 4 x 8
421        BLO     7f
422        VST1.8  {d3}, [r6], r7
423        VST1.8  {d2}, [r8], r7
424        VST1.8  {d1}, [r4], r7
425        VST1.8  {d0}, [r11], r7
426        SUB     r2, r2, r14             // a -= ks
427        BHI     0b
428
429        VPOP    {d8-d13}
430        ADD     sp, sp, 20              // skip pad of 8, r1, r2, r3
431        POP     {r4, r5, r6, r7, r8, r9, r10, r11, pc}
432
433        # Remainder- 1 to 7 bytes of A
434        .p2align 3
4355:
436        AND     r5, r5, 7               // kc remainder 1 to 7
4376:
438        VLD1.8  {d0},  [r3]
439        VLD1.8  {d8},  [r9]!
440        VLD1.8  {d2}, [r12]
441        VLD1.8  {d4}, [r10]
442        VLD1.8  {d6},  [r0]
443
444        VMOVL.S8 q0, d0
445        VMOVL.S8 q4, d8
446        VMOVL.S8 q1, d2
447        VMOVL.S8 q2, d4
448        VMOVL.S8 q3, d6
449        VMLAL.S16 q8, d8, d0[0]
450        VMLAL.S16 q9, d9, d0[0]
451        VMLAL.S16 q10, d8, d2[0]
452        VMLAL.S16 q11, d9, d2[0]
453        VMLAL.S16 q12, d8, d4[0]
454        VMLAL.S16 q13, d9, d4[0]
455        VMLAL.S16 q14, d8, d6[0]
456        VMLAL.S16 q15, d9, d6[0]
457        CMP     r5, 2
458        BLO     4b
459
460        VLD1.8  {d8},  [r9]!
461        VMOVL.S8 q4, d8
462        VMLAL.S16 q8, d8, d0[1]
463        VMLAL.S16 q9, d9, d0[1]
464        VMLAL.S16 q10, d8, d2[1]
465        VMLAL.S16 q11, d9, d2[1]
466        VMLAL.S16 q12, d8, d4[1]
467        VMLAL.S16 q13, d9, d4[1]
468        VMLAL.S16 q14, d8, d6[1]
469        VMLAL.S16 q15, d9, d6[1]
470        BEQ     4b
471
472        VLD1.8  {d8},  [r9]!
473        VMOVL.S8 q4, d8
474        VMLAL.S16 q8, d8, d0[2]
475        VMLAL.S16 q9, d9, d0[2]
476        VMLAL.S16 q10, d8, d2[2]
477        VMLAL.S16 q11, d9, d2[2]
478        VMLAL.S16 q12, d8, d4[2]
479        VMLAL.S16 q13, d9, d4[2]
480        VMLAL.S16 q14, d8, d6[2]
481        VMLAL.S16 q15, d9, d6[2]
482        CMP     r5, 4
483        BLO     4b
484
485        VLD1.8  {d8},  [r9]!
486        VMOVL.S8 q4, d8
487        VMLAL.S16 q8, d8, d0[3]
488        VMLAL.S16 q9, d9, d0[3]
489        VMLAL.S16 q10, d8, d2[3]
490        VMLAL.S16 q11, d9, d2[3]
491        VMLAL.S16 q12, d8, d4[3]
492        VMLAL.S16 q13, d9, d4[3]
493        VMLAL.S16 q14, d8, d6[3]
494        VMLAL.S16 q15, d9, d6[3]
495        BEQ     4b
496
497        VLD1.8  {d8},  [r9]!
498        VMOVL.S8 q4, d8
499        VMLAL.S16 q8, d8, d1[0]
500        VMLAL.S16 q9, d9, d1[0]
501        VMLAL.S16 q10, d8, d3[0]
502        VMLAL.S16 q11, d9, d3[0]
503        VMLAL.S16 q12, d8, d5[0]
504        VMLAL.S16 q13, d9, d5[0]
505        VMLAL.S16 q14, d8, d7[0]
506        VMLAL.S16 q15, d9, d7[0]
507        CMP     r5, 6
508        BLO     4b
509
510        VLD1.8  {d8},  [r9]!
511        VMOVL.S8 q4, d8
512        VMLAL.S16 q8, d8, d1[1]
513        VMLAL.S16 q9, d9, d1[1]
514        VMLAL.S16 q10, d8, d3[1]
515        VMLAL.S16 q11, d9, d3[1]
516        VMLAL.S16 q12, d8, d5[1]
517        VMLAL.S16 q13, d9, d5[1]
518        VMLAL.S16 q14, d8, d7[1]
519        VMLAL.S16 q15, d9, d7[1]
520        BEQ     4b
521
522        VLD1.8  {d8},  [r9]!
523        VMOVL.S8 q4, d8
524        VMLAL.S16 q8, d8, d1[2]
525        VMLAL.S16 q9, d9, d1[2]
526        VMLAL.S16 q10, d8, d3[2]
527        VMLAL.S16 q11, d9, d3[2]
528        VMLAL.S16 q12, d8, d5[2]
529        VMLAL.S16 q13, d9, d5[2]
530        VMLAL.S16 q14, d8, d7[2]
531        VMLAL.S16 q15, d9, d7[2]
532        B       4b
533
534        # Store odd width
535        .p2align 3
5367:
537        TST     r1, 4
538        BEQ     8f
539        VST1.32 {d3[0]}, [r6]!
540        VST1.32 {d2[0]}, [r8]!
541        VST1.32 {d1[0]}, [r4]!
542        VST1.32 {d0[0]}, [r11]!
543        VEXT.8  q1, q1, q1, 4
544        VEXT.8  q0, q0, q0, 4
5458:
546        TST     r1, 2
547        BEQ     9f
548        VST1.16 {d3[0]}, [r6]!
549        VST1.16 {d2[0]}, [r8]!
550        VST1.16 {d1[0]}, [r4]!
551        VST1.16 {d0[0]}, [r11]!
552        VEXT.8  q1, q1, q1, 2
553        VEXT.8  q0, q0, q0, 2
554
5559:
556        TST     r1, 1
557        BEQ     10f
558        VST1.8  {d3[0]}, [r6]
559        VST1.8  {d2[0]}, [r8]
560        VST1.8  {d1[0]}, [r4]
561        VST1.8  {d0[0]}, [r11]
562
56310:
564        VPOP    {d8-d13}
565        ADD     sp, sp, 20              // skip pad of 8, r1, r2, r3
566        POP     {r4, r5, r6, r7, r8, r9, r10, r11, pc}
567
568END_FUNCTION xnn_qc8_igemm_minmax_fp32_ukernel_4x8__aarch32_neonv8_mlal_lane_cortex_a35
569
570#ifdef __ELF__
571.section ".note.GNU-stack","",%progbits
572#endif
573