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_qs8_igemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a7(
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_conv_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 16 bytes
47//  struct {
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//    int8_t output_min;          d13[6]
53//    int8_t output_max;          d13[7]
54//  } rndnu_neon;
55
56BEGIN_FUNCTION xnn_qs8_igemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a7
57        # Push 104 bytes
58        # r1, r2 will be reloaded in outer loop.  r3 is ks
59        PUSH    {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}   // +48
60        SUB     sp, sp, 8                           // +8
61        VPUSH   {d8-d13}                            // +48 = 104
62
63        LDR     r11, [sp, 112]          // c
64        LDR     r6, [sp, 116]           // cm_stride
65        LDR     r2, [sp, 104]           // a
66        LDR     r9, [sp, 108]           // w
67        LDR     r5, [sp, 132]           // params
68        MOV     r14, r3                 // p = ks
69
70        # Clamp C pointers
71        CMP     r0, 2                   // if mr >= 2
72        ADD     r4, r11, r6             //   c1 = c0 + cm_stride
73        MOVLO   r4, r11                 // c1
74                                        // if mr > 2
75        ADD     r8, r4, r6              //   c2 = c1 + cm_stride
76        MOVLS   r8, r4                  // c2
77        CMP     r0, 4                   // if mr >=4
78        ADD     r6, r8, r6              //   c3 = c2 + cm_stride
79        MOVLO   r6, r8                  // c3
80
81        # Load params values
82        VLDM    r5, {d12-d13}           // RNDNU params
83
84        PLD     [r9,  64]               // Prefetch B
85        PLD     [r9, 128]
86        PLD     [r9, 192]
87        PLD     [r9, 256]
88        PLD     [r9, 320]
89        PLD     [r9, 384]
90
91        .p2align 3
920:
93        # Load initial bias from w into accumulators
94        VLDM    r9!, {d16-d19}          // Bias
95        VMOV    q10, q8
96        VMOV    q11, q9
97        STR     r1, [sp, 56]            // save nc
98        VMOV    q12, q8
99        VMOV    q13, q9
100        VMOV    q14, q8
101        VMOV    q15, q9
102
103        .p2align 3
1041:
105        # Load next 4 A pointers
106        LDR     r3, [r2,  0]
107        LDR     r12, [r2,  4]
108        LDR     r10, [r2,  8]
109        LDR     r0, [r2, 12]
110
111        # Add a_offset
112        LDR     r5, [sp, 124]           // a_offset
113        LDR     r7, [sp, 128]           // zero
114        ADD     r2, r2, 16
115        CMP     r3,  r7                 // if a0 == zero
116        ADD     r3,  r3, r5             // a0 += a_offset
117        MOVEQ   r3,  r7                 //   a0 = zero, else += a0 + a_offset
118        CMP     r12,  r7                // if a1 == zero
119        ADD     r12, r12, r5            // a1 += a_offset
120        MOVEQ   r12,  r7                //   a1 = zero, else += a1 + a_offset
121        CMP     r10,  r7                // if a2 == zero
122        ADD     r10, r10, r5            // a2 += a_offset
123        MOVEQ   r10,  r7                //   a2 = zero, else += a2 + a_offset
124        CMP     r0,  r7                 // if a3 == zero
125        ADD     r0,  r0, r5             // a3 += a_offset
126        LDR     r5, [sp, 60]            // kc
127        MOVEQ   r0,  r7                 //   a3 = zero, else += a3 + a_offset
128        SUBS    r5, r5, 8               // kc - 8
129        BLO     5f                      // less than 8 channels?
130
131        // Prologue - load 4A's and B0
132        VLD1.8  {d0},  [r3]!            // A0
133        VLD1.8  {d8},  [r9]!            // B0
134        SUBS    r5, r5, 8               // k = k - 8
135        VLD1.8  {d2}, [r12]!            // A1
136        VLD1.8  {d4}, [r10]!            // A2
137        VLD1.8  {d6},  [r0]!            // A3
138
139        BLO     3f                      // less than 8 channels?
140
141        // Main loop - 8 bytes
142        // 64 bytes for weights.
143        // 5 VMOVL = 4 A and 1 B = 5 cycles
144        // 7 blocks with VLD B, VMOVL, 8 VMLA = 10 cycles
145        // 1 blocks with VLD B, VMLA = 9 cycles
146        // total = 84 cycles
147        .p2align 3
1482:
149        // Extend - 5 cycles
150        VMOVL.S8 q0, d0
151        VMOVL.S8 q4, d8
152        PLD     [r9, 448]
153        VMOVL.S8 q1, d2
154        VMOVL.S8 q2, d4
155        VMOVL.S8 q3, d6
156
157        // BLOCK 0 - 10 cycles
158        VLD1.8  {d10},  [r9]!           // B1
159        VMLAL.S16 q8, d8, d0[0]
160        VMLAL.S16 q9, d9, d0[0]
161        VMLAL.S16 q10, d8, d2[0]
162        VMLAL.S16 q11, d9, d2[0]
163        VMOVL.S8 q5, d10
164        VMLAL.S16 q12, d8, d4[0]
165        VMLAL.S16 q13, d9, d4[0]
166        VMLAL.S16 q14, d8, d6[0]
167        VMLAL.S16 q15, d9, d6[0]
168
169        // BLOCK 1 - 10 cycles
170        VLD1.8  {d8},  [r9]!            // B2
171        VMLAL.S16 q8, d10, d0[1]
172        VMLAL.S16 q9, d11, d0[1]
173        VMLAL.S16 q10, d10, d2[1]
174        VMLAL.S16 q11, d11, d2[1]
175        VMOVL.S8 q4, d8
176        VMLAL.S16 q12, d10, d4[1]
177        VMLAL.S16 q13, d11, d4[1]
178        VMLAL.S16 q14, d10, d6[1]
179        VMLAL.S16 q15, d11, d6[1]
180
181        // BLOCK 2 - 10 cycles
182        VLD1.8  {d10},  [r9]!           // B3
183        VMLAL.S16 q8, d8, d0[2]
184        VMLAL.S16 q9, d9, d0[2]
185        VMLAL.S16 q10, d8, d2[2]
186        VMLAL.S16 q11, d9, d2[2]
187        VMOVL.S8 q5, d10
188        VMLAL.S16 q12, d8, d4[2]
189        VMLAL.S16 q13, d9, d4[2]
190        VMLAL.S16 q14, d8, d6[2]
191        VMLAL.S16 q15, d9, d6[2]
192
193        // BLOCK 3 - 10 cycles
194        VLD1.8  {d8},  [r9]!            // B4
195        VMLAL.S16 q8, d10, d0[3]
196        VMLAL.S16 q9, d11, d0[3]
197        VMLAL.S16 q10, d10, d2[3]
198        VMLAL.S16 q11, d11, d2[3]
199        VLD1.8  {d0},  [r3]!            // A0
200        VMOVL.S8 q4, d8
201        VMLAL.S16 q12, d10, d4[3]
202        VMLAL.S16 q13, d11, d4[3]
203        VMLAL.S16 q14, d10, d6[3]
204        VMLAL.S16 q15, d11, d6[3]
205
206        // BLOCK 4 - 10 cycles
207        VLD1.8  {d10},  [r9]!           // B5
208        VMLAL.S16 q8, d8, d1[0]
209        VMLAL.S16 q9, d9, d1[0]
210        VMLAL.S16 q10, d8, d3[0]
211        VMLAL.S16 q11, d9, d3[0]
212        VLD1.8  {d2}, [r12]!            // A1
213        VMOVL.S8 q5, d10
214        VMLAL.S16 q12, d8, d5[0]
215        VMLAL.S16 q13, d9, d5[0]
216        VMLAL.S16 q14, d8, d7[0]
217        VMLAL.S16 q15, d9, d7[0]
218
219        // BLOCK 5 - 10 cycles
220        VLD1.8  {d8},  [r9]!            // B6
221        VMLAL.S16 q8, d10, d1[1]
222        VMLAL.S16 q9, d11, d1[1]
223        VMLAL.S16 q10, d10, d3[1]
224        VMLAL.S16 q11, d11, d3[1]
225        VLD1.8  {d4}, [r10]!            // A2
226        VMOVL.S8 q4, d8
227        VMLAL.S16 q12, d10, d5[1]
228        VMLAL.S16 q13, d11, d5[1]
229        VMLAL.S16 q14, d10, d7[1]
230        VMLAL.S16 q15, d11, d7[1]
231
232        // BLOCK 6 - 10 cycles
233        VLD1.8  {d10},  [r9]!           // B7
234        VMLAL.S16 q8, d8, d1[2]
235        VMLAL.S16 q9, d9, d1[2]
236        VMLAL.S16 q10, d8, d3[2]
237        VMLAL.S16 q11, d9, d3[2]
238        VLD1.8  {d6},  [r0]!            // A3
239        VMOVL.S8 q5, d10
240        VMLAL.S16 q12, d8, d5[2]
241        VMLAL.S16 q13, d9, d5[2]
242        VMLAL.S16 q14, d8, d7[2]
243        VMLAL.S16 q15, d9, d7[2]
244
245        // BLOCK 7 - 9 cycles
246        VLD1.8  {d8},  [r9]!            // B0
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     2b
257
258        // Epilogue
259
260        .p2align 3
2613:
262        VMOVL.S8 q0, d0
263        VMOVL.S8 q4, d8
264        VMOVL.S8 q1, d2
265        VMOVL.S8 q2, d4
266        VMOVL.S8 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        VMOVL.S8 q5, d10
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        VMOVL.S8 q4, d8
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        VMOVL.S8 q5, d10
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        VMOVL.S8 q4, d8
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        VMOVL.S8 q5, d10
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        VMOVL.S8 q4, d8
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        VMOVL.S8 q5, d10
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     6f
357
3584:
359        # ks loop
360        SUBS    r14, r14, 16            // ks -= MR * sizeof(void*)
361        BHI     1b
362
363        LDR     r7, [sp, 120]           // cn_stride
364        LDR     r14, [sp, 64]           // p = ks
365
366        # RNDNU quantization
367        VDUP.32 q0, d12[0]              // right_pre_shift
368
369        VQSHL.S32 q8,  q8, q0
370        VQSHL.S32 q9,  q9, q0
371        VQSHL.S32 q10, q10, q0
372        VQSHL.S32 q11, q11, q0
373        VQSHL.S32 q12, q12, q0
374        VQSHL.S32 q13, q13, q0
375        VQSHL.S32 q14, q14, q0
376        VQSHL.S32 q15, q15, q0
377
378        VDUP.32 q2, d13[0]              // right_post_shift
379
380        VQDMULH.S32 q8,  q8, d12[1]     // multiplier
381        VQDMULH.S32 q9,  q9, d12[1]
382        VQDMULH.S32 q10, q10, d12[1]
383        VQDMULH.S32 q11, q11, d12[1]
384        VQDMULH.S32 q12, q12, d12[1]
385        VQDMULH.S32 q13, q13, d12[1]
386        VQDMULH.S32 q14, q14, d12[1]
387        VQDMULH.S32 q15, q15, d12[1]
388
389        VRSHL.S32 q8,  q8, q2
390        VRSHL.S32 q9,  q9, q2
391        VRSHL.S32 q10, q10, q2
392        VRSHL.S32 q11, q11, q2
393        VRSHL.S32 q12, q12, q2
394        VRSHL.S32 q13, q13, q2
395        VRSHL.S32 q14, q14, q2
396        VRSHL.S32 q15, q15, q2
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_qs8_igemm_minmax_rndnu_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a7
581
582#ifdef __ELF__
583.section ".note.GNU-stack","",%progbits
584#endif
585