"Fossies" - the Fresh Open Source Software Archive

Member "pytorch-1.8.2/aten/src/ATen/native/quantized/cpu/qnnpack/src/q8conv/4x8-aarch32-neon.S" (23 Jul 2021, 18259 Bytes) of package /linux/misc/pytorch-1.8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PowerPC Assembler source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright (c) Facebook, Inc. and its affiliates.
    3  * All rights reserved.
    4  *
    5  * This source code is licensed under the BSD-style license found in the
    6  * LICENSE file in the root directory of this source tree.
    7  */
    8 
    9 #include <qnnpack/assembly.h>
   10 #include <requantization/runtime-assembly.h>
   11 
   12 .syntax unified
   13 
   14 #  Args passed via 4 registers (16 bytes)
   15 #  r0: mr
   16 #  r1: nr
   17 #  r2: kc
   18 #  r3: ks
   19 #
   20 
   21 #  Args passed via stack.
   22 #  TOS
   23 #  |-----------|
   24 #  |a          | 0
   25 #  |w          | 4
   26 #  |c          | 8
   27 #  |c_stride   | 12
   28 #  |out ch indx| 16
   29 #  |params     | 20
   30 #  |-----------|
   31 #  
   32 
   33 #  After loading w pointer in ip reg.
   34 #  And after pushing r4-r8 and d8-d15 on stack
   35 #  |-----------|
   36 #  |d8 - d15   | 0
   37 #  |r4 - r11   | 64
   38 #  |a          | 96
   39 #  |w          | 100
   40 #  |c          | 104
   41 #  |c_stride   | 108
   42 #  |out ch indx| 112
   43 #  |params     | 116
   44 #  |-----------|
   45 #  
   46 
   47 # void pytorch_q8conv_ukernel_4x8__aarch32_neon(
   48 #     size_t mr,
   49 #     size_t nr,
   50 #     size_t kc,
   51 #     size_t ks,
   52 #     const uint8_t**restrict a,
   53 #     const void*restrict w,
   54 #     uint8_t*restrict c,
   55 #     size_t c_stride,
   56 #     const union pytorch_qnnp_conv_quantization_params quantization_params[restrict static 1])
   57 BEGIN_FUNCTION pytorch_q8conv_ukernel_4x8__aarch32_neon
   58     .arm
   59 #ifndef __APPLE__
   60     .arch armv7-a
   61     .fpu neon
   62 #endif
   63     # Load w
   64     # - ip = w
   65     LDR ip, [sp, 4]
   66     PUSH {r4, r5, r6, r7, r8, r9, r10, r11}
   67 
   68     # Load params:
   69     # - r9 = params
   70     LDR r9, [sp, 52]
   71 
   72     VPUSH {d8-d15}
   73 
   74     # Load bias0123, bias4567
   75     VLDM ip!, {d16-d19}
   76 
   77     # Load a
   78     # - r8 = a
   79     LDR r8, [sp, 96]
   80     # Load output channel index
   81     LDR r5, [sp, 112]
   82     ADD r7, r9, 4
   83     # Load pointer to per channel zero points array
   84     LDR r4, [r9], 8
   85     # Load pointer to per channel requant scale
   86     # add 8 bytes to get to vfmax
   87     LDR r11, [r9], 8
   88     # Load a_zero_point:
   89     # - d14 = a_zero_point
   90     VLD1.8 {d14[]}, [r7]
   91     # Byte offset of output channel index for requant scale.
   92     LSL r6, r5, 2
   93     # Add offset to the base pointer
   94     ADD r5, r4, r5
   95 
   96     # Store in r11 pointer from where to load requant scale.
   97     ADD r11, r11, r6
   98 
   99     # q10 := vacc1x0123
  100     VMOV.I32 q10, q8
  101     # q11 := vacc1x4567
  102     VMOV.I32 q11, q9
  103     # q12 := vacc2x0123
  104     VMOV.I32 q12, q8
  105     # q13 := vacc2x4567
  106     VMOV.I32 q13, q9
  107     # q14 := vacc3x0123
  108     VMOV.I32 q14, q8
  109     # Load b_zero_point:
  110     # - d15 = b_zero_point
  111     VLD1.8 {d15}, [r5]
  112 
  113     # q15 := vacc3x4567
  114     VMOV.I32 q15, q9
  115 
  116     .p2align 5
  117 0:
  118     SUBS r10, r2, 8
  119 
  120     # Load a0, a1, a2, a3
  121     # - r4 = a0
  122     # - r5 = a1
  123     # - r6 = a2
  124     # - r7 = a3
  125     LDM r8!, {r4-r7}
  126 
  127     BLO 2f
  128 
  129 1:
  130     # Load va0
  131     # - d1 = va0
  132     VLD1.8 {d1}, [r4]!
  133 
  134     # Load va1
  135     # - d3 = va1
  136     VLD1.8 {d3}, [r5]!
  137 
  138     # Load vb0-vb7 (channel 0)
  139     # - d9 = vb0-vb7
  140     VLD1.8 {d9}, [ip:64]!
  141 
  142     # Load va2
  143     # - d5 = va2
  144     VLD1.8 {d5}, [r6]!
  145 
  146     # q0 = va0 = a0
  147     SUB_ZERO_POINT q0, d1, d14
  148 
  149     # Load va3
  150     # - d7 = va3
  151     VLD1.8 {d7}, [r7]!
  152 
  153     # q1 = va1 = a1
  154     SUB_ZERO_POINT q1, d3, d14
  155 
  156     # q4 = b0:7 - vb_zero_point
  157     # - d8 = vb0123 (channel 0)
  158     # - d9 = vb4567 (channel 0)
  159     VSUBL.U8 q4, d9, d15
  160 
  161     # q2 = va2 = a2
  162     SUB_ZERO_POINT q2, d5, d14
  163     # q3 = va3 = a3
  164     SUB_ZERO_POINT q3, d7, d14
  165 
  166     ### Channel 0 ###
  167 
  168     # Load b0-b7 (channel 1)
  169     # - d11 = b0-b7
  170     VLD1.8 {d11}, [ip:64]!
  171 
  172     # vacc0x0123 += vb0123 * va0[0]
  173     VMLAL.S16 q8, d8, d0[0]
  174     # vacc0x4567 += vb4567 * va0[0]
  175     VMLAL.S16 q9, d9, d0[0]
  176 
  177     # vacc1x0123 += vb0123 * va1[0]
  178     VMLAL.S16 q10, d8, d2[0]
  179     # vacc1x4567 += vb4567 * va1[0]
  180     VMLAL.S16 q11, d9, d2[0]
  181 
  182     # vacc2x0123 += vb0123 * va2[0]
  183     VMLAL.S16 q12, d8, d4[0]
  184     # vacc2x4567 += vb4567 * va2[0]
  185     VMLAL.S16 q13, d9, d4[0]
  186 
  187     # q5 = b0:7 - vb_zero_point
  188     # - d10 = vb0123 (channel 1)
  189     # - d11 = vb4567 (channel 1)
  190     VSUBL.U8 q5, d11, d15
  191 
  192     # vacc3x0123 += vb0123 * va3[0]
  193     VMLAL.S16 q14, d8, d6[0]
  194     # vacc3x4567 += vb4567 * va3[0]
  195     VMLAL.S16 q15, d9, d6[0]
  196 
  197     ### Channel 1 ###
  198 
  199     # Load b0-b7 (channel 2)
  200     # - d9 = b0-b7
  201     VLD1.8 {d9}, [ip:64]!
  202 
  203     # vacc0x0123 += vb0123 * va0[1]
  204     VMLAL.S16 q8, d10, d0[1]
  205     # vacc0x4567 += vb4567 * va0[1]
  206     VMLAL.S16 q9, d11, d0[1]
  207 
  208     # vacc1x0123 += vb0123 * va1[1]
  209     VMLAL.S16 q10, d10, d2[1]
  210     # vacc1x4567 += vb4567 * va1[1]
  211     VMLAL.S16 q11, d11, d2[1]
  212 
  213     # vacc2x0123 += vb0123 * va2[1]
  214     VMLAL.S16 q12, d10, d4[1]
  215     # vacc2x4567 += vb4567 * va2[1]
  216     VMLAL.S16 q13, d11, d4[1]
  217 
  218     # q4 = b0:7 - vb_zero_point
  219     # - d8 = vb0123 (channel 2)
  220     # - d9 = vb4567 (channel 2)
  221     VSUBL.U8 q4, d9, d15
  222 
  223     # vacc3x0123 += vb0123 * va3[1]
  224     VMLAL.S16 q14, d10, d6[1]
  225     # vacc3x4567 += vb4567 * va3[1]
  226     VMLAL.S16 q15, d11, d6[1]
  227 
  228     ### Channel 2 ###
  229 
  230     # Load b0-b7 (channel 3)
  231     # - d11 = b0-b7
  232     VLD1.8 {d11}, [ip:64]!
  233 
  234     # vacc0x0123 += vb0123 * va0[2]
  235     VMLAL.S16 q8, d8, d0[2]
  236     # vacc0x4567 += vb4567 * va0[2]
  237     VMLAL.S16 q9, d9, d0[2]
  238 
  239     # vacc1x0123 += vb0123 * va1[2]
  240     VMLAL.S16 q10, d8, d2[2]
  241     # vacc1x4567 += vb4567 * va1[2]
  242     VMLAL.S16 q11, d9, d2[2]
  243 
  244     # vacc2x0123 += vb0123 * va2[2]
  245     VMLAL.S16 q12, d8, d4[2]
  246     # vacc2x4567 += vb4567 * va2[2]
  247     VMLAL.S16 q13, d9, d4[2]
  248 
  249     # q5 = b0:7 - vb_zero_point
  250     # - d10 = vb0123 (channel 3)
  251     # - d11 = vb4567 (channel 3)
  252     VSUBL.U8 q5, d11, d15
  253 
  254     # vacc3x0123 += vb0123 * va3[2]
  255     VMLAL.S16 q14, d8, d6[2]
  256     # vacc3x4567 += vb4567 * va3[2]
  257     VMLAL.S16 q15, d9, d6[2]
  258 
  259     ### Channel 3 ###
  260 
  261     # Load b0-b7 (channel 4)
  262     # - d9 = b0-b7
  263     VLD1.8 {d9}, [ip:64]!
  264 
  265     # vacc0x0123 += vb0123 * va0[3]
  266     VMLAL.S16 q8, d10, d0[3]
  267     # vacc0x4567 += vb4567 * va0[3]
  268     VMLAL.S16 q9, d11, d0[3]
  269 
  270     # vacc1x0123 += vb0123 * va1[3]
  271     VMLAL.S16 q10, d10, d2[3]
  272     # vacc1x4567 += vb4567 * va1[3]
  273     VMLAL.S16 q11, d11, d2[3]
  274 
  275     # vacc2x0123 += vb0123 * va2[3]
  276     VMLAL.S16 q12, d10, d4[3]
  277     # vacc2x4567 += vb4567 * va2[3]
  278     VMLAL.S16 q13, d11, d4[3]
  279 
  280     # q5 = b0:7 - vb_zero_point
  281     # - d10 = vb0123 (channel 4)
  282     # - d11 = vb4567 (channel 4)
  283     VSUBL.U8 q4, d9, d15
  284 
  285     # vacc3x0123 += vb0123 * va3[3]
  286     VMLAL.S16 q14, d10, d6[3]
  287     # vacc3x4567 += vb4567 * va3[3]
  288     VMLAL.S16 q15, d11, d6[3]
  289 
  290     ### Channel 4 ###
  291 
  292     # Load b0-b7 (channel 5)
  293     # - d11 = b0-b7
  294     VLD1.8 {d11}, [ip:64]!
  295 
  296     # vacc0x0123 += vb0123 * va0[4]
  297     VMLAL.S16 q8, d8, d1[0]
  298     # vacc0x4567 += vb4567 * va0[4]
  299     VMLAL.S16 q9, d9, d1[0]
  300 
  301     # vacc1x0123 += vb0123 * va1[4]
  302     VMLAL.S16 q10, d8, d3[0]
  303     # vacc1x4567 += vb4567 * va1[4]
  304     VMLAL.S16 q11, d9, d3[0]
  305 
  306     # vacc2x0123 += vb0123 * va2[4]
  307     VMLAL.S16 q12, d8, d5[0]
  308     # vacc2x4567 += vb4567 * va2[4]
  309     VMLAL.S16 q13, d9, d5[0]
  310 
  311     # q4 = b0:7 - vb_zero_point
  312     # - d8 = vb0123 (channel 5)
  313     # - d9 = vb4567 (channel 5)
  314     VSUBL.U8 q5, d11, d15
  315 
  316     # vacc3x0123 += vb0123 * va3[4]
  317     VMLAL.S16 q14, d8, d7[0]
  318     # vacc3x4567 += vb4567 * va3[4]
  319     VMLAL.S16 q15, d9, d7[0]
  320 
  321     ### Channel 5 ###
  322 
  323     # Load b0-b7 (channel 6)
  324     # - d9 = b0-b7
  325     VLD1.8 {d9}, [ip:64]!
  326 
  327     # vacc0x0123 += vb0123 * va0[5]
  328     VMLAL.S16 q8, d10, d1[1]
  329     # vacc0x4567 += vb4567 * va0[5]
  330     VMLAL.S16 q9, d11, d1[1]
  331 
  332     # vacc1x0123 += vb0123 * va1[5]
  333     VMLAL.S16 q10, d10, d3[1]
  334     # vacc1x4567 += vb4567 * va1[5]
  335     VMLAL.S16 q11, d11, d3[1]
  336 
  337     # vacc2x0123 += vb0123 * va2[5]
  338     VMLAL.S16 q12, d10, d5[1]
  339     # vacc2x4567 += vb4567 * va2[5]
  340     VMLAL.S16 q13, d11, d5[1]
  341 
  342     # q4 = b0:7 - vb_zero_point
  343     # - d8 = vb0123 (channel 6)
  344     # - d9 = vb4567 (channel 6)
  345     VSUBL.U8 q4, d9, d15
  346 
  347     # vacc3x0123 += vb0123 * va3[5]
  348     VMLAL.S16 q14, d10, d7[1]
  349     # vacc3x4567 += vb4567 * va3[5]
  350     VMLAL.S16 q15, d11, d7[1]
  351 
  352     ### Channel 6 ###
  353 
  354     # Load b0-b7 (channel 7)
  355     # - d11 = b0-b7
  356     VLD1.8 {d11}, [ip:64]!
  357 
  358     # vacc0x0123 += vb0123 * va0[6]
  359     VMLAL.S16 q8, d8, d1[2]
  360     # vacc0x4567 += vb4567 * va0[6]
  361     VMLAL.S16 q9, d9, d1[2]
  362 
  363     # vacc1x0123 += vb0123 * va1[6]
  364     VMLAL.S16 q10, d8, d3[2]
  365     # vacc1x4567 += vb4567 * va1[6]
  366     VMLAL.S16 q11, d9, d3[2]
  367 
  368     # vacc2x0123 += vb0123 * va2[6]
  369     VMLAL.S16 q12, d8, d5[2]
  370 
  371     # q5 = b0:7 - vb_zero_point
  372     # - d10 = vb0123 (channel 7)
  373     # - d11 = vb4567 (channel 7)
  374     VSUBL.U8 q5, d11, d15
  375 
  376     # vacc2x4567 += vb4567 * va2[6]
  377     VMLAL.S16 q13, d9, d5[2]
  378 
  379     # vacc3x0123 += vb0123 * va3[6]
  380     VMLAL.S16 q14, d8, d7[2]
  381     # vacc3x4567 += vb4567 * va3[6]
  382     VMLAL.S16 q15, d9, d7[2]
  383 
  384     ### Channel 8 ###
  385     SUBS r10, r10, 8
  386 
  387     # vacc0x0123 += vb0123 * va0[7]
  388     VMLAL.S16 q8, d10, d1[3]
  389     # vacc0x4567 += vb4567 * va0[7]
  390     VMLAL.S16 q9, d11, d1[3]
  391 
  392     # vacc1x0123 += vb0123 * va1[7]
  393     VMLAL.S16 q10, d10, d3[3]
  394     # vacc1x4567 += vb4567 * va1[7]
  395     VMLAL.S16 q11, d11, d3[3]
  396 
  397     # vacc2x0123 += vb0123 * va2[7]
  398     VMLAL.S16 q12, d10, d5[3]
  399     # vacc2x4567 += vb4567 * va2[7]
  400     VMLAL.S16 q13, d11, d5[3]
  401 
  402     # vacc3x0123 += vb0123 * va3[7]
  403     VMLAL.S16 q14, d10, d7[3]
  404     # vacc3x4567 += vb4567 * va3[7]
  405     VMLAL.S16 q15, d11, d7[3]
  406 
  407     BHS 1b
  408 
  409 2:
  410     CMP r10, -8
  411     BEQ 3f
  412 
  413     # Adjust a0, a1, a2, a3
  414     ADD r4, r10
  415     ADD r5, r10
  416     ADD r6, r10
  417     ADD r7, r10
  418 
  419     # a_shift = 8 * k - 64
  420     LSL r10, r10, 3
  421     VDUP.32 d13, r10
  422 
  423     # Load va0
  424     # - d1 = va0
  425     VLD1.8 {d1}, [r4]
  426 
  427     # Load va1
  428     # - d3 = va1
  429     VLD1.8 {d3}, [r5]
  430 
  431     # Load b0-b7 (channel 0)
  432     # - d9 = b0-b7
  433     VLD1.8 {d9}, [ip:64]!
  434 
  435     # Load a2
  436     # - d5 = a2
  437     VLD1.8 {d5}, [r6]
  438 
  439     # q0 = va0 = a0
  440     VSHL.U64 d1, d1, d13
  441     SUB_ZERO_POINT q0, d1, d14
  442 
  443     # Load a3
  444     # - d7 = a3
  445     VLD1.8 {d7}, [r7]
  446 
  447     # q1 = va1 = a1
  448     VSHL.U64 d3, d3, d13
  449     SUB_ZERO_POINT q1, d3, d14
  450 
  451     # q4 = b0:7 - vb_zero_point
  452     # - d8 = vb0123 (channel 0)
  453     # - d9 = vb4567 (channel 0)
  454     VSUBL.U8 q4, d9, d15
  455 
  456     # q2 = va2 = a2
  457     VSHL.U64 d5, d5, d13
  458     SUB_ZERO_POINT q2, d5, d14
  459     # q3 = va3 = a3
  460     VSHL.U64 d7, d7, d13
  461     SUB_ZERO_POINT q3, d7, d14
  462 
  463     ### Channel 0 ###
  464 
  465     # vacc0x0123 += vb0123 * va0[0]
  466     VMLAL.S16 q8, d8, d0[0]
  467     # vacc0x4567 += vb4567 * va0[0]
  468     VMLAL.S16 q9, d9, d0[0]
  469 
  470     # vacc1x0123 += vb0123 * va1[0]
  471     VMLAL.S16 q10, d8, d2[0]
  472     # vacc1x4567 += vb4567 * va1[0]
  473     VMLAL.S16 q11, d9, d2[0]
  474 
  475     # vacc2x0123 += vb0123 * va2[0]
  476     VMLAL.S16 q12, d8, d4[0]
  477     # vacc2x4567 += vb4567 * va2[0]
  478     VMLAL.S16 q13, d9, d4[0]
  479 
  480     # vacc3x0123 += vb0123 * va3[0]
  481     VMLAL.S16 q14, d8, d6[0]
  482     # vacc3x4567 += vb4567 * va3[0]
  483     VMLAL.S16 q15, d9, d6[0]
  484 
  485     CMP r10, -48
  486     BLO 3f
  487 
  488     ### Channel 1 ###
  489 
  490     # Load b0-b7 (channel 1)
  491     # - d11 = b0-b7
  492     VLD1.8 {d11}, [ip:64]!
  493 
  494     # q5 = b0:7 - vb_zero_point
  495     # - d10 = vb0123 (channel 1)
  496     # - d11 = vb4567 (channel 1)
  497     VSUBL.U8 q5, d11, d15
  498 
  499     # vacc0x0123 += vb0123 * va0[1]
  500     VMLAL.S16 q8, d10, d0[1]
  501     # vacc0x4567 += vb4567 * va0[1]
  502     VMLAL.S16 q9, d11, d0[1]
  503 
  504     # vacc1x0123 += vb0123 * va1[1]
  505     VMLAL.S16 q10, d10, d2[1]
  506     # vacc1x4567 += vb4567 * va1[1]
  507     VMLAL.S16 q11, d11, d2[1]
  508 
  509     # vacc2x0123 += vb0123 * va2[1]
  510     VMLAL.S16 q12, d10, d4[1]
  511     # vacc2x4567 += vb4567 * va2[1]
  512     VMLAL.S16 q13, d11, d4[1]
  513 
  514     # vacc3x0123 += vb0123 * va3[1]
  515     VMLAL.S16 q14, d10, d6[1]
  516     # vacc3x4567 += vb4567 * va3[1]
  517     VMLAL.S16 q15, d11, d6[1]
  518 
  519     ### Channel 2 ###
  520     BLS 3f
  521 
  522     # Load b0-b7 (channel 2)
  523     # - d9 = b0-b7
  524     VLD1.8 {d9}, [ip:64]!
  525 
  526     # q4 = b0:7 - vb_zero_point
  527     # - d8 = vb0123 (channel 2)
  528     # - d9 = vb4567 (channel 2)
  529     VSUBL.U8 q4, d9, d15
  530 
  531     # vacc0x0123 += vb0123 * va0[2]
  532     VMLAL.S16 q8, d8, d0[2]
  533     # vacc0x4567 += vb4567 * va0[2]
  534     VMLAL.S16 q9, d9, d0[2]
  535 
  536     # vacc1x0123 += vb0123 * va1[2]
  537     VMLAL.S16 q10, d8, d2[2]
  538     # vacc1x4567 += vb4567 * va1[2]
  539     VMLAL.S16 q11, d9, d2[2]
  540 
  541     # vacc2x0123 += vb0123 * va2[2]
  542     VMLAL.S16 q12, d8, d4[2]
  543     # vacc2x4567 += vb4567 * va2[2]
  544     VMLAL.S16 q13, d9, d4[2]
  545 
  546     # vacc3x0123 += vb0123 * va3[2]
  547     VMLAL.S16 q14, d8, d6[2]
  548     # vacc3x4567 += vb4567 * va3[2]
  549     VMLAL.S16 q15, d9, d6[2]
  550 
  551     ### Channel 3 ###
  552     CMP r10, -32
  553     BLO 3f
  554 
  555     # Load b0-b7 (channel 3)
  556     # - d9 = b0-b7
  557     VLD1.8 {d11}, [ip:64]!
  558 
  559     # q4 = b0:7 - vb_zero_point
  560     # - d8 = vb0123 (channel 3)
  561     # - d9 = vb4567 (channel 3)
  562     VSUBL.U8 q5, d11, d15
  563 
  564     # vacc0x0123 += vb0123 * va0[3]
  565     VMLAL.S16 q8, d10, d0[3]
  566     # vacc0x4567 += vb4567 * va0[3]
  567     VMLAL.S16 q9, d11, d0[3]
  568 
  569     # vacc1x0123 += vb0123 * va1[3]
  570     VMLAL.S16 q10, d10, d2[3]
  571     # vacc1x4567 += vb4567 * va1[3]
  572     VMLAL.S16 q11, d11, d2[3]
  573 
  574     # vacc2x0123 += vb0123 * va2[3]
  575     VMLAL.S16 q12, d10, d4[3]
  576     # vacc2x4567 += vb4567 * va2[3]
  577     VMLAL.S16 q13, d11, d4[3]
  578 
  579     # vacc3x0123 += vb0123 * va3[3]
  580     VMLAL.S16 q14, d10, d6[3]
  581     # vacc3x4567 += vb4567 * va3[3]
  582     VMLAL.S16 q15, d11, d6[3]
  583 
  584     ### Channel 4 ###
  585     BLS 3f
  586 
  587     # Load b0-b7 (channel 4)
  588     # - d11 = b0-b7
  589     VLD1.8 {d9}, [ip:64]!
  590 
  591     # q5 = b0:7 - vb_zero_point
  592     # - d10 = vb0123 (channel 4)
  593     # - d11 = vb4567 (channel 4)
  594     VSUBL.U8 q4, d9, d15
  595 
  596     # vacc0x0123 += vb0123 * va0[4]
  597     VMLAL.S16 q8, d8, d1[0]
  598     # vacc0x4567 += vb4567 * va0[4]
  599     VMLAL.S16 q9, d9, d1[0]
  600 
  601     # vacc1x0123 += vb0123 * va1[4]
  602     VMLAL.S16 q10, d8, d3[0]
  603     # vacc1x4567 += vb4567 * va1[4]
  604     VMLAL.S16 q11, d9, d3[0]
  605 
  606     # vacc2x0123 += vb0123 * va2[4]
  607     VMLAL.S16 q12, d8, d5[0]
  608     # vacc2x4567 += vb4567 * va2[4]
  609     VMLAL.S16 q13, d9, d5[0]
  610 
  611     # vacc3x0123 += vb0123 * va3[4]
  612     VMLAL.S16 q14, d8, d7[0]
  613     # vacc3x4567 += vb4567 * va3[4]
  614     VMLAL.S16 q15, d9, d7[0]
  615 
  616     ### Channel 5 ###
  617     CMP r10, -16
  618     BLO 3f
  619 
  620     # Load b0-b7 (channel 5)
  621     # - d13 = b0-b7
  622     VLD1.8 {d11}, [ip:64]!
  623 
  624     # q5 = b0:7 - vb_zero_point
  625     # - d10 = vb0123 (channel 5)
  626     # - d11 = vb4567 (channel 5)
  627     VSUBL.U8 q5, d11, d15
  628 
  629     # vacc0x0123 += vb0123 * va0[5]
  630     VMLAL.S16 q8, d10, d1[1]
  631     # vacc0x4567 += vb4567 * va0[5]
  632     VMLAL.S16 q9, d11, d1[1]
  633 
  634     # vacc1x0123 += vb0123 * va1[5]
  635     VMLAL.S16 q10, d10, d3[1]
  636     # vacc1x4567 += vb4567 * va1[5]
  637     VMLAL.S16 q11, d11, d3[1]
  638 
  639     # vacc2x0123 += vb0123 * va2[5]
  640     VMLAL.S16 q12, d10, d5[1]
  641     # vacc2x4567 += vb4567 * va2[5]
  642     VMLAL.S16 q13, d11, d5[1]
  643 
  644     # vacc3x0123 += vb0123 * va3[5]
  645     VMLAL.S16 q14, d10, d7[1]
  646     # vacc3x4567 += vb4567 * va3[5]
  647     VMLAL.S16 q15, d11, d7[1]
  648 
  649     ### Channel 6 ###
  650     BLS 3f
  651 
  652     # Load b0-b7 (channel 6)
  653     # - d9 = b0-b7
  654     VLD1.8 {d9}, [ip:64]!
  655 
  656     # q4 = b0:7 - vb_zero_point
  657     # - d8 = vb0123 (channel 6)
  658     # - d9 = vb4567 (channel 6)
  659     VSUBL.U8 q4, d9, d15
  660 
  661     # vacc0x0123 += vb0123 * va0[6]
  662     VMLAL.S16 q8, d8, d1[2]
  663     # vacc0x4567 += vb4567 * va0[6]
  664     VMLAL.S16 q9, d9, d1[2]
  665 
  666     # vacc1x0123 += vb0123 * va1[6]
  667     VMLAL.S16 q10, d8, d3[2]
  668     # vacc1x4567 += vb4567 * va1[6]
  669     VMLAL.S16 q11, d9, d3[2]
  670 
  671     # vacc2x0123 += vb0123 * va2[6]
  672     VMLAL.S16 q12, d8, d5[2]
  673 
  674     # vacc2x4567 += vb4567 * va2[6]
  675     VMLAL.S16 q13, d9, d5[2]
  676 
  677     # vacc3x0123 += vb0123 * va3[6]
  678     VMLAL.S16 q14, d8, d7[2]
  679     # vacc3x4567 += vb4567 * va3[6]
  680     VMLAL.S16 q15, d9, d7[2]
  681 
  682     .p2align 4
  683 3:
  684     SUBS r3, r3, 1
  685     BNE 0b
  686 
  687     # Load requantization_scale:
  688     # - d12 = requantization_scale
  689     VLD1.32 {d12, d13}, [r11]!
  690     # Load vfmax:
  691     VLD1.32 {d10[], d11[]}, [r9]!
  692     VLD1.32 {d4, d5}, [r11]
  693     # Load vfmin:
  694     VLD1.32 {d8[], d9[]}, [r9]!
  695     # Load vfmagic:
  696     VLD1.32 {d0[], d1[]}, [r9]!
  697     # Load vimagic:
  698     VLD1.32 {d2[], d3[]}, [r9]!
  699 
  700     VCVT.F32.S32 q8, q8
  701     VCVT.F32.S32 q9, q9
  702     VCVT.F32.S32 q10, q10
  703     VCVT.F32.S32 q11, q11
  704     VCVT.F32.S32 q12, q12
  705     VCVT.F32.S32 q13, q13
  706     VCVT.F32.S32 q14, q14
  707     VCVT.F32.S32 q15, q15
  708 
  709     VMUL.F32 q8, q8, q6
  710     VMUL.F32 q9, q9, q2
  711     VMUL.F32 q10, q10, q6
  712     VMUL.F32 q11, q11, q2
  713     VMUL.F32 q12, q12, q6
  714     VMUL.F32 q13, q13, q2
  715     VMUL.F32 q14, q14, q6
  716     VMUL.F32 q15, q15, q2
  717 
  718     VMIN.F32 q8, q8, q5
  719     VMIN.F32 q9, q9, q5
  720     VMIN.F32 q10, q10, q5
  721     VMIN.F32 q11, q11, q5
  722     VMIN.F32 q12, q12, q5
  723     VMIN.F32 q13, q13, q5
  724     VMIN.F32 q14, q14, q5
  725     VMIN.F32 q15, q15, q5
  726 
  727     VMAX.F32 q8, q8, q4
  728     VMAX.F32 q9, q9, q4
  729     VMAX.F32 q10, q10, q4
  730     VMAX.F32 q11, q11, q4
  731     VMAX.F32 q12, q12, q4
  732     VMAX.F32 q13, q13, q4
  733     VMAX.F32 q14, q14, q4
  734     VMAX.F32 q15, q15, q4
  735 
  736     VADD.F32 q8, q8, q0
  737     VADD.F32 q9, q9, q0
  738     VADD.F32 q10, q10, q0
  739     VADD.F32 q11, q11, q0
  740     VADD.F32 q12, q12, q0
  741     VADD.F32 q13, q13, q0
  742     VADD.F32 q14, q14, q0
  743     VADD.F32 q15, q15, q0
  744 
  745     # Load c, c_stride:
  746     # - r2 = c
  747     # - r2 = c_stride
  748     LDRD r2, r3, [sp, 104]
  749 
  750     VSUB.S32 q8, q8, q1
  751     VSUB.S32 q9, q9, q1
  752     VSUB.S32 q10, q10, q1
  753     VSUB.S32 q11, q11, q1
  754     VSUB.S32 q12, q12, q1
  755     VSUB.S32 q13, q13, q1
  756     VSUB.S32 q14, q14, q1
  757     VSUB.S32 q15, q15, q1
  758 
  759     ADD r4, r2, r3
  760     VQMOVN.S32 d16,  q8
  761     VQMOVN.S32 d17,  q9
  762     CMP r0, 2
  763     VQMOVN.S32 d18, q10
  764     VQMOVN.S32 d19, q11
  765     MOVLO r4, r2
  766     VQMOVN.S32 d20, q12
  767     VQMOVN.S32 d21, q13
  768     VQMOVN.S32 d22, q14
  769     VQMOVN.S32 d23, q15
  770 
  771 
  772     ADD r5, r4, r3
  773     VQMOVUN.S16 d16,  q8
  774     MOVLS r5, r4
  775     VQMOVUN.S16 d17,  q9
  776     VQMOVUN.S16 d18, q10
  777     CMP r0, 4
  778     ADD r3, r5, r3
  779 
  780     MOVNE r3, r5
  781     CMP r1, 8
  782     VQMOVUN.S16 d19, q11
  783 
  784 
  785     BNE 5f
  786 
  787     VST1.8 {d16}, [r2]
  788     VST1.8 {d17}, [r4]
  789     VST1.8 {d18}, [r5]
  790     VST1.8 {d19}, [r3]
  791 
  792     VPOP {d8-d15}
  793     POP {r4, r5, r6, r7, r8, r9, r10, r11}
  794     BX lr
  795 
  796     .p2align 3
  797 5:
  798     CMP r1, 4
  799     BLO 6f
  800 
  801     VST1.32 {d16[0]}, [r2]!
  802     VST1.32 {d17[0]}, [r4]!
  803     VST1.32 {d18[0]}, [r5]!
  804     VST1.32 {d19[0]}, [r3]!
  805 
  806     SUB r1, 4
  807     VEXT.8 q8, q8, q8, 4
  808     VEXT.8 q9, q9, q9, 4
  809 
  810 6:
  811     CMP r1, 2
  812     BLO 7f
  813 
  814     VST1.16 {d16[0]}, [r2]!
  815     VST1.16 {d17[0]}, [r4]!
  816     VST1.16 {d18[0]}, [r5]!
  817     VST1.16 {d19[0]}, [r3]!
  818 
  819     SUB r1, 2
  820     VEXT.8 q8, q8, q8, 2
  821     VEXT.8 q9, q9, q9, 2
  822 
  823 7:
  824     TEQ r1, 0
  825     BEQ 8f
  826 
  827     VST1.8 {d16[0]}, [r2]
  828     VST1.8 {d17[0]}, [r4]
  829     VST1.8 {d18[0]}, [r5]
  830     VST1.8 {d19[0]}, [r3]
  831 
  832 8:
  833     VPOP {d8-d15}
  834     POP {r4, r5, r6, r7, r8, r9, r10, r11}
  835     BX lr
  836 END_FUNCTION pytorch_q8conv_ukernel_4x8__aarch32_neon
  837 
  838 #ifdef __ELF__
  839 .section ".note.GNU-stack","",%progbits
  840 #endif