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_prfm_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_prfm_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 PLD [r9, 64] // Prefetch B 82 PLD [r9, 128] 83 PLD [r9, 192] 84 PLD [r9, 256] 85 PLD [r9, 320] 86 PLD [r9, 384] 87 88 .p2align 3 890: 90 # Load initial bias from w into accumulators 91 VLDM r9!, {d16-d19} // Bias 92 VMOV q10, q8 93 VMOV q11, q9 94 STR r1, [sp, 56] // save nc 95 VMOV q12, q8 96 VMOV q13, q9 97 VMOV q14, q8 98 VMOV q15, q9 99 100 .p2align 3 1011: 102 # Load next 4 A pointers 103 LDR r3, [r2, 0] 104 LDR r12, [r2, 4] 105 LDR r10, [r2, 8] 106 LDR r0, [r2, 12] 107 108 # Add a_offset 109 LDR r5, [sp, 124] // a_offset 110 LDR r7, [sp, 128] // zero 111 ADD r2, r2, 16 112 CMP r3, r7 // if a0 == zero 113 ADD r3, r3, r5 // a0 += a_offset 114 MOVEQ r3, r7 // a0 = zero, else += a0 + a_offset 115 CMP r12, r7 // if a1 == zero 116 ADD r12, r12, r5 // a1 += a_offset 117 MOVEQ r12, r7 // a1 = zero, else += a1 + a_offset 118 CMP r10, r7 // if a2 == zero 119 ADD r10, r10, r5 // a2 += a_offset 120 MOVEQ r10, r7 // a2 = zero, else += a2 + a_offset 121 CMP r0, r7 // if a3 == zero 122 ADD r0, r0, r5 // a3 += a_offset 123 LDR r5, [sp, 60] // kc 124 MOVEQ r0, r7 // a3 = zero, else += a3 + a_offset 125 SUBS r5, r5, 8 // kc - 8 126 BLO 5f // less than 8 channels? 127 128 // Prologue - load 4A's and B0 129 VLD1.8 {d0}, [r3]! // A0 130 VLD1.8 {d8}, [r9]! // B0 131 SUBS r5, r5, 8 // k = k - 8 132 VLD1.8 {d2}, [r12]! // A1 133 VLD1.8 {d4}, [r10]! // A2 134 VLD1.8 {d6}, [r0]! // A3 135 136 BLO 3f // less than 8 channels? 137 138 // Main loop - 8 bytes 139 // 64 bytes for weights. 140 // 5 VMOVL = 4 A and 1 B = 5 cycles 141 // 7 blocks with VLD B, VMOVL, 8 VMLA = 10 cycles 142 // 1 blocks with VLD B, VMLA = 9 cycles 143 // total = 84 cycles 144 .p2align 3 1452: 146 // Extend - 5 cycles 147 VMOVL.S8 q0, d0 148 VMOVL.S8 q4, d8 149 PLD [r9, 448] 150 VMOVL.S8 q1, d2 151 VMOVL.S8 q2, d4 152 VMOVL.S8 q3, d6 153 154 // BLOCK 0 - 10 cycles 155 VLD1.8 {d10}, [r9]! // B1 156 VMLAL.S16 q8, d8, d0[0] 157 VMLAL.S16 q9, d9, d0[0] 158 VMLAL.S16 q10, d8, d2[0] 159 VMLAL.S16 q11, d9, d2[0] 160 VMOVL.S8 q5, d10 161 VMLAL.S16 q12, d8, d4[0] 162 VMLAL.S16 q13, d9, d4[0] 163 VMLAL.S16 q14, d8, d6[0] 164 VMLAL.S16 q15, d9, d6[0] 165 166 // BLOCK 1 - 10 cycles 167 VLD1.8 {d8}, [r9]! // B2 168 VMLAL.S16 q8, d10, d0[1] 169 VMLAL.S16 q9, d11, d0[1] 170 VMLAL.S16 q10, d10, d2[1] 171 VMLAL.S16 q11, d11, d2[1] 172 VMOVL.S8 q4, d8 173 VMLAL.S16 q12, d10, d4[1] 174 VMLAL.S16 q13, d11, d4[1] 175 VMLAL.S16 q14, d10, d6[1] 176 VMLAL.S16 q15, d11, d6[1] 177 178 // BLOCK 2 - 10 cycles 179 VLD1.8 {d10}, [r9]! // B3 180 VMLAL.S16 q8, d8, d0[2] 181 VMLAL.S16 q9, d9, d0[2] 182 VMLAL.S16 q10, d8, d2[2] 183 VMLAL.S16 q11, d9, d2[2] 184 VMOVL.S8 q5, d10 185 VMLAL.S16 q12, d8, d4[2] 186 VMLAL.S16 q13, d9, d4[2] 187 VMLAL.S16 q14, d8, d6[2] 188 VMLAL.S16 q15, d9, d6[2] 189 190 // BLOCK 3 - 10 cycles 191 VLD1.8 {d8}, [r9]! // B4 192 VMLAL.S16 q8, d10, d0[3] 193 VMLAL.S16 q9, d11, d0[3] 194 VMLAL.S16 q10, d10, d2[3] 195 VMLAL.S16 q11, d11, d2[3] 196 VLD1.8 {d0}, [r3]! // A0 197 VMOVL.S8 q4, d8 198 VMLAL.S16 q12, d10, d4[3] 199 VMLAL.S16 q13, d11, d4[3] 200 VMLAL.S16 q14, d10, d6[3] 201 VMLAL.S16 q15, d11, d6[3] 202 203 // BLOCK 4 - 10 cycles 204 VLD1.8 {d10}, [r9]! // B5 205 VMLAL.S16 q8, d8, d1[0] 206 VMLAL.S16 q9, d9, d1[0] 207 VMLAL.S16 q10, d8, d3[0] 208 VMLAL.S16 q11, d9, d3[0] 209 VLD1.8 {d2}, [r12]! // A1 210 VMOVL.S8 q5, d10 211 VMLAL.S16 q12, d8, d5[0] 212 VMLAL.S16 q13, d9, d5[0] 213 VMLAL.S16 q14, d8, d7[0] 214 VMLAL.S16 q15, d9, d7[0] 215 216 // BLOCK 5 - 10 cycles 217 VLD1.8 {d8}, [r9]! // B6 218 VMLAL.S16 q8, d10, d1[1] 219 VMLAL.S16 q9, d11, d1[1] 220 VMLAL.S16 q10, d10, d3[1] 221 VMLAL.S16 q11, d11, d3[1] 222 VLD1.8 {d4}, [r10]! // A2 223 VMOVL.S8 q4, d8 224 VMLAL.S16 q12, d10, d5[1] 225 VMLAL.S16 q13, d11, d5[1] 226 VMLAL.S16 q14, d10, d7[1] 227 VMLAL.S16 q15, d11, d7[1] 228 229 // BLOCK 6 - 10 cycles 230 VLD1.8 {d10}, [r9]! // B7 231 VMLAL.S16 q8, d8, d1[2] 232 VMLAL.S16 q9, d9, d1[2] 233 VMLAL.S16 q10, d8, d3[2] 234 VMLAL.S16 q11, d9, d3[2] 235 VLD1.8 {d6}, [r0]! // A3 236 VMOVL.S8 q5, d10 237 VMLAL.S16 q12, d8, d5[2] 238 VMLAL.S16 q13, d9, d5[2] 239 VMLAL.S16 q14, d8, d7[2] 240 VMLAL.S16 q15, d9, d7[2] 241 242 // BLOCK 7 - 9 cycles 243 VLD1.8 {d8}, [r9]! // B0 244 VMLAL.S16 q8, d10, d1[3] 245 VMLAL.S16 q9, d11, d1[3] 246 VMLAL.S16 q10, d10, d3[3] 247 VMLAL.S16 q11, d11, d3[3] 248 VMLAL.S16 q12, d10, d5[3] 249 VMLAL.S16 q13, d11, d5[3] 250 SUBS r5, r5, 8 251 VMLAL.S16 q14, d10, d7[3] 252 VMLAL.S16 q15, d11, d7[3] 253 BHS 2b 254 255 // Epilogue 256 257 .p2align 3 2583: 259 VMOVL.S8 q0, d0 260 VMOVL.S8 q4, d8 261 VMOVL.S8 q1, d2 262 VMOVL.S8 q2, d4 263 VMOVL.S8 q3, d6 264 265 VLD1.8 {d10}, [r9]! // B1 266 VMLAL.S16 q8, d8, d0[0] 267 VMLAL.S16 q9, d9, d0[0] 268 VMLAL.S16 q10, d8, d2[0] 269 VMLAL.S16 q11, d9, d2[0] 270 VMOVL.S8 q5, d10 271 VMLAL.S16 q12, d8, d4[0] 272 VMLAL.S16 q13, d9, d4[0] 273 VMLAL.S16 q14, d8, d6[0] 274 VMLAL.S16 q15, d9, d6[0] 275 276 VLD1.8 {d8}, [r9]! // B2 277 VMLAL.S16 q8, d10, d0[1] 278 VMLAL.S16 q9, d11, d0[1] 279 VMLAL.S16 q10, d10, d2[1] 280 VMLAL.S16 q11, d11, d2[1] 281 VMOVL.S8 q4, d8 282 VMLAL.S16 q12, d10, d4[1] 283 VMLAL.S16 q13, d11, d4[1] 284 VMLAL.S16 q14, d10, d6[1] 285 VMLAL.S16 q15, d11, d6[1] 286 287 VLD1.8 {d10}, [r9]! // B3 288 VMLAL.S16 q8, d8, d0[2] 289 VMLAL.S16 q9, d9, d0[2] 290 VMLAL.S16 q10, d8, d2[2] 291 VMLAL.S16 q11, d9, d2[2] 292 VMOVL.S8 q5, d10 293 VMLAL.S16 q12, d8, d4[2] 294 VMLAL.S16 q13, d9, d4[2] 295 VMLAL.S16 q14, d8, d6[2] 296 VMLAL.S16 q15, d9, d6[2] 297 298 VLD1.8 {d8}, [r9]! // B4 299 VMLAL.S16 q8, d10, d0[3] 300 VMLAL.S16 q9, d11, d0[3] 301 VMLAL.S16 q10, d10, d2[3] 302 VMLAL.S16 q11, d11, d2[3] 303 VMOVL.S8 q4, d8 304 VMLAL.S16 q12, d10, d4[3] 305 VMLAL.S16 q13, d11, d4[3] 306 VMLAL.S16 q14, d10, d6[3] 307 VMLAL.S16 q15, d11, d6[3] 308 309 VLD1.8 {d10}, [r9]! // B5 310 VMLAL.S16 q8, d8, d1[0] 311 VMLAL.S16 q9, d9, d1[0] 312 VMLAL.S16 q10, d8, d3[0] 313 VMLAL.S16 q11, d9, d3[0] 314 VMOVL.S8 q5, d10 315 VMLAL.S16 q12, d8, d5[0] 316 VMLAL.S16 q13, d9, d5[0] 317 VMLAL.S16 q14, d8, d7[0] 318 VMLAL.S16 q15, d9, d7[0] 319 320 VLD1.8 {d8}, [r9]! // B6 321 VMLAL.S16 q8, d10, d1[1] 322 VMLAL.S16 q9, d11, d1[1] 323 VMLAL.S16 q10, d10, d3[1] 324 VMLAL.S16 q11, d11, d3[1] 325 VMOVL.S8 q4, d8 326 VMLAL.S16 q12, d10, d5[1] 327 VMLAL.S16 q13, d11, d5[1] 328 VMLAL.S16 q14, d10, d7[1] 329 VMLAL.S16 q15, d11, d7[1] 330 331 VLD1.8 {d10}, [r9]! // B7 332 VMLAL.S16 q8, d8, d1[2] 333 VMLAL.S16 q9, d9, d1[2] 334 VMLAL.S16 q10, d8, d3[2] 335 VMLAL.S16 q11, d9, d3[2] 336 VMOVL.S8 q5, d10 337 VMLAL.S16 q12, d8, d5[2] 338 VMLAL.S16 q13, d9, d5[2] 339 VMLAL.S16 q14, d8, d7[2] 340 VMLAL.S16 q15, d9, d7[2] 341 342 VMLAL.S16 q8, d10, d1[3] 343 VMLAL.S16 q9, d11, d1[3] 344 VMLAL.S16 q10, d10, d3[3] 345 VMLAL.S16 q11, d11, d3[3] 346 VMLAL.S16 q12, d10, d5[3] 347 VMLAL.S16 q13, d11, d5[3] 348 ADDS r5, r5, 8 349 VMLAL.S16 q14, d10, d7[3] 350 VMLAL.S16 q15, d11, d7[3] 351 352 # Is there a remainder?- 1-7 bytes of A 353 BNE 6f 354 3554: 356 # ks loop 357 SUBS r14, r14, 16 // ks -= MR * sizeof(void*) 358 BHI 1b 359 360 LDR r7, [sp, 120] // cn_stride 361 LDR r14, [sp, 64] // p = ks 362 363 # QC8 FP32 quantization 364 VLD1.8 {q0-q1}, [r9]! 365 366 VCVT.F32.S32 q8, q8 367 VCVT.F32.S32 q9, q9 368 VCVT.F32.S32 q10, q10 369 VCVT.F32.S32 q11, q11 370 VCVT.F32.S32 q12, q12 371 VCVT.F32.S32 q13, q13 372 VCVT.F32.S32 q14, q14 373 VCVT.F32.S32 q15, q15 374 375 VMUL.F32 q8, q8, q0 // multiplier 376 VMUL.F32 q9, q9, q1 377 VMUL.F32 q10, q10, q0 378 VMUL.F32 q11, q11, q1 379 VMUL.F32 q12, q12, q0 380 VMUL.F32 q13, q13, q1 381 VMUL.F32 q14, q14, q0 382 VMUL.F32 q15, q15, q1 383 384 VCVTN.S32.F32 q8, q8 385 VCVTN.S32.F32 q9, q9 386 VCVTN.S32.F32 q10, q10 387 VCVTN.S32.F32 q11, q11 388 VCVTN.S32.F32 q12, q12 389 VCVTN.S32.F32 q13, q13 390 VCVTN.S32.F32 q14, q14 391 VCVTN.S32.F32 q15, q15 392 393 VDUP.16 q0, d13[2] // output_zero_point 394 395 VQMOVN.S32 d16, q8 396 VQMOVN.S32 d17, q9 397 VQMOVN.S32 d18, q10 398 VQMOVN.S32 d19, q11 399 VQMOVN.S32 d20, q12 400 VQMOVN.S32 d21, q13 401 VQMOVN.S32 d22, q14 402 VQMOVN.S32 d23, q15 403 404 VQADD.S16 q8, q8, q0 405 VQADD.S16 q9, q9, q0 406 VQADD.S16 q10, q10, q0 407 VQADD.S16 q11, q11, q0 408 409 LDR r1, [sp, 56] // restore nc 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 SUBS r1, r1, 8 // nc -= 8 423 424 VMIN.S8 q0, q0, q13 425 VMIN.S8 q1, q1, q13 426 427 # Store full 4 x 8 428 BLO 7f 429 VST1.8 {d3}, [r6], r7 430 VST1.8 {d2}, [r8], r7 431 VST1.8 {d1}, [r4], r7 432 VST1.8 {d0}, [r11], r7 433 SUB r2, r2, r14 // a -= ks 434 BHI 0b 435 436 VPOP {d8-d13} 437 ADD sp, sp, 20 // skip pad of 8, r1, r2, r3 438 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc} 439 440 # Remainder- 1 to 7 bytes of A 441 .p2align 3 4425: 443 AND r5, r5, 7 // kc remainder 1 to 7 4446: 445 VLD1.8 {d0}, [r3] 446 VLD1.8 {d8}, [r9]! 447 VLD1.8 {d2}, [r12] 448 VLD1.8 {d4}, [r10] 449 VLD1.8 {d6}, [r0] 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 4b 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 4b 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 4b 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 4b 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 4b 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 4b 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 4b 540 541 # Store odd width 542 .p2align 3 5437: 544 TST r1, 4 545 BEQ 8f 546 VST1.32 {d3[0]}, [r6]! 547 VST1.32 {d2[0]}, [r8]! 548 VST1.32 {d1[0]}, [r4]! 549 VST1.32 {d0[0]}, [r11]! 550 VEXT.8 q1, q1, q1, 4 551 VEXT.8 q0, q0, q0, 4 5528: 553 TST r1, 2 554 BEQ 9f 555 VST1.16 {d3[0]}, [r6]! 556 VST1.16 {d2[0]}, [r8]! 557 VST1.16 {d1[0]}, [r4]! 558 VST1.16 {d0[0]}, [r11]! 559 VEXT.8 q1, q1, q1, 2 560 VEXT.8 q0, q0, q0, 2 561 5629: 563 TST r1, 1 564 BEQ 10f 565 VST1.8 {d3[0]}, [r6] 566 VST1.8 {d2[0]}, [r8] 567 VST1.8 {d1[0]}, [r4] 568 VST1.8 {d0[0]}, [r11] 569 57010: 571 VPOP {d8-d13} 572 ADD sp, sp, 20 // skip pad of 8, r1, r2, r3 573 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc} 574 575END_FUNCTION xnn_qc8_igemm_minmax_fp32_ukernel_4x8__aarch32_neonv8_mlal_lane_prfm_cortex_a35 576 577#ifdef __ELF__ 578.section ".note.GNU-stack","",%progbits 579#endif 580