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