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