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_neon_mlal_lane_prfm_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 10 bytes 48// struct { 49// float magic_bias; d12[0] 50// int32_t magic_bias_less_output_zero_point; d12[1] 51// int8_t output_min; d13[6] 52// int8_t output_max; d13[7] 53// } xnn_qs8_minmax_params.neon; 54 55BEGIN_FUNCTION xnn_qc8_igemm_minmax_fp32_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a53 56 # Push 104 bytes 57 # r1, r2 will be reloaded in outer loop. r3 is ks 58 PUSH {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr} // +48 59 SUB sp, sp, 8 // +8 60 VPUSH {d8-d13} // +48 = 104 61 62 LDR r11, [sp, 112] // c 63 LDR r6, [sp, 116] // cm_stride 64 LDR r2, [sp, 104] // a 65 LDR r9, [sp, 108] // w 66 LDR r5, [sp, 132] // params 67 MOV r14, r3 // p = ks 68 69 # Clamp C pointers 70 CMP r0, 2 // if mr >= 2 71 ADD r4, r11, r6 // c1 = c0 + cm_stride 72 MOVLO r4, r11 // c1 73 // if mr > 2 74 ADD r8, r4, r6 // c2 = c1 + cm_stride 75 MOVLS r8, r4 // c2 76 CMP r0, 4 // if mr >=4 77 ADD r6, r8, r6 // c3 = c2 + cm_stride 78 MOVLO r6, r8 // c3 79 80 # Load params values 81 VLDM r5!, {d12} // QC8 neon params 82 VLD1.16 {d13[]}, [r5] 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 BLO 3f // less than 8 channels? 139 140 // Main loop - 8 bytes 141 // 64 bytes for weights. 142 // 5 VMOVL = 4 A and 1 B = 5 cycles 143 // 7 blocks with VLD B, VMOVL, 8 VMLA = 10 cycles 144 // 1 blocks with VLD B, VMLA = 9 cycles 145 // total = 84 cycles 146 .p2align 3 1472: 148 // Extend - 5 cycles 149 VMOVL.S8 q0, d0 150 PLD [r3, 128] 151 VMOVL.S8 q4, d8 152 PLD [r9, 448] 153 VMOVL.S8 q1, d2 154 PLD [r12, 128] 155 VMOVL.S8 q2, d4 156 PLD [r0, 128] 157 VMOVL.S8 q3, d6 158 PLD [r10, 128] 159 160 // BLOCK 0 - 10 cycles 161 VLD1.8 {d10}, [r9]! // B1 162 VMLAL.S16 q8, d8, d0[0] 163 VMLAL.S16 q9, d9, d0[0] 164 VMLAL.S16 q10, d8, d2[0] 165 VMLAL.S16 q11, d9, d2[0] 166 VMOVL.S8 q5, d10 167 VMLAL.S16 q12, d8, d4[0] 168 VMLAL.S16 q13, d9, d4[0] 169 VMLAL.S16 q14, d8, d6[0] 170 VMLAL.S16 q15, d9, d6[0] 171 172 // BLOCK 1 - 10 cycles 173 VLD1.8 {d8}, [r9]! // B2 174 VMLAL.S16 q8, d10, d0[1] 175 VMLAL.S16 q9, d11, d0[1] 176 VMLAL.S16 q10, d10, d2[1] 177 VMLAL.S16 q11, d11, d2[1] 178 VMOVL.S8 q4, d8 179 VMLAL.S16 q12, d10, d4[1] 180 VMLAL.S16 q13, d11, d4[1] 181 VMLAL.S16 q14, d10, d6[1] 182 VMLAL.S16 q15, d11, d6[1] 183 184 // BLOCK 2 - 10 cycles 185 VLD1.8 {d10}, [r9]! // B3 186 VMLAL.S16 q8, d8, d0[2] 187 VMLAL.S16 q9, d9, d0[2] 188 VMLAL.S16 q10, d8, d2[2] 189 VMLAL.S16 q11, d9, d2[2] 190 VMOVL.S8 q5, d10 191 VMLAL.S16 q12, d8, d4[2] 192 VMLAL.S16 q13, d9, d4[2] 193 VMLAL.S16 q14, d8, d6[2] 194 VMLAL.S16 q15, d9, d6[2] 195 196 // BLOCK 3 - 10 cycles 197 VLD1.8 {d8}, [r9]! // B4 198 VMLAL.S16 q8, d10, d0[3] 199 VMLAL.S16 q9, d11, d0[3] 200 VMLAL.S16 q10, d10, d2[3] 201 VMLAL.S16 q11, d11, d2[3] 202 VMOVL.S8 q4, d8 203 VMLAL.S16 q12, d10, d4[3] 204 LDR r1, [r3] // A0 low 205 VMLAL.S16 q13, d11, d4[3] 206 LDR r7, [r3, 4] // A0 high 207 VMLAL.S16 q14, d10, d6[3] 208 ADD r3, r3, 8 209 VMLAL.S16 q15, d11, d6[3] 210 211 // BLOCK 4 - 10 cycles 212 VLD1.8 {d10}, [r9]! // B5 213 VMOV d0, r1, r7 // A0 VMOV 214 VMLAL.S16 q8, d8, d1[0] 215 VMLAL.S16 q9, d9, d1[0] 216 VMLAL.S16 q10, d8, d3[0] 217 VMLAL.S16 q11, d9, d3[0] 218 VMOVL.S8 q5, d10 219 VMLAL.S16 q12, d8, d5[0] 220 LDR r1, [r12] // A1 low 221 VMLAL.S16 q13, d9, d5[0] 222 LDR r7, [r12, 4] // A1 high 223 VMLAL.S16 q14, d8, d7[0] 224 ADD r12, r12, 8 225 VMLAL.S16 q15, d9, d7[0] 226 227 // BLOCK 5 - 10 cycles 228 VLD1.8 {d8}, [r9]! // B6 229 VMOV d2, r1, r7 // A1 VMOV 230 VMLAL.S16 q8, d10, d1[1] 231 VMLAL.S16 q9, d11, d1[1] 232 VMLAL.S16 q10, d10, d3[1] 233 VMLAL.S16 q11, d11, d3[1] 234 VMOVL.S8 q4, d8 235 VMLAL.S16 q12, d10, d5[1] 236 LDR r1, [r10] // A2 low 237 VMLAL.S16 q13, d11, d5[1] 238 LDR r7, [r10, 4] // A2 high 239 VMLAL.S16 q14, d10, d7[1] 240 ADD r10, r10, 8 241 VMLAL.S16 q15, d11, d7[1] 242 243 // BLOCK 6 - 10 cycles 244 VLD1.8 {d10}, [r9]! // B7 245 VMOV d4, r1, r7 // A2 VMOV 246 VMLAL.S16 q8, d8, d1[2] 247 VMLAL.S16 q9, d9, d1[2] 248 VMLAL.S16 q10, d8, d3[2] 249 VMLAL.S16 q11, d9, d3[2] 250 VMOVL.S8 q5, d10 251 VMLAL.S16 q12, d8, d5[2] 252 LDR r1, [r0] // A3 low 253 VMLAL.S16 q13, d9, d5[2] 254 LDR r7, [r0, 4] // A3 high 255 VMLAL.S16 q14, d8, d7[2] 256 ADD r0, r0, 8 257 VMLAL.S16 q15, d9, d7[2] 258 259 // BLOCK 7 - 9 cycles 260 VLD1.8 {d8}, [r9]! // B0 261 VMOV d6, r1, r7 // A3 VMOV 262 VMLAL.S16 q8, d10, d1[3] 263 VMLAL.S16 q9, d11, d1[3] 264 VMLAL.S16 q10, d10, d3[3] 265 VMLAL.S16 q11, d11, d3[3] 266 VMLAL.S16 q12, d10, d5[3] 267 VMLAL.S16 q13, d11, d5[3] 268 SUBS r5, r5, 8 269 VMLAL.S16 q14, d10, d7[3] 270 VMLAL.S16 q15, d11, d7[3] 271 BHS 2b 272 273 // Epilogue 274 275 .p2align 3 2763: 277 VMOVL.S8 q0, d0 278 VMOVL.S8 q4, d8 279 VMOVL.S8 q1, d2 280 VMOVL.S8 q2, d4 281 VMOVL.S8 q3, d6 282 283 VLD1.8 {d10}, [r9]! // B1 284 VMLAL.S16 q8, d8, d0[0] 285 VMLAL.S16 q9, d9, d0[0] 286 VMLAL.S16 q10, d8, d2[0] 287 VMLAL.S16 q11, d9, d2[0] 288 VMOVL.S8 q5, d10 289 VMLAL.S16 q12, d8, d4[0] 290 VMLAL.S16 q13, d9, d4[0] 291 VMLAL.S16 q14, d8, d6[0] 292 VMLAL.S16 q15, d9, d6[0] 293 294 VLD1.8 {d8}, [r9]! // B2 295 VMLAL.S16 q8, d10, d0[1] 296 VMLAL.S16 q9, d11, d0[1] 297 VMLAL.S16 q10, d10, d2[1] 298 VMLAL.S16 q11, d11, d2[1] 299 VMOVL.S8 q4, d8 300 VMLAL.S16 q12, d10, d4[1] 301 VMLAL.S16 q13, d11, d4[1] 302 VMLAL.S16 q14, d10, d6[1] 303 VMLAL.S16 q15, d11, d6[1] 304 305 VLD1.8 {d10}, [r9]! // B3 306 VMLAL.S16 q8, d8, d0[2] 307 VMLAL.S16 q9, d9, d0[2] 308 VMLAL.S16 q10, d8, d2[2] 309 VMLAL.S16 q11, d9, d2[2] 310 VMOVL.S8 q5, d10 311 VMLAL.S16 q12, d8, d4[2] 312 VMLAL.S16 q13, d9, d4[2] 313 VMLAL.S16 q14, d8, d6[2] 314 VMLAL.S16 q15, d9, d6[2] 315 316 VLD1.8 {d8}, [r9]! // B4 317 VMLAL.S16 q8, d10, d0[3] 318 VMLAL.S16 q9, d11, d0[3] 319 VMLAL.S16 q10, d10, d2[3] 320 VMLAL.S16 q11, d11, d2[3] 321 VMOVL.S8 q4, d8 322 VMLAL.S16 q12, d10, d4[3] 323 VMLAL.S16 q13, d11, d4[3] 324 VMLAL.S16 q14, d10, d6[3] 325 VMLAL.S16 q15, d11, d6[3] 326 327 VLD1.8 {d10}, [r9]! // B5 328 VMLAL.S16 q8, d8, d1[0] 329 VMLAL.S16 q9, d9, d1[0] 330 VMLAL.S16 q10, d8, d3[0] 331 VMLAL.S16 q11, d9, d3[0] 332 VMOVL.S8 q5, d10 333 VMLAL.S16 q12, d8, d5[0] 334 VMLAL.S16 q13, d9, d5[0] 335 VMLAL.S16 q14, d8, d7[0] 336 VMLAL.S16 q15, d9, d7[0] 337 338 VLD1.8 {d8}, [r9]! // B6 339 VMLAL.S16 q8, d10, d1[1] 340 VMLAL.S16 q9, d11, d1[1] 341 VMLAL.S16 q10, d10, d3[1] 342 VMLAL.S16 q11, d11, d3[1] 343 VMOVL.S8 q4, d8 344 VMLAL.S16 q12, d10, d5[1] 345 VMLAL.S16 q13, d11, d5[1] 346 VMLAL.S16 q14, d10, d7[1] 347 VMLAL.S16 q15, d11, d7[1] 348 349 VLD1.8 {d10}, [r9]! // B7 350 VMLAL.S16 q8, d8, d1[2] 351 VMLAL.S16 q9, d9, d1[2] 352 VMLAL.S16 q10, d8, d3[2] 353 VMLAL.S16 q11, d9, d3[2] 354 VMOVL.S8 q5, d10 355 VMLAL.S16 q12, d8, d5[2] 356 VMLAL.S16 q13, d9, d5[2] 357 VMLAL.S16 q14, d8, d7[2] 358 VMLAL.S16 q15, d9, d7[2] 359 360 VMLAL.S16 q8, d10, d1[3] 361 VMLAL.S16 q9, d11, d1[3] 362 VMLAL.S16 q10, d10, d3[3] 363 VMLAL.S16 q11, d11, d3[3] 364 VMLAL.S16 q12, d10, d5[3] 365 VMLAL.S16 q13, d11, d5[3] 366 ADDS r5, r5, 8 367 VMLAL.S16 q14, d10, d7[3] 368 VMLAL.S16 q15, d11, d7[3] 369 370 # Is there a remainder?- 1-7 bytes of A 371 BNE 6f 372 3734: 374 # ks loop 375 SUBS r14, r14, 16 // ks -= MR * sizeof(void*) 376 BHI 1b 377 378 LDR r7, [sp, 120] // cn_stride 379 LDR r14, [sp, 64] // p = ks 380 381 # QC8 FP32 quantization 382 VLD1.8 {q0-q1}, [r9]! 383 384 VDUP.32 q2, d12[0] // magic_bias 385 VDUP.32 q3, d12[1] // magic_bias_less_output_zero_point 386 387 VCVT.F32.S32 q8, q8 388 VCVT.F32.S32 q9, q9 389 VCVT.F32.S32 q10, q10 390 VCVT.F32.S32 q11, q11 391 VCVT.F32.S32 q12, q12 392 VCVT.F32.S32 q13, q13 393 VCVT.F32.S32 q14, q14 394 VCVT.F32.S32 q15, q15 395 396 VMUL.F32 q8, q8, q0 // multiplier 397 VMUL.F32 q9, q9, q1 398 VMUL.F32 q10, q10, q0 399 VMUL.F32 q11, q11, q1 400 VMUL.F32 q12, q12, q0 401 VMUL.F32 q13, q13, q1 402 VMUL.F32 q14, q14, q0 403 VMUL.F32 q15, q15, q1 404 405 VADD.F32 q8, q8, q2 // magic_bias 406 VADD.F32 q9, q9, q2 407 VADD.F32 q10, q10, q2 408 VADD.F32 q11, q11, q2 409 VADD.F32 q12, q12, q2 410 VADD.F32 q13, q13, q2 411 VADD.F32 q14, q14, q2 412 VADD.F32 q15, q15, q2 413 414 VQSUB.S32 q8, q8, q3 // magic_bias_less_output_zero_point 415 VQSUB.S32 q9, q9, q3 416 VQSUB.S32 q10, q10, q3 417 VQSUB.S32 q11, q11, q3 418 VQSUB.S32 q12, q12, q3 419 VQSUB.S32 q13, q13, q3 420 VQSUB.S32 q14, q14, q3 421 VQSUB.S32 q15, q15, q3 422 423 424 VQMOVN.S32 d16, q8 425 VQMOVN.S32 d17, q9 426 VQMOVN.S32 d18, q10 427 VQMOVN.S32 d19, q11 428 VQMOVN.S32 d20, q12 429 VQMOVN.S32 d21, q13 430 VQMOVN.S32 d22, q14 431 VQMOVN.S32 d23, q15 432 433 434 LDR r1, [sp, 56] // restore nc 435 VDUP.8 q12, d13[6] // output_min 436 437 VQMOVN.S16 d0, q8 438 VQMOVN.S16 d1, q9 439 VQMOVN.S16 d2, q10 440 VQMOVN.S16 d3, q11 441 442 VDUP.8 q13, d13[7] // output_max 443 444 VMAX.S8 q0, q0, q12 445 VMAX.S8 q1, q1, q12 446 447 SUBS r1, r1, 8 // nc -= 8 448 449 VMIN.S8 q0, q0, q13 450 VMIN.S8 q1, q1, q13 451 452 # Store full 4 x 8 453 BLO 7f 454 VST1.8 {d3}, [r6], r7 455 VST1.8 {d2}, [r8], r7 456 VST1.8 {d1}, [r4], r7 457 VST1.8 {d0}, [r11], r7 458 SUB r2, r2, r14 // a -= ks 459 BHI 0b 460 461 VPOP {d8-d13} 462 ADD sp, sp, 20 // skip pad of 8, r1, r2, r3 463 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc} 464 465 # Remainder- 1 to 7 bytes of A 466 .p2align 3 4675: 468 AND r5, r5, 7 // kc remainder 1 to 7 4696: 470 VLD1.8 {d0}, [r3] 471 VLD1.8 {d8}, [r9]! 472 VLD1.8 {d2}, [r12] 473 VLD1.8 {d4}, [r10] 474 VLD1.8 {d6}, [r0] 475 476 VMOVL.S8 q0, d0 477 VMOVL.S8 q4, d8 478 VMOVL.S8 q1, d2 479 VMOVL.S8 q2, d4 480 VMOVL.S8 q3, d6 481 VMLAL.S16 q8, d8, d0[0] 482 VMLAL.S16 q9, d9, d0[0] 483 VMLAL.S16 q10, d8, d2[0] 484 VMLAL.S16 q11, d9, d2[0] 485 VMLAL.S16 q12, d8, d4[0] 486 VMLAL.S16 q13, d9, d4[0] 487 VMLAL.S16 q14, d8, d6[0] 488 VMLAL.S16 q15, d9, d6[0] 489 CMP r5, 2 490 BLO 4b 491 492 VLD1.8 {d8}, [r9]! 493 VMOVL.S8 q4, d8 494 VMLAL.S16 q8, d8, d0[1] 495 VMLAL.S16 q9, d9, d0[1] 496 VMLAL.S16 q10, d8, d2[1] 497 VMLAL.S16 q11, d9, d2[1] 498 VMLAL.S16 q12, d8, d4[1] 499 VMLAL.S16 q13, d9, d4[1] 500 VMLAL.S16 q14, d8, d6[1] 501 VMLAL.S16 q15, d9, d6[1] 502 BEQ 4b 503 504 VLD1.8 {d8}, [r9]! 505 VMOVL.S8 q4, d8 506 VMLAL.S16 q8, d8, d0[2] 507 VMLAL.S16 q9, d9, d0[2] 508 VMLAL.S16 q10, d8, d2[2] 509 VMLAL.S16 q11, d9, d2[2] 510 VMLAL.S16 q12, d8, d4[2] 511 VMLAL.S16 q13, d9, d4[2] 512 VMLAL.S16 q14, d8, d6[2] 513 VMLAL.S16 q15, d9, d6[2] 514 CMP r5, 4 515 BLO 4b 516 517 VLD1.8 {d8}, [r9]! 518 VMOVL.S8 q4, d8 519 VMLAL.S16 q8, d8, d0[3] 520 VMLAL.S16 q9, d9, d0[3] 521 VMLAL.S16 q10, d8, d2[3] 522 VMLAL.S16 q11, d9, d2[3] 523 VMLAL.S16 q12, d8, d4[3] 524 VMLAL.S16 q13, d9, d4[3] 525 VMLAL.S16 q14, d8, d6[3] 526 VMLAL.S16 q15, d9, d6[3] 527 BEQ 4b 528 529 VLD1.8 {d8}, [r9]! 530 VMOVL.S8 q4, d8 531 VMLAL.S16 q8, d8, d1[0] 532 VMLAL.S16 q9, d9, d1[0] 533 VMLAL.S16 q10, d8, d3[0] 534 VMLAL.S16 q11, d9, d3[0] 535 VMLAL.S16 q12, d8, d5[0] 536 VMLAL.S16 q13, d9, d5[0] 537 VMLAL.S16 q14, d8, d7[0] 538 VMLAL.S16 q15, d9, d7[0] 539 CMP r5, 6 540 BLO 4b 541 542 VLD1.8 {d8}, [r9]! 543 VMOVL.S8 q4, d8 544 VMLAL.S16 q8, d8, d1[1] 545 VMLAL.S16 q9, d9, d1[1] 546 VMLAL.S16 q10, d8, d3[1] 547 VMLAL.S16 q11, d9, d3[1] 548 VMLAL.S16 q12, d8, d5[1] 549 VMLAL.S16 q13, d9, d5[1] 550 VMLAL.S16 q14, d8, d7[1] 551 VMLAL.S16 q15, d9, d7[1] 552 BEQ 4b 553 554 VLD1.8 {d8}, [r9]! 555 VMOVL.S8 q4, d8 556 VMLAL.S16 q8, d8, d1[2] 557 VMLAL.S16 q9, d9, d1[2] 558 VMLAL.S16 q10, d8, d3[2] 559 VMLAL.S16 q11, d9, d3[2] 560 VMLAL.S16 q12, d8, d5[2] 561 VMLAL.S16 q13, d9, d5[2] 562 VMLAL.S16 q14, d8, d7[2] 563 VMLAL.S16 q15, d9, d7[2] 564 B 4b 565 566 # Store odd width 567 .p2align 3 5687: 569 TST r1, 4 570 BEQ 8f 571 VST1.32 {d3[0]}, [r6]! 572 VST1.32 {d2[0]}, [r8]! 573 VST1.32 {d1[0]}, [r4]! 574 VST1.32 {d0[0]}, [r11]! 575 VEXT.8 q1, q1, q1, 4 576 VEXT.8 q0, q0, q0, 4 5778: 578 TST r1, 2 579 BEQ 9f 580 VST1.16 {d3[0]}, [r6]! 581 VST1.16 {d2[0]}, [r8]! 582 VST1.16 {d1[0]}, [r4]! 583 VST1.16 {d0[0]}, [r11]! 584 VEXT.8 q1, q1, q1, 2 585 VEXT.8 q0, q0, q0, 2 586 5879: 588 TST r1, 1 589 BEQ 10f 590 VST1.8 {d3[0]}, [r6] 591 VST1.8 {d2[0]}, [r8] 592 VST1.8 {d1[0]}, [r4] 593 VST1.8 {d0[0]}, [r11] 594 59510: 596 VPOP {d8-d13} 597 ADD sp, sp, 20 // skip pad of 8, r1, r2, r3 598 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc} 599 600END_FUNCTION xnn_qc8_igemm_minmax_fp32_ukernel_4x8__aarch32_neon_mlal_lane_prfm_cortex_a53 601 602#ifdef __ELF__ 603.section ".note.GNU-stack","",%progbits 604#endif 605