"Fossies" - the Fresh Open Source Software Archive

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