Home | History | Annotate | Download | only in meta
      1 // Copyright 2016 The Gemmlowp Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef GEMMLOWP_META_STREAMS_ARM_32_H_
     16 #define GEMMLOWP_META_STREAMS_ARM_32_H_
     17 
     18 #ifdef GEMMLOWP_NEON_32
     19 
     20 #include <cassert>
     21 #include <cstdint>
     22 
     23 namespace gemmlowp {
     24 namespace meta {
     25 
     26 template <>
     27 inline void Stream<uint8_t, 1, 8, 0, RowMajorWithSum>::Pack(
     28     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
     29 #ifdef DEBUG
     30 #ifdef DEBUG_METAGEMM_VERBOSE
     31   std::cout << __FILE__ << "(" << __LINE__
     32             << ") RowMajorWithSum<uint8_t, 1, 8, 0, RowMajorWithSum>::Pack()"
     33             << std::endl
     34             << std::flush;
     35 #endif
     36 #endif
     37   int params_count_copy = params.count;
     38   asm volatile(
     39       "vmov.i16 q8, #0\n"
     40 
     41       "1:"
     42       "subs %[count], %[count], #8\n"
     43 
     44       // Load Aggregate Store: 1x8.
     45       "vld1.32 {d0}, [%[in]]!\n"
     46       "vaddw.u8 q8, q8, d0\n"
     47       "vst1.32 {d0}, [%[out]:64]!\n"
     48 
     49       "bne 1b\n"
     50 
     51       // Aggregator Reduction.
     52       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
     53       "vdup.32 q1, %[additive_sum_offset]\n"
     54       "vpaddl.u16 q8, q8\n"
     55       "vpadd.u32 d16, d16, d17\n"
     56       "vpadd.u32 d16, d16, d16\n"
     57       "vmul.i32 q8, q8, d0[0]\n"
     58       "vadd.i32 q8, q8, q1\n"
     59       "vst1.32 {d16, d17}, [%[out]:64]\n"
     60       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
     61       : [stride] "r"(params.stride),
     62         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
     63         [additive_sum_offset] "r"(params.additive_sum_offset)
     64       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
     65 }
     66 
     67 template <>
     68 inline void Stream<uint8_t, 1, 8, 1, RowMajorWithSum>::Pack(
     69     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
     70 #ifdef DEBUG
     71 #ifdef DEBUG_METAGEMM_VERBOSE
     72   std::cout << __FILE__ << "(" << __LINE__
     73             << ") RowMajorWithSum<uint8_t, 1, 8, 1, RowMajorWithSum>::Pack()"
     74             << std::endl
     75             << std::flush;
     76 #endif
     77 #endif
     78   int params_count_copy = params.count;
     79   asm volatile(
     80       "vmov.i16 q8, #0\n"
     81 
     82       // Reduce count by leftovers.
     83       "subs %[count], %[count], #1\n"
     84       "beq 2f\n"
     85 
     86       "1:"
     87       "subs %[count], %[count], #8\n"
     88 
     89       // Load Aggregate Store: 1x8.
     90       "vld1.32 {d0}, [%[in]]!\n"
     91       "vaddw.u8 q8, q8, d0\n"
     92       "vst1.32 {d0}, [%[out]:64]!\n"
     93 
     94       "bne 1b\n"
     95 
     96       "2:"
     97 
     98       // Load Aggregate Store: 1x1.
     99       "vmov.i8 d0, #0\n"
    100       "vld1.8 {d0[0]}, [%[in]]!\n"
    101       "vaddw.u8 q8, q8, d0\n"
    102       "vst1.32 {d0}, [%[out]:64]!\n"
    103 
    104       // Aggregator Reduction.
    105       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    106       "vdup.32 q1, %[additive_sum_offset]\n"
    107       "vpaddl.u16 q8, q8\n"
    108       "vpadd.u32 d16, d16, d17\n"
    109       "vpadd.u32 d16, d16, d16\n"
    110       "vmul.i32 q8, q8, d0[0]\n"
    111       "vadd.i32 q8, q8, q1\n"
    112       "vst1.32 {d16, d17}, [%[out]:64]\n"
    113       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    114       : [stride] "r"(params.stride),
    115         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    116         [additive_sum_offset] "r"(params.additive_sum_offset)
    117       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    118 }
    119 
    120 template <>
    121 inline void Stream<uint8_t, 1, 8, 2, RowMajorWithSum>::Pack(
    122     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    123 #ifdef DEBUG
    124 #ifdef DEBUG_METAGEMM_VERBOSE
    125   std::cout << __FILE__ << "(" << __LINE__
    126             << ") RowMajorWithSum<uint8_t, 1, 8, 2, RowMajorWithSum>::Pack()"
    127             << std::endl
    128             << std::flush;
    129 #endif
    130 #endif
    131   int params_count_copy = params.count;
    132   asm volatile(
    133       "vmov.i16 q8, #0\n"
    134 
    135       // Reduce count by leftovers.
    136       "subs %[count], %[count], #2\n"
    137       "beq 2f\n"
    138 
    139       "1:"
    140       "subs %[count], %[count], #8\n"
    141 
    142       // Load Aggregate Store: 1x8.
    143       "vld1.32 {d0}, [%[in]]!\n"
    144       "vaddw.u8 q8, q8, d0\n"
    145       "vst1.32 {d0}, [%[out]:64]!\n"
    146 
    147       "bne 1b\n"
    148 
    149       "2:"
    150 
    151       // Load Aggregate Store: 1x2.
    152       "vmov.i8 d0, #0\n"
    153       "vld1.16 {d0[0]}, [%[in]]!\n"
    154       "vaddw.u8 q8, q8, d0\n"
    155       "vst1.32 {d0}, [%[out]:64]!\n"
    156 
    157       // Aggregator Reduction.
    158       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    159       "vdup.32 q1, %[additive_sum_offset]\n"
    160       "vpaddl.u16 q8, q8\n"
    161       "vpadd.u32 d16, d16, d17\n"
    162       "vpadd.u32 d16, d16, d16\n"
    163       "vmul.i32 q8, q8, d0[0]\n"
    164       "vadd.i32 q8, q8, q1\n"
    165       "vst1.32 {d16, d17}, [%[out]:64]\n"
    166       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    167       : [stride] "r"(params.stride),
    168         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    169         [additive_sum_offset] "r"(params.additive_sum_offset)
    170       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    171 }
    172 
    173 template <>
    174 inline void Stream<uint8_t, 1, 8, 3, RowMajorWithSum>::Pack(
    175     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    176 #ifdef DEBUG
    177 #ifdef DEBUG_METAGEMM_VERBOSE
    178   std::cout << __FILE__ << "(" << __LINE__
    179             << ") RowMajorWithSum<uint8_t, 1, 8, 3, RowMajorWithSum>::Pack()"
    180             << std::endl
    181             << std::flush;
    182 #endif
    183 #endif
    184   int params_count_copy = params.count;
    185   asm volatile(
    186       "vmov.i16 q8, #0\n"
    187 
    188       // Reduce count by leftovers.
    189       "subs %[count], %[count], #3\n"
    190       "beq 2f\n"
    191 
    192       "1:"
    193       "subs %[count], %[count], #8\n"
    194 
    195       // Load Aggregate Store: 1x8.
    196       "vld1.32 {d0}, [%[in]]!\n"
    197       "vaddw.u8 q8, q8, d0\n"
    198       "vst1.32 {d0}, [%[out]:64]!\n"
    199 
    200       "bne 1b\n"
    201 
    202       "2:"
    203 
    204       // Load Aggregate Store: 1x3.
    205       "vmov.i8 d0, #0\n"
    206       "vld1.16 {d0[0]}, [%[in]]!\n"
    207       "vld1.8 {d0[2]}, [%[in]]!\n"
    208       "vaddw.u8 q8, q8, d0\n"
    209       "vst1.32 {d0}, [%[out]:64]!\n"
    210 
    211       // Aggregator Reduction.
    212       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    213       "vdup.32 q1, %[additive_sum_offset]\n"
    214       "vpaddl.u16 q8, q8\n"
    215       "vpadd.u32 d16, d16, d17\n"
    216       "vpadd.u32 d16, d16, d16\n"
    217       "vmul.i32 q8, q8, d0[0]\n"
    218       "vadd.i32 q8, q8, q1\n"
    219       "vst1.32 {d16, d17}, [%[out]:64]\n"
    220       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    221       : [stride] "r"(params.stride),
    222         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    223         [additive_sum_offset] "r"(params.additive_sum_offset)
    224       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    225 }
    226 
    227 template <>
    228 inline void Stream<uint8_t, 1, 8, 4, RowMajorWithSum>::Pack(
    229     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    230 #ifdef DEBUG
    231 #ifdef DEBUG_METAGEMM_VERBOSE
    232   std::cout << __FILE__ << "(" << __LINE__
    233             << ") RowMajorWithSum<uint8_t, 1, 8, 4, RowMajorWithSum>::Pack()"
    234             << std::endl
    235             << std::flush;
    236 #endif
    237 #endif
    238   int params_count_copy = params.count;
    239   asm volatile(
    240       "vmov.i16 q8, #0\n"
    241 
    242       // Reduce count by leftovers.
    243       "subs %[count], %[count], #4\n"
    244       "beq 2f\n"
    245 
    246       "1:"
    247       "subs %[count], %[count], #8\n"
    248 
    249       // Load Aggregate Store: 1x8.
    250       "vld1.32 {d0}, [%[in]]!\n"
    251       "vaddw.u8 q8, q8, d0\n"
    252       "vst1.32 {d0}, [%[out]:64]!\n"
    253 
    254       "bne 1b\n"
    255 
    256       "2:"
    257 
    258       // Load Aggregate Store: 1x4.
    259       "vmov.i8 d0, #0\n"
    260       "vld1.32 {d0[0]}, [%[in]]!\n"
    261       "vaddw.u8 q8, q8, d0\n"
    262       "vst1.32 {d0}, [%[out]:64]!\n"
    263 
    264       // Aggregator Reduction.
    265       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    266       "vdup.32 q1, %[additive_sum_offset]\n"
    267       "vpaddl.u16 q8, q8\n"
    268       "vpadd.u32 d16, d16, d17\n"
    269       "vpadd.u32 d16, d16, d16\n"
    270       "vmul.i32 q8, q8, d0[0]\n"
    271       "vadd.i32 q8, q8, q1\n"
    272       "vst1.32 {d16, d17}, [%[out]:64]\n"
    273       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    274       : [stride] "r"(params.stride),
    275         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    276         [additive_sum_offset] "r"(params.additive_sum_offset)
    277       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    278 }
    279 
    280 template <>
    281 inline void Stream<uint8_t, 1, 8, 5, RowMajorWithSum>::Pack(
    282     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    283 #ifdef DEBUG
    284 #ifdef DEBUG_METAGEMM_VERBOSE
    285   std::cout << __FILE__ << "(" << __LINE__
    286             << ") RowMajorWithSum<uint8_t, 1, 8, 5, RowMajorWithSum>::Pack()"
    287             << std::endl
    288             << std::flush;
    289 #endif
    290 #endif
    291   int params_count_copy = params.count;
    292   asm volatile(
    293       "vmov.i16 q8, #0\n"
    294 
    295       // Reduce count by leftovers.
    296       "subs %[count], %[count], #5\n"
    297       "beq 2f\n"
    298 
    299       "1:"
    300       "subs %[count], %[count], #8\n"
    301 
    302       // Load Aggregate Store: 1x8.
    303       "vld1.32 {d0}, [%[in]]!\n"
    304       "vaddw.u8 q8, q8, d0\n"
    305       "vst1.32 {d0}, [%[out]:64]!\n"
    306 
    307       "bne 1b\n"
    308 
    309       "2:"
    310 
    311       // Load Aggregate Store: 1x5.
    312       "vmov.i8 d0, #0\n"
    313       "vld1.32 {d0[0]}, [%[in]]!\n"
    314       "vld1.8 {d0[4]}, [%[in]]!\n"
    315       "vaddw.u8 q8, q8, d0\n"
    316       "vst1.32 {d0}, [%[out]:64]!\n"
    317 
    318       // Aggregator Reduction.
    319       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    320       "vdup.32 q1, %[additive_sum_offset]\n"
    321       "vpaddl.u16 q8, q8\n"
    322       "vpadd.u32 d16, d16, d17\n"
    323       "vpadd.u32 d16, d16, d16\n"
    324       "vmul.i32 q8, q8, d0[0]\n"
    325       "vadd.i32 q8, q8, q1\n"
    326       "vst1.32 {d16, d17}, [%[out]:64]\n"
    327       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    328       : [stride] "r"(params.stride),
    329         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    330         [additive_sum_offset] "r"(params.additive_sum_offset)
    331       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    332 }
    333 
    334 template <>
    335 inline void Stream<uint8_t, 1, 8, 6, RowMajorWithSum>::Pack(
    336     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    337 #ifdef DEBUG
    338 #ifdef DEBUG_METAGEMM_VERBOSE
    339   std::cout << __FILE__ << "(" << __LINE__
    340             << ") RowMajorWithSum<uint8_t, 1, 8, 6, RowMajorWithSum>::Pack()"
    341             << std::endl
    342             << std::flush;
    343 #endif
    344 #endif
    345   int params_count_copy = params.count;
    346   asm volatile(
    347       "vmov.i16 q8, #0\n"
    348 
    349       // Reduce count by leftovers.
    350       "subs %[count], %[count], #6\n"
    351       "beq 2f\n"
    352 
    353       "1:"
    354       "subs %[count], %[count], #8\n"
    355 
    356       // Load Aggregate Store: 1x8.
    357       "vld1.32 {d0}, [%[in]]!\n"
    358       "vaddw.u8 q8, q8, d0\n"
    359       "vst1.32 {d0}, [%[out]:64]!\n"
    360 
    361       "bne 1b\n"
    362 
    363       "2:"
    364 
    365       // Load Aggregate Store: 1x6.
    366       "vmov.i8 d0, #0\n"
    367       "vld1.32 {d0[0]}, [%[in]]!\n"
    368       "vld1.16 {d0[2]}, [%[in]]!\n"
    369       "vaddw.u8 q8, q8, d0\n"
    370       "vst1.32 {d0}, [%[out]:64]!\n"
    371 
    372       // Aggregator Reduction.
    373       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    374       "vdup.32 q1, %[additive_sum_offset]\n"
    375       "vpaddl.u16 q8, q8\n"
    376       "vpadd.u32 d16, d16, d17\n"
    377       "vpadd.u32 d16, d16, d16\n"
    378       "vmul.i32 q8, q8, d0[0]\n"
    379       "vadd.i32 q8, q8, q1\n"
    380       "vst1.32 {d16, d17}, [%[out]:64]\n"
    381       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    382       : [stride] "r"(params.stride),
    383         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    384         [additive_sum_offset] "r"(params.additive_sum_offset)
    385       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    386 }
    387 
    388 template <>
    389 inline void Stream<uint8_t, 1, 8, 7, RowMajorWithSum>::Pack(
    390     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    391 #ifdef DEBUG
    392 #ifdef DEBUG_METAGEMM_VERBOSE
    393   std::cout << __FILE__ << "(" << __LINE__
    394             << ") RowMajorWithSum<uint8_t, 1, 8, 7, RowMajorWithSum>::Pack()"
    395             << std::endl
    396             << std::flush;
    397 #endif
    398 #endif
    399   int params_count_copy = params.count;
    400   asm volatile(
    401       "vmov.i16 q8, #0\n"
    402 
    403       // Reduce count by leftovers.
    404       "subs %[count], %[count], #7\n"
    405       "beq 2f\n"
    406 
    407       "1:"
    408       "subs %[count], %[count], #8\n"
    409 
    410       // Load Aggregate Store: 1x8.
    411       "vld1.32 {d0}, [%[in]]!\n"
    412       "vaddw.u8 q8, q8, d0\n"
    413       "vst1.32 {d0}, [%[out]:64]!\n"
    414 
    415       "bne 1b\n"
    416 
    417       "2:"
    418 
    419       // Load Aggregate Store: 1x7.
    420       "vmov.i8 d0, #0\n"
    421       "vld1.32 {d0[0]}, [%[in]]!\n"
    422       "vld1.16 {d0[2]}, [%[in]]!\n"
    423       "vld1.8 {d0[6]}, [%[in]]!\n"
    424       "vaddw.u8 q8, q8, d0\n"
    425       "vst1.32 {d0}, [%[out]:64]!\n"
    426 
    427       // Aggregator Reduction.
    428       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    429       "vdup.32 q1, %[additive_sum_offset]\n"
    430       "vpaddl.u16 q8, q8\n"
    431       "vpadd.u32 d16, d16, d17\n"
    432       "vpadd.u32 d16, d16, d16\n"
    433       "vmul.i32 q8, q8, d0[0]\n"
    434       "vadd.i32 q8, q8, q1\n"
    435       "vst1.32 {d16, d17}, [%[out]:64]\n"
    436       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    437       : [stride] "r"(params.stride),
    438         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    439         [additive_sum_offset] "r"(params.additive_sum_offset)
    440       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
    441 }
    442 
    443 template <>
    444 inline void Stream<uint8_t, 2, 8, 0, RowMajorWithSum>::Pack(
    445     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    446 #ifdef DEBUG
    447 #ifdef DEBUG_METAGEMM_VERBOSE
    448   std::cout << __FILE__ << "(" << __LINE__
    449             << ") RowMajorWithSum<uint8_t, 2, 8, 0, RowMajorWithSum>::Pack()"
    450             << std::endl
    451             << std::flush;
    452 #endif
    453 #endif
    454   int params_count_copy = params.count;
    455   asm volatile(
    456       "add r0, %[in], %[stride]\n"
    457       "vmov.i16 q8, #0\n"
    458       "vmov.i16 q9, #0\n"
    459 
    460       "1:"
    461       "subs %[count], %[count], #8\n"
    462 
    463       // Load Aggregate Store: 2x8.
    464       "vld1.32 {d0}, [%[in]]!\n"
    465       "vld1.32 {d1}, [r0]!\n"
    466       "vaddw.u8 q8, q8, d0\n"
    467       "vaddw.u8 q9, q9, d1\n"
    468       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    469 
    470       "bne 1b\n"
    471 
    472       // Aggregator Reduction.
    473       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    474       "vdup.32 q1, %[additive_sum_offset]\n"
    475       "vpaddl.u16 q8, q8\n"
    476       "vpaddl.u16 q9, q9\n"
    477       "vpadd.u32 d16, d16, d17\n"
    478       "vpadd.u32 d18, d18, d19\n"
    479       "vpadd.u32 d16, d16, d18\n"
    480       "vmul.i32 q8, q8, d0[0]\n"
    481       "vadd.i32 q8, q8, q1\n"
    482       "vst1.32 {d16, d17}, [%[out]:128]\n"
    483       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    484       : [stride] "r"(params.stride),
    485         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    486         [additive_sum_offset] "r"(params.additive_sum_offset)
    487       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    488         "memory");
    489 }
    490 
    491 template <>
    492 inline void Stream<uint8_t, 2, 8, 1, RowMajorWithSum>::Pack(
    493     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    494 #ifdef DEBUG
    495 #ifdef DEBUG_METAGEMM_VERBOSE
    496   std::cout << __FILE__ << "(" << __LINE__
    497             << ") RowMajorWithSum<uint8_t, 2, 8, 1, RowMajorWithSum>::Pack()"
    498             << std::endl
    499             << std::flush;
    500 #endif
    501 #endif
    502   int params_count_copy = params.count;
    503   asm volatile(
    504       "add r0, %[in], %[stride]\n"
    505       "vmov.i16 q8, #0\n"
    506       "vmov.i16 q9, #0\n"
    507 
    508       // Reduce count by leftovers.
    509       "subs %[count], %[count], #1\n"
    510       "beq 2f\n"
    511 
    512       "1:"
    513       "subs %[count], %[count], #8\n"
    514 
    515       // Load Aggregate Store: 2x8.
    516       "vld1.32 {d0}, [%[in]]!\n"
    517       "vld1.32 {d1}, [r0]!\n"
    518       "vaddw.u8 q8, q8, d0\n"
    519       "vaddw.u8 q9, q9, d1\n"
    520       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    521 
    522       "bne 1b\n"
    523 
    524       "2:"
    525 
    526       // Load Aggregate Store: 2x1.
    527       "vmov.i8 d0, #0\n"
    528       "vmov.i8 d1, #0\n"
    529       "vld1.8 {d0[0]}, [%[in]]!\n"
    530       "vld1.8 {d1[0]}, [r0]!\n"
    531       "vaddw.u8 q8, q8, d0\n"
    532       "vaddw.u8 q9, q9, d1\n"
    533       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    534 
    535       // Aggregator Reduction.
    536       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    537       "vdup.32 q1, %[additive_sum_offset]\n"
    538       "vpaddl.u16 q8, q8\n"
    539       "vpaddl.u16 q9, q9\n"
    540       "vpadd.u32 d16, d16, d17\n"
    541       "vpadd.u32 d18, d18, d19\n"
    542       "vpadd.u32 d16, d16, d18\n"
    543       "vmul.i32 q8, q8, d0[0]\n"
    544       "vadd.i32 q8, q8, q1\n"
    545       "vst1.32 {d16, d17}, [%[out]:128]\n"
    546       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    547       : [stride] "r"(params.stride),
    548         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    549         [additive_sum_offset] "r"(params.additive_sum_offset)
    550       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    551         "memory");
    552 }
    553 
    554 template <>
    555 inline void Stream<uint8_t, 2, 8, 2, RowMajorWithSum>::Pack(
    556     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    557 #ifdef DEBUG
    558 #ifdef DEBUG_METAGEMM_VERBOSE
    559   std::cout << __FILE__ << "(" << __LINE__
    560             << ") RowMajorWithSum<uint8_t, 2, 8, 2, RowMajorWithSum>::Pack()"
    561             << std::endl
    562             << std::flush;
    563 #endif
    564 #endif
    565   int params_count_copy = params.count;
    566   asm volatile(
    567       "add r0, %[in], %[stride]\n"
    568       "vmov.i16 q8, #0\n"
    569       "vmov.i16 q9, #0\n"
    570 
    571       // Reduce count by leftovers.
    572       "subs %[count], %[count], #2\n"
    573       "beq 2f\n"
    574 
    575       "1:"
    576       "subs %[count], %[count], #8\n"
    577 
    578       // Load Aggregate Store: 2x8.
    579       "vld1.32 {d0}, [%[in]]!\n"
    580       "vld1.32 {d1}, [r0]!\n"
    581       "vaddw.u8 q8, q8, d0\n"
    582       "vaddw.u8 q9, q9, d1\n"
    583       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    584 
    585       "bne 1b\n"
    586 
    587       "2:"
    588 
    589       // Load Aggregate Store: 2x2.
    590       "vmov.i8 d0, #0\n"
    591       "vmov.i8 d1, #0\n"
    592       "vld1.16 {d0[0]}, [%[in]]!\n"
    593       "vld1.16 {d1[0]}, [r0]!\n"
    594       "vaddw.u8 q8, q8, d0\n"
    595       "vaddw.u8 q9, q9, d1\n"
    596       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    597 
    598       // Aggregator Reduction.
    599       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    600       "vdup.32 q1, %[additive_sum_offset]\n"
    601       "vpaddl.u16 q8, q8\n"
    602       "vpaddl.u16 q9, q9\n"
    603       "vpadd.u32 d16, d16, d17\n"
    604       "vpadd.u32 d18, d18, d19\n"
    605       "vpadd.u32 d16, d16, d18\n"
    606       "vmul.i32 q8, q8, d0[0]\n"
    607       "vadd.i32 q8, q8, q1\n"
    608       "vst1.32 {d16, d17}, [%[out]:128]\n"
    609       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    610       : [stride] "r"(params.stride),
    611         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    612         [additive_sum_offset] "r"(params.additive_sum_offset)
    613       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    614         "memory");
    615 }
    616 
    617 template <>
    618 inline void Stream<uint8_t, 2, 8, 3, RowMajorWithSum>::Pack(
    619     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    620 #ifdef DEBUG
    621 #ifdef DEBUG_METAGEMM_VERBOSE
    622   std::cout << __FILE__ << "(" << __LINE__
    623             << ") RowMajorWithSum<uint8_t, 2, 8, 3, RowMajorWithSum>::Pack()"
    624             << std::endl
    625             << std::flush;
    626 #endif
    627 #endif
    628   int params_count_copy = params.count;
    629   asm volatile(
    630       "add r0, %[in], %[stride]\n"
    631       "vmov.i16 q8, #0\n"
    632       "vmov.i16 q9, #0\n"
    633 
    634       // Reduce count by leftovers.
    635       "subs %[count], %[count], #3\n"
    636       "beq 2f\n"
    637 
    638       "1:"
    639       "subs %[count], %[count], #8\n"
    640 
    641       // Load Aggregate Store: 2x8.
    642       "vld1.32 {d0}, [%[in]]!\n"
    643       "vld1.32 {d1}, [r0]!\n"
    644       "vaddw.u8 q8, q8, d0\n"
    645       "vaddw.u8 q9, q9, d1\n"
    646       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    647 
    648       "bne 1b\n"
    649 
    650       "2:"
    651 
    652       // Load Aggregate Store: 2x3.
    653       "vmov.i8 d0, #0\n"
    654       "vmov.i8 d1, #0\n"
    655       "vld1.16 {d0[0]}, [%[in]]!\n"
    656       "vld1.8 {d0[2]}, [%[in]]!\n"
    657       "vld1.16 {d1[0]}, [r0]!\n"
    658       "vld1.8 {d1[2]}, [r0]!\n"
    659       "vaddw.u8 q8, q8, d0\n"
    660       "vaddw.u8 q9, q9, d1\n"
    661       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    662 
    663       // Aggregator Reduction.
    664       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    665       "vdup.32 q1, %[additive_sum_offset]\n"
    666       "vpaddl.u16 q8, q8\n"
    667       "vpaddl.u16 q9, q9\n"
    668       "vpadd.u32 d16, d16, d17\n"
    669       "vpadd.u32 d18, d18, d19\n"
    670       "vpadd.u32 d16, d16, d18\n"
    671       "vmul.i32 q8, q8, d0[0]\n"
    672       "vadd.i32 q8, q8, q1\n"
    673       "vst1.32 {d16, d17}, [%[out]:128]\n"
    674       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    675       : [stride] "r"(params.stride),
    676         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    677         [additive_sum_offset] "r"(params.additive_sum_offset)
    678       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    679         "memory");
    680 }
    681 
    682 template <>
    683 inline void Stream<uint8_t, 2, 8, 4, RowMajorWithSum>::Pack(
    684     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    685 #ifdef DEBUG
    686 #ifdef DEBUG_METAGEMM_VERBOSE
    687   std::cout << __FILE__ << "(" << __LINE__
    688             << ") RowMajorWithSum<uint8_t, 2, 8, 4, RowMajorWithSum>::Pack()"
    689             << std::endl
    690             << std::flush;
    691 #endif
    692 #endif
    693   int params_count_copy = params.count;
    694   asm volatile(
    695       "add r0, %[in], %[stride]\n"
    696       "vmov.i16 q8, #0\n"
    697       "vmov.i16 q9, #0\n"
    698 
    699       // Reduce count by leftovers.
    700       "subs %[count], %[count], #4\n"
    701       "beq 2f\n"
    702 
    703       "1:"
    704       "subs %[count], %[count], #8\n"
    705 
    706       // Load Aggregate Store: 2x8.
    707       "vld1.32 {d0}, [%[in]]!\n"
    708       "vld1.32 {d1}, [r0]!\n"
    709       "vaddw.u8 q8, q8, d0\n"
    710       "vaddw.u8 q9, q9, d1\n"
    711       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    712 
    713       "bne 1b\n"
    714 
    715       "2:"
    716 
    717       // Load Aggregate Store: 2x4.
    718       "vmov.i8 d0, #0\n"
    719       "vmov.i8 d1, #0\n"
    720       "vld1.32 {d0[0]}, [%[in]]!\n"
    721       "vld1.32 {d1[0]}, [r0]!\n"
    722       "vaddw.u8 q8, q8, d0\n"
    723       "vaddw.u8 q9, q9, d1\n"
    724       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    725 
    726       // Aggregator Reduction.
    727       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    728       "vdup.32 q1, %[additive_sum_offset]\n"
    729       "vpaddl.u16 q8, q8\n"
    730       "vpaddl.u16 q9, q9\n"
    731       "vpadd.u32 d16, d16, d17\n"
    732       "vpadd.u32 d18, d18, d19\n"
    733       "vpadd.u32 d16, d16, d18\n"
    734       "vmul.i32 q8, q8, d0[0]\n"
    735       "vadd.i32 q8, q8, q1\n"
    736       "vst1.32 {d16, d17}, [%[out]:128]\n"
    737       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    738       : [stride] "r"(params.stride),
    739         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    740         [additive_sum_offset] "r"(params.additive_sum_offset)
    741       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    742         "memory");
    743 }
    744 
    745 template <>
    746 inline void Stream<uint8_t, 2, 8, 5, RowMajorWithSum>::Pack(
    747     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    748 #ifdef DEBUG
    749 #ifdef DEBUG_METAGEMM_VERBOSE
    750   std::cout << __FILE__ << "(" << __LINE__
    751             << ") RowMajorWithSum<uint8_t, 2, 8, 5, RowMajorWithSum>::Pack()"
    752             << std::endl
    753             << std::flush;
    754 #endif
    755 #endif
    756   int params_count_copy = params.count;
    757   asm volatile(
    758       "add r0, %[in], %[stride]\n"
    759       "vmov.i16 q8, #0\n"
    760       "vmov.i16 q9, #0\n"
    761 
    762       // Reduce count by leftovers.
    763       "subs %[count], %[count], #5\n"
    764       "beq 2f\n"
    765 
    766       "1:"
    767       "subs %[count], %[count], #8\n"
    768 
    769       // Load Aggregate Store: 2x8.
    770       "vld1.32 {d0}, [%[in]]!\n"
    771       "vld1.32 {d1}, [r0]!\n"
    772       "vaddw.u8 q8, q8, d0\n"
    773       "vaddw.u8 q9, q9, d1\n"
    774       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    775 
    776       "bne 1b\n"
    777 
    778       "2:"
    779 
    780       // Load Aggregate Store: 2x5.
    781       "vmov.i8 d0, #0\n"
    782       "vmov.i8 d1, #0\n"
    783       "vld1.32 {d0[0]}, [%[in]]!\n"
    784       "vld1.8 {d0[4]}, [%[in]]!\n"
    785       "vld1.32 {d1[0]}, [r0]!\n"
    786       "vld1.8 {d1[4]}, [r0]!\n"
    787       "vaddw.u8 q8, q8, d0\n"
    788       "vaddw.u8 q9, q9, d1\n"
    789       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    790 
    791       // Aggregator Reduction.
    792       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    793       "vdup.32 q1, %[additive_sum_offset]\n"
    794       "vpaddl.u16 q8, q8\n"
    795       "vpaddl.u16 q9, q9\n"
    796       "vpadd.u32 d16, d16, d17\n"
    797       "vpadd.u32 d18, d18, d19\n"
    798       "vpadd.u32 d16, d16, d18\n"
    799       "vmul.i32 q8, q8, d0[0]\n"
    800       "vadd.i32 q8, q8, q1\n"
    801       "vst1.32 {d16, d17}, [%[out]:128]\n"
    802       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    803       : [stride] "r"(params.stride),
    804         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    805         [additive_sum_offset] "r"(params.additive_sum_offset)
    806       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    807         "memory");
    808 }
    809 
    810 template <>
    811 inline void Stream<uint8_t, 2, 8, 6, RowMajorWithSum>::Pack(
    812     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    813 #ifdef DEBUG
    814 #ifdef DEBUG_METAGEMM_VERBOSE
    815   std::cout << __FILE__ << "(" << __LINE__
    816             << ") RowMajorWithSum<uint8_t, 2, 8, 6, RowMajorWithSum>::Pack()"
    817             << std::endl
    818             << std::flush;
    819 #endif
    820 #endif
    821   int params_count_copy = params.count;
    822   asm volatile(
    823       "add r0, %[in], %[stride]\n"
    824       "vmov.i16 q8, #0\n"
    825       "vmov.i16 q9, #0\n"
    826 
    827       // Reduce count by leftovers.
    828       "subs %[count], %[count], #6\n"
    829       "beq 2f\n"
    830 
    831       "1:"
    832       "subs %[count], %[count], #8\n"
    833 
    834       // Load Aggregate Store: 2x8.
    835       "vld1.32 {d0}, [%[in]]!\n"
    836       "vld1.32 {d1}, [r0]!\n"
    837       "vaddw.u8 q8, q8, d0\n"
    838       "vaddw.u8 q9, q9, d1\n"
    839       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    840 
    841       "bne 1b\n"
    842 
    843       "2:"
    844 
    845       // Load Aggregate Store: 2x6.
    846       "vmov.i8 d0, #0\n"
    847       "vmov.i8 d1, #0\n"
    848       "vld1.32 {d0[0]}, [%[in]]!\n"
    849       "vld1.16 {d0[2]}, [%[in]]!\n"
    850       "vld1.32 {d1[0]}, [r0]!\n"
    851       "vld1.16 {d1[2]}, [r0]!\n"
    852       "vaddw.u8 q8, q8, d0\n"
    853       "vaddw.u8 q9, q9, d1\n"
    854       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    855 
    856       // Aggregator Reduction.
    857       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    858       "vdup.32 q1, %[additive_sum_offset]\n"
    859       "vpaddl.u16 q8, q8\n"
    860       "vpaddl.u16 q9, q9\n"
    861       "vpadd.u32 d16, d16, d17\n"
    862       "vpadd.u32 d18, d18, d19\n"
    863       "vpadd.u32 d16, d16, d18\n"
    864       "vmul.i32 q8, q8, d0[0]\n"
    865       "vadd.i32 q8, q8, q1\n"
    866       "vst1.32 {d16, d17}, [%[out]:128]\n"
    867       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    868       : [stride] "r"(params.stride),
    869         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    870         [additive_sum_offset] "r"(params.additive_sum_offset)
    871       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    872         "memory");
    873 }
    874 
    875 template <>
    876 inline void Stream<uint8_t, 2, 8, 7, RowMajorWithSum>::Pack(
    877     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    878 #ifdef DEBUG
    879 #ifdef DEBUG_METAGEMM_VERBOSE
    880   std::cout << __FILE__ << "(" << __LINE__
    881             << ") RowMajorWithSum<uint8_t, 2, 8, 7, RowMajorWithSum>::Pack()"
    882             << std::endl
    883             << std::flush;
    884 #endif
    885 #endif
    886   int params_count_copy = params.count;
    887   asm volatile(
    888       "add r0, %[in], %[stride]\n"
    889       "vmov.i16 q8, #0\n"
    890       "vmov.i16 q9, #0\n"
    891 
    892       // Reduce count by leftovers.
    893       "subs %[count], %[count], #7\n"
    894       "beq 2f\n"
    895 
    896       "1:"
    897       "subs %[count], %[count], #8\n"
    898 
    899       // Load Aggregate Store: 2x8.
    900       "vld1.32 {d0}, [%[in]]!\n"
    901       "vld1.32 {d1}, [r0]!\n"
    902       "vaddw.u8 q8, q8, d0\n"
    903       "vaddw.u8 q9, q9, d1\n"
    904       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    905 
    906       "bne 1b\n"
    907 
    908       "2:"
    909 
    910       // Load Aggregate Store: 2x7.
    911       "vmov.i8 d0, #0\n"
    912       "vmov.i8 d1, #0\n"
    913       "vld1.32 {d0[0]}, [%[in]]!\n"
    914       "vld1.16 {d0[2]}, [%[in]]!\n"
    915       "vld1.8 {d0[6]}, [%[in]]!\n"
    916       "vld1.32 {d1[0]}, [r0]!\n"
    917       "vld1.16 {d1[2]}, [r0]!\n"
    918       "vld1.8 {d1[6]}, [r0]!\n"
    919       "vaddw.u8 q8, q8, d0\n"
    920       "vaddw.u8 q9, q9, d1\n"
    921       "vst1.32 {d0, d1}, [%[out]:128]!\n"
    922 
    923       // Aggregator Reduction.
    924       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    925       "vdup.32 q1, %[additive_sum_offset]\n"
    926       "vpaddl.u16 q8, q8\n"
    927       "vpaddl.u16 q9, q9\n"
    928       "vpadd.u32 d16, d16, d17\n"
    929       "vpadd.u32 d18, d18, d19\n"
    930       "vpadd.u32 d16, d16, d18\n"
    931       "vmul.i32 q8, q8, d0[0]\n"
    932       "vadd.i32 q8, q8, q1\n"
    933       "vst1.32 {d16, d17}, [%[out]:128]\n"
    934       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    935       : [stride] "r"(params.stride),
    936         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    937         [additive_sum_offset] "r"(params.additive_sum_offset)
    938       : "r0", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc",
    939         "memory");
    940 }
    941 
    942 template <>
    943 inline void Stream<uint8_t, 3, 8, 0, RowMajorWithSum>::Pack(
    944     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
    945 #ifdef DEBUG
    946 #ifdef DEBUG_METAGEMM_VERBOSE
    947   std::cout << __FILE__ << "(" << __LINE__
    948             << ") RowMajorWithSum<uint8_t, 3, 8, 0, RowMajorWithSum>::Pack()"
    949             << std::endl
    950             << std::flush;
    951 #endif
    952 #endif
    953   int params_count_copy = params.count;
    954   asm volatile(
    955       "add r0, %[in], %[stride]\n"
    956       "add r1, r0, %[stride]\n"
    957       "vmov.i16 q8, #0\n"
    958       "vmov.i16 q9, #0\n"
    959       "vmov.i16 q10, #0\n"
    960 
    961       "1:"
    962       "subs %[count], %[count], #8\n"
    963 
    964       // Load Aggregate Store: 3x8.
    965       "vld1.32 {d0}, [%[in]]!\n"
    966       "vld1.32 {d1}, [r0]!\n"
    967       "vld1.32 {d2}, [r1]!\n"
    968       "vaddw.u8 q8, q8, d0\n"
    969       "vaddw.u8 q9, q9, d1\n"
    970       "vaddw.u8 q10, q10, d2\n"
    971       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
    972 
    973       "bne 1b\n"
    974 
    975       // Aggregator Reduction.
    976       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
    977       "vdup.32 q1, %[additive_sum_offset]\n"
    978       "vpaddl.u16 q8, q8\n"
    979       "vpaddl.u16 q9, q9\n"
    980       "vpaddl.u16 q10, q10\n"
    981       "vpadd.u32 d16, d16, d17\n"
    982       "vpadd.u32 d18, d18, d19\n"
    983       "vpadd.u32 d20, d20, d21\n"
    984       "vpadd.u32 d16, d16, d18\n"
    985       "vpadd.u32 d17, d20, d20\n"
    986       "vmul.i32 q8, q8, d0[0]\n"
    987       "vadd.i32 q8, q8, q1\n"
    988       "vst1.32 {d16, d17}, [%[out]:64]\n"
    989       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
    990       : [stride] "r"(params.stride),
    991         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
    992         [additive_sum_offset] "r"(params.additive_sum_offset)
    993       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
    994         "d21", "cc", "memory");
    995 }
    996 
    997 template <>
    998 inline void Stream<uint8_t, 3, 8, 1, RowMajorWithSum>::Pack(
    999     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1000 #ifdef DEBUG
   1001 #ifdef DEBUG_METAGEMM_VERBOSE
   1002   std::cout << __FILE__ << "(" << __LINE__
   1003             << ") RowMajorWithSum<uint8_t, 3, 8, 1, RowMajorWithSum>::Pack()"
   1004             << std::endl
   1005             << std::flush;
   1006 #endif
   1007 #endif
   1008   int params_count_copy = params.count;
   1009   asm volatile(
   1010       "add r0, %[in], %[stride]\n"
   1011       "add r1, r0, %[stride]\n"
   1012       "vmov.i16 q8, #0\n"
   1013       "vmov.i16 q9, #0\n"
   1014       "vmov.i16 q10, #0\n"
   1015 
   1016       // Reduce count by leftovers.
   1017       "subs %[count], %[count], #1\n"
   1018       "beq 2f\n"
   1019 
   1020       "1:"
   1021       "subs %[count], %[count], #8\n"
   1022 
   1023       // Load Aggregate Store: 3x8.
   1024       "vld1.32 {d0}, [%[in]]!\n"
   1025       "vld1.32 {d1}, [r0]!\n"
   1026       "vld1.32 {d2}, [r1]!\n"
   1027       "vaddw.u8 q8, q8, d0\n"
   1028       "vaddw.u8 q9, q9, d1\n"
   1029       "vaddw.u8 q10, q10, d2\n"
   1030       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1031 
   1032       "bne 1b\n"
   1033 
   1034       "2:"
   1035 
   1036       // Load Aggregate Store: 3x1.
   1037       "vmov.i8 d0, #0\n"
   1038       "vmov.i8 d1, #0\n"
   1039       "vmov.i8 d2, #0\n"
   1040       "vld1.8 {d0[0]}, [%[in]]!\n"
   1041       "vld1.8 {d1[0]}, [r0]!\n"
   1042       "vld1.8 {d2[0]}, [r1]!\n"
   1043       "vaddw.u8 q8, q8, d0\n"
   1044       "vaddw.u8 q9, q9, d1\n"
   1045       "vaddw.u8 q10, q10, d2\n"
   1046       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1047 
   1048       // Aggregator Reduction.
   1049       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1050       "vdup.32 q1, %[additive_sum_offset]\n"
   1051       "vpaddl.u16 q8, q8\n"
   1052       "vpaddl.u16 q9, q9\n"
   1053       "vpaddl.u16 q10, q10\n"
   1054       "vpadd.u32 d16, d16, d17\n"
   1055       "vpadd.u32 d18, d18, d19\n"
   1056       "vpadd.u32 d20, d20, d21\n"
   1057       "vpadd.u32 d16, d16, d18\n"
   1058       "vpadd.u32 d17, d20, d20\n"
   1059       "vmul.i32 q8, q8, d0[0]\n"
   1060       "vadd.i32 q8, q8, q1\n"
   1061       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1062       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1063       : [stride] "r"(params.stride),
   1064         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1065         [additive_sum_offset] "r"(params.additive_sum_offset)
   1066       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1067         "d21", "cc", "memory");
   1068 }
   1069 
   1070 template <>
   1071 inline void Stream<uint8_t, 3, 8, 2, RowMajorWithSum>::Pack(
   1072     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1073 #ifdef DEBUG
   1074 #ifdef DEBUG_METAGEMM_VERBOSE
   1075   std::cout << __FILE__ << "(" << __LINE__
   1076             << ") RowMajorWithSum<uint8_t, 3, 8, 2, RowMajorWithSum>::Pack()"
   1077             << std::endl
   1078             << std::flush;
   1079 #endif
   1080 #endif
   1081   int params_count_copy = params.count;
   1082   asm volatile(
   1083       "add r0, %[in], %[stride]\n"
   1084       "add r1, r0, %[stride]\n"
   1085       "vmov.i16 q8, #0\n"
   1086       "vmov.i16 q9, #0\n"
   1087       "vmov.i16 q10, #0\n"
   1088 
   1089       // Reduce count by leftovers.
   1090       "subs %[count], %[count], #2\n"
   1091       "beq 2f\n"
   1092 
   1093       "1:"
   1094       "subs %[count], %[count], #8\n"
   1095 
   1096       // Load Aggregate Store: 3x8.
   1097       "vld1.32 {d0}, [%[in]]!\n"
   1098       "vld1.32 {d1}, [r0]!\n"
   1099       "vld1.32 {d2}, [r1]!\n"
   1100       "vaddw.u8 q8, q8, d0\n"
   1101       "vaddw.u8 q9, q9, d1\n"
   1102       "vaddw.u8 q10, q10, d2\n"
   1103       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1104 
   1105       "bne 1b\n"
   1106 
   1107       "2:"
   1108 
   1109       // Load Aggregate Store: 3x2.
   1110       "vmov.i8 d0, #0\n"
   1111       "vmov.i8 d1, #0\n"
   1112       "vmov.i8 d2, #0\n"
   1113       "vld1.16 {d0[0]}, [%[in]]!\n"
   1114       "vld1.16 {d1[0]}, [r0]!\n"
   1115       "vld1.16 {d2[0]}, [r1]!\n"
   1116       "vaddw.u8 q8, q8, d0\n"
   1117       "vaddw.u8 q9, q9, d1\n"
   1118       "vaddw.u8 q10, q10, d2\n"
   1119       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1120 
   1121       // Aggregator Reduction.
   1122       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1123       "vdup.32 q1, %[additive_sum_offset]\n"
   1124       "vpaddl.u16 q8, q8\n"
   1125       "vpaddl.u16 q9, q9\n"
   1126       "vpaddl.u16 q10, q10\n"
   1127       "vpadd.u32 d16, d16, d17\n"
   1128       "vpadd.u32 d18, d18, d19\n"
   1129       "vpadd.u32 d20, d20, d21\n"
   1130       "vpadd.u32 d16, d16, d18\n"
   1131       "vpadd.u32 d17, d20, d20\n"
   1132       "vmul.i32 q8, q8, d0[0]\n"
   1133       "vadd.i32 q8, q8, q1\n"
   1134       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1135       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1136       : [stride] "r"(params.stride),
   1137         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1138         [additive_sum_offset] "r"(params.additive_sum_offset)
   1139       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1140         "d21", "cc", "memory");
   1141 }
   1142 
   1143 template <>
   1144 inline void Stream<uint8_t, 3, 8, 3, RowMajorWithSum>::Pack(
   1145     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1146 #ifdef DEBUG
   1147 #ifdef DEBUG_METAGEMM_VERBOSE
   1148   std::cout << __FILE__ << "(" << __LINE__
   1149             << ") RowMajorWithSum<uint8_t, 3, 8, 3, RowMajorWithSum>::Pack()"
   1150             << std::endl
   1151             << std::flush;
   1152 #endif
   1153 #endif
   1154   int params_count_copy = params.count;
   1155   asm volatile(
   1156       "add r0, %[in], %[stride]\n"
   1157       "add r1, r0, %[stride]\n"
   1158       "vmov.i16 q8, #0\n"
   1159       "vmov.i16 q9, #0\n"
   1160       "vmov.i16 q10, #0\n"
   1161 
   1162       // Reduce count by leftovers.
   1163       "subs %[count], %[count], #3\n"
   1164       "beq 2f\n"
   1165 
   1166       "1:"
   1167       "subs %[count], %[count], #8\n"
   1168 
   1169       // Load Aggregate Store: 3x8.
   1170       "vld1.32 {d0}, [%[in]]!\n"
   1171       "vld1.32 {d1}, [r0]!\n"
   1172       "vld1.32 {d2}, [r1]!\n"
   1173       "vaddw.u8 q8, q8, d0\n"
   1174       "vaddw.u8 q9, q9, d1\n"
   1175       "vaddw.u8 q10, q10, d2\n"
   1176       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1177 
   1178       "bne 1b\n"
   1179 
   1180       "2:"
   1181 
   1182       // Load Aggregate Store: 3x3.
   1183       "vmov.i8 d0, #0\n"
   1184       "vmov.i8 d1, #0\n"
   1185       "vmov.i8 d2, #0\n"
   1186       "vld1.16 {d0[0]}, [%[in]]!\n"
   1187       "vld1.8 {d0[2]}, [%[in]]!\n"
   1188       "vld1.16 {d1[0]}, [r0]!\n"
   1189       "vld1.8 {d1[2]}, [r0]!\n"
   1190       "vld1.16 {d2[0]}, [r1]!\n"
   1191       "vld1.8 {d2[2]}, [r1]!\n"
   1192       "vaddw.u8 q8, q8, d0\n"
   1193       "vaddw.u8 q9, q9, d1\n"
   1194       "vaddw.u8 q10, q10, d2\n"
   1195       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1196 
   1197       // Aggregator Reduction.
   1198       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1199       "vdup.32 q1, %[additive_sum_offset]\n"
   1200       "vpaddl.u16 q8, q8\n"
   1201       "vpaddl.u16 q9, q9\n"
   1202       "vpaddl.u16 q10, q10\n"
   1203       "vpadd.u32 d16, d16, d17\n"
   1204       "vpadd.u32 d18, d18, d19\n"
   1205       "vpadd.u32 d20, d20, d21\n"
   1206       "vpadd.u32 d16, d16, d18\n"
   1207       "vpadd.u32 d17, d20, d20\n"
   1208       "vmul.i32 q8, q8, d0[0]\n"
   1209       "vadd.i32 q8, q8, q1\n"
   1210       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1211       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1212       : [stride] "r"(params.stride),
   1213         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1214         [additive_sum_offset] "r"(params.additive_sum_offset)
   1215       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1216         "d21", "cc", "memory");
   1217 }
   1218 
   1219 template <>
   1220 inline void Stream<uint8_t, 3, 8, 4, RowMajorWithSum>::Pack(
   1221     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1222 #ifdef DEBUG
   1223 #ifdef DEBUG_METAGEMM_VERBOSE
   1224   std::cout << __FILE__ << "(" << __LINE__
   1225             << ") RowMajorWithSum<uint8_t, 3, 8, 4, RowMajorWithSum>::Pack()"
   1226             << std::endl
   1227             << std::flush;
   1228 #endif
   1229 #endif
   1230   int params_count_copy = params.count;
   1231   asm volatile(
   1232       "add r0, %[in], %[stride]\n"
   1233       "add r1, r0, %[stride]\n"
   1234       "vmov.i16 q8, #0\n"
   1235       "vmov.i16 q9, #0\n"
   1236       "vmov.i16 q10, #0\n"
   1237 
   1238       // Reduce count by leftovers.
   1239       "subs %[count], %[count], #4\n"
   1240       "beq 2f\n"
   1241 
   1242       "1:"
   1243       "subs %[count], %[count], #8\n"
   1244 
   1245       // Load Aggregate Store: 3x8.
   1246       "vld1.32 {d0}, [%[in]]!\n"
   1247       "vld1.32 {d1}, [r0]!\n"
   1248       "vld1.32 {d2}, [r1]!\n"
   1249       "vaddw.u8 q8, q8, d0\n"
   1250       "vaddw.u8 q9, q9, d1\n"
   1251       "vaddw.u8 q10, q10, d2\n"
   1252       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1253 
   1254       "bne 1b\n"
   1255 
   1256       "2:"
   1257 
   1258       // Load Aggregate Store: 3x4.
   1259       "vmov.i8 d0, #0\n"
   1260       "vmov.i8 d1, #0\n"
   1261       "vmov.i8 d2, #0\n"
   1262       "vld1.32 {d0[0]}, [%[in]]!\n"
   1263       "vld1.32 {d1[0]}, [r0]!\n"
   1264       "vld1.32 {d2[0]}, [r1]!\n"
   1265       "vaddw.u8 q8, q8, d0\n"
   1266       "vaddw.u8 q9, q9, d1\n"
   1267       "vaddw.u8 q10, q10, d2\n"
   1268       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1269 
   1270       // Aggregator Reduction.
   1271       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1272       "vdup.32 q1, %[additive_sum_offset]\n"
   1273       "vpaddl.u16 q8, q8\n"
   1274       "vpaddl.u16 q9, q9\n"
   1275       "vpaddl.u16 q10, q10\n"
   1276       "vpadd.u32 d16, d16, d17\n"
   1277       "vpadd.u32 d18, d18, d19\n"
   1278       "vpadd.u32 d20, d20, d21\n"
   1279       "vpadd.u32 d16, d16, d18\n"
   1280       "vpadd.u32 d17, d20, d20\n"
   1281       "vmul.i32 q8, q8, d0[0]\n"
   1282       "vadd.i32 q8, q8, q1\n"
   1283       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1284       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1285       : [stride] "r"(params.stride),
   1286         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1287         [additive_sum_offset] "r"(params.additive_sum_offset)
   1288       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1289         "d21", "cc", "memory");
   1290 }
   1291 
   1292 template <>
   1293 inline void Stream<uint8_t, 3, 8, 5, RowMajorWithSum>::Pack(
   1294     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1295 #ifdef DEBUG
   1296 #ifdef DEBUG_METAGEMM_VERBOSE
   1297   std::cout << __FILE__ << "(" << __LINE__
   1298             << ") RowMajorWithSum<uint8_t, 3, 8, 5, RowMajorWithSum>::Pack()"
   1299             << std::endl
   1300             << std::flush;
   1301 #endif
   1302 #endif
   1303   int params_count_copy = params.count;
   1304   asm volatile(
   1305       "add r0, %[in], %[stride]\n"
   1306       "add r1, r0, %[stride]\n"
   1307       "vmov.i16 q8, #0\n"
   1308       "vmov.i16 q9, #0\n"
   1309       "vmov.i16 q10, #0\n"
   1310 
   1311       // Reduce count by leftovers.
   1312       "subs %[count], %[count], #5\n"
   1313       "beq 2f\n"
   1314 
   1315       "1:"
   1316       "subs %[count], %[count], #8\n"
   1317 
   1318       // Load Aggregate Store: 3x8.
   1319       "vld1.32 {d0}, [%[in]]!\n"
   1320       "vld1.32 {d1}, [r0]!\n"
   1321       "vld1.32 {d2}, [r1]!\n"
   1322       "vaddw.u8 q8, q8, d0\n"
   1323       "vaddw.u8 q9, q9, d1\n"
   1324       "vaddw.u8 q10, q10, d2\n"
   1325       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1326 
   1327       "bne 1b\n"
   1328 
   1329       "2:"
   1330 
   1331       // Load Aggregate Store: 3x5.
   1332       "vmov.i8 d0, #0\n"
   1333       "vmov.i8 d1, #0\n"
   1334       "vmov.i8 d2, #0\n"
   1335       "vld1.32 {d0[0]}, [%[in]]!\n"
   1336       "vld1.8 {d0[4]}, [%[in]]!\n"
   1337       "vld1.32 {d1[0]}, [r0]!\n"
   1338       "vld1.8 {d1[4]}, [r0]!\n"
   1339       "vld1.32 {d2[0]}, [r1]!\n"
   1340       "vld1.8 {d2[4]}, [r1]!\n"
   1341       "vaddw.u8 q8, q8, d0\n"
   1342       "vaddw.u8 q9, q9, d1\n"
   1343       "vaddw.u8 q10, q10, d2\n"
   1344       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1345 
   1346       // Aggregator Reduction.
   1347       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1348       "vdup.32 q1, %[additive_sum_offset]\n"
   1349       "vpaddl.u16 q8, q8\n"
   1350       "vpaddl.u16 q9, q9\n"
   1351       "vpaddl.u16 q10, q10\n"
   1352       "vpadd.u32 d16, d16, d17\n"
   1353       "vpadd.u32 d18, d18, d19\n"
   1354       "vpadd.u32 d20, d20, d21\n"
   1355       "vpadd.u32 d16, d16, d18\n"
   1356       "vpadd.u32 d17, d20, d20\n"
   1357       "vmul.i32 q8, q8, d0[0]\n"
   1358       "vadd.i32 q8, q8, q1\n"
   1359       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1360       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1361       : [stride] "r"(params.stride),
   1362         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1363         [additive_sum_offset] "r"(params.additive_sum_offset)
   1364       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1365         "d21", "cc", "memory");
   1366 }
   1367 
   1368 template <>
   1369 inline void Stream<uint8_t, 3, 8, 6, RowMajorWithSum>::Pack(
   1370     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1371 #ifdef DEBUG
   1372 #ifdef DEBUG_METAGEMM_VERBOSE
   1373   std::cout << __FILE__ << "(" << __LINE__
   1374             << ") RowMajorWithSum<uint8_t, 3, 8, 6, RowMajorWithSum>::Pack()"
   1375             << std::endl
   1376             << std::flush;
   1377 #endif
   1378 #endif
   1379   int params_count_copy = params.count;
   1380   asm volatile(
   1381       "add r0, %[in], %[stride]\n"
   1382       "add r1, r0, %[stride]\n"
   1383       "vmov.i16 q8, #0\n"
   1384       "vmov.i16 q9, #0\n"
   1385       "vmov.i16 q10, #0\n"
   1386 
   1387       // Reduce count by leftovers.
   1388       "subs %[count], %[count], #6\n"
   1389       "beq 2f\n"
   1390 
   1391       "1:"
   1392       "subs %[count], %[count], #8\n"
   1393 
   1394       // Load Aggregate Store: 3x8.
   1395       "vld1.32 {d0}, [%[in]]!\n"
   1396       "vld1.32 {d1}, [r0]!\n"
   1397       "vld1.32 {d2}, [r1]!\n"
   1398       "vaddw.u8 q8, q8, d0\n"
   1399       "vaddw.u8 q9, q9, d1\n"
   1400       "vaddw.u8 q10, q10, d2\n"
   1401       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1402 
   1403       "bne 1b\n"
   1404 
   1405       "2:"
   1406 
   1407       // Load Aggregate Store: 3x6.
   1408       "vmov.i8 d0, #0\n"
   1409       "vmov.i8 d1, #0\n"
   1410       "vmov.i8 d2, #0\n"
   1411       "vld1.32 {d0[0]}, [%[in]]!\n"
   1412       "vld1.16 {d0[2]}, [%[in]]!\n"
   1413       "vld1.32 {d1[0]}, [r0]!\n"
   1414       "vld1.16 {d1[2]}, [r0]!\n"
   1415       "vld1.32 {d2[0]}, [r1]!\n"
   1416       "vld1.16 {d2[2]}, [r1]!\n"
   1417       "vaddw.u8 q8, q8, d0\n"
   1418       "vaddw.u8 q9, q9, d1\n"
   1419       "vaddw.u8 q10, q10, d2\n"
   1420       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1421 
   1422       // Aggregator Reduction.
   1423       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1424       "vdup.32 q1, %[additive_sum_offset]\n"
   1425       "vpaddl.u16 q8, q8\n"
   1426       "vpaddl.u16 q9, q9\n"
   1427       "vpaddl.u16 q10, q10\n"
   1428       "vpadd.u32 d16, d16, d17\n"
   1429       "vpadd.u32 d18, d18, d19\n"
   1430       "vpadd.u32 d20, d20, d21\n"
   1431       "vpadd.u32 d16, d16, d18\n"
   1432       "vpadd.u32 d17, d20, d20\n"
   1433       "vmul.i32 q8, q8, d0[0]\n"
   1434       "vadd.i32 q8, q8, q1\n"
   1435       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1436       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1437       : [stride] "r"(params.stride),
   1438         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1439         [additive_sum_offset] "r"(params.additive_sum_offset)
   1440       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1441         "d21", "cc", "memory");
   1442 }
   1443 
   1444 template <>
   1445 inline void Stream<uint8_t, 3, 8, 7, RowMajorWithSum>::Pack(
   1446     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1447 #ifdef DEBUG
   1448 #ifdef DEBUG_METAGEMM_VERBOSE
   1449   std::cout << __FILE__ << "(" << __LINE__
   1450             << ") RowMajorWithSum<uint8_t, 3, 8, 7, RowMajorWithSum>::Pack()"
   1451             << std::endl
   1452             << std::flush;
   1453 #endif
   1454 #endif
   1455   int params_count_copy = params.count;
   1456   asm volatile(
   1457       "add r0, %[in], %[stride]\n"
   1458       "add r1, r0, %[stride]\n"
   1459       "vmov.i16 q8, #0\n"
   1460       "vmov.i16 q9, #0\n"
   1461       "vmov.i16 q10, #0\n"
   1462 
   1463       // Reduce count by leftovers.
   1464       "subs %[count], %[count], #7\n"
   1465       "beq 2f\n"
   1466 
   1467       "1:"
   1468       "subs %[count], %[count], #8\n"
   1469 
   1470       // Load Aggregate Store: 3x8.
   1471       "vld1.32 {d0}, [%[in]]!\n"
   1472       "vld1.32 {d1}, [r0]!\n"
   1473       "vld1.32 {d2}, [r1]!\n"
   1474       "vaddw.u8 q8, q8, d0\n"
   1475       "vaddw.u8 q9, q9, d1\n"
   1476       "vaddw.u8 q10, q10, d2\n"
   1477       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1478 
   1479       "bne 1b\n"
   1480 
   1481       "2:"
   1482 
   1483       // Load Aggregate Store: 3x7.
   1484       "vmov.i8 d0, #0\n"
   1485       "vmov.i8 d1, #0\n"
   1486       "vmov.i8 d2, #0\n"
   1487       "vld1.32 {d0[0]}, [%[in]]!\n"
   1488       "vld1.16 {d0[2]}, [%[in]]!\n"
   1489       "vld1.8 {d0[6]}, [%[in]]!\n"
   1490       "vld1.32 {d1[0]}, [r0]!\n"
   1491       "vld1.16 {d1[2]}, [r0]!\n"
   1492       "vld1.8 {d1[6]}, [r0]!\n"
   1493       "vld1.32 {d2[0]}, [r1]!\n"
   1494       "vld1.16 {d2[2]}, [r1]!\n"
   1495       "vld1.8 {d2[6]}, [r1]!\n"
   1496       "vaddw.u8 q8, q8, d0\n"
   1497       "vaddw.u8 q9, q9, d1\n"
   1498       "vaddw.u8 q10, q10, d2\n"
   1499       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   1500 
   1501       // Aggregator Reduction.
   1502       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1503       "vdup.32 q1, %[additive_sum_offset]\n"
   1504       "vpaddl.u16 q8, q8\n"
   1505       "vpaddl.u16 q9, q9\n"
   1506       "vpaddl.u16 q10, q10\n"
   1507       "vpadd.u32 d16, d16, d17\n"
   1508       "vpadd.u32 d18, d18, d19\n"
   1509       "vpadd.u32 d20, d20, d21\n"
   1510       "vpadd.u32 d16, d16, d18\n"
   1511       "vpadd.u32 d17, d20, d20\n"
   1512       "vmul.i32 q8, q8, d0[0]\n"
   1513       "vadd.i32 q8, q8, q1\n"
   1514       "vst1.32 {d16, d17}, [%[out]:64]\n"
   1515       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1516       : [stride] "r"(params.stride),
   1517         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1518         [additive_sum_offset] "r"(params.additive_sum_offset)
   1519       : "r0", "r1", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20",
   1520         "d21", "cc", "memory");
   1521 }
   1522 
   1523 template <>
   1524 inline void Stream<uint8_t, 4, 8, 0, RowMajorWithSum>::Pack(
   1525     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1526 #ifdef DEBUG
   1527 #ifdef DEBUG_METAGEMM_VERBOSE
   1528   std::cout << __FILE__ << "(" << __LINE__
   1529             << ") RowMajorWithSum<uint8_t, 4, 8, 0, RowMajorWithSum>::Pack()"
   1530             << std::endl
   1531             << std::flush;
   1532 #endif
   1533 #endif
   1534   int params_count_copy = params.count;
   1535   asm volatile(
   1536       "add r0, %[in], %[stride]\n"
   1537       "add r1, r0, %[stride]\n"
   1538       "add r2, r1, %[stride]\n"
   1539       "vmov.i16 q8, #0\n"
   1540       "vmov.i16 q9, #0\n"
   1541       "vmov.i16 q10, #0\n"
   1542       "vmov.i16 q11, #0\n"
   1543 
   1544       "1:"
   1545       "subs %[count], %[count], #8\n"
   1546 
   1547       // Load Aggregate Store: 4x8.
   1548       "vld1.32 {d0}, [%[in]]!\n"
   1549       "vld1.32 {d1}, [r0]!\n"
   1550       "vld1.32 {d2}, [r1]!\n"
   1551       "vld1.32 {d3}, [r2]!\n"
   1552       "vaddw.u8 q8, q8, d0\n"
   1553       "vaddw.u8 q9, q9, d1\n"
   1554       "vaddw.u8 q10, q10, d2\n"
   1555       "vaddw.u8 q11, q11, d3\n"
   1556       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1557 
   1558       "bne 1b\n"
   1559 
   1560       // Aggregator Reduction.
   1561       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1562       "vdup.32 q1, %[additive_sum_offset]\n"
   1563       "vpaddl.u16 q8, q8\n"
   1564       "vpaddl.u16 q9, q9\n"
   1565       "vpaddl.u16 q10, q10\n"
   1566       "vpaddl.u16 q11, q11\n"
   1567       "vpadd.u32 d16, d16, d17\n"
   1568       "vpadd.u32 d18, d18, d19\n"
   1569       "vpadd.u32 d20, d20, d21\n"
   1570       "vpadd.u32 d22, d22, d23\n"
   1571       "vpadd.u32 d16, d16, d18\n"
   1572       "vpadd.u32 d17, d20, d22\n"
   1573       "vmul.i32 q8, q8, d0[0]\n"
   1574       "vadd.i32 q8, q8, q1\n"
   1575       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1576       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1577       : [stride] "r"(params.stride),
   1578         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1579         [additive_sum_offset] "r"(params.additive_sum_offset)
   1580       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1581         "d20", "d21", "d22", "d23", "cc", "memory");
   1582 }
   1583 
   1584 template <>
   1585 inline void Stream<uint8_t, 4, 8, 1, RowMajorWithSum>::Pack(
   1586     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1587 #ifdef DEBUG
   1588 #ifdef DEBUG_METAGEMM_VERBOSE
   1589   std::cout << __FILE__ << "(" << __LINE__
   1590             << ") RowMajorWithSum<uint8_t, 4, 8, 1, RowMajorWithSum>::Pack()"
   1591             << std::endl
   1592             << std::flush;
   1593 #endif
   1594 #endif
   1595   int params_count_copy = params.count;
   1596   asm volatile(
   1597       "add r0, %[in], %[stride]\n"
   1598       "add r1, r0, %[stride]\n"
   1599       "add r2, r1, %[stride]\n"
   1600       "vmov.i16 q8, #0\n"
   1601       "vmov.i16 q9, #0\n"
   1602       "vmov.i16 q10, #0\n"
   1603       "vmov.i16 q11, #0\n"
   1604 
   1605       // Reduce count by leftovers.
   1606       "subs %[count], %[count], #1\n"
   1607       "beq 2f\n"
   1608 
   1609       "1:"
   1610       "subs %[count], %[count], #8\n"
   1611 
   1612       // Load Aggregate Store: 4x8.
   1613       "vld1.32 {d0}, [%[in]]!\n"
   1614       "vld1.32 {d1}, [r0]!\n"
   1615       "vld1.32 {d2}, [r1]!\n"
   1616       "vld1.32 {d3}, [r2]!\n"
   1617       "vaddw.u8 q8, q8, d0\n"
   1618       "vaddw.u8 q9, q9, d1\n"
   1619       "vaddw.u8 q10, q10, d2\n"
   1620       "vaddw.u8 q11, q11, d3\n"
   1621       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1622 
   1623       "bne 1b\n"
   1624 
   1625       "2:"
   1626 
   1627       // Load Aggregate Store: 4x1.
   1628       "vmov.i8 d0, #0\n"
   1629       "vmov.i8 d1, #0\n"
   1630       "vmov.i8 d2, #0\n"
   1631       "vmov.i8 d3, #0\n"
   1632       "vld1.8 {d0[0]}, [%[in]]!\n"
   1633       "vld1.8 {d1[0]}, [r0]!\n"
   1634       "vld1.8 {d2[0]}, [r1]!\n"
   1635       "vld1.8 {d3[0]}, [r2]!\n"
   1636       "vaddw.u8 q8, q8, d0\n"
   1637       "vaddw.u8 q9, q9, d1\n"
   1638       "vaddw.u8 q10, q10, d2\n"
   1639       "vaddw.u8 q11, q11, d3\n"
   1640       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1641 
   1642       // Aggregator Reduction.
   1643       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1644       "vdup.32 q1, %[additive_sum_offset]\n"
   1645       "vpaddl.u16 q8, q8\n"
   1646       "vpaddl.u16 q9, q9\n"
   1647       "vpaddl.u16 q10, q10\n"
   1648       "vpaddl.u16 q11, q11\n"
   1649       "vpadd.u32 d16, d16, d17\n"
   1650       "vpadd.u32 d18, d18, d19\n"
   1651       "vpadd.u32 d20, d20, d21\n"
   1652       "vpadd.u32 d22, d22, d23\n"
   1653       "vpadd.u32 d16, d16, d18\n"
   1654       "vpadd.u32 d17, d20, d22\n"
   1655       "vmul.i32 q8, q8, d0[0]\n"
   1656       "vadd.i32 q8, q8, q1\n"
   1657       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1658       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1659       : [stride] "r"(params.stride),
   1660         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1661         [additive_sum_offset] "r"(params.additive_sum_offset)
   1662       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1663         "d20", "d21", "d22", "d23", "cc", "memory");
   1664 }
   1665 
   1666 template <>
   1667 inline void Stream<uint8_t, 4, 8, 2, RowMajorWithSum>::Pack(
   1668     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1669 #ifdef DEBUG
   1670 #ifdef DEBUG_METAGEMM_VERBOSE
   1671   std::cout << __FILE__ << "(" << __LINE__
   1672             << ") RowMajorWithSum<uint8_t, 4, 8, 2, RowMajorWithSum>::Pack()"
   1673             << std::endl
   1674             << std::flush;
   1675 #endif
   1676 #endif
   1677   int params_count_copy = params.count;
   1678   asm volatile(
   1679       "add r0, %[in], %[stride]\n"
   1680       "add r1, r0, %[stride]\n"
   1681       "add r2, r1, %[stride]\n"
   1682       "vmov.i16 q8, #0\n"
   1683       "vmov.i16 q9, #0\n"
   1684       "vmov.i16 q10, #0\n"
   1685       "vmov.i16 q11, #0\n"
   1686 
   1687       // Reduce count by leftovers.
   1688       "subs %[count], %[count], #2\n"
   1689       "beq 2f\n"
   1690 
   1691       "1:"
   1692       "subs %[count], %[count], #8\n"
   1693 
   1694       // Load Aggregate Store: 4x8.
   1695       "vld1.32 {d0}, [%[in]]!\n"
   1696       "vld1.32 {d1}, [r0]!\n"
   1697       "vld1.32 {d2}, [r1]!\n"
   1698       "vld1.32 {d3}, [r2]!\n"
   1699       "vaddw.u8 q8, q8, d0\n"
   1700       "vaddw.u8 q9, q9, d1\n"
   1701       "vaddw.u8 q10, q10, d2\n"
   1702       "vaddw.u8 q11, q11, d3\n"
   1703       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1704 
   1705       "bne 1b\n"
   1706 
   1707       "2:"
   1708 
   1709       // Load Aggregate Store: 4x2.
   1710       "vmov.i8 d0, #0\n"
   1711       "vmov.i8 d1, #0\n"
   1712       "vmov.i8 d2, #0\n"
   1713       "vmov.i8 d3, #0\n"
   1714       "vld1.16 {d0[0]}, [%[in]]!\n"
   1715       "vld1.16 {d1[0]}, [r0]!\n"
   1716       "vld1.16 {d2[0]}, [r1]!\n"
   1717       "vld1.16 {d3[0]}, [r2]!\n"
   1718       "vaddw.u8 q8, q8, d0\n"
   1719       "vaddw.u8 q9, q9, d1\n"
   1720       "vaddw.u8 q10, q10, d2\n"
   1721       "vaddw.u8 q11, q11, d3\n"
   1722       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1723 
   1724       // Aggregator Reduction.
   1725       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1726       "vdup.32 q1, %[additive_sum_offset]\n"
   1727       "vpaddl.u16 q8, q8\n"
   1728       "vpaddl.u16 q9, q9\n"
   1729       "vpaddl.u16 q10, q10\n"
   1730       "vpaddl.u16 q11, q11\n"
   1731       "vpadd.u32 d16, d16, d17\n"
   1732       "vpadd.u32 d18, d18, d19\n"
   1733       "vpadd.u32 d20, d20, d21\n"
   1734       "vpadd.u32 d22, d22, d23\n"
   1735       "vpadd.u32 d16, d16, d18\n"
   1736       "vpadd.u32 d17, d20, d22\n"
   1737       "vmul.i32 q8, q8, d0[0]\n"
   1738       "vadd.i32 q8, q8, q1\n"
   1739       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1740       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1741       : [stride] "r"(params.stride),
   1742         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1743         [additive_sum_offset] "r"(params.additive_sum_offset)
   1744       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1745         "d20", "d21", "d22", "d23", "cc", "memory");
   1746 }
   1747 
   1748 template <>
   1749 inline void Stream<uint8_t, 4, 8, 3, RowMajorWithSum>::Pack(
   1750     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1751 #ifdef DEBUG
   1752 #ifdef DEBUG_METAGEMM_VERBOSE
   1753   std::cout << __FILE__ << "(" << __LINE__
   1754             << ") RowMajorWithSum<uint8_t, 4, 8, 3, RowMajorWithSum>::Pack()"
   1755             << std::endl
   1756             << std::flush;
   1757 #endif
   1758 #endif
   1759   int params_count_copy = params.count;
   1760   asm volatile(
   1761       "add r0, %[in], %[stride]\n"
   1762       "add r1, r0, %[stride]\n"
   1763       "add r2, r1, %[stride]\n"
   1764       "vmov.i16 q8, #0\n"
   1765       "vmov.i16 q9, #0\n"
   1766       "vmov.i16 q10, #0\n"
   1767       "vmov.i16 q11, #0\n"
   1768 
   1769       // Reduce count by leftovers.
   1770       "subs %[count], %[count], #3\n"
   1771       "beq 2f\n"
   1772 
   1773       "1:"
   1774       "subs %[count], %[count], #8\n"
   1775 
   1776       // Load Aggregate Store: 4x8.
   1777       "vld1.32 {d0}, [%[in]]!\n"
   1778       "vld1.32 {d1}, [r0]!\n"
   1779       "vld1.32 {d2}, [r1]!\n"
   1780       "vld1.32 {d3}, [r2]!\n"
   1781       "vaddw.u8 q8, q8, d0\n"
   1782       "vaddw.u8 q9, q9, d1\n"
   1783       "vaddw.u8 q10, q10, d2\n"
   1784       "vaddw.u8 q11, q11, d3\n"
   1785       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1786 
   1787       "bne 1b\n"
   1788 
   1789       "2:"
   1790 
   1791       // Load Aggregate Store: 4x3.
   1792       "vmov.i8 d0, #0\n"
   1793       "vmov.i8 d1, #0\n"
   1794       "vmov.i8 d2, #0\n"
   1795       "vmov.i8 d3, #0\n"
   1796       "vld1.16 {d0[0]}, [%[in]]!\n"
   1797       "vld1.8 {d0[2]}, [%[in]]!\n"
   1798       "vld1.16 {d1[0]}, [r0]!\n"
   1799       "vld1.8 {d1[2]}, [r0]!\n"
   1800       "vld1.16 {d2[0]}, [r1]!\n"
   1801       "vld1.8 {d2[2]}, [r1]!\n"
   1802       "vld1.16 {d3[0]}, [r2]!\n"
   1803       "vld1.8 {d3[2]}, [r2]!\n"
   1804       "vaddw.u8 q8, q8, d0\n"
   1805       "vaddw.u8 q9, q9, d1\n"
   1806       "vaddw.u8 q10, q10, d2\n"
   1807       "vaddw.u8 q11, q11, d3\n"
   1808       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1809 
   1810       // Aggregator Reduction.
   1811       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1812       "vdup.32 q1, %[additive_sum_offset]\n"
   1813       "vpaddl.u16 q8, q8\n"
   1814       "vpaddl.u16 q9, q9\n"
   1815       "vpaddl.u16 q10, q10\n"
   1816       "vpaddl.u16 q11, q11\n"
   1817       "vpadd.u32 d16, d16, d17\n"
   1818       "vpadd.u32 d18, d18, d19\n"
   1819       "vpadd.u32 d20, d20, d21\n"
   1820       "vpadd.u32 d22, d22, d23\n"
   1821       "vpadd.u32 d16, d16, d18\n"
   1822       "vpadd.u32 d17, d20, d22\n"
   1823       "vmul.i32 q8, q8, d0[0]\n"
   1824       "vadd.i32 q8, q8, q1\n"
   1825       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1826       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1827       : [stride] "r"(params.stride),
   1828         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1829         [additive_sum_offset] "r"(params.additive_sum_offset)
   1830       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1831         "d20", "d21", "d22", "d23", "cc", "memory");
   1832 }
   1833 
   1834 template <>
   1835 inline void Stream<uint8_t, 4, 8, 4, RowMajorWithSum>::Pack(
   1836     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1837 #ifdef DEBUG
   1838 #ifdef DEBUG_METAGEMM_VERBOSE
   1839   std::cout << __FILE__ << "(" << __LINE__
   1840             << ") RowMajorWithSum<uint8_t, 4, 8, 4, RowMajorWithSum>::Pack()"
   1841             << std::endl
   1842             << std::flush;
   1843 #endif
   1844 #endif
   1845   int params_count_copy = params.count;
   1846   asm volatile(
   1847       "add r0, %[in], %[stride]\n"
   1848       "add r1, r0, %[stride]\n"
   1849       "add r2, r1, %[stride]\n"
   1850       "vmov.i16 q8, #0\n"
   1851       "vmov.i16 q9, #0\n"
   1852       "vmov.i16 q10, #0\n"
   1853       "vmov.i16 q11, #0\n"
   1854 
   1855       // Reduce count by leftovers.
   1856       "subs %[count], %[count], #4\n"
   1857       "beq 2f\n"
   1858 
   1859       "1:"
   1860       "subs %[count], %[count], #8\n"
   1861 
   1862       // Load Aggregate Store: 4x8.
   1863       "vld1.32 {d0}, [%[in]]!\n"
   1864       "vld1.32 {d1}, [r0]!\n"
   1865       "vld1.32 {d2}, [r1]!\n"
   1866       "vld1.32 {d3}, [r2]!\n"
   1867       "vaddw.u8 q8, q8, d0\n"
   1868       "vaddw.u8 q9, q9, d1\n"
   1869       "vaddw.u8 q10, q10, d2\n"
   1870       "vaddw.u8 q11, q11, d3\n"
   1871       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1872 
   1873       "bne 1b\n"
   1874 
   1875       "2:"
   1876 
   1877       // Load Aggregate Store: 4x4.
   1878       "vmov.i8 d0, #0\n"
   1879       "vmov.i8 d1, #0\n"
   1880       "vmov.i8 d2, #0\n"
   1881       "vmov.i8 d3, #0\n"
   1882       "vld1.32 {d0[0]}, [%[in]]!\n"
   1883       "vld1.32 {d1[0]}, [r0]!\n"
   1884       "vld1.32 {d2[0]}, [r1]!\n"
   1885       "vld1.32 {d3[0]}, [r2]!\n"
   1886       "vaddw.u8 q8, q8, d0\n"
   1887       "vaddw.u8 q9, q9, d1\n"
   1888       "vaddw.u8 q10, q10, d2\n"
   1889       "vaddw.u8 q11, q11, d3\n"
   1890       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1891 
   1892       // Aggregator Reduction.
   1893       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1894       "vdup.32 q1, %[additive_sum_offset]\n"
   1895       "vpaddl.u16 q8, q8\n"
   1896       "vpaddl.u16 q9, q9\n"
   1897       "vpaddl.u16 q10, q10\n"
   1898       "vpaddl.u16 q11, q11\n"
   1899       "vpadd.u32 d16, d16, d17\n"
   1900       "vpadd.u32 d18, d18, d19\n"
   1901       "vpadd.u32 d20, d20, d21\n"
   1902       "vpadd.u32 d22, d22, d23\n"
   1903       "vpadd.u32 d16, d16, d18\n"
   1904       "vpadd.u32 d17, d20, d22\n"
   1905       "vmul.i32 q8, q8, d0[0]\n"
   1906       "vadd.i32 q8, q8, q1\n"
   1907       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1908       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1909       : [stride] "r"(params.stride),
   1910         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1911         [additive_sum_offset] "r"(params.additive_sum_offset)
   1912       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1913         "d20", "d21", "d22", "d23", "cc", "memory");
   1914 }
   1915 
   1916 template <>
   1917 inline void Stream<uint8_t, 4, 8, 5, RowMajorWithSum>::Pack(
   1918     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   1919 #ifdef DEBUG
   1920 #ifdef DEBUG_METAGEMM_VERBOSE
   1921   std::cout << __FILE__ << "(" << __LINE__
   1922             << ") RowMajorWithSum<uint8_t, 4, 8, 5, RowMajorWithSum>::Pack()"
   1923             << std::endl
   1924             << std::flush;
   1925 #endif
   1926 #endif
   1927   int params_count_copy = params.count;
   1928   asm volatile(
   1929       "add r0, %[in], %[stride]\n"
   1930       "add r1, r0, %[stride]\n"
   1931       "add r2, r1, %[stride]\n"
   1932       "vmov.i16 q8, #0\n"
   1933       "vmov.i16 q9, #0\n"
   1934       "vmov.i16 q10, #0\n"
   1935       "vmov.i16 q11, #0\n"
   1936 
   1937       // Reduce count by leftovers.
   1938       "subs %[count], %[count], #5\n"
   1939       "beq 2f\n"
   1940 
   1941       "1:"
   1942       "subs %[count], %[count], #8\n"
   1943 
   1944       // Load Aggregate Store: 4x8.
   1945       "vld1.32 {d0}, [%[in]]!\n"
   1946       "vld1.32 {d1}, [r0]!\n"
   1947       "vld1.32 {d2}, [r1]!\n"
   1948       "vld1.32 {d3}, [r2]!\n"
   1949       "vaddw.u8 q8, q8, d0\n"
   1950       "vaddw.u8 q9, q9, d1\n"
   1951       "vaddw.u8 q10, q10, d2\n"
   1952       "vaddw.u8 q11, q11, d3\n"
   1953       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1954 
   1955       "bne 1b\n"
   1956 
   1957       "2:"
   1958 
   1959       // Load Aggregate Store: 4x5.
   1960       "vmov.i8 d0, #0\n"
   1961       "vmov.i8 d1, #0\n"
   1962       "vmov.i8 d2, #0\n"
   1963       "vmov.i8 d3, #0\n"
   1964       "vld1.32 {d0[0]}, [%[in]]!\n"
   1965       "vld1.8 {d0[4]}, [%[in]]!\n"
   1966       "vld1.32 {d1[0]}, [r0]!\n"
   1967       "vld1.8 {d1[4]}, [r0]!\n"
   1968       "vld1.32 {d2[0]}, [r1]!\n"
   1969       "vld1.8 {d2[4]}, [r1]!\n"
   1970       "vld1.32 {d3[0]}, [r2]!\n"
   1971       "vld1.8 {d3[4]}, [r2]!\n"
   1972       "vaddw.u8 q8, q8, d0\n"
   1973       "vaddw.u8 q9, q9, d1\n"
   1974       "vaddw.u8 q10, q10, d2\n"
   1975       "vaddw.u8 q11, q11, d3\n"
   1976       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   1977 
   1978       // Aggregator Reduction.
   1979       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   1980       "vdup.32 q1, %[additive_sum_offset]\n"
   1981       "vpaddl.u16 q8, q8\n"
   1982       "vpaddl.u16 q9, q9\n"
   1983       "vpaddl.u16 q10, q10\n"
   1984       "vpaddl.u16 q11, q11\n"
   1985       "vpadd.u32 d16, d16, d17\n"
   1986       "vpadd.u32 d18, d18, d19\n"
   1987       "vpadd.u32 d20, d20, d21\n"
   1988       "vpadd.u32 d22, d22, d23\n"
   1989       "vpadd.u32 d16, d16, d18\n"
   1990       "vpadd.u32 d17, d20, d22\n"
   1991       "vmul.i32 q8, q8, d0[0]\n"
   1992       "vadd.i32 q8, q8, q1\n"
   1993       "vst1.32 {d16, d17}, [%[out]:128]\n"
   1994       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   1995       : [stride] "r"(params.stride),
   1996         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   1997         [additive_sum_offset] "r"(params.additive_sum_offset)
   1998       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   1999         "d20", "d21", "d22", "d23", "cc", "memory");
   2000 }
   2001 
   2002 template <>
   2003 inline void Stream<uint8_t, 4, 8, 6, RowMajorWithSum>::Pack(
   2004     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2005 #ifdef DEBUG
   2006 #ifdef DEBUG_METAGEMM_VERBOSE
   2007   std::cout << __FILE__ << "(" << __LINE__
   2008             << ") RowMajorWithSum<uint8_t, 4, 8, 6, RowMajorWithSum>::Pack()"
   2009             << std::endl
   2010             << std::flush;
   2011 #endif
   2012 #endif
   2013   int params_count_copy = params.count;
   2014   asm volatile(
   2015       "add r0, %[in], %[stride]\n"
   2016       "add r1, r0, %[stride]\n"
   2017       "add r2, r1, %[stride]\n"
   2018       "vmov.i16 q8, #0\n"
   2019       "vmov.i16 q9, #0\n"
   2020       "vmov.i16 q10, #0\n"
   2021       "vmov.i16 q11, #0\n"
   2022 
   2023       // Reduce count by leftovers.
   2024       "subs %[count], %[count], #6\n"
   2025       "beq 2f\n"
   2026 
   2027       "1:"
   2028       "subs %[count], %[count], #8\n"
   2029 
   2030       // Load Aggregate Store: 4x8.
   2031       "vld1.32 {d0}, [%[in]]!\n"
   2032       "vld1.32 {d1}, [r0]!\n"
   2033       "vld1.32 {d2}, [r1]!\n"
   2034       "vld1.32 {d3}, [r2]!\n"
   2035       "vaddw.u8 q8, q8, d0\n"
   2036       "vaddw.u8 q9, q9, d1\n"
   2037       "vaddw.u8 q10, q10, d2\n"
   2038       "vaddw.u8 q11, q11, d3\n"
   2039       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   2040 
   2041       "bne 1b\n"
   2042 
   2043       "2:"
   2044 
   2045       // Load Aggregate Store: 4x6.
   2046       "vmov.i8 d0, #0\n"
   2047       "vmov.i8 d1, #0\n"
   2048       "vmov.i8 d2, #0\n"
   2049       "vmov.i8 d3, #0\n"
   2050       "vld1.32 {d0[0]}, [%[in]]!\n"
   2051       "vld1.16 {d0[2]}, [%[in]]!\n"
   2052       "vld1.32 {d1[0]}, [r0]!\n"
   2053       "vld1.16 {d1[2]}, [r0]!\n"
   2054       "vld1.32 {d2[0]}, [r1]!\n"
   2055       "vld1.16 {d2[2]}, [r1]!\n"
   2056       "vld1.32 {d3[0]}, [r2]!\n"
   2057       "vld1.16 {d3[2]}, [r2]!\n"
   2058       "vaddw.u8 q8, q8, d0\n"
   2059       "vaddw.u8 q9, q9, d1\n"
   2060       "vaddw.u8 q10, q10, d2\n"
   2061       "vaddw.u8 q11, q11, d3\n"
   2062       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   2063 
   2064       // Aggregator Reduction.
   2065       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2066       "vdup.32 q1, %[additive_sum_offset]\n"
   2067       "vpaddl.u16 q8, q8\n"
   2068       "vpaddl.u16 q9, q9\n"
   2069       "vpaddl.u16 q10, q10\n"
   2070       "vpaddl.u16 q11, q11\n"
   2071       "vpadd.u32 d16, d16, d17\n"
   2072       "vpadd.u32 d18, d18, d19\n"
   2073       "vpadd.u32 d20, d20, d21\n"
   2074       "vpadd.u32 d22, d22, d23\n"
   2075       "vpadd.u32 d16, d16, d18\n"
   2076       "vpadd.u32 d17, d20, d22\n"
   2077       "vmul.i32 q8, q8, d0[0]\n"
   2078       "vadd.i32 q8, q8, q1\n"
   2079       "vst1.32 {d16, d17}, [%[out]:128]\n"
   2080       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2081       : [stride] "r"(params.stride),
   2082         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2083         [additive_sum_offset] "r"(params.additive_sum_offset)
   2084       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   2085         "d20", "d21", "d22", "d23", "cc", "memory");
   2086 }
   2087 
   2088 template <>
   2089 inline void Stream<uint8_t, 4, 8, 7, RowMajorWithSum>::Pack(
   2090     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2091 #ifdef DEBUG
   2092 #ifdef DEBUG_METAGEMM_VERBOSE
   2093   std::cout << __FILE__ << "(" << __LINE__
   2094             << ") RowMajorWithSum<uint8_t, 4, 8, 7, RowMajorWithSum>::Pack()"
   2095             << std::endl
   2096             << std::flush;
   2097 #endif
   2098 #endif
   2099   int params_count_copy = params.count;
   2100   asm volatile(
   2101       "add r0, %[in], %[stride]\n"
   2102       "add r1, r0, %[stride]\n"
   2103       "add r2, r1, %[stride]\n"
   2104       "vmov.i16 q8, #0\n"
   2105       "vmov.i16 q9, #0\n"
   2106       "vmov.i16 q10, #0\n"
   2107       "vmov.i16 q11, #0\n"
   2108 
   2109       // Reduce count by leftovers.
   2110       "subs %[count], %[count], #7\n"
   2111       "beq 2f\n"
   2112 
   2113       "1:"
   2114       "subs %[count], %[count], #8\n"
   2115 
   2116       // Load Aggregate Store: 4x8.
   2117       "vld1.32 {d0}, [%[in]]!\n"
   2118       "vld1.32 {d1}, [r0]!\n"
   2119       "vld1.32 {d2}, [r1]!\n"
   2120       "vld1.32 {d3}, [r2]!\n"
   2121       "vaddw.u8 q8, q8, d0\n"
   2122       "vaddw.u8 q9, q9, d1\n"
   2123       "vaddw.u8 q10, q10, d2\n"
   2124       "vaddw.u8 q11, q11, d3\n"
   2125       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   2126 
   2127       "bne 1b\n"
   2128 
   2129       "2:"
   2130 
   2131       // Load Aggregate Store: 4x7.
   2132       "vmov.i8 d0, #0\n"
   2133       "vmov.i8 d1, #0\n"
   2134       "vmov.i8 d2, #0\n"
   2135       "vmov.i8 d3, #0\n"
   2136       "vld1.32 {d0[0]}, [%[in]]!\n"
   2137       "vld1.16 {d0[2]}, [%[in]]!\n"
   2138       "vld1.8 {d0[6]}, [%[in]]!\n"
   2139       "vld1.32 {d1[0]}, [r0]!\n"
   2140       "vld1.16 {d1[2]}, [r0]!\n"
   2141       "vld1.8 {d1[6]}, [r0]!\n"
   2142       "vld1.32 {d2[0]}, [r1]!\n"
   2143       "vld1.16 {d2[2]}, [r1]!\n"
   2144       "vld1.8 {d2[6]}, [r1]!\n"
   2145       "vld1.32 {d3[0]}, [r2]!\n"
   2146       "vld1.16 {d3[2]}, [r2]!\n"
   2147       "vld1.8 {d3[6]}, [r2]!\n"
   2148       "vaddw.u8 q8, q8, d0\n"
   2149       "vaddw.u8 q9, q9, d1\n"
   2150       "vaddw.u8 q10, q10, d2\n"
   2151       "vaddw.u8 q11, q11, d3\n"
   2152       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   2153 
   2154       // Aggregator Reduction.
   2155       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2156       "vdup.32 q1, %[additive_sum_offset]\n"
   2157       "vpaddl.u16 q8, q8\n"
   2158       "vpaddl.u16 q9, q9\n"
   2159       "vpaddl.u16 q10, q10\n"
   2160       "vpaddl.u16 q11, q11\n"
   2161       "vpadd.u32 d16, d16, d17\n"
   2162       "vpadd.u32 d18, d18, d19\n"
   2163       "vpadd.u32 d20, d20, d21\n"
   2164       "vpadd.u32 d22, d22, d23\n"
   2165       "vpadd.u32 d16, d16, d18\n"
   2166       "vpadd.u32 d17, d20, d22\n"
   2167       "vmul.i32 q8, q8, d0[0]\n"
   2168       "vadd.i32 q8, q8, q1\n"
   2169       "vst1.32 {d16, d17}, [%[out]:128]\n"
   2170       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2171       : [stride] "r"(params.stride),
   2172         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2173         [additive_sum_offset] "r"(params.additive_sum_offset)
   2174       : "r0", "r1", "r2", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
   2175         "d20", "d21", "d22", "d23", "cc", "memory");
   2176 }
   2177 
   2178 template <>
   2179 inline void Stream<uint8_t, 5, 8, 0, RowMajorWithSum>::Pack(
   2180     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2181 #ifdef DEBUG
   2182 #ifdef DEBUG_METAGEMM_VERBOSE
   2183   std::cout << __FILE__ << "(" << __LINE__
   2184             << ") RowMajorWithSum<uint8_t, 5, 8, 0, RowMajorWithSum>::Pack()"
   2185             << std::endl
   2186             << std::flush;
   2187 #endif
   2188 #endif
   2189   int params_count_copy = params.count;
   2190   asm volatile(
   2191       "add r0, %[in], %[stride]\n"
   2192       "add r1, r0, %[stride]\n"
   2193       "add r2, r1, %[stride]\n"
   2194       "add r3, r2, %[stride]\n"
   2195       "vmov.i16 q8, #0\n"
   2196       "vmov.i16 q9, #0\n"
   2197       "vmov.i16 q10, #0\n"
   2198       "vmov.i16 q11, #0\n"
   2199       "vmov.i16 q12, #0\n"
   2200 
   2201       "1:"
   2202       "subs %[count], %[count], #8\n"
   2203 
   2204       // Load Aggregate Store: 5x8.
   2205       "vld1.32 {d0}, [%[in]]!\n"
   2206       "vld1.32 {d1}, [r0]!\n"
   2207       "vld1.32 {d2}, [r1]!\n"
   2208       "vld1.32 {d3}, [r2]!\n"
   2209       "vld1.32 {d4}, [r3]!\n"
   2210       "vaddw.u8 q8, q8, d0\n"
   2211       "vaddw.u8 q9, q9, d1\n"
   2212       "vaddw.u8 q10, q10, d2\n"
   2213       "vaddw.u8 q11, q11, d3\n"
   2214       "vaddw.u8 q12, q12, d4\n"
   2215       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2216       "vst1.32 {d4}, [%[out]:64]!\n"
   2217 
   2218       "bne 1b\n"
   2219 
   2220       // Aggregator Reduction.
   2221       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2222       "vdup.32 q1, %[additive_sum_offset]\n"
   2223       "vpaddl.u16 q8, q8\n"
   2224       "vpaddl.u16 q9, q9\n"
   2225       "vpaddl.u16 q10, q10\n"
   2226       "vpaddl.u16 q11, q11\n"
   2227       "vpaddl.u16 q12, q12\n"
   2228       "vpadd.u32 d16, d16, d17\n"
   2229       "vpadd.u32 d18, d18, d19\n"
   2230       "vpadd.u32 d20, d20, d21\n"
   2231       "vpadd.u32 d22, d22, d23\n"
   2232       "vpadd.u32 d24, d24, d25\n"
   2233       "vpadd.u32 d16, d16, d18\n"
   2234       "vpadd.u32 d17, d20, d22\n"
   2235       "vpadd.u32 d18, d24, d24\n"
   2236       "vmul.i32 q8, q8, d0[0]\n"
   2237       "vmul.i32 q9, q9, d0[0]\n"
   2238       "vadd.i32 q8, q8, q1\n"
   2239       "vadd.i32 q9, q9, q1\n"
   2240       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2241       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2242       : [stride] "r"(params.stride),
   2243         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2244         [additive_sum_offset] "r"(params.additive_sum_offset)
   2245       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2246         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2247 }
   2248 
   2249 template <>
   2250 inline void Stream<uint8_t, 5, 8, 1, RowMajorWithSum>::Pack(
   2251     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2252 #ifdef DEBUG
   2253 #ifdef DEBUG_METAGEMM_VERBOSE
   2254   std::cout << __FILE__ << "(" << __LINE__
   2255             << ") RowMajorWithSum<uint8_t, 5, 8, 1, RowMajorWithSum>::Pack()"
   2256             << std::endl
   2257             << std::flush;
   2258 #endif
   2259 #endif
   2260   int params_count_copy = params.count;
   2261   asm volatile(
   2262       "add r0, %[in], %[stride]\n"
   2263       "add r1, r0, %[stride]\n"
   2264       "add r2, r1, %[stride]\n"
   2265       "add r3, r2, %[stride]\n"
   2266       "vmov.i16 q8, #0\n"
   2267       "vmov.i16 q9, #0\n"
   2268       "vmov.i16 q10, #0\n"
   2269       "vmov.i16 q11, #0\n"
   2270       "vmov.i16 q12, #0\n"
   2271 
   2272       // Reduce count by leftovers.
   2273       "subs %[count], %[count], #1\n"
   2274       "beq 2f\n"
   2275 
   2276       "1:"
   2277       "subs %[count], %[count], #8\n"
   2278 
   2279       // Load Aggregate Store: 5x8.
   2280       "vld1.32 {d0}, [%[in]]!\n"
   2281       "vld1.32 {d1}, [r0]!\n"
   2282       "vld1.32 {d2}, [r1]!\n"
   2283       "vld1.32 {d3}, [r2]!\n"
   2284       "vld1.32 {d4}, [r3]!\n"
   2285       "vaddw.u8 q8, q8, d0\n"
   2286       "vaddw.u8 q9, q9, d1\n"
   2287       "vaddw.u8 q10, q10, d2\n"
   2288       "vaddw.u8 q11, q11, d3\n"
   2289       "vaddw.u8 q12, q12, d4\n"
   2290       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2291       "vst1.32 {d4}, [%[out]:64]!\n"
   2292 
   2293       "bne 1b\n"
   2294 
   2295       "2:"
   2296 
   2297       // Load Aggregate Store: 5x1.
   2298       "vmov.i8 d0, #0\n"
   2299       "vmov.i8 d1, #0\n"
   2300       "vmov.i8 d2, #0\n"
   2301       "vmov.i8 d3, #0\n"
   2302       "vmov.i8 d4, #0\n"
   2303       "vld1.8 {d0[0]}, [%[in]]!\n"
   2304       "vld1.8 {d1[0]}, [r0]!\n"
   2305       "vld1.8 {d2[0]}, [r1]!\n"
   2306       "vld1.8 {d3[0]}, [r2]!\n"
   2307       "vld1.8 {d4[0]}, [r3]!\n"
   2308       "vaddw.u8 q8, q8, d0\n"
   2309       "vaddw.u8 q9, q9, d1\n"
   2310       "vaddw.u8 q10, q10, d2\n"
   2311       "vaddw.u8 q11, q11, d3\n"
   2312       "vaddw.u8 q12, q12, d4\n"
   2313       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2314       "vst1.32 {d4}, [%[out]:64]!\n"
   2315 
   2316       // Aggregator Reduction.
   2317       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2318       "vdup.32 q1, %[additive_sum_offset]\n"
   2319       "vpaddl.u16 q8, q8\n"
   2320       "vpaddl.u16 q9, q9\n"
   2321       "vpaddl.u16 q10, q10\n"
   2322       "vpaddl.u16 q11, q11\n"
   2323       "vpaddl.u16 q12, q12\n"
   2324       "vpadd.u32 d16, d16, d17\n"
   2325       "vpadd.u32 d18, d18, d19\n"
   2326       "vpadd.u32 d20, d20, d21\n"
   2327       "vpadd.u32 d22, d22, d23\n"
   2328       "vpadd.u32 d24, d24, d25\n"
   2329       "vpadd.u32 d16, d16, d18\n"
   2330       "vpadd.u32 d17, d20, d22\n"
   2331       "vpadd.u32 d18, d24, d24\n"
   2332       "vmul.i32 q8, q8, d0[0]\n"
   2333       "vmul.i32 q9, q9, d0[0]\n"
   2334       "vadd.i32 q8, q8, q1\n"
   2335       "vadd.i32 q9, q9, q1\n"
   2336       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2337       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2338       : [stride] "r"(params.stride),
   2339         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2340         [additive_sum_offset] "r"(params.additive_sum_offset)
   2341       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2342         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2343 }
   2344 
   2345 template <>
   2346 inline void Stream<uint8_t, 5, 8, 2, RowMajorWithSum>::Pack(
   2347     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2348 #ifdef DEBUG
   2349 #ifdef DEBUG_METAGEMM_VERBOSE
   2350   std::cout << __FILE__ << "(" << __LINE__
   2351             << ") RowMajorWithSum<uint8_t, 5, 8, 2, RowMajorWithSum>::Pack()"
   2352             << std::endl
   2353             << std::flush;
   2354 #endif
   2355 #endif
   2356   int params_count_copy = params.count;
   2357   asm volatile(
   2358       "add r0, %[in], %[stride]\n"
   2359       "add r1, r0, %[stride]\n"
   2360       "add r2, r1, %[stride]\n"
   2361       "add r3, r2, %[stride]\n"
   2362       "vmov.i16 q8, #0\n"
   2363       "vmov.i16 q9, #0\n"
   2364       "vmov.i16 q10, #0\n"
   2365       "vmov.i16 q11, #0\n"
   2366       "vmov.i16 q12, #0\n"
   2367 
   2368       // Reduce count by leftovers.
   2369       "subs %[count], %[count], #2\n"
   2370       "beq 2f\n"
   2371 
   2372       "1:"
   2373       "subs %[count], %[count], #8\n"
   2374 
   2375       // Load Aggregate Store: 5x8.
   2376       "vld1.32 {d0}, [%[in]]!\n"
   2377       "vld1.32 {d1}, [r0]!\n"
   2378       "vld1.32 {d2}, [r1]!\n"
   2379       "vld1.32 {d3}, [r2]!\n"
   2380       "vld1.32 {d4}, [r3]!\n"
   2381       "vaddw.u8 q8, q8, d0\n"
   2382       "vaddw.u8 q9, q9, d1\n"
   2383       "vaddw.u8 q10, q10, d2\n"
   2384       "vaddw.u8 q11, q11, d3\n"
   2385       "vaddw.u8 q12, q12, d4\n"
   2386       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2387       "vst1.32 {d4}, [%[out]:64]!\n"
   2388 
   2389       "bne 1b\n"
   2390 
   2391       "2:"
   2392 
   2393       // Load Aggregate Store: 5x2.
   2394       "vmov.i8 d0, #0\n"
   2395       "vmov.i8 d1, #0\n"
   2396       "vmov.i8 d2, #0\n"
   2397       "vmov.i8 d3, #0\n"
   2398       "vmov.i8 d4, #0\n"
   2399       "vld1.16 {d0[0]}, [%[in]]!\n"
   2400       "vld1.16 {d1[0]}, [r0]!\n"
   2401       "vld1.16 {d2[0]}, [r1]!\n"
   2402       "vld1.16 {d3[0]}, [r2]!\n"
   2403       "vld1.16 {d4[0]}, [r3]!\n"
   2404       "vaddw.u8 q8, q8, d0\n"
   2405       "vaddw.u8 q9, q9, d1\n"
   2406       "vaddw.u8 q10, q10, d2\n"
   2407       "vaddw.u8 q11, q11, d3\n"
   2408       "vaddw.u8 q12, q12, d4\n"
   2409       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2410       "vst1.32 {d4}, [%[out]:64]!\n"
   2411 
   2412       // Aggregator Reduction.
   2413       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2414       "vdup.32 q1, %[additive_sum_offset]\n"
   2415       "vpaddl.u16 q8, q8\n"
   2416       "vpaddl.u16 q9, q9\n"
   2417       "vpaddl.u16 q10, q10\n"
   2418       "vpaddl.u16 q11, q11\n"
   2419       "vpaddl.u16 q12, q12\n"
   2420       "vpadd.u32 d16, d16, d17\n"
   2421       "vpadd.u32 d18, d18, d19\n"
   2422       "vpadd.u32 d20, d20, d21\n"
   2423       "vpadd.u32 d22, d22, d23\n"
   2424       "vpadd.u32 d24, d24, d25\n"
   2425       "vpadd.u32 d16, d16, d18\n"
   2426       "vpadd.u32 d17, d20, d22\n"
   2427       "vpadd.u32 d18, d24, d24\n"
   2428       "vmul.i32 q8, q8, d0[0]\n"
   2429       "vmul.i32 q9, q9, d0[0]\n"
   2430       "vadd.i32 q8, q8, q1\n"
   2431       "vadd.i32 q9, q9, q1\n"
   2432       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2433       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2434       : [stride] "r"(params.stride),
   2435         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2436         [additive_sum_offset] "r"(params.additive_sum_offset)
   2437       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2438         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2439 }
   2440 
   2441 template <>
   2442 inline void Stream<uint8_t, 5, 8, 3, RowMajorWithSum>::Pack(
   2443     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2444 #ifdef DEBUG
   2445 #ifdef DEBUG_METAGEMM_VERBOSE
   2446   std::cout << __FILE__ << "(" << __LINE__
   2447             << ") RowMajorWithSum<uint8_t, 5, 8, 3, RowMajorWithSum>::Pack()"
   2448             << std::endl
   2449             << std::flush;
   2450 #endif
   2451 #endif
   2452   int params_count_copy = params.count;
   2453   asm volatile(
   2454       "add r0, %[in], %[stride]\n"
   2455       "add r1, r0, %[stride]\n"
   2456       "add r2, r1, %[stride]\n"
   2457       "add r3, r2, %[stride]\n"
   2458       "vmov.i16 q8, #0\n"
   2459       "vmov.i16 q9, #0\n"
   2460       "vmov.i16 q10, #0\n"
   2461       "vmov.i16 q11, #0\n"
   2462       "vmov.i16 q12, #0\n"
   2463 
   2464       // Reduce count by leftovers.
   2465       "subs %[count], %[count], #3\n"
   2466       "beq 2f\n"
   2467 
   2468       "1:"
   2469       "subs %[count], %[count], #8\n"
   2470 
   2471       // Load Aggregate Store: 5x8.
   2472       "vld1.32 {d0}, [%[in]]!\n"
   2473       "vld1.32 {d1}, [r0]!\n"
   2474       "vld1.32 {d2}, [r1]!\n"
   2475       "vld1.32 {d3}, [r2]!\n"
   2476       "vld1.32 {d4}, [r3]!\n"
   2477       "vaddw.u8 q8, q8, d0\n"
   2478       "vaddw.u8 q9, q9, d1\n"
   2479       "vaddw.u8 q10, q10, d2\n"
   2480       "vaddw.u8 q11, q11, d3\n"
   2481       "vaddw.u8 q12, q12, d4\n"
   2482       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2483       "vst1.32 {d4}, [%[out]:64]!\n"
   2484 
   2485       "bne 1b\n"
   2486 
   2487       "2:"
   2488 
   2489       // Load Aggregate Store: 5x3.
   2490       "vmov.i8 d0, #0\n"
   2491       "vmov.i8 d1, #0\n"
   2492       "vmov.i8 d2, #0\n"
   2493       "vmov.i8 d3, #0\n"
   2494       "vmov.i8 d4, #0\n"
   2495       "vld1.16 {d0[0]}, [%[in]]!\n"
   2496       "vld1.8 {d0[2]}, [%[in]]!\n"
   2497       "vld1.16 {d1[0]}, [r0]!\n"
   2498       "vld1.8 {d1[2]}, [r0]!\n"
   2499       "vld1.16 {d2[0]}, [r1]!\n"
   2500       "vld1.8 {d2[2]}, [r1]!\n"
   2501       "vld1.16 {d3[0]}, [r2]!\n"
   2502       "vld1.8 {d3[2]}, [r2]!\n"
   2503       "vld1.16 {d4[0]}, [r3]!\n"
   2504       "vld1.8 {d4[2]}, [r3]!\n"
   2505       "vaddw.u8 q8, q8, d0\n"
   2506       "vaddw.u8 q9, q9, d1\n"
   2507       "vaddw.u8 q10, q10, d2\n"
   2508       "vaddw.u8 q11, q11, d3\n"
   2509       "vaddw.u8 q12, q12, d4\n"
   2510       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2511       "vst1.32 {d4}, [%[out]:64]!\n"
   2512 
   2513       // Aggregator Reduction.
   2514       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2515       "vdup.32 q1, %[additive_sum_offset]\n"
   2516       "vpaddl.u16 q8, q8\n"
   2517       "vpaddl.u16 q9, q9\n"
   2518       "vpaddl.u16 q10, q10\n"
   2519       "vpaddl.u16 q11, q11\n"
   2520       "vpaddl.u16 q12, q12\n"
   2521       "vpadd.u32 d16, d16, d17\n"
   2522       "vpadd.u32 d18, d18, d19\n"
   2523       "vpadd.u32 d20, d20, d21\n"
   2524       "vpadd.u32 d22, d22, d23\n"
   2525       "vpadd.u32 d24, d24, d25\n"
   2526       "vpadd.u32 d16, d16, d18\n"
   2527       "vpadd.u32 d17, d20, d22\n"
   2528       "vpadd.u32 d18, d24, d24\n"
   2529       "vmul.i32 q8, q8, d0[0]\n"
   2530       "vmul.i32 q9, q9, d0[0]\n"
   2531       "vadd.i32 q8, q8, q1\n"
   2532       "vadd.i32 q9, q9, q1\n"
   2533       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2534       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2535       : [stride] "r"(params.stride),
   2536         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2537         [additive_sum_offset] "r"(params.additive_sum_offset)
   2538       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2539         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2540 }
   2541 
   2542 template <>
   2543 inline void Stream<uint8_t, 5, 8, 4, RowMajorWithSum>::Pack(
   2544     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2545 #ifdef DEBUG
   2546 #ifdef DEBUG_METAGEMM_VERBOSE
   2547   std::cout << __FILE__ << "(" << __LINE__
   2548             << ") RowMajorWithSum<uint8_t, 5, 8, 4, RowMajorWithSum>::Pack()"
   2549             << std::endl
   2550             << std::flush;
   2551 #endif
   2552 #endif
   2553   int params_count_copy = params.count;
   2554   asm volatile(
   2555       "add r0, %[in], %[stride]\n"
   2556       "add r1, r0, %[stride]\n"
   2557       "add r2, r1, %[stride]\n"
   2558       "add r3, r2, %[stride]\n"
   2559       "vmov.i16 q8, #0\n"
   2560       "vmov.i16 q9, #0\n"
   2561       "vmov.i16 q10, #0\n"
   2562       "vmov.i16 q11, #0\n"
   2563       "vmov.i16 q12, #0\n"
   2564 
   2565       // Reduce count by leftovers.
   2566       "subs %[count], %[count], #4\n"
   2567       "beq 2f\n"
   2568 
   2569       "1:"
   2570       "subs %[count], %[count], #8\n"
   2571 
   2572       // Load Aggregate Store: 5x8.
   2573       "vld1.32 {d0}, [%[in]]!\n"
   2574       "vld1.32 {d1}, [r0]!\n"
   2575       "vld1.32 {d2}, [r1]!\n"
   2576       "vld1.32 {d3}, [r2]!\n"
   2577       "vld1.32 {d4}, [r3]!\n"
   2578       "vaddw.u8 q8, q8, d0\n"
   2579       "vaddw.u8 q9, q9, d1\n"
   2580       "vaddw.u8 q10, q10, d2\n"
   2581       "vaddw.u8 q11, q11, d3\n"
   2582       "vaddw.u8 q12, q12, d4\n"
   2583       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2584       "vst1.32 {d4}, [%[out]:64]!\n"
   2585 
   2586       "bne 1b\n"
   2587 
   2588       "2:"
   2589 
   2590       // Load Aggregate Store: 5x4.
   2591       "vmov.i8 d0, #0\n"
   2592       "vmov.i8 d1, #0\n"
   2593       "vmov.i8 d2, #0\n"
   2594       "vmov.i8 d3, #0\n"
   2595       "vmov.i8 d4, #0\n"
   2596       "vld1.32 {d0[0]}, [%[in]]!\n"
   2597       "vld1.32 {d1[0]}, [r0]!\n"
   2598       "vld1.32 {d2[0]}, [r1]!\n"
   2599       "vld1.32 {d3[0]}, [r2]!\n"
   2600       "vld1.32 {d4[0]}, [r3]!\n"
   2601       "vaddw.u8 q8, q8, d0\n"
   2602       "vaddw.u8 q9, q9, d1\n"
   2603       "vaddw.u8 q10, q10, d2\n"
   2604       "vaddw.u8 q11, q11, d3\n"
   2605       "vaddw.u8 q12, q12, d4\n"
   2606       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2607       "vst1.32 {d4}, [%[out]:64]!\n"
   2608 
   2609       // Aggregator Reduction.
   2610       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2611       "vdup.32 q1, %[additive_sum_offset]\n"
   2612       "vpaddl.u16 q8, q8\n"
   2613       "vpaddl.u16 q9, q9\n"
   2614       "vpaddl.u16 q10, q10\n"
   2615       "vpaddl.u16 q11, q11\n"
   2616       "vpaddl.u16 q12, q12\n"
   2617       "vpadd.u32 d16, d16, d17\n"
   2618       "vpadd.u32 d18, d18, d19\n"
   2619       "vpadd.u32 d20, d20, d21\n"
   2620       "vpadd.u32 d22, d22, d23\n"
   2621       "vpadd.u32 d24, d24, d25\n"
   2622       "vpadd.u32 d16, d16, d18\n"
   2623       "vpadd.u32 d17, d20, d22\n"
   2624       "vpadd.u32 d18, d24, d24\n"
   2625       "vmul.i32 q8, q8, d0[0]\n"
   2626       "vmul.i32 q9, q9, d0[0]\n"
   2627       "vadd.i32 q8, q8, q1\n"
   2628       "vadd.i32 q9, q9, q1\n"
   2629       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2630       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2631       : [stride] "r"(params.stride),
   2632         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2633         [additive_sum_offset] "r"(params.additive_sum_offset)
   2634       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2635         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2636 }
   2637 
   2638 template <>
   2639 inline void Stream<uint8_t, 5, 8, 5, RowMajorWithSum>::Pack(
   2640     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2641 #ifdef DEBUG
   2642 #ifdef DEBUG_METAGEMM_VERBOSE
   2643   std::cout << __FILE__ << "(" << __LINE__
   2644             << ") RowMajorWithSum<uint8_t, 5, 8, 5, RowMajorWithSum>::Pack()"
   2645             << std::endl
   2646             << std::flush;
   2647 #endif
   2648 #endif
   2649   int params_count_copy = params.count;
   2650   asm volatile(
   2651       "add r0, %[in], %[stride]\n"
   2652       "add r1, r0, %[stride]\n"
   2653       "add r2, r1, %[stride]\n"
   2654       "add r3, r2, %[stride]\n"
   2655       "vmov.i16 q8, #0\n"
   2656       "vmov.i16 q9, #0\n"
   2657       "vmov.i16 q10, #0\n"
   2658       "vmov.i16 q11, #0\n"
   2659       "vmov.i16 q12, #0\n"
   2660 
   2661       // Reduce count by leftovers.
   2662       "subs %[count], %[count], #5\n"
   2663       "beq 2f\n"
   2664 
   2665       "1:"
   2666       "subs %[count], %[count], #8\n"
   2667 
   2668       // Load Aggregate Store: 5x8.
   2669       "vld1.32 {d0}, [%[in]]!\n"
   2670       "vld1.32 {d1}, [r0]!\n"
   2671       "vld1.32 {d2}, [r1]!\n"
   2672       "vld1.32 {d3}, [r2]!\n"
   2673       "vld1.32 {d4}, [r3]!\n"
   2674       "vaddw.u8 q8, q8, d0\n"
   2675       "vaddw.u8 q9, q9, d1\n"
   2676       "vaddw.u8 q10, q10, d2\n"
   2677       "vaddw.u8 q11, q11, d3\n"
   2678       "vaddw.u8 q12, q12, d4\n"
   2679       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2680       "vst1.32 {d4}, [%[out]:64]!\n"
   2681 
   2682       "bne 1b\n"
   2683 
   2684       "2:"
   2685 
   2686       // Load Aggregate Store: 5x5.
   2687       "vmov.i8 d0, #0\n"
   2688       "vmov.i8 d1, #0\n"
   2689       "vmov.i8 d2, #0\n"
   2690       "vmov.i8 d3, #0\n"
   2691       "vmov.i8 d4, #0\n"
   2692       "vld1.32 {d0[0]}, [%[in]]!\n"
   2693       "vld1.8 {d0[4]}, [%[in]]!\n"
   2694       "vld1.32 {d1[0]}, [r0]!\n"
   2695       "vld1.8 {d1[4]}, [r0]!\n"
   2696       "vld1.32 {d2[0]}, [r1]!\n"
   2697       "vld1.8 {d2[4]}, [r1]!\n"
   2698       "vld1.32 {d3[0]}, [r2]!\n"
   2699       "vld1.8 {d3[4]}, [r2]!\n"
   2700       "vld1.32 {d4[0]}, [r3]!\n"
   2701       "vld1.8 {d4[4]}, [r3]!\n"
   2702       "vaddw.u8 q8, q8, d0\n"
   2703       "vaddw.u8 q9, q9, d1\n"
   2704       "vaddw.u8 q10, q10, d2\n"
   2705       "vaddw.u8 q11, q11, d3\n"
   2706       "vaddw.u8 q12, q12, d4\n"
   2707       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2708       "vst1.32 {d4}, [%[out]:64]!\n"
   2709 
   2710       // Aggregator Reduction.
   2711       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2712       "vdup.32 q1, %[additive_sum_offset]\n"
   2713       "vpaddl.u16 q8, q8\n"
   2714       "vpaddl.u16 q9, q9\n"
   2715       "vpaddl.u16 q10, q10\n"
   2716       "vpaddl.u16 q11, q11\n"
   2717       "vpaddl.u16 q12, q12\n"
   2718       "vpadd.u32 d16, d16, d17\n"
   2719       "vpadd.u32 d18, d18, d19\n"
   2720       "vpadd.u32 d20, d20, d21\n"
   2721       "vpadd.u32 d22, d22, d23\n"
   2722       "vpadd.u32 d24, d24, d25\n"
   2723       "vpadd.u32 d16, d16, d18\n"
   2724       "vpadd.u32 d17, d20, d22\n"
   2725       "vpadd.u32 d18, d24, d24\n"
   2726       "vmul.i32 q8, q8, d0[0]\n"
   2727       "vmul.i32 q9, q9, d0[0]\n"
   2728       "vadd.i32 q8, q8, q1\n"
   2729       "vadd.i32 q9, q9, q1\n"
   2730       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2731       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2732       : [stride] "r"(params.stride),
   2733         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2734         [additive_sum_offset] "r"(params.additive_sum_offset)
   2735       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2736         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2737 }
   2738 
   2739 template <>
   2740 inline void Stream<uint8_t, 5, 8, 6, RowMajorWithSum>::Pack(
   2741     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2742 #ifdef DEBUG
   2743 #ifdef DEBUG_METAGEMM_VERBOSE
   2744   std::cout << __FILE__ << "(" << __LINE__
   2745             << ") RowMajorWithSum<uint8_t, 5, 8, 6, RowMajorWithSum>::Pack()"
   2746             << std::endl
   2747             << std::flush;
   2748 #endif
   2749 #endif
   2750   int params_count_copy = params.count;
   2751   asm volatile(
   2752       "add r0, %[in], %[stride]\n"
   2753       "add r1, r0, %[stride]\n"
   2754       "add r2, r1, %[stride]\n"
   2755       "add r3, r2, %[stride]\n"
   2756       "vmov.i16 q8, #0\n"
   2757       "vmov.i16 q9, #0\n"
   2758       "vmov.i16 q10, #0\n"
   2759       "vmov.i16 q11, #0\n"
   2760       "vmov.i16 q12, #0\n"
   2761 
   2762       // Reduce count by leftovers.
   2763       "subs %[count], %[count], #6\n"
   2764       "beq 2f\n"
   2765 
   2766       "1:"
   2767       "subs %[count], %[count], #8\n"
   2768 
   2769       // Load Aggregate Store: 5x8.
   2770       "vld1.32 {d0}, [%[in]]!\n"
   2771       "vld1.32 {d1}, [r0]!\n"
   2772       "vld1.32 {d2}, [r1]!\n"
   2773       "vld1.32 {d3}, [r2]!\n"
   2774       "vld1.32 {d4}, [r3]!\n"
   2775       "vaddw.u8 q8, q8, d0\n"
   2776       "vaddw.u8 q9, q9, d1\n"
   2777       "vaddw.u8 q10, q10, d2\n"
   2778       "vaddw.u8 q11, q11, d3\n"
   2779       "vaddw.u8 q12, q12, d4\n"
   2780       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2781       "vst1.32 {d4}, [%[out]:64]!\n"
   2782 
   2783       "bne 1b\n"
   2784 
   2785       "2:"
   2786 
   2787       // Load Aggregate Store: 5x6.
   2788       "vmov.i8 d0, #0\n"
   2789       "vmov.i8 d1, #0\n"
   2790       "vmov.i8 d2, #0\n"
   2791       "vmov.i8 d3, #0\n"
   2792       "vmov.i8 d4, #0\n"
   2793       "vld1.32 {d0[0]}, [%[in]]!\n"
   2794       "vld1.16 {d0[2]}, [%[in]]!\n"
   2795       "vld1.32 {d1[0]}, [r0]!\n"
   2796       "vld1.16 {d1[2]}, [r0]!\n"
   2797       "vld1.32 {d2[0]}, [r1]!\n"
   2798       "vld1.16 {d2[2]}, [r1]!\n"
   2799       "vld1.32 {d3[0]}, [r2]!\n"
   2800       "vld1.16 {d3[2]}, [r2]!\n"
   2801       "vld1.32 {d4[0]}, [r3]!\n"
   2802       "vld1.16 {d4[2]}, [r3]!\n"
   2803       "vaddw.u8 q8, q8, d0\n"
   2804       "vaddw.u8 q9, q9, d1\n"
   2805       "vaddw.u8 q10, q10, d2\n"
   2806       "vaddw.u8 q11, q11, d3\n"
   2807       "vaddw.u8 q12, q12, d4\n"
   2808       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2809       "vst1.32 {d4}, [%[out]:64]!\n"
   2810 
   2811       // Aggregator Reduction.
   2812       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2813       "vdup.32 q1, %[additive_sum_offset]\n"
   2814       "vpaddl.u16 q8, q8\n"
   2815       "vpaddl.u16 q9, q9\n"
   2816       "vpaddl.u16 q10, q10\n"
   2817       "vpaddl.u16 q11, q11\n"
   2818       "vpaddl.u16 q12, q12\n"
   2819       "vpadd.u32 d16, d16, d17\n"
   2820       "vpadd.u32 d18, d18, d19\n"
   2821       "vpadd.u32 d20, d20, d21\n"
   2822       "vpadd.u32 d22, d22, d23\n"
   2823       "vpadd.u32 d24, d24, d25\n"
   2824       "vpadd.u32 d16, d16, d18\n"
   2825       "vpadd.u32 d17, d20, d22\n"
   2826       "vpadd.u32 d18, d24, d24\n"
   2827       "vmul.i32 q8, q8, d0[0]\n"
   2828       "vmul.i32 q9, q9, d0[0]\n"
   2829       "vadd.i32 q8, q8, q1\n"
   2830       "vadd.i32 q9, q9, q1\n"
   2831       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2832       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2833       : [stride] "r"(params.stride),
   2834         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2835         [additive_sum_offset] "r"(params.additive_sum_offset)
   2836       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2837         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2838 }
   2839 
   2840 template <>
   2841 inline void Stream<uint8_t, 5, 8, 7, RowMajorWithSum>::Pack(
   2842     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2843 #ifdef DEBUG
   2844 #ifdef DEBUG_METAGEMM_VERBOSE
   2845   std::cout << __FILE__ << "(" << __LINE__
   2846             << ") RowMajorWithSum<uint8_t, 5, 8, 7, RowMajorWithSum>::Pack()"
   2847             << std::endl
   2848             << std::flush;
   2849 #endif
   2850 #endif
   2851   int params_count_copy = params.count;
   2852   asm volatile(
   2853       "add r0, %[in], %[stride]\n"
   2854       "add r1, r0, %[stride]\n"
   2855       "add r2, r1, %[stride]\n"
   2856       "add r3, r2, %[stride]\n"
   2857       "vmov.i16 q8, #0\n"
   2858       "vmov.i16 q9, #0\n"
   2859       "vmov.i16 q10, #0\n"
   2860       "vmov.i16 q11, #0\n"
   2861       "vmov.i16 q12, #0\n"
   2862 
   2863       // Reduce count by leftovers.
   2864       "subs %[count], %[count], #7\n"
   2865       "beq 2f\n"
   2866 
   2867       "1:"
   2868       "subs %[count], %[count], #8\n"
   2869 
   2870       // Load Aggregate Store: 5x8.
   2871       "vld1.32 {d0}, [%[in]]!\n"
   2872       "vld1.32 {d1}, [r0]!\n"
   2873       "vld1.32 {d2}, [r1]!\n"
   2874       "vld1.32 {d3}, [r2]!\n"
   2875       "vld1.32 {d4}, [r3]!\n"
   2876       "vaddw.u8 q8, q8, d0\n"
   2877       "vaddw.u8 q9, q9, d1\n"
   2878       "vaddw.u8 q10, q10, d2\n"
   2879       "vaddw.u8 q11, q11, d3\n"
   2880       "vaddw.u8 q12, q12, d4\n"
   2881       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2882       "vst1.32 {d4}, [%[out]:64]!\n"
   2883 
   2884       "bne 1b\n"
   2885 
   2886       "2:"
   2887 
   2888       // Load Aggregate Store: 5x7.
   2889       "vmov.i8 d0, #0\n"
   2890       "vmov.i8 d1, #0\n"
   2891       "vmov.i8 d2, #0\n"
   2892       "vmov.i8 d3, #0\n"
   2893       "vmov.i8 d4, #0\n"
   2894       "vld1.32 {d0[0]}, [%[in]]!\n"
   2895       "vld1.16 {d0[2]}, [%[in]]!\n"
   2896       "vld1.8 {d0[6]}, [%[in]]!\n"
   2897       "vld1.32 {d1[0]}, [r0]!\n"
   2898       "vld1.16 {d1[2]}, [r0]!\n"
   2899       "vld1.8 {d1[6]}, [r0]!\n"
   2900       "vld1.32 {d2[0]}, [r1]!\n"
   2901       "vld1.16 {d2[2]}, [r1]!\n"
   2902       "vld1.8 {d2[6]}, [r1]!\n"
   2903       "vld1.32 {d3[0]}, [r2]!\n"
   2904       "vld1.16 {d3[2]}, [r2]!\n"
   2905       "vld1.8 {d3[6]}, [r2]!\n"
   2906       "vld1.32 {d4[0]}, [r3]!\n"
   2907       "vld1.16 {d4[2]}, [r3]!\n"
   2908       "vld1.8 {d4[6]}, [r3]!\n"
   2909       "vaddw.u8 q8, q8, d0\n"
   2910       "vaddw.u8 q9, q9, d1\n"
   2911       "vaddw.u8 q10, q10, d2\n"
   2912       "vaddw.u8 q11, q11, d3\n"
   2913       "vaddw.u8 q12, q12, d4\n"
   2914       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   2915       "vst1.32 {d4}, [%[out]:64]!\n"
   2916 
   2917       // Aggregator Reduction.
   2918       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2919       "vdup.32 q1, %[additive_sum_offset]\n"
   2920       "vpaddl.u16 q8, q8\n"
   2921       "vpaddl.u16 q9, q9\n"
   2922       "vpaddl.u16 q10, q10\n"
   2923       "vpaddl.u16 q11, q11\n"
   2924       "vpaddl.u16 q12, q12\n"
   2925       "vpadd.u32 d16, d16, d17\n"
   2926       "vpadd.u32 d18, d18, d19\n"
   2927       "vpadd.u32 d20, d20, d21\n"
   2928       "vpadd.u32 d22, d22, d23\n"
   2929       "vpadd.u32 d24, d24, d25\n"
   2930       "vpadd.u32 d16, d16, d18\n"
   2931       "vpadd.u32 d17, d20, d22\n"
   2932       "vpadd.u32 d18, d24, d24\n"
   2933       "vmul.i32 q8, q8, d0[0]\n"
   2934       "vmul.i32 q9, q9, d0[0]\n"
   2935       "vadd.i32 q8, q8, q1\n"
   2936       "vadd.i32 q9, q9, q1\n"
   2937       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   2938       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   2939       : [stride] "r"(params.stride),
   2940         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   2941         [additive_sum_offset] "r"(params.additive_sum_offset)
   2942       : "r0", "r1", "r2", "r3", "d0", "d1", "d2", "d3", "d4", "d16", "d17",
   2943         "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "cc", "memory");
   2944 }
   2945 
   2946 template <>
   2947 inline void Stream<uint8_t, 6, 8, 0, RowMajorWithSum>::Pack(
   2948     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   2949 #ifdef DEBUG
   2950 #ifdef DEBUG_METAGEMM_VERBOSE
   2951   std::cout << __FILE__ << "(" << __LINE__
   2952             << ") RowMajorWithSum<uint8_t, 6, 8, 0, RowMajorWithSum>::Pack()"
   2953             << std::endl
   2954             << std::flush;
   2955 #endif
   2956 #endif
   2957   int params_count_copy = params.count;
   2958   asm volatile(
   2959       "add r0, %[in], %[stride]\n"
   2960       "add r1, r0, %[stride]\n"
   2961       "add r2, r1, %[stride]\n"
   2962       "add r3, r2, %[stride]\n"
   2963       "add r4, r3, %[stride]\n"
   2964       "vmov.i16 q8, #0\n"
   2965       "vmov.i16 q9, #0\n"
   2966       "vmov.i16 q10, #0\n"
   2967       "vmov.i16 q11, #0\n"
   2968       "vmov.i16 q12, #0\n"
   2969       "vmov.i16 q13, #0\n"
   2970 
   2971       "1:"
   2972       "subs %[count], %[count], #8\n"
   2973 
   2974       // Load Aggregate Store: 6x8.
   2975       "vld1.32 {d0}, [%[in]]!\n"
   2976       "vld1.32 {d1}, [r0]!\n"
   2977       "vld1.32 {d2}, [r1]!\n"
   2978       "vld1.32 {d3}, [r2]!\n"
   2979       "vld1.32 {d4}, [r3]!\n"
   2980       "vld1.32 {d5}, [r4]!\n"
   2981       "vaddw.u8 q8, q8, d0\n"
   2982       "vaddw.u8 q9, q9, d1\n"
   2983       "vaddw.u8 q10, q10, d2\n"
   2984       "vaddw.u8 q11, q11, d3\n"
   2985       "vaddw.u8 q12, q12, d4\n"
   2986       "vaddw.u8 q13, q13, d5\n"
   2987       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   2988       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   2989 
   2990       "bne 1b\n"
   2991 
   2992       // Aggregator Reduction.
   2993       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   2994       "vdup.32 q1, %[additive_sum_offset]\n"
   2995       "vpaddl.u16 q8, q8\n"
   2996       "vpaddl.u16 q9, q9\n"
   2997       "vpaddl.u16 q10, q10\n"
   2998       "vpaddl.u16 q11, q11\n"
   2999       "vpaddl.u16 q12, q12\n"
   3000       "vpaddl.u16 q13, q13\n"
   3001       "vpadd.u32 d16, d16, d17\n"
   3002       "vpadd.u32 d18, d18, d19\n"
   3003       "vpadd.u32 d20, d20, d21\n"
   3004       "vpadd.u32 d22, d22, d23\n"
   3005       "vpadd.u32 d24, d24, d25\n"
   3006       "vpadd.u32 d26, d26, d27\n"
   3007       "vpadd.u32 d16, d16, d18\n"
   3008       "vpadd.u32 d17, d20, d22\n"
   3009       "vpadd.u32 d18, d24, d26\n"
   3010       "vmul.i32 q8, q8, d0[0]\n"
   3011       "vmul.i32 q9, q9, d0[0]\n"
   3012       "vadd.i32 q8, q8, q1\n"
   3013       "vadd.i32 q9, q9, q1\n"
   3014       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3015       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3016       : [stride] "r"(params.stride),
   3017         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3018         [additive_sum_offset] "r"(params.additive_sum_offset)
   3019       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3020         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3021         "d27", "cc", "memory");
   3022 }
   3023 
   3024 template <>
   3025 inline void Stream<uint8_t, 6, 8, 1, RowMajorWithSum>::Pack(
   3026     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3027 #ifdef DEBUG
   3028 #ifdef DEBUG_METAGEMM_VERBOSE
   3029   std::cout << __FILE__ << "(" << __LINE__
   3030             << ") RowMajorWithSum<uint8_t, 6, 8, 1, RowMajorWithSum>::Pack()"
   3031             << std::endl
   3032             << std::flush;
   3033 #endif
   3034 #endif
   3035   int params_count_copy = params.count;
   3036   asm volatile(
   3037       "add r0, %[in], %[stride]\n"
   3038       "add r1, r0, %[stride]\n"
   3039       "add r2, r1, %[stride]\n"
   3040       "add r3, r2, %[stride]\n"
   3041       "add r4, r3, %[stride]\n"
   3042       "vmov.i16 q8, #0\n"
   3043       "vmov.i16 q9, #0\n"
   3044       "vmov.i16 q10, #0\n"
   3045       "vmov.i16 q11, #0\n"
   3046       "vmov.i16 q12, #0\n"
   3047       "vmov.i16 q13, #0\n"
   3048 
   3049       // Reduce count by leftovers.
   3050       "subs %[count], %[count], #1\n"
   3051       "beq 2f\n"
   3052 
   3053       "1:"
   3054       "subs %[count], %[count], #8\n"
   3055 
   3056       // Load Aggregate Store: 6x8.
   3057       "vld1.32 {d0}, [%[in]]!\n"
   3058       "vld1.32 {d1}, [r0]!\n"
   3059       "vld1.32 {d2}, [r1]!\n"
   3060       "vld1.32 {d3}, [r2]!\n"
   3061       "vld1.32 {d4}, [r3]!\n"
   3062       "vld1.32 {d5}, [r4]!\n"
   3063       "vaddw.u8 q8, q8, d0\n"
   3064       "vaddw.u8 q9, q9, d1\n"
   3065       "vaddw.u8 q10, q10, d2\n"
   3066       "vaddw.u8 q11, q11, d3\n"
   3067       "vaddw.u8 q12, q12, d4\n"
   3068       "vaddw.u8 q13, q13, d5\n"
   3069       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3070       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3071 
   3072       "bne 1b\n"
   3073 
   3074       "2:"
   3075 
   3076       // Load Aggregate Store: 6x1.
   3077       "vmov.i8 d0, #0\n"
   3078       "vmov.i8 d1, #0\n"
   3079       "vmov.i8 d2, #0\n"
   3080       "vmov.i8 d3, #0\n"
   3081       "vmov.i8 d4, #0\n"
   3082       "vmov.i8 d5, #0\n"
   3083       "vld1.8 {d0[0]}, [%[in]]!\n"
   3084       "vld1.8 {d1[0]}, [r0]!\n"
   3085       "vld1.8 {d2[0]}, [r1]!\n"
   3086       "vld1.8 {d3[0]}, [r2]!\n"
   3087       "vld1.8 {d4[0]}, [r3]!\n"
   3088       "vld1.8 {d5[0]}, [r4]!\n"
   3089       "vaddw.u8 q8, q8, d0\n"
   3090       "vaddw.u8 q9, q9, d1\n"
   3091       "vaddw.u8 q10, q10, d2\n"
   3092       "vaddw.u8 q11, q11, d3\n"
   3093       "vaddw.u8 q12, q12, d4\n"
   3094       "vaddw.u8 q13, q13, d5\n"
   3095       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3096       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3097 
   3098       // Aggregator Reduction.
   3099       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3100       "vdup.32 q1, %[additive_sum_offset]\n"
   3101       "vpaddl.u16 q8, q8\n"
   3102       "vpaddl.u16 q9, q9\n"
   3103       "vpaddl.u16 q10, q10\n"
   3104       "vpaddl.u16 q11, q11\n"
   3105       "vpaddl.u16 q12, q12\n"
   3106       "vpaddl.u16 q13, q13\n"
   3107       "vpadd.u32 d16, d16, d17\n"
   3108       "vpadd.u32 d18, d18, d19\n"
   3109       "vpadd.u32 d20, d20, d21\n"
   3110       "vpadd.u32 d22, d22, d23\n"
   3111       "vpadd.u32 d24, d24, d25\n"
   3112       "vpadd.u32 d26, d26, d27\n"
   3113       "vpadd.u32 d16, d16, d18\n"
   3114       "vpadd.u32 d17, d20, d22\n"
   3115       "vpadd.u32 d18, d24, d26\n"
   3116       "vmul.i32 q8, q8, d0[0]\n"
   3117       "vmul.i32 q9, q9, d0[0]\n"
   3118       "vadd.i32 q8, q8, q1\n"
   3119       "vadd.i32 q9, q9, q1\n"
   3120       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3121       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3122       : [stride] "r"(params.stride),
   3123         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3124         [additive_sum_offset] "r"(params.additive_sum_offset)
   3125       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3126         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3127         "d27", "cc", "memory");
   3128 }
   3129 
   3130 template <>
   3131 inline void Stream<uint8_t, 6, 8, 2, RowMajorWithSum>::Pack(
   3132     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3133 #ifdef DEBUG
   3134 #ifdef DEBUG_METAGEMM_VERBOSE
   3135   std::cout << __FILE__ << "(" << __LINE__
   3136             << ") RowMajorWithSum<uint8_t, 6, 8, 2, RowMajorWithSum>::Pack()"
   3137             << std::endl
   3138             << std::flush;
   3139 #endif
   3140 #endif
   3141   int params_count_copy = params.count;
   3142   asm volatile(
   3143       "add r0, %[in], %[stride]\n"
   3144       "add r1, r0, %[stride]\n"
   3145       "add r2, r1, %[stride]\n"
   3146       "add r3, r2, %[stride]\n"
   3147       "add r4, r3, %[stride]\n"
   3148       "vmov.i16 q8, #0\n"
   3149       "vmov.i16 q9, #0\n"
   3150       "vmov.i16 q10, #0\n"
   3151       "vmov.i16 q11, #0\n"
   3152       "vmov.i16 q12, #0\n"
   3153       "vmov.i16 q13, #0\n"
   3154 
   3155       // Reduce count by leftovers.
   3156       "subs %[count], %[count], #2\n"
   3157       "beq 2f\n"
   3158 
   3159       "1:"
   3160       "subs %[count], %[count], #8\n"
   3161 
   3162       // Load Aggregate Store: 6x8.
   3163       "vld1.32 {d0}, [%[in]]!\n"
   3164       "vld1.32 {d1}, [r0]!\n"
   3165       "vld1.32 {d2}, [r1]!\n"
   3166       "vld1.32 {d3}, [r2]!\n"
   3167       "vld1.32 {d4}, [r3]!\n"
   3168       "vld1.32 {d5}, [r4]!\n"
   3169       "vaddw.u8 q8, q8, d0\n"
   3170       "vaddw.u8 q9, q9, d1\n"
   3171       "vaddw.u8 q10, q10, d2\n"
   3172       "vaddw.u8 q11, q11, d3\n"
   3173       "vaddw.u8 q12, q12, d4\n"
   3174       "vaddw.u8 q13, q13, d5\n"
   3175       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3176       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3177 
   3178       "bne 1b\n"
   3179 
   3180       "2:"
   3181 
   3182       // Load Aggregate Store: 6x2.
   3183       "vmov.i8 d0, #0\n"
   3184       "vmov.i8 d1, #0\n"
   3185       "vmov.i8 d2, #0\n"
   3186       "vmov.i8 d3, #0\n"
   3187       "vmov.i8 d4, #0\n"
   3188       "vmov.i8 d5, #0\n"
   3189       "vld1.16 {d0[0]}, [%[in]]!\n"
   3190       "vld1.16 {d1[0]}, [r0]!\n"
   3191       "vld1.16 {d2[0]}, [r1]!\n"
   3192       "vld1.16 {d3[0]}, [r2]!\n"
   3193       "vld1.16 {d4[0]}, [r3]!\n"
   3194       "vld1.16 {d5[0]}, [r4]!\n"
   3195       "vaddw.u8 q8, q8, d0\n"
   3196       "vaddw.u8 q9, q9, d1\n"
   3197       "vaddw.u8 q10, q10, d2\n"
   3198       "vaddw.u8 q11, q11, d3\n"
   3199       "vaddw.u8 q12, q12, d4\n"
   3200       "vaddw.u8 q13, q13, d5\n"
   3201       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3202       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3203 
   3204       // Aggregator Reduction.
   3205       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3206       "vdup.32 q1, %[additive_sum_offset]\n"
   3207       "vpaddl.u16 q8, q8\n"
   3208       "vpaddl.u16 q9, q9\n"
   3209       "vpaddl.u16 q10, q10\n"
   3210       "vpaddl.u16 q11, q11\n"
   3211       "vpaddl.u16 q12, q12\n"
   3212       "vpaddl.u16 q13, q13\n"
   3213       "vpadd.u32 d16, d16, d17\n"
   3214       "vpadd.u32 d18, d18, d19\n"
   3215       "vpadd.u32 d20, d20, d21\n"
   3216       "vpadd.u32 d22, d22, d23\n"
   3217       "vpadd.u32 d24, d24, d25\n"
   3218       "vpadd.u32 d26, d26, d27\n"
   3219       "vpadd.u32 d16, d16, d18\n"
   3220       "vpadd.u32 d17, d20, d22\n"
   3221       "vpadd.u32 d18, d24, d26\n"
   3222       "vmul.i32 q8, q8, d0[0]\n"
   3223       "vmul.i32 q9, q9, d0[0]\n"
   3224       "vadd.i32 q8, q8, q1\n"
   3225       "vadd.i32 q9, q9, q1\n"
   3226       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3227       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3228       : [stride] "r"(params.stride),
   3229         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3230         [additive_sum_offset] "r"(params.additive_sum_offset)
   3231       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3232         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3233         "d27", "cc", "memory");
   3234 }
   3235 
   3236 template <>
   3237 inline void Stream<uint8_t, 6, 8, 3, RowMajorWithSum>::Pack(
   3238     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3239 #ifdef DEBUG
   3240 #ifdef DEBUG_METAGEMM_VERBOSE
   3241   std::cout << __FILE__ << "(" << __LINE__
   3242             << ") RowMajorWithSum<uint8_t, 6, 8, 3, RowMajorWithSum>::Pack()"
   3243             << std::endl
   3244             << std::flush;
   3245 #endif
   3246 #endif
   3247   int params_count_copy = params.count;
   3248   asm volatile(
   3249       "add r0, %[in], %[stride]\n"
   3250       "add r1, r0, %[stride]\n"
   3251       "add r2, r1, %[stride]\n"
   3252       "add r3, r2, %[stride]\n"
   3253       "add r4, r3, %[stride]\n"
   3254       "vmov.i16 q8, #0\n"
   3255       "vmov.i16 q9, #0\n"
   3256       "vmov.i16 q10, #0\n"
   3257       "vmov.i16 q11, #0\n"
   3258       "vmov.i16 q12, #0\n"
   3259       "vmov.i16 q13, #0\n"
   3260 
   3261       // Reduce count by leftovers.
   3262       "subs %[count], %[count], #3\n"
   3263       "beq 2f\n"
   3264 
   3265       "1:"
   3266       "subs %[count], %[count], #8\n"
   3267 
   3268       // Load Aggregate Store: 6x8.
   3269       "vld1.32 {d0}, [%[in]]!\n"
   3270       "vld1.32 {d1}, [r0]!\n"
   3271       "vld1.32 {d2}, [r1]!\n"
   3272       "vld1.32 {d3}, [r2]!\n"
   3273       "vld1.32 {d4}, [r3]!\n"
   3274       "vld1.32 {d5}, [r4]!\n"
   3275       "vaddw.u8 q8, q8, d0\n"
   3276       "vaddw.u8 q9, q9, d1\n"
   3277       "vaddw.u8 q10, q10, d2\n"
   3278       "vaddw.u8 q11, q11, d3\n"
   3279       "vaddw.u8 q12, q12, d4\n"
   3280       "vaddw.u8 q13, q13, d5\n"
   3281       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3282       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3283 
   3284       "bne 1b\n"
   3285 
   3286       "2:"
   3287 
   3288       // Load Aggregate Store: 6x3.
   3289       "vmov.i8 d0, #0\n"
   3290       "vmov.i8 d1, #0\n"
   3291       "vmov.i8 d2, #0\n"
   3292       "vmov.i8 d3, #0\n"
   3293       "vmov.i8 d4, #0\n"
   3294       "vmov.i8 d5, #0\n"
   3295       "vld1.16 {d0[0]}, [%[in]]!\n"
   3296       "vld1.8 {d0[2]}, [%[in]]!\n"
   3297       "vld1.16 {d1[0]}, [r0]!\n"
   3298       "vld1.8 {d1[2]}, [r0]!\n"
   3299       "vld1.16 {d2[0]}, [r1]!\n"
   3300       "vld1.8 {d2[2]}, [r1]!\n"
   3301       "vld1.16 {d3[0]}, [r2]!\n"
   3302       "vld1.8 {d3[2]}, [r2]!\n"
   3303       "vld1.16 {d4[0]}, [r3]!\n"
   3304       "vld1.8 {d4[2]}, [r3]!\n"
   3305       "vld1.16 {d5[0]}, [r4]!\n"
   3306       "vld1.8 {d5[2]}, [r4]!\n"
   3307       "vaddw.u8 q8, q8, d0\n"
   3308       "vaddw.u8 q9, q9, d1\n"
   3309       "vaddw.u8 q10, q10, d2\n"
   3310       "vaddw.u8 q11, q11, d3\n"
   3311       "vaddw.u8 q12, q12, d4\n"
   3312       "vaddw.u8 q13, q13, d5\n"
   3313       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3314       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3315 
   3316       // Aggregator Reduction.
   3317       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3318       "vdup.32 q1, %[additive_sum_offset]\n"
   3319       "vpaddl.u16 q8, q8\n"
   3320       "vpaddl.u16 q9, q9\n"
   3321       "vpaddl.u16 q10, q10\n"
   3322       "vpaddl.u16 q11, q11\n"
   3323       "vpaddl.u16 q12, q12\n"
   3324       "vpaddl.u16 q13, q13\n"
   3325       "vpadd.u32 d16, d16, d17\n"
   3326       "vpadd.u32 d18, d18, d19\n"
   3327       "vpadd.u32 d20, d20, d21\n"
   3328       "vpadd.u32 d22, d22, d23\n"
   3329       "vpadd.u32 d24, d24, d25\n"
   3330       "vpadd.u32 d26, d26, d27\n"
   3331       "vpadd.u32 d16, d16, d18\n"
   3332       "vpadd.u32 d17, d20, d22\n"
   3333       "vpadd.u32 d18, d24, d26\n"
   3334       "vmul.i32 q8, q8, d0[0]\n"
   3335       "vmul.i32 q9, q9, d0[0]\n"
   3336       "vadd.i32 q8, q8, q1\n"
   3337       "vadd.i32 q9, q9, q1\n"
   3338       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3339       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3340       : [stride] "r"(params.stride),
   3341         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3342         [additive_sum_offset] "r"(params.additive_sum_offset)
   3343       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3344         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3345         "d27", "cc", "memory");
   3346 }
   3347 
   3348 template <>
   3349 inline void Stream<uint8_t, 6, 8, 4, RowMajorWithSum>::Pack(
   3350     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3351 #ifdef DEBUG
   3352 #ifdef DEBUG_METAGEMM_VERBOSE
   3353   std::cout << __FILE__ << "(" << __LINE__
   3354             << ") RowMajorWithSum<uint8_t, 6, 8, 4, RowMajorWithSum>::Pack()"
   3355             << std::endl
   3356             << std::flush;
   3357 #endif
   3358 #endif
   3359   int params_count_copy = params.count;
   3360   asm volatile(
   3361       "add r0, %[in], %[stride]\n"
   3362       "add r1, r0, %[stride]\n"
   3363       "add r2, r1, %[stride]\n"
   3364       "add r3, r2, %[stride]\n"
   3365       "add r4, r3, %[stride]\n"
   3366       "vmov.i16 q8, #0\n"
   3367       "vmov.i16 q9, #0\n"
   3368       "vmov.i16 q10, #0\n"
   3369       "vmov.i16 q11, #0\n"
   3370       "vmov.i16 q12, #0\n"
   3371       "vmov.i16 q13, #0\n"
   3372 
   3373       // Reduce count by leftovers.
   3374       "subs %[count], %[count], #4\n"
   3375       "beq 2f\n"
   3376 
   3377       "1:"
   3378       "subs %[count], %[count], #8\n"
   3379 
   3380       // Load Aggregate Store: 6x8.
   3381       "vld1.32 {d0}, [%[in]]!\n"
   3382       "vld1.32 {d1}, [r0]!\n"
   3383       "vld1.32 {d2}, [r1]!\n"
   3384       "vld1.32 {d3}, [r2]!\n"
   3385       "vld1.32 {d4}, [r3]!\n"
   3386       "vld1.32 {d5}, [r4]!\n"
   3387       "vaddw.u8 q8, q8, d0\n"
   3388       "vaddw.u8 q9, q9, d1\n"
   3389       "vaddw.u8 q10, q10, d2\n"
   3390       "vaddw.u8 q11, q11, d3\n"
   3391       "vaddw.u8 q12, q12, d4\n"
   3392       "vaddw.u8 q13, q13, d5\n"
   3393       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3394       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3395 
   3396       "bne 1b\n"
   3397 
   3398       "2:"
   3399 
   3400       // Load Aggregate Store: 6x4.
   3401       "vmov.i8 d0, #0\n"
   3402       "vmov.i8 d1, #0\n"
   3403       "vmov.i8 d2, #0\n"
   3404       "vmov.i8 d3, #0\n"
   3405       "vmov.i8 d4, #0\n"
   3406       "vmov.i8 d5, #0\n"
   3407       "vld1.32 {d0[0]}, [%[in]]!\n"
   3408       "vld1.32 {d1[0]}, [r0]!\n"
   3409       "vld1.32 {d2[0]}, [r1]!\n"
   3410       "vld1.32 {d3[0]}, [r2]!\n"
   3411       "vld1.32 {d4[0]}, [r3]!\n"
   3412       "vld1.32 {d5[0]}, [r4]!\n"
   3413       "vaddw.u8 q8, q8, d0\n"
   3414       "vaddw.u8 q9, q9, d1\n"
   3415       "vaddw.u8 q10, q10, d2\n"
   3416       "vaddw.u8 q11, q11, d3\n"
   3417       "vaddw.u8 q12, q12, d4\n"
   3418       "vaddw.u8 q13, q13, d5\n"
   3419       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3420       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3421 
   3422       // Aggregator Reduction.
   3423       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3424       "vdup.32 q1, %[additive_sum_offset]\n"
   3425       "vpaddl.u16 q8, q8\n"
   3426       "vpaddl.u16 q9, q9\n"
   3427       "vpaddl.u16 q10, q10\n"
   3428       "vpaddl.u16 q11, q11\n"
   3429       "vpaddl.u16 q12, q12\n"
   3430       "vpaddl.u16 q13, q13\n"
   3431       "vpadd.u32 d16, d16, d17\n"
   3432       "vpadd.u32 d18, d18, d19\n"
   3433       "vpadd.u32 d20, d20, d21\n"
   3434       "vpadd.u32 d22, d22, d23\n"
   3435       "vpadd.u32 d24, d24, d25\n"
   3436       "vpadd.u32 d26, d26, d27\n"
   3437       "vpadd.u32 d16, d16, d18\n"
   3438       "vpadd.u32 d17, d20, d22\n"
   3439       "vpadd.u32 d18, d24, d26\n"
   3440       "vmul.i32 q8, q8, d0[0]\n"
   3441       "vmul.i32 q9, q9, d0[0]\n"
   3442       "vadd.i32 q8, q8, q1\n"
   3443       "vadd.i32 q9, q9, q1\n"
   3444       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3445       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3446       : [stride] "r"(params.stride),
   3447         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3448         [additive_sum_offset] "r"(params.additive_sum_offset)
   3449       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3450         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3451         "d27", "cc", "memory");
   3452 }
   3453 
   3454 template <>
   3455 inline void Stream<uint8_t, 6, 8, 5, RowMajorWithSum>::Pack(
   3456     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3457 #ifdef DEBUG
   3458 #ifdef DEBUG_METAGEMM_VERBOSE
   3459   std::cout << __FILE__ << "(" << __LINE__
   3460             << ") RowMajorWithSum<uint8_t, 6, 8, 5, RowMajorWithSum>::Pack()"
   3461             << std::endl
   3462             << std::flush;
   3463 #endif
   3464 #endif
   3465   int params_count_copy = params.count;
   3466   asm volatile(
   3467       "add r0, %[in], %[stride]\n"
   3468       "add r1, r0, %[stride]\n"
   3469       "add r2, r1, %[stride]\n"
   3470       "add r3, r2, %[stride]\n"
   3471       "add r4, r3, %[stride]\n"
   3472       "vmov.i16 q8, #0\n"
   3473       "vmov.i16 q9, #0\n"
   3474       "vmov.i16 q10, #0\n"
   3475       "vmov.i16 q11, #0\n"
   3476       "vmov.i16 q12, #0\n"
   3477       "vmov.i16 q13, #0\n"
   3478 
   3479       // Reduce count by leftovers.
   3480       "subs %[count], %[count], #5\n"
   3481       "beq 2f\n"
   3482 
   3483       "1:"
   3484       "subs %[count], %[count], #8\n"
   3485 
   3486       // Load Aggregate Store: 6x8.
   3487       "vld1.32 {d0}, [%[in]]!\n"
   3488       "vld1.32 {d1}, [r0]!\n"
   3489       "vld1.32 {d2}, [r1]!\n"
   3490       "vld1.32 {d3}, [r2]!\n"
   3491       "vld1.32 {d4}, [r3]!\n"
   3492       "vld1.32 {d5}, [r4]!\n"
   3493       "vaddw.u8 q8, q8, d0\n"
   3494       "vaddw.u8 q9, q9, d1\n"
   3495       "vaddw.u8 q10, q10, d2\n"
   3496       "vaddw.u8 q11, q11, d3\n"
   3497       "vaddw.u8 q12, q12, d4\n"
   3498       "vaddw.u8 q13, q13, d5\n"
   3499       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3500       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3501 
   3502       "bne 1b\n"
   3503 
   3504       "2:"
   3505 
   3506       // Load Aggregate Store: 6x5.
   3507       "vmov.i8 d0, #0\n"
   3508       "vmov.i8 d1, #0\n"
   3509       "vmov.i8 d2, #0\n"
   3510       "vmov.i8 d3, #0\n"
   3511       "vmov.i8 d4, #0\n"
   3512       "vmov.i8 d5, #0\n"
   3513       "vld1.32 {d0[0]}, [%[in]]!\n"
   3514       "vld1.8 {d0[4]}, [%[in]]!\n"
   3515       "vld1.32 {d1[0]}, [r0]!\n"
   3516       "vld1.8 {d1[4]}, [r0]!\n"
   3517       "vld1.32 {d2[0]}, [r1]!\n"
   3518       "vld1.8 {d2[4]}, [r1]!\n"
   3519       "vld1.32 {d3[0]}, [r2]!\n"
   3520       "vld1.8 {d3[4]}, [r2]!\n"
   3521       "vld1.32 {d4[0]}, [r3]!\n"
   3522       "vld1.8 {d4[4]}, [r3]!\n"
   3523       "vld1.32 {d5[0]}, [r4]!\n"
   3524       "vld1.8 {d5[4]}, [r4]!\n"
   3525       "vaddw.u8 q8, q8, d0\n"
   3526       "vaddw.u8 q9, q9, d1\n"
   3527       "vaddw.u8 q10, q10, d2\n"
   3528       "vaddw.u8 q11, q11, d3\n"
   3529       "vaddw.u8 q12, q12, d4\n"
   3530       "vaddw.u8 q13, q13, d5\n"
   3531       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3532       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3533 
   3534       // Aggregator Reduction.
   3535       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3536       "vdup.32 q1, %[additive_sum_offset]\n"
   3537       "vpaddl.u16 q8, q8\n"
   3538       "vpaddl.u16 q9, q9\n"
   3539       "vpaddl.u16 q10, q10\n"
   3540       "vpaddl.u16 q11, q11\n"
   3541       "vpaddl.u16 q12, q12\n"
   3542       "vpaddl.u16 q13, q13\n"
   3543       "vpadd.u32 d16, d16, d17\n"
   3544       "vpadd.u32 d18, d18, d19\n"
   3545       "vpadd.u32 d20, d20, d21\n"
   3546       "vpadd.u32 d22, d22, d23\n"
   3547       "vpadd.u32 d24, d24, d25\n"
   3548       "vpadd.u32 d26, d26, d27\n"
   3549       "vpadd.u32 d16, d16, d18\n"
   3550       "vpadd.u32 d17, d20, d22\n"
   3551       "vpadd.u32 d18, d24, d26\n"
   3552       "vmul.i32 q8, q8, d0[0]\n"
   3553       "vmul.i32 q9, q9, d0[0]\n"
   3554       "vadd.i32 q8, q8, q1\n"
   3555       "vadd.i32 q9, q9, q1\n"
   3556       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3557       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3558       : [stride] "r"(params.stride),
   3559         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3560         [additive_sum_offset] "r"(params.additive_sum_offset)
   3561       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3562         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3563         "d27", "cc", "memory");
   3564 }
   3565 
   3566 template <>
   3567 inline void Stream<uint8_t, 6, 8, 6, RowMajorWithSum>::Pack(
   3568     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3569 #ifdef DEBUG
   3570 #ifdef DEBUG_METAGEMM_VERBOSE
   3571   std::cout << __FILE__ << "(" << __LINE__
   3572             << ") RowMajorWithSum<uint8_t, 6, 8, 6, RowMajorWithSum>::Pack()"
   3573             << std::endl
   3574             << std::flush;
   3575 #endif
   3576 #endif
   3577   int params_count_copy = params.count;
   3578   asm volatile(
   3579       "add r0, %[in], %[stride]\n"
   3580       "add r1, r0, %[stride]\n"
   3581       "add r2, r1, %[stride]\n"
   3582       "add r3, r2, %[stride]\n"
   3583       "add r4, r3, %[stride]\n"
   3584       "vmov.i16 q8, #0\n"
   3585       "vmov.i16 q9, #0\n"
   3586       "vmov.i16 q10, #0\n"
   3587       "vmov.i16 q11, #0\n"
   3588       "vmov.i16 q12, #0\n"
   3589       "vmov.i16 q13, #0\n"
   3590 
   3591       // Reduce count by leftovers.
   3592       "subs %[count], %[count], #6\n"
   3593       "beq 2f\n"
   3594 
   3595       "1:"
   3596       "subs %[count], %[count], #8\n"
   3597 
   3598       // Load Aggregate Store: 6x8.
   3599       "vld1.32 {d0}, [%[in]]!\n"
   3600       "vld1.32 {d1}, [r0]!\n"
   3601       "vld1.32 {d2}, [r1]!\n"
   3602       "vld1.32 {d3}, [r2]!\n"
   3603       "vld1.32 {d4}, [r3]!\n"
   3604       "vld1.32 {d5}, [r4]!\n"
   3605       "vaddw.u8 q8, q8, d0\n"
   3606       "vaddw.u8 q9, q9, d1\n"
   3607       "vaddw.u8 q10, q10, d2\n"
   3608       "vaddw.u8 q11, q11, d3\n"
   3609       "vaddw.u8 q12, q12, d4\n"
   3610       "vaddw.u8 q13, q13, d5\n"
   3611       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3612       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3613 
   3614       "bne 1b\n"
   3615 
   3616       "2:"
   3617 
   3618       // Load Aggregate Store: 6x6.
   3619       "vmov.i8 d0, #0\n"
   3620       "vmov.i8 d1, #0\n"
   3621       "vmov.i8 d2, #0\n"
   3622       "vmov.i8 d3, #0\n"
   3623       "vmov.i8 d4, #0\n"
   3624       "vmov.i8 d5, #0\n"
   3625       "vld1.32 {d0[0]}, [%[in]]!\n"
   3626       "vld1.16 {d0[2]}, [%[in]]!\n"
   3627       "vld1.32 {d1[0]}, [r0]!\n"
   3628       "vld1.16 {d1[2]}, [r0]!\n"
   3629       "vld1.32 {d2[0]}, [r1]!\n"
   3630       "vld1.16 {d2[2]}, [r1]!\n"
   3631       "vld1.32 {d3[0]}, [r2]!\n"
   3632       "vld1.16 {d3[2]}, [r2]!\n"
   3633       "vld1.32 {d4[0]}, [r3]!\n"
   3634       "vld1.16 {d4[2]}, [r3]!\n"
   3635       "vld1.32 {d5[0]}, [r4]!\n"
   3636       "vld1.16 {d5[2]}, [r4]!\n"
   3637       "vaddw.u8 q8, q8, d0\n"
   3638       "vaddw.u8 q9, q9, d1\n"
   3639       "vaddw.u8 q10, q10, d2\n"
   3640       "vaddw.u8 q11, q11, d3\n"
   3641       "vaddw.u8 q12, q12, d4\n"
   3642       "vaddw.u8 q13, q13, d5\n"
   3643       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3644       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3645 
   3646       // Aggregator Reduction.
   3647       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3648       "vdup.32 q1, %[additive_sum_offset]\n"
   3649       "vpaddl.u16 q8, q8\n"
   3650       "vpaddl.u16 q9, q9\n"
   3651       "vpaddl.u16 q10, q10\n"
   3652       "vpaddl.u16 q11, q11\n"
   3653       "vpaddl.u16 q12, q12\n"
   3654       "vpaddl.u16 q13, q13\n"
   3655       "vpadd.u32 d16, d16, d17\n"
   3656       "vpadd.u32 d18, d18, d19\n"
   3657       "vpadd.u32 d20, d20, d21\n"
   3658       "vpadd.u32 d22, d22, d23\n"
   3659       "vpadd.u32 d24, d24, d25\n"
   3660       "vpadd.u32 d26, d26, d27\n"
   3661       "vpadd.u32 d16, d16, d18\n"
   3662       "vpadd.u32 d17, d20, d22\n"
   3663       "vpadd.u32 d18, d24, d26\n"
   3664       "vmul.i32 q8, q8, d0[0]\n"
   3665       "vmul.i32 q9, q9, d0[0]\n"
   3666       "vadd.i32 q8, q8, q1\n"
   3667       "vadd.i32 q9, q9, q1\n"
   3668       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3669       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3670       : [stride] "r"(params.stride),
   3671         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3672         [additive_sum_offset] "r"(params.additive_sum_offset)
   3673       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3674         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3675         "d27", "cc", "memory");
   3676 }
   3677 
   3678 template <>
   3679 inline void Stream<uint8_t, 6, 8, 7, RowMajorWithSum>::Pack(
   3680     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3681 #ifdef DEBUG
   3682 #ifdef DEBUG_METAGEMM_VERBOSE
   3683   std::cout << __FILE__ << "(" << __LINE__
   3684             << ") RowMajorWithSum<uint8_t, 6, 8, 7, RowMajorWithSum>::Pack()"
   3685             << std::endl
   3686             << std::flush;
   3687 #endif
   3688 #endif
   3689   int params_count_copy = params.count;
   3690   asm volatile(
   3691       "add r0, %[in], %[stride]\n"
   3692       "add r1, r0, %[stride]\n"
   3693       "add r2, r1, %[stride]\n"
   3694       "add r3, r2, %[stride]\n"
   3695       "add r4, r3, %[stride]\n"
   3696       "vmov.i16 q8, #0\n"
   3697       "vmov.i16 q9, #0\n"
   3698       "vmov.i16 q10, #0\n"
   3699       "vmov.i16 q11, #0\n"
   3700       "vmov.i16 q12, #0\n"
   3701       "vmov.i16 q13, #0\n"
   3702 
   3703       // Reduce count by leftovers.
   3704       "subs %[count], %[count], #7\n"
   3705       "beq 2f\n"
   3706 
   3707       "1:"
   3708       "subs %[count], %[count], #8\n"
   3709 
   3710       // Load Aggregate Store: 6x8.
   3711       "vld1.32 {d0}, [%[in]]!\n"
   3712       "vld1.32 {d1}, [r0]!\n"
   3713       "vld1.32 {d2}, [r1]!\n"
   3714       "vld1.32 {d3}, [r2]!\n"
   3715       "vld1.32 {d4}, [r3]!\n"
   3716       "vld1.32 {d5}, [r4]!\n"
   3717       "vaddw.u8 q8, q8, d0\n"
   3718       "vaddw.u8 q9, q9, d1\n"
   3719       "vaddw.u8 q10, q10, d2\n"
   3720       "vaddw.u8 q11, q11, d3\n"
   3721       "vaddw.u8 q12, q12, d4\n"
   3722       "vaddw.u8 q13, q13, d5\n"
   3723       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3724       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3725 
   3726       "bne 1b\n"
   3727 
   3728       "2:"
   3729 
   3730       // Load Aggregate Store: 6x7.
   3731       "vmov.i8 d0, #0\n"
   3732       "vmov.i8 d1, #0\n"
   3733       "vmov.i8 d2, #0\n"
   3734       "vmov.i8 d3, #0\n"
   3735       "vmov.i8 d4, #0\n"
   3736       "vmov.i8 d5, #0\n"
   3737       "vld1.32 {d0[0]}, [%[in]]!\n"
   3738       "vld1.16 {d0[2]}, [%[in]]!\n"
   3739       "vld1.8 {d0[6]}, [%[in]]!\n"
   3740       "vld1.32 {d1[0]}, [r0]!\n"
   3741       "vld1.16 {d1[2]}, [r0]!\n"
   3742       "vld1.8 {d1[6]}, [r0]!\n"
   3743       "vld1.32 {d2[0]}, [r1]!\n"
   3744       "vld1.16 {d2[2]}, [r1]!\n"
   3745       "vld1.8 {d2[6]}, [r1]!\n"
   3746       "vld1.32 {d3[0]}, [r2]!\n"
   3747       "vld1.16 {d3[2]}, [r2]!\n"
   3748       "vld1.8 {d3[6]}, [r2]!\n"
   3749       "vld1.32 {d4[0]}, [r3]!\n"
   3750       "vld1.16 {d4[2]}, [r3]!\n"
   3751       "vld1.8 {d4[6]}, [r3]!\n"
   3752       "vld1.32 {d5[0]}, [r4]!\n"
   3753       "vld1.16 {d5[2]}, [r4]!\n"
   3754       "vld1.8 {d5[6]}, [r4]!\n"
   3755       "vaddw.u8 q8, q8, d0\n"
   3756       "vaddw.u8 q9, q9, d1\n"
   3757       "vaddw.u8 q10, q10, d2\n"
   3758       "vaddw.u8 q11, q11, d3\n"
   3759       "vaddw.u8 q12, q12, d4\n"
   3760       "vaddw.u8 q13, q13, d5\n"
   3761       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   3762       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   3763 
   3764       // Aggregator Reduction.
   3765       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   3766       "vdup.32 q1, %[additive_sum_offset]\n"
   3767       "vpaddl.u16 q8, q8\n"
   3768       "vpaddl.u16 q9, q9\n"
   3769       "vpaddl.u16 q10, q10\n"
   3770       "vpaddl.u16 q11, q11\n"
   3771       "vpaddl.u16 q12, q12\n"
   3772       "vpaddl.u16 q13, q13\n"
   3773       "vpadd.u32 d16, d16, d17\n"
   3774       "vpadd.u32 d18, d18, d19\n"
   3775       "vpadd.u32 d20, d20, d21\n"
   3776       "vpadd.u32 d22, d22, d23\n"
   3777       "vpadd.u32 d24, d24, d25\n"
   3778       "vpadd.u32 d26, d26, d27\n"
   3779       "vpadd.u32 d16, d16, d18\n"
   3780       "vpadd.u32 d17, d20, d22\n"
   3781       "vpadd.u32 d18, d24, d26\n"
   3782       "vmul.i32 q8, q8, d0[0]\n"
   3783       "vmul.i32 q9, q9, d0[0]\n"
   3784       "vadd.i32 q8, q8, q1\n"
   3785       "vadd.i32 q9, q9, q1\n"
   3786       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   3787       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3788       : [stride] "r"(params.stride),
   3789         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset),
   3790         [additive_sum_offset] "r"(params.additive_sum_offset)
   3791       : "r0", "r1", "r2", "r3", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d16",
   3792         "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26",
   3793         "d27", "cc", "memory");
   3794 }
   3795 
   3796 template <>
   3797 inline void Stream<uint8_t, 7, 8, 0, RowMajorWithSum>::Pack(
   3798     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3799 #ifdef DEBUG
   3800 #ifdef DEBUG_METAGEMM_VERBOSE
   3801   std::cout << __FILE__ << "(" << __LINE__
   3802             << ") RowMajorWithSum<uint8_t, 7, 8, 0, RowMajorWithSum>::Pack()"
   3803             << std::endl
   3804             << std::flush;
   3805 #endif
   3806 #endif
   3807   int params_count_copy = params.count;
   3808   asm volatile(
   3809       "add r0, %[in], %[stride]\n"
   3810       "add r1, r0, %[stride]\n"
   3811       "add r2, r1, %[stride]\n"
   3812       "add r3, r2, %[stride]\n"
   3813       "add r4, r3, %[stride]\n"
   3814       "add r5, r4, %[stride]\n"
   3815       "vmov.i16 q8, #0\n"
   3816       "vmov.i16 q9, #0\n"
   3817       "vmov.i16 q10, #0\n"
   3818       "vmov.i16 q11, #0\n"
   3819       "vmov.i16 q12, #0\n"
   3820       "vmov.i16 q13, #0\n"
   3821       "vmov.i16 q14, #0\n"
   3822 
   3823       "1:"
   3824       "subs %[count], %[count], #8\n"
   3825 
   3826       // Load Aggregate Store: 7x8.
   3827       "vld1.32 {d0}, [%[in]]!\n"
   3828       "vld1.32 {d1}, [r0]!\n"
   3829       "vld1.32 {d2}, [r1]!\n"
   3830       "vld1.32 {d3}, [r2]!\n"
   3831       "vld1.32 {d4}, [r3]!\n"
   3832       "vld1.32 {d5}, [r4]!\n"
   3833       "vld1.32 {d6}, [r5]!\n"
   3834       "vaddw.u8 q8, q8, d0\n"
   3835       "vaddw.u8 q9, q9, d1\n"
   3836       "vaddw.u8 q10, q10, d2\n"
   3837       "vaddw.u8 q11, q11, d3\n"
   3838       "vaddw.u8 q12, q12, d4\n"
   3839       "vaddw.u8 q13, q13, d5\n"
   3840       "vaddw.u8 q14, q14, d6\n"
   3841       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   3842       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   3843 
   3844       "bne 1b\n"
   3845 
   3846       // Aggregator Reduction.
   3847       "ldr r0, %[multiplicative_sum_offset]\n"
   3848       "ldr r1, %[additive_sum_offset]\n"
   3849       "vmov.32 d0[0], r0\n"
   3850       "vdup.32 q1, r1\n"
   3851       "vpaddl.u16 q8, q8\n"
   3852       "vpaddl.u16 q9, q9\n"
   3853       "vpaddl.u16 q10, q10\n"
   3854       "vpaddl.u16 q11, q11\n"
   3855       "vpaddl.u16 q12, q12\n"
   3856       "vpaddl.u16 q13, q13\n"
   3857       "vpaddl.u16 q14, q14\n"
   3858       "vpadd.u32 d16, d16, d17\n"
   3859       "vpadd.u32 d18, d18, d19\n"
   3860       "vpadd.u32 d20, d20, d21\n"
   3861       "vpadd.u32 d22, d22, d23\n"
   3862       "vpadd.u32 d24, d24, d25\n"
   3863       "vpadd.u32 d26, d26, d27\n"
   3864       "vpadd.u32 d28, d28, d29\n"
   3865       "vpadd.u32 d16, d16, d18\n"
   3866       "vpadd.u32 d17, d20, d22\n"
   3867       "vpadd.u32 d18, d24, d26\n"
   3868       "vpadd.u32 d19, d28, d28\n"
   3869       "vmul.i32 q8, q8, d0[0]\n"
   3870       "vmul.i32 q9, q9, d0[0]\n"
   3871       "vadd.i32 q8, q8, q1\n"
   3872       "vadd.i32 q9, q9, q1\n"
   3873       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   3874       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3875       : [stride] "r"(params.stride),
   3876         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   3877         [additive_sum_offset] "m"(params.additive_sum_offset)
   3878       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   3879         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   3880         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   3881 }
   3882 
   3883 template <>
   3884 inline void Stream<uint8_t, 7, 8, 1, RowMajorWithSum>::Pack(
   3885     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   3886 #ifdef DEBUG
   3887 #ifdef DEBUG_METAGEMM_VERBOSE
   3888   std::cout << __FILE__ << "(" << __LINE__
   3889             << ") RowMajorWithSum<uint8_t, 7, 8, 1, RowMajorWithSum>::Pack()"
   3890             << std::endl
   3891             << std::flush;
   3892 #endif
   3893 #endif
   3894   int params_count_copy = params.count;
   3895   asm volatile(
   3896       "add r0, %[in], %[stride]\n"
   3897       "add r1, r0, %[stride]\n"
   3898       "add r2, r1, %[stride]\n"
   3899       "add r3, r2, %[stride]\n"
   3900       "add r4, r3, %[stride]\n"
   3901       "add r5, r4, %[stride]\n"
   3902       "vmov.i16 q8, #0\n"
   3903       "vmov.i16 q9, #0\n"
   3904       "vmov.i16 q10, #0\n"
   3905       "vmov.i16 q11, #0\n"
   3906       "vmov.i16 q12, #0\n"
   3907       "vmov.i16 q13, #0\n"
   3908       "vmov.i16 q14, #0\n"
   3909 
   3910       // Reduce count by leftovers.
   3911       "subs %[count], %[count], #1\n"
   3912       "beq 2f\n"
   3913 
   3914       "1:"
   3915       "subs %[count], %[count], #8\n"
   3916 
   3917       // Load Aggregate Store: 7x8.
   3918       "vld1.32 {d0}, [%[in]]!\n"
   3919       "vld1.32 {d1}, [r0]!\n"
   3920       "vld1.32 {d2}, [r1]!\n"
   3921       "vld1.32 {d3}, [r2]!\n"
   3922       "vld1.32 {d4}, [r3]!\n"
   3923       "vld1.32 {d5}, [r4]!\n"
   3924       "vld1.32 {d6}, [r5]!\n"
   3925       "vaddw.u8 q8, q8, d0\n"
   3926       "vaddw.u8 q9, q9, d1\n"
   3927       "vaddw.u8 q10, q10, d2\n"
   3928       "vaddw.u8 q11, q11, d3\n"
   3929       "vaddw.u8 q12, q12, d4\n"
   3930       "vaddw.u8 q13, q13, d5\n"
   3931       "vaddw.u8 q14, q14, d6\n"
   3932       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   3933       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   3934 
   3935       "bne 1b\n"
   3936 
   3937       "2:"
   3938 
   3939       // Load Aggregate Store: 7x1.
   3940       "vmov.i8 d0, #0\n"
   3941       "vmov.i8 d1, #0\n"
   3942       "vmov.i8 d2, #0\n"
   3943       "vmov.i8 d3, #0\n"
   3944       "vmov.i8 d4, #0\n"
   3945       "vmov.i8 d5, #0\n"
   3946       "vmov.i8 d6, #0\n"
   3947       "vld1.8 {d0[0]}, [%[in]]!\n"
   3948       "vld1.8 {d1[0]}, [r0]!\n"
   3949       "vld1.8 {d2[0]}, [r1]!\n"
   3950       "vld1.8 {d3[0]}, [r2]!\n"
   3951       "vld1.8 {d4[0]}, [r3]!\n"
   3952       "vld1.8 {d5[0]}, [r4]!\n"
   3953       "vld1.8 {d6[0]}, [r5]!\n"
   3954       "vaddw.u8 q8, q8, d0\n"
   3955       "vaddw.u8 q9, q9, d1\n"
   3956       "vaddw.u8 q10, q10, d2\n"
   3957       "vaddw.u8 q11, q11, d3\n"
   3958       "vaddw.u8 q12, q12, d4\n"
   3959       "vaddw.u8 q13, q13, d5\n"
   3960       "vaddw.u8 q14, q14, d6\n"
   3961       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   3962       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   3963 
   3964       // Aggregator Reduction.
   3965       "ldr r0, %[multiplicative_sum_offset]\n"
   3966       "ldr r1, %[additive_sum_offset]\n"
   3967       "vmov.32 d0[0], r0\n"
   3968       "vdup.32 q1, r1\n"
   3969       "vpaddl.u16 q8, q8\n"
   3970       "vpaddl.u16 q9, q9\n"
   3971       "vpaddl.u16 q10, q10\n"
   3972       "vpaddl.u16 q11, q11\n"
   3973       "vpaddl.u16 q12, q12\n"
   3974       "vpaddl.u16 q13, q13\n"
   3975       "vpaddl.u16 q14, q14\n"
   3976       "vpadd.u32 d16, d16, d17\n"
   3977       "vpadd.u32 d18, d18, d19\n"
   3978       "vpadd.u32 d20, d20, d21\n"
   3979       "vpadd.u32 d22, d22, d23\n"
   3980       "vpadd.u32 d24, d24, d25\n"
   3981       "vpadd.u32 d26, d26, d27\n"
   3982       "vpadd.u32 d28, d28, d29\n"
   3983       "vpadd.u32 d16, d16, d18\n"
   3984       "vpadd.u32 d17, d20, d22\n"
   3985       "vpadd.u32 d18, d24, d26\n"
   3986       "vpadd.u32 d19, d28, d28\n"
   3987       "vmul.i32 q8, q8, d0[0]\n"
   3988       "vmul.i32 q9, q9, d0[0]\n"
   3989       "vadd.i32 q8, q8, q1\n"
   3990       "vadd.i32 q9, q9, q1\n"
   3991       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   3992       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   3993       : [stride] "r"(params.stride),
   3994         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   3995         [additive_sum_offset] "m"(params.additive_sum_offset)
   3996       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   3997         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   3998         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   3999 }
   4000 
   4001 template <>
   4002 inline void Stream<uint8_t, 7, 8, 2, RowMajorWithSum>::Pack(
   4003     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4004 #ifdef DEBUG
   4005 #ifdef DEBUG_METAGEMM_VERBOSE
   4006   std::cout << __FILE__ << "(" << __LINE__
   4007             << ") RowMajorWithSum<uint8_t, 7, 8, 2, RowMajorWithSum>::Pack()"
   4008             << std::endl
   4009             << std::flush;
   4010 #endif
   4011 #endif
   4012   int params_count_copy = params.count;
   4013   asm volatile(
   4014       "add r0, %[in], %[stride]\n"
   4015       "add r1, r0, %[stride]\n"
   4016       "add r2, r1, %[stride]\n"
   4017       "add r3, r2, %[stride]\n"
   4018       "add r4, r3, %[stride]\n"
   4019       "add r5, r4, %[stride]\n"
   4020       "vmov.i16 q8, #0\n"
   4021       "vmov.i16 q9, #0\n"
   4022       "vmov.i16 q10, #0\n"
   4023       "vmov.i16 q11, #0\n"
   4024       "vmov.i16 q12, #0\n"
   4025       "vmov.i16 q13, #0\n"
   4026       "vmov.i16 q14, #0\n"
   4027 
   4028       // Reduce count by leftovers.
   4029       "subs %[count], %[count], #2\n"
   4030       "beq 2f\n"
   4031 
   4032       "1:"
   4033       "subs %[count], %[count], #8\n"
   4034 
   4035       // Load Aggregate Store: 7x8.
   4036       "vld1.32 {d0}, [%[in]]!\n"
   4037       "vld1.32 {d1}, [r0]!\n"
   4038       "vld1.32 {d2}, [r1]!\n"
   4039       "vld1.32 {d3}, [r2]!\n"
   4040       "vld1.32 {d4}, [r3]!\n"
   4041       "vld1.32 {d5}, [r4]!\n"
   4042       "vld1.32 {d6}, [r5]!\n"
   4043       "vaddw.u8 q8, q8, d0\n"
   4044       "vaddw.u8 q9, q9, d1\n"
   4045       "vaddw.u8 q10, q10, d2\n"
   4046       "vaddw.u8 q11, q11, d3\n"
   4047       "vaddw.u8 q12, q12, d4\n"
   4048       "vaddw.u8 q13, q13, d5\n"
   4049       "vaddw.u8 q14, q14, d6\n"
   4050       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4051       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4052 
   4053       "bne 1b\n"
   4054 
   4055       "2:"
   4056 
   4057       // Load Aggregate Store: 7x2.
   4058       "vmov.i8 d0, #0\n"
   4059       "vmov.i8 d1, #0\n"
   4060       "vmov.i8 d2, #0\n"
   4061       "vmov.i8 d3, #0\n"
   4062       "vmov.i8 d4, #0\n"
   4063       "vmov.i8 d5, #0\n"
   4064       "vmov.i8 d6, #0\n"
   4065       "vld1.16 {d0[0]}, [%[in]]!\n"
   4066       "vld1.16 {d1[0]}, [r0]!\n"
   4067       "vld1.16 {d2[0]}, [r1]!\n"
   4068       "vld1.16 {d3[0]}, [r2]!\n"
   4069       "vld1.16 {d4[0]}, [r3]!\n"
   4070       "vld1.16 {d5[0]}, [r4]!\n"
   4071       "vld1.16 {d6[0]}, [r5]!\n"
   4072       "vaddw.u8 q8, q8, d0\n"
   4073       "vaddw.u8 q9, q9, d1\n"
   4074       "vaddw.u8 q10, q10, d2\n"
   4075       "vaddw.u8 q11, q11, d3\n"
   4076       "vaddw.u8 q12, q12, d4\n"
   4077       "vaddw.u8 q13, q13, d5\n"
   4078       "vaddw.u8 q14, q14, d6\n"
   4079       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4080       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4081 
   4082       // Aggregator Reduction.
   4083       "ldr r0, %[multiplicative_sum_offset]\n"
   4084       "ldr r1, %[additive_sum_offset]\n"
   4085       "vmov.32 d0[0], r0\n"
   4086       "vdup.32 q1, r1\n"
   4087       "vpaddl.u16 q8, q8\n"
   4088       "vpaddl.u16 q9, q9\n"
   4089       "vpaddl.u16 q10, q10\n"
   4090       "vpaddl.u16 q11, q11\n"
   4091       "vpaddl.u16 q12, q12\n"
   4092       "vpaddl.u16 q13, q13\n"
   4093       "vpaddl.u16 q14, q14\n"
   4094       "vpadd.u32 d16, d16, d17\n"
   4095       "vpadd.u32 d18, d18, d19\n"
   4096       "vpadd.u32 d20, d20, d21\n"
   4097       "vpadd.u32 d22, d22, d23\n"
   4098       "vpadd.u32 d24, d24, d25\n"
   4099       "vpadd.u32 d26, d26, d27\n"
   4100       "vpadd.u32 d28, d28, d29\n"
   4101       "vpadd.u32 d16, d16, d18\n"
   4102       "vpadd.u32 d17, d20, d22\n"
   4103       "vpadd.u32 d18, d24, d26\n"
   4104       "vpadd.u32 d19, d28, d28\n"
   4105       "vmul.i32 q8, q8, d0[0]\n"
   4106       "vmul.i32 q9, q9, d0[0]\n"
   4107       "vadd.i32 q8, q8, q1\n"
   4108       "vadd.i32 q9, q9, q1\n"
   4109       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4110       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4111       : [stride] "r"(params.stride),
   4112         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4113         [additive_sum_offset] "m"(params.additive_sum_offset)
   4114       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4115         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4116         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4117 }
   4118 
   4119 template <>
   4120 inline void Stream<uint8_t, 7, 8, 3, RowMajorWithSum>::Pack(
   4121     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4122 #ifdef DEBUG
   4123 #ifdef DEBUG_METAGEMM_VERBOSE
   4124   std::cout << __FILE__ << "(" << __LINE__
   4125             << ") RowMajorWithSum<uint8_t, 7, 8, 3, RowMajorWithSum>::Pack()"
   4126             << std::endl
   4127             << std::flush;
   4128 #endif
   4129 #endif
   4130   int params_count_copy = params.count;
   4131   asm volatile(
   4132       "add r0, %[in], %[stride]\n"
   4133       "add r1, r0, %[stride]\n"
   4134       "add r2, r1, %[stride]\n"
   4135       "add r3, r2, %[stride]\n"
   4136       "add r4, r3, %[stride]\n"
   4137       "add r5, r4, %[stride]\n"
   4138       "vmov.i16 q8, #0\n"
   4139       "vmov.i16 q9, #0\n"
   4140       "vmov.i16 q10, #0\n"
   4141       "vmov.i16 q11, #0\n"
   4142       "vmov.i16 q12, #0\n"
   4143       "vmov.i16 q13, #0\n"
   4144       "vmov.i16 q14, #0\n"
   4145 
   4146       // Reduce count by leftovers.
   4147       "subs %[count], %[count], #3\n"
   4148       "beq 2f\n"
   4149 
   4150       "1:"
   4151       "subs %[count], %[count], #8\n"
   4152 
   4153       // Load Aggregate Store: 7x8.
   4154       "vld1.32 {d0}, [%[in]]!\n"
   4155       "vld1.32 {d1}, [r0]!\n"
   4156       "vld1.32 {d2}, [r1]!\n"
   4157       "vld1.32 {d3}, [r2]!\n"
   4158       "vld1.32 {d4}, [r3]!\n"
   4159       "vld1.32 {d5}, [r4]!\n"
   4160       "vld1.32 {d6}, [r5]!\n"
   4161       "vaddw.u8 q8, q8, d0\n"
   4162       "vaddw.u8 q9, q9, d1\n"
   4163       "vaddw.u8 q10, q10, d2\n"
   4164       "vaddw.u8 q11, q11, d3\n"
   4165       "vaddw.u8 q12, q12, d4\n"
   4166       "vaddw.u8 q13, q13, d5\n"
   4167       "vaddw.u8 q14, q14, d6\n"
   4168       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4169       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4170 
   4171       "bne 1b\n"
   4172 
   4173       "2:"
   4174 
   4175       // Load Aggregate Store: 7x3.
   4176       "vmov.i8 d0, #0\n"
   4177       "vmov.i8 d1, #0\n"
   4178       "vmov.i8 d2, #0\n"
   4179       "vmov.i8 d3, #0\n"
   4180       "vmov.i8 d4, #0\n"
   4181       "vmov.i8 d5, #0\n"
   4182       "vmov.i8 d6, #0\n"
   4183       "vld1.16 {d0[0]}, [%[in]]!\n"
   4184       "vld1.8 {d0[2]}, [%[in]]!\n"
   4185       "vld1.16 {d1[0]}, [r0]!\n"
   4186       "vld1.8 {d1[2]}, [r0]!\n"
   4187       "vld1.16 {d2[0]}, [r1]!\n"
   4188       "vld1.8 {d2[2]}, [r1]!\n"
   4189       "vld1.16 {d3[0]}, [r2]!\n"
   4190       "vld1.8 {d3[2]}, [r2]!\n"
   4191       "vld1.16 {d4[0]}, [r3]!\n"
   4192       "vld1.8 {d4[2]}, [r3]!\n"
   4193       "vld1.16 {d5[0]}, [r4]!\n"
   4194       "vld1.8 {d5[2]}, [r4]!\n"
   4195       "vld1.16 {d6[0]}, [r5]!\n"
   4196       "vld1.8 {d6[2]}, [r5]!\n"
   4197       "vaddw.u8 q8, q8, d0\n"
   4198       "vaddw.u8 q9, q9, d1\n"
   4199       "vaddw.u8 q10, q10, d2\n"
   4200       "vaddw.u8 q11, q11, d3\n"
   4201       "vaddw.u8 q12, q12, d4\n"
   4202       "vaddw.u8 q13, q13, d5\n"
   4203       "vaddw.u8 q14, q14, d6\n"
   4204       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4205       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4206 
   4207       // Aggregator Reduction.
   4208       "ldr r0, %[multiplicative_sum_offset]\n"
   4209       "ldr r1, %[additive_sum_offset]\n"
   4210       "vmov.32 d0[0], r0\n"
   4211       "vdup.32 q1, r1\n"
   4212       "vpaddl.u16 q8, q8\n"
   4213       "vpaddl.u16 q9, q9\n"
   4214       "vpaddl.u16 q10, q10\n"
   4215       "vpaddl.u16 q11, q11\n"
   4216       "vpaddl.u16 q12, q12\n"
   4217       "vpaddl.u16 q13, q13\n"
   4218       "vpaddl.u16 q14, q14\n"
   4219       "vpadd.u32 d16, d16, d17\n"
   4220       "vpadd.u32 d18, d18, d19\n"
   4221       "vpadd.u32 d20, d20, d21\n"
   4222       "vpadd.u32 d22, d22, d23\n"
   4223       "vpadd.u32 d24, d24, d25\n"
   4224       "vpadd.u32 d26, d26, d27\n"
   4225       "vpadd.u32 d28, d28, d29\n"
   4226       "vpadd.u32 d16, d16, d18\n"
   4227       "vpadd.u32 d17, d20, d22\n"
   4228       "vpadd.u32 d18, d24, d26\n"
   4229       "vpadd.u32 d19, d28, d28\n"
   4230       "vmul.i32 q8, q8, d0[0]\n"
   4231       "vmul.i32 q9, q9, d0[0]\n"
   4232       "vadd.i32 q8, q8, q1\n"
   4233       "vadd.i32 q9, q9, q1\n"
   4234       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4235       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4236       : [stride] "r"(params.stride),
   4237         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4238         [additive_sum_offset] "m"(params.additive_sum_offset)
   4239       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4240         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4241         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4242 }
   4243 
   4244 template <>
   4245 inline void Stream<uint8_t, 7, 8, 4, RowMajorWithSum>::Pack(
   4246     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4247 #ifdef DEBUG
   4248 #ifdef DEBUG_METAGEMM_VERBOSE
   4249   std::cout << __FILE__ << "(" << __LINE__
   4250             << ") RowMajorWithSum<uint8_t, 7, 8, 4, RowMajorWithSum>::Pack()"
   4251             << std::endl
   4252             << std::flush;
   4253 #endif
   4254 #endif
   4255   int params_count_copy = params.count;
   4256   asm volatile(
   4257       "add r0, %[in], %[stride]\n"
   4258       "add r1, r0, %[stride]\n"
   4259       "add r2, r1, %[stride]\n"
   4260       "add r3, r2, %[stride]\n"
   4261       "add r4, r3, %[stride]\n"
   4262       "add r5, r4, %[stride]\n"
   4263       "vmov.i16 q8, #0\n"
   4264       "vmov.i16 q9, #0\n"
   4265       "vmov.i16 q10, #0\n"
   4266       "vmov.i16 q11, #0\n"
   4267       "vmov.i16 q12, #0\n"
   4268       "vmov.i16 q13, #0\n"
   4269       "vmov.i16 q14, #0\n"
   4270 
   4271       // Reduce count by leftovers.
   4272       "subs %[count], %[count], #4\n"
   4273       "beq 2f\n"
   4274 
   4275       "1:"
   4276       "subs %[count], %[count], #8\n"
   4277 
   4278       // Load Aggregate Store: 7x8.
   4279       "vld1.32 {d0}, [%[in]]!\n"
   4280       "vld1.32 {d1}, [r0]!\n"
   4281       "vld1.32 {d2}, [r1]!\n"
   4282       "vld1.32 {d3}, [r2]!\n"
   4283       "vld1.32 {d4}, [r3]!\n"
   4284       "vld1.32 {d5}, [r4]!\n"
   4285       "vld1.32 {d6}, [r5]!\n"
   4286       "vaddw.u8 q8, q8, d0\n"
   4287       "vaddw.u8 q9, q9, d1\n"
   4288       "vaddw.u8 q10, q10, d2\n"
   4289       "vaddw.u8 q11, q11, d3\n"
   4290       "vaddw.u8 q12, q12, d4\n"
   4291       "vaddw.u8 q13, q13, d5\n"
   4292       "vaddw.u8 q14, q14, d6\n"
   4293       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4294       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4295 
   4296       "bne 1b\n"
   4297 
   4298       "2:"
   4299 
   4300       // Load Aggregate Store: 7x4.
   4301       "vmov.i8 d0, #0\n"
   4302       "vmov.i8 d1, #0\n"
   4303       "vmov.i8 d2, #0\n"
   4304       "vmov.i8 d3, #0\n"
   4305       "vmov.i8 d4, #0\n"
   4306       "vmov.i8 d5, #0\n"
   4307       "vmov.i8 d6, #0\n"
   4308       "vld1.32 {d0[0]}, [%[in]]!\n"
   4309       "vld1.32 {d1[0]}, [r0]!\n"
   4310       "vld1.32 {d2[0]}, [r1]!\n"
   4311       "vld1.32 {d3[0]}, [r2]!\n"
   4312       "vld1.32 {d4[0]}, [r3]!\n"
   4313       "vld1.32 {d5[0]}, [r4]!\n"
   4314       "vld1.32 {d6[0]}, [r5]!\n"
   4315       "vaddw.u8 q8, q8, d0\n"
   4316       "vaddw.u8 q9, q9, d1\n"
   4317       "vaddw.u8 q10, q10, d2\n"
   4318       "vaddw.u8 q11, q11, d3\n"
   4319       "vaddw.u8 q12, q12, d4\n"
   4320       "vaddw.u8 q13, q13, d5\n"
   4321       "vaddw.u8 q14, q14, d6\n"
   4322       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4323       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4324 
   4325       // Aggregator Reduction.
   4326       "ldr r0, %[multiplicative_sum_offset]\n"
   4327       "ldr r1, %[additive_sum_offset]\n"
   4328       "vmov.32 d0[0], r0\n"
   4329       "vdup.32 q1, r1\n"
   4330       "vpaddl.u16 q8, q8\n"
   4331       "vpaddl.u16 q9, q9\n"
   4332       "vpaddl.u16 q10, q10\n"
   4333       "vpaddl.u16 q11, q11\n"
   4334       "vpaddl.u16 q12, q12\n"
   4335       "vpaddl.u16 q13, q13\n"
   4336       "vpaddl.u16 q14, q14\n"
   4337       "vpadd.u32 d16, d16, d17\n"
   4338       "vpadd.u32 d18, d18, d19\n"
   4339       "vpadd.u32 d20, d20, d21\n"
   4340       "vpadd.u32 d22, d22, d23\n"
   4341       "vpadd.u32 d24, d24, d25\n"
   4342       "vpadd.u32 d26, d26, d27\n"
   4343       "vpadd.u32 d28, d28, d29\n"
   4344       "vpadd.u32 d16, d16, d18\n"
   4345       "vpadd.u32 d17, d20, d22\n"
   4346       "vpadd.u32 d18, d24, d26\n"
   4347       "vpadd.u32 d19, d28, d28\n"
   4348       "vmul.i32 q8, q8, d0[0]\n"
   4349       "vmul.i32 q9, q9, d0[0]\n"
   4350       "vadd.i32 q8, q8, q1\n"
   4351       "vadd.i32 q9, q9, q1\n"
   4352       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4353       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4354       : [stride] "r"(params.stride),
   4355         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4356         [additive_sum_offset] "m"(params.additive_sum_offset)
   4357       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4358         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4359         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4360 }
   4361 
   4362 template <>
   4363 inline void Stream<uint8_t, 7, 8, 5, RowMajorWithSum>::Pack(
   4364     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4365 #ifdef DEBUG
   4366 #ifdef DEBUG_METAGEMM_VERBOSE
   4367   std::cout << __FILE__ << "(" << __LINE__
   4368             << ") RowMajorWithSum<uint8_t, 7, 8, 5, RowMajorWithSum>::Pack()"
   4369             << std::endl
   4370             << std::flush;
   4371 #endif
   4372 #endif
   4373   int params_count_copy = params.count;
   4374   asm volatile(
   4375       "add r0, %[in], %[stride]\n"
   4376       "add r1, r0, %[stride]\n"
   4377       "add r2, r1, %[stride]\n"
   4378       "add r3, r2, %[stride]\n"
   4379       "add r4, r3, %[stride]\n"
   4380       "add r5, r4, %[stride]\n"
   4381       "vmov.i16 q8, #0\n"
   4382       "vmov.i16 q9, #0\n"
   4383       "vmov.i16 q10, #0\n"
   4384       "vmov.i16 q11, #0\n"
   4385       "vmov.i16 q12, #0\n"
   4386       "vmov.i16 q13, #0\n"
   4387       "vmov.i16 q14, #0\n"
   4388 
   4389       // Reduce count by leftovers.
   4390       "subs %[count], %[count], #5\n"
   4391       "beq 2f\n"
   4392 
   4393       "1:"
   4394       "subs %[count], %[count], #8\n"
   4395 
   4396       // Load Aggregate Store: 7x8.
   4397       "vld1.32 {d0}, [%[in]]!\n"
   4398       "vld1.32 {d1}, [r0]!\n"
   4399       "vld1.32 {d2}, [r1]!\n"
   4400       "vld1.32 {d3}, [r2]!\n"
   4401       "vld1.32 {d4}, [r3]!\n"
   4402       "vld1.32 {d5}, [r4]!\n"
   4403       "vld1.32 {d6}, [r5]!\n"
   4404       "vaddw.u8 q8, q8, d0\n"
   4405       "vaddw.u8 q9, q9, d1\n"
   4406       "vaddw.u8 q10, q10, d2\n"
   4407       "vaddw.u8 q11, q11, d3\n"
   4408       "vaddw.u8 q12, q12, d4\n"
   4409       "vaddw.u8 q13, q13, d5\n"
   4410       "vaddw.u8 q14, q14, d6\n"
   4411       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4412       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4413 
   4414       "bne 1b\n"
   4415 
   4416       "2:"
   4417 
   4418       // Load Aggregate Store: 7x5.
   4419       "vmov.i8 d0, #0\n"
   4420       "vmov.i8 d1, #0\n"
   4421       "vmov.i8 d2, #0\n"
   4422       "vmov.i8 d3, #0\n"
   4423       "vmov.i8 d4, #0\n"
   4424       "vmov.i8 d5, #0\n"
   4425       "vmov.i8 d6, #0\n"
   4426       "vld1.32 {d0[0]}, [%[in]]!\n"
   4427       "vld1.8 {d0[4]}, [%[in]]!\n"
   4428       "vld1.32 {d1[0]}, [r0]!\n"
   4429       "vld1.8 {d1[4]}, [r0]!\n"
   4430       "vld1.32 {d2[0]}, [r1]!\n"
   4431       "vld1.8 {d2[4]}, [r1]!\n"
   4432       "vld1.32 {d3[0]}, [r2]!\n"
   4433       "vld1.8 {d3[4]}, [r2]!\n"
   4434       "vld1.32 {d4[0]}, [r3]!\n"
   4435       "vld1.8 {d4[4]}, [r3]!\n"
   4436       "vld1.32 {d5[0]}, [r4]!\n"
   4437       "vld1.8 {d5[4]}, [r4]!\n"
   4438       "vld1.32 {d6[0]}, [r5]!\n"
   4439       "vld1.8 {d6[4]}, [r5]!\n"
   4440       "vaddw.u8 q8, q8, d0\n"
   4441       "vaddw.u8 q9, q9, d1\n"
   4442       "vaddw.u8 q10, q10, d2\n"
   4443       "vaddw.u8 q11, q11, d3\n"
   4444       "vaddw.u8 q12, q12, d4\n"
   4445       "vaddw.u8 q13, q13, d5\n"
   4446       "vaddw.u8 q14, q14, d6\n"
   4447       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4448       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4449 
   4450       // Aggregator Reduction.
   4451       "ldr r0, %[multiplicative_sum_offset]\n"
   4452       "ldr r1, %[additive_sum_offset]\n"
   4453       "vmov.32 d0[0], r0\n"
   4454       "vdup.32 q1, r1\n"
   4455       "vpaddl.u16 q8, q8\n"
   4456       "vpaddl.u16 q9, q9\n"
   4457       "vpaddl.u16 q10, q10\n"
   4458       "vpaddl.u16 q11, q11\n"
   4459       "vpaddl.u16 q12, q12\n"
   4460       "vpaddl.u16 q13, q13\n"
   4461       "vpaddl.u16 q14, q14\n"
   4462       "vpadd.u32 d16, d16, d17\n"
   4463       "vpadd.u32 d18, d18, d19\n"
   4464       "vpadd.u32 d20, d20, d21\n"
   4465       "vpadd.u32 d22, d22, d23\n"
   4466       "vpadd.u32 d24, d24, d25\n"
   4467       "vpadd.u32 d26, d26, d27\n"
   4468       "vpadd.u32 d28, d28, d29\n"
   4469       "vpadd.u32 d16, d16, d18\n"
   4470       "vpadd.u32 d17, d20, d22\n"
   4471       "vpadd.u32 d18, d24, d26\n"
   4472       "vpadd.u32 d19, d28, d28\n"
   4473       "vmul.i32 q8, q8, d0[0]\n"
   4474       "vmul.i32 q9, q9, d0[0]\n"
   4475       "vadd.i32 q8, q8, q1\n"
   4476       "vadd.i32 q9, q9, q1\n"
   4477       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4478       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4479       : [stride] "r"(params.stride),
   4480         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4481         [additive_sum_offset] "m"(params.additive_sum_offset)
   4482       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4483         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4484         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4485 }
   4486 
   4487 template <>
   4488 inline void Stream<uint8_t, 7, 8, 6, RowMajorWithSum>::Pack(
   4489     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4490 #ifdef DEBUG
   4491 #ifdef DEBUG_METAGEMM_VERBOSE
   4492   std::cout << __FILE__ << "(" << __LINE__
   4493             << ") RowMajorWithSum<uint8_t, 7, 8, 6, RowMajorWithSum>::Pack()"
   4494             << std::endl
   4495             << std::flush;
   4496 #endif
   4497 #endif
   4498   int params_count_copy = params.count;
   4499   asm volatile(
   4500       "add r0, %[in], %[stride]\n"
   4501       "add r1, r0, %[stride]\n"
   4502       "add r2, r1, %[stride]\n"
   4503       "add r3, r2, %[stride]\n"
   4504       "add r4, r3, %[stride]\n"
   4505       "add r5, r4, %[stride]\n"
   4506       "vmov.i16 q8, #0\n"
   4507       "vmov.i16 q9, #0\n"
   4508       "vmov.i16 q10, #0\n"
   4509       "vmov.i16 q11, #0\n"
   4510       "vmov.i16 q12, #0\n"
   4511       "vmov.i16 q13, #0\n"
   4512       "vmov.i16 q14, #0\n"
   4513 
   4514       // Reduce count by leftovers.
   4515       "subs %[count], %[count], #6\n"
   4516       "beq 2f\n"
   4517 
   4518       "1:"
   4519       "subs %[count], %[count], #8\n"
   4520 
   4521       // Load Aggregate Store: 7x8.
   4522       "vld1.32 {d0}, [%[in]]!\n"
   4523       "vld1.32 {d1}, [r0]!\n"
   4524       "vld1.32 {d2}, [r1]!\n"
   4525       "vld1.32 {d3}, [r2]!\n"
   4526       "vld1.32 {d4}, [r3]!\n"
   4527       "vld1.32 {d5}, [r4]!\n"
   4528       "vld1.32 {d6}, [r5]!\n"
   4529       "vaddw.u8 q8, q8, d0\n"
   4530       "vaddw.u8 q9, q9, d1\n"
   4531       "vaddw.u8 q10, q10, d2\n"
   4532       "vaddw.u8 q11, q11, d3\n"
   4533       "vaddw.u8 q12, q12, d4\n"
   4534       "vaddw.u8 q13, q13, d5\n"
   4535       "vaddw.u8 q14, q14, d6\n"
   4536       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4537       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4538 
   4539       "bne 1b\n"
   4540 
   4541       "2:"
   4542 
   4543       // Load Aggregate Store: 7x6.
   4544       "vmov.i8 d0, #0\n"
   4545       "vmov.i8 d1, #0\n"
   4546       "vmov.i8 d2, #0\n"
   4547       "vmov.i8 d3, #0\n"
   4548       "vmov.i8 d4, #0\n"
   4549       "vmov.i8 d5, #0\n"
   4550       "vmov.i8 d6, #0\n"
   4551       "vld1.32 {d0[0]}, [%[in]]!\n"
   4552       "vld1.16 {d0[2]}, [%[in]]!\n"
   4553       "vld1.32 {d1[0]}, [r0]!\n"
   4554       "vld1.16 {d1[2]}, [r0]!\n"
   4555       "vld1.32 {d2[0]}, [r1]!\n"
   4556       "vld1.16 {d2[2]}, [r1]!\n"
   4557       "vld1.32 {d3[0]}, [r2]!\n"
   4558       "vld1.16 {d3[2]}, [r2]!\n"
   4559       "vld1.32 {d4[0]}, [r3]!\n"
   4560       "vld1.16 {d4[2]}, [r3]!\n"
   4561       "vld1.32 {d5[0]}, [r4]!\n"
   4562       "vld1.16 {d5[2]}, [r4]!\n"
   4563       "vld1.32 {d6[0]}, [r5]!\n"
   4564       "vld1.16 {d6[2]}, [r5]!\n"
   4565       "vaddw.u8 q8, q8, d0\n"
   4566       "vaddw.u8 q9, q9, d1\n"
   4567       "vaddw.u8 q10, q10, d2\n"
   4568       "vaddw.u8 q11, q11, d3\n"
   4569       "vaddw.u8 q12, q12, d4\n"
   4570       "vaddw.u8 q13, q13, d5\n"
   4571       "vaddw.u8 q14, q14, d6\n"
   4572       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4573       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4574 
   4575       // Aggregator Reduction.
   4576       "ldr r0, %[multiplicative_sum_offset]\n"
   4577       "ldr r1, %[additive_sum_offset]\n"
   4578       "vmov.32 d0[0], r0\n"
   4579       "vdup.32 q1, r1\n"
   4580       "vpaddl.u16 q8, q8\n"
   4581       "vpaddl.u16 q9, q9\n"
   4582       "vpaddl.u16 q10, q10\n"
   4583       "vpaddl.u16 q11, q11\n"
   4584       "vpaddl.u16 q12, q12\n"
   4585       "vpaddl.u16 q13, q13\n"
   4586       "vpaddl.u16 q14, q14\n"
   4587       "vpadd.u32 d16, d16, d17\n"
   4588       "vpadd.u32 d18, d18, d19\n"
   4589       "vpadd.u32 d20, d20, d21\n"
   4590       "vpadd.u32 d22, d22, d23\n"
   4591       "vpadd.u32 d24, d24, d25\n"
   4592       "vpadd.u32 d26, d26, d27\n"
   4593       "vpadd.u32 d28, d28, d29\n"
   4594       "vpadd.u32 d16, d16, d18\n"
   4595       "vpadd.u32 d17, d20, d22\n"
   4596       "vpadd.u32 d18, d24, d26\n"
   4597       "vpadd.u32 d19, d28, d28\n"
   4598       "vmul.i32 q8, q8, d0[0]\n"
   4599       "vmul.i32 q9, q9, d0[0]\n"
   4600       "vadd.i32 q8, q8, q1\n"
   4601       "vadd.i32 q9, q9, q1\n"
   4602       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4603       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4604       : [stride] "r"(params.stride),
   4605         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4606         [additive_sum_offset] "m"(params.additive_sum_offset)
   4607       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4608         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4609         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4610 }
   4611 
   4612 template <>
   4613 inline void Stream<uint8_t, 7, 8, 7, RowMajorWithSum>::Pack(
   4614     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4615 #ifdef DEBUG
   4616 #ifdef DEBUG_METAGEMM_VERBOSE
   4617   std::cout << __FILE__ << "(" << __LINE__
   4618             << ") RowMajorWithSum<uint8_t, 7, 8, 7, RowMajorWithSum>::Pack()"
   4619             << std::endl
   4620             << std::flush;
   4621 #endif
   4622 #endif
   4623   int params_count_copy = params.count;
   4624   asm volatile(
   4625       "add r0, %[in], %[stride]\n"
   4626       "add r1, r0, %[stride]\n"
   4627       "add r2, r1, %[stride]\n"
   4628       "add r3, r2, %[stride]\n"
   4629       "add r4, r3, %[stride]\n"
   4630       "add r5, r4, %[stride]\n"
   4631       "vmov.i16 q8, #0\n"
   4632       "vmov.i16 q9, #0\n"
   4633       "vmov.i16 q10, #0\n"
   4634       "vmov.i16 q11, #0\n"
   4635       "vmov.i16 q12, #0\n"
   4636       "vmov.i16 q13, #0\n"
   4637       "vmov.i16 q14, #0\n"
   4638 
   4639       // Reduce count by leftovers.
   4640       "subs %[count], %[count], #7\n"
   4641       "beq 2f\n"
   4642 
   4643       "1:"
   4644       "subs %[count], %[count], #8\n"
   4645 
   4646       // Load Aggregate Store: 7x8.
   4647       "vld1.32 {d0}, [%[in]]!\n"
   4648       "vld1.32 {d1}, [r0]!\n"
   4649       "vld1.32 {d2}, [r1]!\n"
   4650       "vld1.32 {d3}, [r2]!\n"
   4651       "vld1.32 {d4}, [r3]!\n"
   4652       "vld1.32 {d5}, [r4]!\n"
   4653       "vld1.32 {d6}, [r5]!\n"
   4654       "vaddw.u8 q8, q8, d0\n"
   4655       "vaddw.u8 q9, q9, d1\n"
   4656       "vaddw.u8 q10, q10, d2\n"
   4657       "vaddw.u8 q11, q11, d3\n"
   4658       "vaddw.u8 q12, q12, d4\n"
   4659       "vaddw.u8 q13, q13, d5\n"
   4660       "vaddw.u8 q14, q14, d6\n"
   4661       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4662       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4663 
   4664       "bne 1b\n"
   4665 
   4666       "2:"
   4667 
   4668       // Load Aggregate Store: 7x7.
   4669       "vmov.i8 d0, #0\n"
   4670       "vmov.i8 d1, #0\n"
   4671       "vmov.i8 d2, #0\n"
   4672       "vmov.i8 d3, #0\n"
   4673       "vmov.i8 d4, #0\n"
   4674       "vmov.i8 d5, #0\n"
   4675       "vmov.i8 d6, #0\n"
   4676       "vld1.32 {d0[0]}, [%[in]]!\n"
   4677       "vld1.16 {d0[2]}, [%[in]]!\n"
   4678       "vld1.8 {d0[6]}, [%[in]]!\n"
   4679       "vld1.32 {d1[0]}, [r0]!\n"
   4680       "vld1.16 {d1[2]}, [r0]!\n"
   4681       "vld1.8 {d1[6]}, [r0]!\n"
   4682       "vld1.32 {d2[0]}, [r1]!\n"
   4683       "vld1.16 {d2[2]}, [r1]!\n"
   4684       "vld1.8 {d2[6]}, [r1]!\n"
   4685       "vld1.32 {d3[0]}, [r2]!\n"
   4686       "vld1.16 {d3[2]}, [r2]!\n"
   4687       "vld1.8 {d3[6]}, [r2]!\n"
   4688       "vld1.32 {d4[0]}, [r3]!\n"
   4689       "vld1.16 {d4[2]}, [r3]!\n"
   4690       "vld1.8 {d4[6]}, [r3]!\n"
   4691       "vld1.32 {d5[0]}, [r4]!\n"
   4692       "vld1.16 {d5[2]}, [r4]!\n"
   4693       "vld1.8 {d5[6]}, [r4]!\n"
   4694       "vld1.32 {d6[0]}, [r5]!\n"
   4695       "vld1.16 {d6[2]}, [r5]!\n"
   4696       "vld1.8 {d6[6]}, [r5]!\n"
   4697       "vaddw.u8 q8, q8, d0\n"
   4698       "vaddw.u8 q9, q9, d1\n"
   4699       "vaddw.u8 q10, q10, d2\n"
   4700       "vaddw.u8 q11, q11, d3\n"
   4701       "vaddw.u8 q12, q12, d4\n"
   4702       "vaddw.u8 q13, q13, d5\n"
   4703       "vaddw.u8 q14, q14, d6\n"
   4704       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   4705       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   4706 
   4707       // Aggregator Reduction.
   4708       "ldr r0, %[multiplicative_sum_offset]\n"
   4709       "ldr r1, %[additive_sum_offset]\n"
   4710       "vmov.32 d0[0], r0\n"
   4711       "vdup.32 q1, r1\n"
   4712       "vpaddl.u16 q8, q8\n"
   4713       "vpaddl.u16 q9, q9\n"
   4714       "vpaddl.u16 q10, q10\n"
   4715       "vpaddl.u16 q11, q11\n"
   4716       "vpaddl.u16 q12, q12\n"
   4717       "vpaddl.u16 q13, q13\n"
   4718       "vpaddl.u16 q14, q14\n"
   4719       "vpadd.u32 d16, d16, d17\n"
   4720       "vpadd.u32 d18, d18, d19\n"
   4721       "vpadd.u32 d20, d20, d21\n"
   4722       "vpadd.u32 d22, d22, d23\n"
   4723       "vpadd.u32 d24, d24, d25\n"
   4724       "vpadd.u32 d26, d26, d27\n"
   4725       "vpadd.u32 d28, d28, d29\n"
   4726       "vpadd.u32 d16, d16, d18\n"
   4727       "vpadd.u32 d17, d20, d22\n"
   4728       "vpadd.u32 d18, d24, d26\n"
   4729       "vpadd.u32 d19, d28, d28\n"
   4730       "vmul.i32 q8, q8, d0[0]\n"
   4731       "vmul.i32 q9, q9, d0[0]\n"
   4732       "vadd.i32 q8, q8, q1\n"
   4733       "vadd.i32 q9, q9, q1\n"
   4734       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   4735       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4736       : [stride] "r"(params.stride),
   4737         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4738         [additive_sum_offset] "m"(params.additive_sum_offset)
   4739       : "r0", "r1", "r2", "r3", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5",
   4740         "d6", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
   4741         "d25", "d26", "d27", "d28", "d29", "cc", "memory");
   4742 }
   4743 
   4744 template <>
   4745 inline void Stream<uint8_t, 8, 8, 0, RowMajorWithSum>::Pack(
   4746     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4747 #ifdef DEBUG
   4748 #ifdef DEBUG_METAGEMM_VERBOSE
   4749   std::cout << __FILE__ << "(" << __LINE__
   4750             << ") RowMajorWithSum<uint8_t, 8, 8, 0, RowMajorWithSum>::Pack()"
   4751             << std::endl
   4752             << std::flush;
   4753 #endif
   4754 #endif
   4755   int params_count_copy = params.count;
   4756   asm volatile(
   4757       "add r0, %[in], %[stride]\n"
   4758       "add r1, r0, %[stride]\n"
   4759       "add r2, r1, %[stride]\n"
   4760       "add r3, r2, %[stride]\n"
   4761       "add r4, r3, %[stride]\n"
   4762       "add r5, r4, %[stride]\n"
   4763       "add r6, r5, %[stride]\n"
   4764       "vmov.i16 q8, #0\n"
   4765       "vmov.i16 q9, #0\n"
   4766       "vmov.i16 q10, #0\n"
   4767       "vmov.i16 q11, #0\n"
   4768       "vmov.i16 q12, #0\n"
   4769       "vmov.i16 q13, #0\n"
   4770       "vmov.i16 q14, #0\n"
   4771       "vmov.i16 q15, #0\n"
   4772 
   4773       "1:"
   4774       "subs %[count], %[count], #8\n"
   4775 
   4776       // Load Aggregate Store: 8x8.
   4777       "vld1.32 {d0}, [%[in]]!\n"
   4778       "vld1.32 {d1}, [r0]!\n"
   4779       "vld1.32 {d2}, [r1]!\n"
   4780       "vld1.32 {d3}, [r2]!\n"
   4781       "vld1.32 {d4}, [r3]!\n"
   4782       "vld1.32 {d5}, [r4]!\n"
   4783       "vld1.32 {d6}, [r5]!\n"
   4784       "vld1.32 {d7}, [r6]!\n"
   4785       "vaddw.u8 q8, q8, d0\n"
   4786       "vaddw.u8 q9, q9, d1\n"
   4787       "vaddw.u8 q10, q10, d2\n"
   4788       "vaddw.u8 q11, q11, d3\n"
   4789       "vaddw.u8 q12, q12, d4\n"
   4790       "vaddw.u8 q13, q13, d5\n"
   4791       "vaddw.u8 q14, q14, d6\n"
   4792       "vaddw.u8 q15, q15, d7\n"
   4793       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   4794       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   4795 
   4796       "bne 1b\n"
   4797 
   4798       // Aggregator Reduction.
   4799       "ldr r0, %[multiplicative_sum_offset]\n"
   4800       "ldr r1, %[additive_sum_offset]\n"
   4801       "vmov.32 d0[0], r0\n"
   4802       "vdup.32 q1, r1\n"
   4803       "vpaddl.u16 q8, q8\n"
   4804       "vpaddl.u16 q9, q9\n"
   4805       "vpaddl.u16 q10, q10\n"
   4806       "vpaddl.u16 q11, q11\n"
   4807       "vpaddl.u16 q12, q12\n"
   4808       "vpaddl.u16 q13, q13\n"
   4809       "vpaddl.u16 q14, q14\n"
   4810       "vpaddl.u16 q15, q15\n"
   4811       "vpadd.u32 d16, d16, d17\n"
   4812       "vpadd.u32 d18, d18, d19\n"
   4813       "vpadd.u32 d20, d20, d21\n"
   4814       "vpadd.u32 d22, d22, d23\n"
   4815       "vpadd.u32 d24, d24, d25\n"
   4816       "vpadd.u32 d26, d26, d27\n"
   4817       "vpadd.u32 d28, d28, d29\n"
   4818       "vpadd.u32 d30, d30, d31\n"
   4819       "vpadd.u32 d16, d16, d18\n"
   4820       "vpadd.u32 d17, d20, d22\n"
   4821       "vpadd.u32 d18, d24, d26\n"
   4822       "vpadd.u32 d19, d28, d30\n"
   4823       "vmul.i32 q8, q8, d0[0]\n"
   4824       "vmul.i32 q9, q9, d0[0]\n"
   4825       "vadd.i32 q8, q8, q1\n"
   4826       "vadd.i32 q9, q9, q1\n"
   4827       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   4828       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4829       : [stride] "r"(params.stride),
   4830         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4831         [additive_sum_offset] "m"(params.additive_sum_offset)
   4832       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   4833         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   4834         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   4835         "memory");
   4836 }
   4837 
   4838 template <>
   4839 inline void Stream<uint8_t, 8, 8, 1, RowMajorWithSum>::Pack(
   4840     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4841 #ifdef DEBUG
   4842 #ifdef DEBUG_METAGEMM_VERBOSE
   4843   std::cout << __FILE__ << "(" << __LINE__
   4844             << ") RowMajorWithSum<uint8_t, 8, 8, 1, RowMajorWithSum>::Pack()"
   4845             << std::endl
   4846             << std::flush;
   4847 #endif
   4848 #endif
   4849   int params_count_copy = params.count;
   4850   asm volatile(
   4851       "add r0, %[in], %[stride]\n"
   4852       "add r1, r0, %[stride]\n"
   4853       "add r2, r1, %[stride]\n"
   4854       "add r3, r2, %[stride]\n"
   4855       "add r4, r3, %[stride]\n"
   4856       "add r5, r4, %[stride]\n"
   4857       "add r6, r5, %[stride]\n"
   4858       "vmov.i16 q8, #0\n"
   4859       "vmov.i16 q9, #0\n"
   4860       "vmov.i16 q10, #0\n"
   4861       "vmov.i16 q11, #0\n"
   4862       "vmov.i16 q12, #0\n"
   4863       "vmov.i16 q13, #0\n"
   4864       "vmov.i16 q14, #0\n"
   4865       "vmov.i16 q15, #0\n"
   4866 
   4867       // Reduce count by leftovers.
   4868       "subs %[count], %[count], #1\n"
   4869       "beq 2f\n"
   4870 
   4871       "1:"
   4872       "subs %[count], %[count], #8\n"
   4873 
   4874       // Load Aggregate Store: 8x8.
   4875       "vld1.32 {d0}, [%[in]]!\n"
   4876       "vld1.32 {d1}, [r0]!\n"
   4877       "vld1.32 {d2}, [r1]!\n"
   4878       "vld1.32 {d3}, [r2]!\n"
   4879       "vld1.32 {d4}, [r3]!\n"
   4880       "vld1.32 {d5}, [r4]!\n"
   4881       "vld1.32 {d6}, [r5]!\n"
   4882       "vld1.32 {d7}, [r6]!\n"
   4883       "vaddw.u8 q8, q8, d0\n"
   4884       "vaddw.u8 q9, q9, d1\n"
   4885       "vaddw.u8 q10, q10, d2\n"
   4886       "vaddw.u8 q11, q11, d3\n"
   4887       "vaddw.u8 q12, q12, d4\n"
   4888       "vaddw.u8 q13, q13, d5\n"
   4889       "vaddw.u8 q14, q14, d6\n"
   4890       "vaddw.u8 q15, q15, d7\n"
   4891       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   4892       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   4893 
   4894       "bne 1b\n"
   4895 
   4896       "2:"
   4897 
   4898       // Load Aggregate Store: 8x1.
   4899       "vmov.i8 d0, #0\n"
   4900       "vmov.i8 d1, #0\n"
   4901       "vmov.i8 d2, #0\n"
   4902       "vmov.i8 d3, #0\n"
   4903       "vmov.i8 d4, #0\n"
   4904       "vmov.i8 d5, #0\n"
   4905       "vmov.i8 d6, #0\n"
   4906       "vmov.i8 d7, #0\n"
   4907       "vld1.8 {d0[0]}, [%[in]]!\n"
   4908       "vld1.8 {d1[0]}, [r0]!\n"
   4909       "vld1.8 {d2[0]}, [r1]!\n"
   4910       "vld1.8 {d3[0]}, [r2]!\n"
   4911       "vld1.8 {d4[0]}, [r3]!\n"
   4912       "vld1.8 {d5[0]}, [r4]!\n"
   4913       "vld1.8 {d6[0]}, [r5]!\n"
   4914       "vld1.8 {d7[0]}, [r6]!\n"
   4915       "vaddw.u8 q8, q8, d0\n"
   4916       "vaddw.u8 q9, q9, d1\n"
   4917       "vaddw.u8 q10, q10, d2\n"
   4918       "vaddw.u8 q11, q11, d3\n"
   4919       "vaddw.u8 q12, q12, d4\n"
   4920       "vaddw.u8 q13, q13, d5\n"
   4921       "vaddw.u8 q14, q14, d6\n"
   4922       "vaddw.u8 q15, q15, d7\n"
   4923       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   4924       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   4925 
   4926       // Aggregator Reduction.
   4927       "ldr r0, %[multiplicative_sum_offset]\n"
   4928       "ldr r1, %[additive_sum_offset]\n"
   4929       "vmov.32 d0[0], r0\n"
   4930       "vdup.32 q1, r1\n"
   4931       "vpaddl.u16 q8, q8\n"
   4932       "vpaddl.u16 q9, q9\n"
   4933       "vpaddl.u16 q10, q10\n"
   4934       "vpaddl.u16 q11, q11\n"
   4935       "vpaddl.u16 q12, q12\n"
   4936       "vpaddl.u16 q13, q13\n"
   4937       "vpaddl.u16 q14, q14\n"
   4938       "vpaddl.u16 q15, q15\n"
   4939       "vpadd.u32 d16, d16, d17\n"
   4940       "vpadd.u32 d18, d18, d19\n"
   4941       "vpadd.u32 d20, d20, d21\n"
   4942       "vpadd.u32 d22, d22, d23\n"
   4943       "vpadd.u32 d24, d24, d25\n"
   4944       "vpadd.u32 d26, d26, d27\n"
   4945       "vpadd.u32 d28, d28, d29\n"
   4946       "vpadd.u32 d30, d30, d31\n"
   4947       "vpadd.u32 d16, d16, d18\n"
   4948       "vpadd.u32 d17, d20, d22\n"
   4949       "vpadd.u32 d18, d24, d26\n"
   4950       "vpadd.u32 d19, d28, d30\n"
   4951       "vmul.i32 q8, q8, d0[0]\n"
   4952       "vmul.i32 q9, q9, d0[0]\n"
   4953       "vadd.i32 q8, q8, q1\n"
   4954       "vadd.i32 q9, q9, q1\n"
   4955       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   4956       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   4957       : [stride] "r"(params.stride),
   4958         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   4959         [additive_sum_offset] "m"(params.additive_sum_offset)
   4960       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   4961         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   4962         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   4963         "memory");
   4964 }
   4965 
   4966 template <>
   4967 inline void Stream<uint8_t, 8, 8, 2, RowMajorWithSum>::Pack(
   4968     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   4969 #ifdef DEBUG
   4970 #ifdef DEBUG_METAGEMM_VERBOSE
   4971   std::cout << __FILE__ << "(" << __LINE__
   4972             << ") RowMajorWithSum<uint8_t, 8, 8, 2, RowMajorWithSum>::Pack()"
   4973             << std::endl
   4974             << std::flush;
   4975 #endif
   4976 #endif
   4977   int params_count_copy = params.count;
   4978   asm volatile(
   4979       "add r0, %[in], %[stride]\n"
   4980       "add r1, r0, %[stride]\n"
   4981       "add r2, r1, %[stride]\n"
   4982       "add r3, r2, %[stride]\n"
   4983       "add r4, r3, %[stride]\n"
   4984       "add r5, r4, %[stride]\n"
   4985       "add r6, r5, %[stride]\n"
   4986       "vmov.i16 q8, #0\n"
   4987       "vmov.i16 q9, #0\n"
   4988       "vmov.i16 q10, #0\n"
   4989       "vmov.i16 q11, #0\n"
   4990       "vmov.i16 q12, #0\n"
   4991       "vmov.i16 q13, #0\n"
   4992       "vmov.i16 q14, #0\n"
   4993       "vmov.i16 q15, #0\n"
   4994 
   4995       // Reduce count by leftovers.
   4996       "subs %[count], %[count], #2\n"
   4997       "beq 2f\n"
   4998 
   4999       "1:"
   5000       "subs %[count], %[count], #8\n"
   5001 
   5002       // Load Aggregate Store: 8x8.
   5003       "vld1.32 {d0}, [%[in]]!\n"
   5004       "vld1.32 {d1}, [r0]!\n"
   5005       "vld1.32 {d2}, [r1]!\n"
   5006       "vld1.32 {d3}, [r2]!\n"
   5007       "vld1.32 {d4}, [r3]!\n"
   5008       "vld1.32 {d5}, [r4]!\n"
   5009       "vld1.32 {d6}, [r5]!\n"
   5010       "vld1.32 {d7}, [r6]!\n"
   5011       "vaddw.u8 q8, q8, d0\n"
   5012       "vaddw.u8 q9, q9, d1\n"
   5013       "vaddw.u8 q10, q10, d2\n"
   5014       "vaddw.u8 q11, q11, d3\n"
   5015       "vaddw.u8 q12, q12, d4\n"
   5016       "vaddw.u8 q13, q13, d5\n"
   5017       "vaddw.u8 q14, q14, d6\n"
   5018       "vaddw.u8 q15, q15, d7\n"
   5019       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5020       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5021 
   5022       "bne 1b\n"
   5023 
   5024       "2:"
   5025 
   5026       // Load Aggregate Store: 8x2.
   5027       "vmov.i8 d0, #0\n"
   5028       "vmov.i8 d1, #0\n"
   5029       "vmov.i8 d2, #0\n"
   5030       "vmov.i8 d3, #0\n"
   5031       "vmov.i8 d4, #0\n"
   5032       "vmov.i8 d5, #0\n"
   5033       "vmov.i8 d6, #0\n"
   5034       "vmov.i8 d7, #0\n"
   5035       "vld1.16 {d0[0]}, [%[in]]!\n"
   5036       "vld1.16 {d1[0]}, [r0]!\n"
   5037       "vld1.16 {d2[0]}, [r1]!\n"
   5038       "vld1.16 {d3[0]}, [r2]!\n"
   5039       "vld1.16 {d4[0]}, [r3]!\n"
   5040       "vld1.16 {d5[0]}, [r4]!\n"
   5041       "vld1.16 {d6[0]}, [r5]!\n"
   5042       "vld1.16 {d7[0]}, [r6]!\n"
   5043       "vaddw.u8 q8, q8, d0\n"
   5044       "vaddw.u8 q9, q9, d1\n"
   5045       "vaddw.u8 q10, q10, d2\n"
   5046       "vaddw.u8 q11, q11, d3\n"
   5047       "vaddw.u8 q12, q12, d4\n"
   5048       "vaddw.u8 q13, q13, d5\n"
   5049       "vaddw.u8 q14, q14, d6\n"
   5050       "vaddw.u8 q15, q15, d7\n"
   5051       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5052       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5053 
   5054       // Aggregator Reduction.
   5055       "ldr r0, %[multiplicative_sum_offset]\n"
   5056       "ldr r1, %[additive_sum_offset]\n"
   5057       "vmov.32 d0[0], r0\n"
   5058       "vdup.32 q1, r1\n"
   5059       "vpaddl.u16 q8, q8\n"
   5060       "vpaddl.u16 q9, q9\n"
   5061       "vpaddl.u16 q10, q10\n"
   5062       "vpaddl.u16 q11, q11\n"
   5063       "vpaddl.u16 q12, q12\n"
   5064       "vpaddl.u16 q13, q13\n"
   5065       "vpaddl.u16 q14, q14\n"
   5066       "vpaddl.u16 q15, q15\n"
   5067       "vpadd.u32 d16, d16, d17\n"
   5068       "vpadd.u32 d18, d18, d19\n"
   5069       "vpadd.u32 d20, d20, d21\n"
   5070       "vpadd.u32 d22, d22, d23\n"
   5071       "vpadd.u32 d24, d24, d25\n"
   5072       "vpadd.u32 d26, d26, d27\n"
   5073       "vpadd.u32 d28, d28, d29\n"
   5074       "vpadd.u32 d30, d30, d31\n"
   5075       "vpadd.u32 d16, d16, d18\n"
   5076       "vpadd.u32 d17, d20, d22\n"
   5077       "vpadd.u32 d18, d24, d26\n"
   5078       "vpadd.u32 d19, d28, d30\n"
   5079       "vmul.i32 q8, q8, d0[0]\n"
   5080       "vmul.i32 q9, q9, d0[0]\n"
   5081       "vadd.i32 q8, q8, q1\n"
   5082       "vadd.i32 q9, q9, q1\n"
   5083       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5084       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5085       : [stride] "r"(params.stride),
   5086         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5087         [additive_sum_offset] "m"(params.additive_sum_offset)
   5088       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5089         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5090         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5091         "memory");
   5092 }
   5093 
   5094 template <>
   5095 inline void Stream<uint8_t, 8, 8, 3, RowMajorWithSum>::Pack(
   5096     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   5097 #ifdef DEBUG
   5098 #ifdef DEBUG_METAGEMM_VERBOSE
   5099   std::cout << __FILE__ << "(" << __LINE__
   5100             << ") RowMajorWithSum<uint8_t, 8, 8, 3, RowMajorWithSum>::Pack()"
   5101             << std::endl
   5102             << std::flush;
   5103 #endif
   5104 #endif
   5105   int params_count_copy = params.count;
   5106   asm volatile(
   5107       "add r0, %[in], %[stride]\n"
   5108       "add r1, r0, %[stride]\n"
   5109       "add r2, r1, %[stride]\n"
   5110       "add r3, r2, %[stride]\n"
   5111       "add r4, r3, %[stride]\n"
   5112       "add r5, r4, %[stride]\n"
   5113       "add r6, r5, %[stride]\n"
   5114       "vmov.i16 q8, #0\n"
   5115       "vmov.i16 q9, #0\n"
   5116       "vmov.i16 q10, #0\n"
   5117       "vmov.i16 q11, #0\n"
   5118       "vmov.i16 q12, #0\n"
   5119       "vmov.i16 q13, #0\n"
   5120       "vmov.i16 q14, #0\n"
   5121       "vmov.i16 q15, #0\n"
   5122 
   5123       // Reduce count by leftovers.
   5124       "subs %[count], %[count], #3\n"
   5125       "beq 2f\n"
   5126 
   5127       "1:"
   5128       "subs %[count], %[count], #8\n"
   5129 
   5130       // Load Aggregate Store: 8x8.
   5131       "vld1.32 {d0}, [%[in]]!\n"
   5132       "vld1.32 {d1}, [r0]!\n"
   5133       "vld1.32 {d2}, [r1]!\n"
   5134       "vld1.32 {d3}, [r2]!\n"
   5135       "vld1.32 {d4}, [r3]!\n"
   5136       "vld1.32 {d5}, [r4]!\n"
   5137       "vld1.32 {d6}, [r5]!\n"
   5138       "vld1.32 {d7}, [r6]!\n"
   5139       "vaddw.u8 q8, q8, d0\n"
   5140       "vaddw.u8 q9, q9, d1\n"
   5141       "vaddw.u8 q10, q10, d2\n"
   5142       "vaddw.u8 q11, q11, d3\n"
   5143       "vaddw.u8 q12, q12, d4\n"
   5144       "vaddw.u8 q13, q13, d5\n"
   5145       "vaddw.u8 q14, q14, d6\n"
   5146       "vaddw.u8 q15, q15, d7\n"
   5147       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5148       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5149 
   5150       "bne 1b\n"
   5151 
   5152       "2:"
   5153 
   5154       // Load Aggregate Store: 8x3.
   5155       "vmov.i8 d0, #0\n"
   5156       "vmov.i8 d1, #0\n"
   5157       "vmov.i8 d2, #0\n"
   5158       "vmov.i8 d3, #0\n"
   5159       "vmov.i8 d4, #0\n"
   5160       "vmov.i8 d5, #0\n"
   5161       "vmov.i8 d6, #0\n"
   5162       "vmov.i8 d7, #0\n"
   5163       "vld1.16 {d0[0]}, [%[in]]!\n"
   5164       "vld1.8 {d0[2]}, [%[in]]!\n"
   5165       "vld1.16 {d1[0]}, [r0]!\n"
   5166       "vld1.8 {d1[2]}, [r0]!\n"
   5167       "vld1.16 {d2[0]}, [r1]!\n"
   5168       "vld1.8 {d2[2]}, [r1]!\n"
   5169       "vld1.16 {d3[0]}, [r2]!\n"
   5170       "vld1.8 {d3[2]}, [r2]!\n"
   5171       "vld1.16 {d4[0]}, [r3]!\n"
   5172       "vld1.8 {d4[2]}, [r3]!\n"
   5173       "vld1.16 {d5[0]}, [r4]!\n"
   5174       "vld1.8 {d5[2]}, [r4]!\n"
   5175       "vld1.16 {d6[0]}, [r5]!\n"
   5176       "vld1.8 {d6[2]}, [r5]!\n"
   5177       "vld1.16 {d7[0]}, [r6]!\n"
   5178       "vld1.8 {d7[2]}, [r6]!\n"
   5179       "vaddw.u8 q8, q8, d0\n"
   5180       "vaddw.u8 q9, q9, d1\n"
   5181       "vaddw.u8 q10, q10, d2\n"
   5182       "vaddw.u8 q11, q11, d3\n"
   5183       "vaddw.u8 q12, q12, d4\n"
   5184       "vaddw.u8 q13, q13, d5\n"
   5185       "vaddw.u8 q14, q14, d6\n"
   5186       "vaddw.u8 q15, q15, d7\n"
   5187       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5188       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5189 
   5190       // Aggregator Reduction.
   5191       "ldr r0, %[multiplicative_sum_offset]\n"
   5192       "ldr r1, %[additive_sum_offset]\n"
   5193       "vmov.32 d0[0], r0\n"
   5194       "vdup.32 q1, r1\n"
   5195       "vpaddl.u16 q8, q8\n"
   5196       "vpaddl.u16 q9, q9\n"
   5197       "vpaddl.u16 q10, q10\n"
   5198       "vpaddl.u16 q11, q11\n"
   5199       "vpaddl.u16 q12, q12\n"
   5200       "vpaddl.u16 q13, q13\n"
   5201       "vpaddl.u16 q14, q14\n"
   5202       "vpaddl.u16 q15, q15\n"
   5203       "vpadd.u32 d16, d16, d17\n"
   5204       "vpadd.u32 d18, d18, d19\n"
   5205       "vpadd.u32 d20, d20, d21\n"
   5206       "vpadd.u32 d22, d22, d23\n"
   5207       "vpadd.u32 d24, d24, d25\n"
   5208       "vpadd.u32 d26, d26, d27\n"
   5209       "vpadd.u32 d28, d28, d29\n"
   5210       "vpadd.u32 d30, d30, d31\n"
   5211       "vpadd.u32 d16, d16, d18\n"
   5212       "vpadd.u32 d17, d20, d22\n"
   5213       "vpadd.u32 d18, d24, d26\n"
   5214       "vpadd.u32 d19, d28, d30\n"
   5215       "vmul.i32 q8, q8, d0[0]\n"
   5216       "vmul.i32 q9, q9, d0[0]\n"
   5217       "vadd.i32 q8, q8, q1\n"
   5218       "vadd.i32 q9, q9, q1\n"
   5219       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5220       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5221       : [stride] "r"(params.stride),
   5222         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5223         [additive_sum_offset] "m"(params.additive_sum_offset)
   5224       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5225         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5226         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5227         "memory");
   5228 }
   5229 
   5230 template <>
   5231 inline void Stream<uint8_t, 8, 8, 4, RowMajorWithSum>::Pack(
   5232     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   5233 #ifdef DEBUG
   5234 #ifdef DEBUG_METAGEMM_VERBOSE
   5235   std::cout << __FILE__ << "(" << __LINE__
   5236             << ") RowMajorWithSum<uint8_t, 8, 8, 4, RowMajorWithSum>::Pack()"
   5237             << std::endl
   5238             << std::flush;
   5239 #endif
   5240 #endif
   5241   int params_count_copy = params.count;
   5242   asm volatile(
   5243       "add r0, %[in], %[stride]\n"
   5244       "add r1, r0, %[stride]\n"
   5245       "add r2, r1, %[stride]\n"
   5246       "add r3, r2, %[stride]\n"
   5247       "add r4, r3, %[stride]\n"
   5248       "add r5, r4, %[stride]\n"
   5249       "add r6, r5, %[stride]\n"
   5250       "vmov.i16 q8, #0\n"
   5251       "vmov.i16 q9, #0\n"
   5252       "vmov.i16 q10, #0\n"
   5253       "vmov.i16 q11, #0\n"
   5254       "vmov.i16 q12, #0\n"
   5255       "vmov.i16 q13, #0\n"
   5256       "vmov.i16 q14, #0\n"
   5257       "vmov.i16 q15, #0\n"
   5258 
   5259       // Reduce count by leftovers.
   5260       "subs %[count], %[count], #4\n"
   5261       "beq 2f\n"
   5262 
   5263       "1:"
   5264       "subs %[count], %[count], #8\n"
   5265 
   5266       // Load Aggregate Store: 8x8.
   5267       "vld1.32 {d0}, [%[in]]!\n"
   5268       "vld1.32 {d1}, [r0]!\n"
   5269       "vld1.32 {d2}, [r1]!\n"
   5270       "vld1.32 {d3}, [r2]!\n"
   5271       "vld1.32 {d4}, [r3]!\n"
   5272       "vld1.32 {d5}, [r4]!\n"
   5273       "vld1.32 {d6}, [r5]!\n"
   5274       "vld1.32 {d7}, [r6]!\n"
   5275       "vaddw.u8 q8, q8, d0\n"
   5276       "vaddw.u8 q9, q9, d1\n"
   5277       "vaddw.u8 q10, q10, d2\n"
   5278       "vaddw.u8 q11, q11, d3\n"
   5279       "vaddw.u8 q12, q12, d4\n"
   5280       "vaddw.u8 q13, q13, d5\n"
   5281       "vaddw.u8 q14, q14, d6\n"
   5282       "vaddw.u8 q15, q15, d7\n"
   5283       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5284       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5285 
   5286       "bne 1b\n"
   5287 
   5288       "2:"
   5289 
   5290       // Load Aggregate Store: 8x4.
   5291       "vmov.i8 d0, #0\n"
   5292       "vmov.i8 d1, #0\n"
   5293       "vmov.i8 d2, #0\n"
   5294       "vmov.i8 d3, #0\n"
   5295       "vmov.i8 d4, #0\n"
   5296       "vmov.i8 d5, #0\n"
   5297       "vmov.i8 d6, #0\n"
   5298       "vmov.i8 d7, #0\n"
   5299       "vld1.32 {d0[0]}, [%[in]]!\n"
   5300       "vld1.32 {d1[0]}, [r0]!\n"
   5301       "vld1.32 {d2[0]}, [r1]!\n"
   5302       "vld1.32 {d3[0]}, [r2]!\n"
   5303       "vld1.32 {d4[0]}, [r3]!\n"
   5304       "vld1.32 {d5[0]}, [r4]!\n"
   5305       "vld1.32 {d6[0]}, [r5]!\n"
   5306       "vld1.32 {d7[0]}, [r6]!\n"
   5307       "vaddw.u8 q8, q8, d0\n"
   5308       "vaddw.u8 q9, q9, d1\n"
   5309       "vaddw.u8 q10, q10, d2\n"
   5310       "vaddw.u8 q11, q11, d3\n"
   5311       "vaddw.u8 q12, q12, d4\n"
   5312       "vaddw.u8 q13, q13, d5\n"
   5313       "vaddw.u8 q14, q14, d6\n"
   5314       "vaddw.u8 q15, q15, d7\n"
   5315       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5316       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5317 
   5318       // Aggregator Reduction.
   5319       "ldr r0, %[multiplicative_sum_offset]\n"
   5320       "ldr r1, %[additive_sum_offset]\n"
   5321       "vmov.32 d0[0], r0\n"
   5322       "vdup.32 q1, r1\n"
   5323       "vpaddl.u16 q8, q8\n"
   5324       "vpaddl.u16 q9, q9\n"
   5325       "vpaddl.u16 q10, q10\n"
   5326       "vpaddl.u16 q11, q11\n"
   5327       "vpaddl.u16 q12, q12\n"
   5328       "vpaddl.u16 q13, q13\n"
   5329       "vpaddl.u16 q14, q14\n"
   5330       "vpaddl.u16 q15, q15\n"
   5331       "vpadd.u32 d16, d16, d17\n"
   5332       "vpadd.u32 d18, d18, d19\n"
   5333       "vpadd.u32 d20, d20, d21\n"
   5334       "vpadd.u32 d22, d22, d23\n"
   5335       "vpadd.u32 d24, d24, d25\n"
   5336       "vpadd.u32 d26, d26, d27\n"
   5337       "vpadd.u32 d28, d28, d29\n"
   5338       "vpadd.u32 d30, d30, d31\n"
   5339       "vpadd.u32 d16, d16, d18\n"
   5340       "vpadd.u32 d17, d20, d22\n"
   5341       "vpadd.u32 d18, d24, d26\n"
   5342       "vpadd.u32 d19, d28, d30\n"
   5343       "vmul.i32 q8, q8, d0[0]\n"
   5344       "vmul.i32 q9, q9, d0[0]\n"
   5345       "vadd.i32 q8, q8, q1\n"
   5346       "vadd.i32 q9, q9, q1\n"
   5347       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5348       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5349       : [stride] "r"(params.stride),
   5350         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5351         [additive_sum_offset] "m"(params.additive_sum_offset)
   5352       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5353         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5354         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5355         "memory");
   5356 }
   5357 
   5358 template <>
   5359 inline void Stream<uint8_t, 8, 8, 5, RowMajorWithSum>::Pack(
   5360     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   5361 #ifdef DEBUG
   5362 #ifdef DEBUG_METAGEMM_VERBOSE
   5363   std::cout << __FILE__ << "(" << __LINE__
   5364             << ") RowMajorWithSum<uint8_t, 8, 8, 5, RowMajorWithSum>::Pack()"
   5365             << std::endl
   5366             << std::flush;
   5367 #endif
   5368 #endif
   5369   int params_count_copy = params.count;
   5370   asm volatile(
   5371       "add r0, %[in], %[stride]\n"
   5372       "add r1, r0, %[stride]\n"
   5373       "add r2, r1, %[stride]\n"
   5374       "add r3, r2, %[stride]\n"
   5375       "add r4, r3, %[stride]\n"
   5376       "add r5, r4, %[stride]\n"
   5377       "add r6, r5, %[stride]\n"
   5378       "vmov.i16 q8, #0\n"
   5379       "vmov.i16 q9, #0\n"
   5380       "vmov.i16 q10, #0\n"
   5381       "vmov.i16 q11, #0\n"
   5382       "vmov.i16 q12, #0\n"
   5383       "vmov.i16 q13, #0\n"
   5384       "vmov.i16 q14, #0\n"
   5385       "vmov.i16 q15, #0\n"
   5386 
   5387       // Reduce count by leftovers.
   5388       "subs %[count], %[count], #5\n"
   5389       "beq 2f\n"
   5390 
   5391       "1:"
   5392       "subs %[count], %[count], #8\n"
   5393 
   5394       // Load Aggregate Store: 8x8.
   5395       "vld1.32 {d0}, [%[in]]!\n"
   5396       "vld1.32 {d1}, [r0]!\n"
   5397       "vld1.32 {d2}, [r1]!\n"
   5398       "vld1.32 {d3}, [r2]!\n"
   5399       "vld1.32 {d4}, [r3]!\n"
   5400       "vld1.32 {d5}, [r4]!\n"
   5401       "vld1.32 {d6}, [r5]!\n"
   5402       "vld1.32 {d7}, [r6]!\n"
   5403       "vaddw.u8 q8, q8, d0\n"
   5404       "vaddw.u8 q9, q9, d1\n"
   5405       "vaddw.u8 q10, q10, d2\n"
   5406       "vaddw.u8 q11, q11, d3\n"
   5407       "vaddw.u8 q12, q12, d4\n"
   5408       "vaddw.u8 q13, q13, d5\n"
   5409       "vaddw.u8 q14, q14, d6\n"
   5410       "vaddw.u8 q15, q15, d7\n"
   5411       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5412       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5413 
   5414       "bne 1b\n"
   5415 
   5416       "2:"
   5417 
   5418       // Load Aggregate Store: 8x5.
   5419       "vmov.i8 d0, #0\n"
   5420       "vmov.i8 d1, #0\n"
   5421       "vmov.i8 d2, #0\n"
   5422       "vmov.i8 d3, #0\n"
   5423       "vmov.i8 d4, #0\n"
   5424       "vmov.i8 d5, #0\n"
   5425       "vmov.i8 d6, #0\n"
   5426       "vmov.i8 d7, #0\n"
   5427       "vld1.32 {d0[0]}, [%[in]]!\n"
   5428       "vld1.8 {d0[4]}, [%[in]]!\n"
   5429       "vld1.32 {d1[0]}, [r0]!\n"
   5430       "vld1.8 {d1[4]}, [r0]!\n"
   5431       "vld1.32 {d2[0]}, [r1]!\n"
   5432       "vld1.8 {d2[4]}, [r1]!\n"
   5433       "vld1.32 {d3[0]}, [r2]!\n"
   5434       "vld1.8 {d3[4]}, [r2]!\n"
   5435       "vld1.32 {d4[0]}, [r3]!\n"
   5436       "vld1.8 {d4[4]}, [r3]!\n"
   5437       "vld1.32 {d5[0]}, [r4]!\n"
   5438       "vld1.8 {d5[4]}, [r4]!\n"
   5439       "vld1.32 {d6[0]}, [r5]!\n"
   5440       "vld1.8 {d6[4]}, [r5]!\n"
   5441       "vld1.32 {d7[0]}, [r6]!\n"
   5442       "vld1.8 {d7[4]}, [r6]!\n"
   5443       "vaddw.u8 q8, q8, d0\n"
   5444       "vaddw.u8 q9, q9, d1\n"
   5445       "vaddw.u8 q10, q10, d2\n"
   5446       "vaddw.u8 q11, q11, d3\n"
   5447       "vaddw.u8 q12, q12, d4\n"
   5448       "vaddw.u8 q13, q13, d5\n"
   5449       "vaddw.u8 q14, q14, d6\n"
   5450       "vaddw.u8 q15, q15, d7\n"
   5451       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5452       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5453 
   5454       // Aggregator Reduction.
   5455       "ldr r0, %[multiplicative_sum_offset]\n"
   5456       "ldr r1, %[additive_sum_offset]\n"
   5457       "vmov.32 d0[0], r0\n"
   5458       "vdup.32 q1, r1\n"
   5459       "vpaddl.u16 q8, q8\n"
   5460       "vpaddl.u16 q9, q9\n"
   5461       "vpaddl.u16 q10, q10\n"
   5462       "vpaddl.u16 q11, q11\n"
   5463       "vpaddl.u16 q12, q12\n"
   5464       "vpaddl.u16 q13, q13\n"
   5465       "vpaddl.u16 q14, q14\n"
   5466       "vpaddl.u16 q15, q15\n"
   5467       "vpadd.u32 d16, d16, d17\n"
   5468       "vpadd.u32 d18, d18, d19\n"
   5469       "vpadd.u32 d20, d20, d21\n"
   5470       "vpadd.u32 d22, d22, d23\n"
   5471       "vpadd.u32 d24, d24, d25\n"
   5472       "vpadd.u32 d26, d26, d27\n"
   5473       "vpadd.u32 d28, d28, d29\n"
   5474       "vpadd.u32 d30, d30, d31\n"
   5475       "vpadd.u32 d16, d16, d18\n"
   5476       "vpadd.u32 d17, d20, d22\n"
   5477       "vpadd.u32 d18, d24, d26\n"
   5478       "vpadd.u32 d19, d28, d30\n"
   5479       "vmul.i32 q8, q8, d0[0]\n"
   5480       "vmul.i32 q9, q9, d0[0]\n"
   5481       "vadd.i32 q8, q8, q1\n"
   5482       "vadd.i32 q9, q9, q1\n"
   5483       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5484       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5485       : [stride] "r"(params.stride),
   5486         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5487         [additive_sum_offset] "m"(params.additive_sum_offset)
   5488       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5489         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5490         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5491         "memory");
   5492 }
   5493 
   5494 template <>
   5495 inline void Stream<uint8_t, 8, 8, 6, RowMajorWithSum>::Pack(
   5496     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   5497 #ifdef DEBUG
   5498 #ifdef DEBUG_METAGEMM_VERBOSE
   5499   std::cout << __FILE__ << "(" << __LINE__
   5500             << ") RowMajorWithSum<uint8_t, 8, 8, 6, RowMajorWithSum>::Pack()"
   5501             << std::endl
   5502             << std::flush;
   5503 #endif
   5504 #endif
   5505   int params_count_copy = params.count;
   5506   asm volatile(
   5507       "add r0, %[in], %[stride]\n"
   5508       "add r1, r0, %[stride]\n"
   5509       "add r2, r1, %[stride]\n"
   5510       "add r3, r2, %[stride]\n"
   5511       "add r4, r3, %[stride]\n"
   5512       "add r5, r4, %[stride]\n"
   5513       "add r6, r5, %[stride]\n"
   5514       "vmov.i16 q8, #0\n"
   5515       "vmov.i16 q9, #0\n"
   5516       "vmov.i16 q10, #0\n"
   5517       "vmov.i16 q11, #0\n"
   5518       "vmov.i16 q12, #0\n"
   5519       "vmov.i16 q13, #0\n"
   5520       "vmov.i16 q14, #0\n"
   5521       "vmov.i16 q15, #0\n"
   5522 
   5523       // Reduce count by leftovers.
   5524       "subs %[count], %[count], #6\n"
   5525       "beq 2f\n"
   5526 
   5527       "1:"
   5528       "subs %[count], %[count], #8\n"
   5529 
   5530       // Load Aggregate Store: 8x8.
   5531       "vld1.32 {d0}, [%[in]]!\n"
   5532       "vld1.32 {d1}, [r0]!\n"
   5533       "vld1.32 {d2}, [r1]!\n"
   5534       "vld1.32 {d3}, [r2]!\n"
   5535       "vld1.32 {d4}, [r3]!\n"
   5536       "vld1.32 {d5}, [r4]!\n"
   5537       "vld1.32 {d6}, [r5]!\n"
   5538       "vld1.32 {d7}, [r6]!\n"
   5539       "vaddw.u8 q8, q8, d0\n"
   5540       "vaddw.u8 q9, q9, d1\n"
   5541       "vaddw.u8 q10, q10, d2\n"
   5542       "vaddw.u8 q11, q11, d3\n"
   5543       "vaddw.u8 q12, q12, d4\n"
   5544       "vaddw.u8 q13, q13, d5\n"
   5545       "vaddw.u8 q14, q14, d6\n"
   5546       "vaddw.u8 q15, q15, d7\n"
   5547       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5548       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5549 
   5550       "bne 1b\n"
   5551 
   5552       "2:"
   5553 
   5554       // Load Aggregate Store: 8x6.
   5555       "vmov.i8 d0, #0\n"
   5556       "vmov.i8 d1, #0\n"
   5557       "vmov.i8 d2, #0\n"
   5558       "vmov.i8 d3, #0\n"
   5559       "vmov.i8 d4, #0\n"
   5560       "vmov.i8 d5, #0\n"
   5561       "vmov.i8 d6, #0\n"
   5562       "vmov.i8 d7, #0\n"
   5563       "vld1.32 {d0[0]}, [%[in]]!\n"
   5564       "vld1.16 {d0[2]}, [%[in]]!\n"
   5565       "vld1.32 {d1[0]}, [r0]!\n"
   5566       "vld1.16 {d1[2]}, [r0]!\n"
   5567       "vld1.32 {d2[0]}, [r1]!\n"
   5568       "vld1.16 {d2[2]}, [r1]!\n"
   5569       "vld1.32 {d3[0]}, [r2]!\n"
   5570       "vld1.16 {d3[2]}, [r2]!\n"
   5571       "vld1.32 {d4[0]}, [r3]!\n"
   5572       "vld1.16 {d4[2]}, [r3]!\n"
   5573       "vld1.32 {d5[0]}, [r4]!\n"
   5574       "vld1.16 {d5[2]}, [r4]!\n"
   5575       "vld1.32 {d6[0]}, [r5]!\n"
   5576       "vld1.16 {d6[2]}, [r5]!\n"
   5577       "vld1.32 {d7[0]}, [r6]!\n"
   5578       "vld1.16 {d7[2]}, [r6]!\n"
   5579       "vaddw.u8 q8, q8, d0\n"
   5580       "vaddw.u8 q9, q9, d1\n"
   5581       "vaddw.u8 q10, q10, d2\n"
   5582       "vaddw.u8 q11, q11, d3\n"
   5583       "vaddw.u8 q12, q12, d4\n"
   5584       "vaddw.u8 q13, q13, d5\n"
   5585       "vaddw.u8 q14, q14, d6\n"
   5586       "vaddw.u8 q15, q15, d7\n"
   5587       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5588       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5589 
   5590       // Aggregator Reduction.
   5591       "ldr r0, %[multiplicative_sum_offset]\n"
   5592       "ldr r1, %[additive_sum_offset]\n"
   5593       "vmov.32 d0[0], r0\n"
   5594       "vdup.32 q1, r1\n"
   5595       "vpaddl.u16 q8, q8\n"
   5596       "vpaddl.u16 q9, q9\n"
   5597       "vpaddl.u16 q10, q10\n"
   5598       "vpaddl.u16 q11, q11\n"
   5599       "vpaddl.u16 q12, q12\n"
   5600       "vpaddl.u16 q13, q13\n"
   5601       "vpaddl.u16 q14, q14\n"
   5602       "vpaddl.u16 q15, q15\n"
   5603       "vpadd.u32 d16, d16, d17\n"
   5604       "vpadd.u32 d18, d18, d19\n"
   5605       "vpadd.u32 d20, d20, d21\n"
   5606       "vpadd.u32 d22, d22, d23\n"
   5607       "vpadd.u32 d24, d24, d25\n"
   5608       "vpadd.u32 d26, d26, d27\n"
   5609       "vpadd.u32 d28, d28, d29\n"
   5610       "vpadd.u32 d30, d30, d31\n"
   5611       "vpadd.u32 d16, d16, d18\n"
   5612       "vpadd.u32 d17, d20, d22\n"
   5613       "vpadd.u32 d18, d24, d26\n"
   5614       "vpadd.u32 d19, d28, d30\n"
   5615       "vmul.i32 q8, q8, d0[0]\n"
   5616       "vmul.i32 q9, q9, d0[0]\n"
   5617       "vadd.i32 q8, q8, q1\n"
   5618       "vadd.i32 q9, q9, q1\n"
   5619       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5620       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5621       : [stride] "r"(params.stride),
   5622         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5623         [additive_sum_offset] "m"(params.additive_sum_offset)
   5624       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5625         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5626         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5627         "memory");
   5628 }
   5629 
   5630 template <>
   5631 inline void Stream<uint8_t, 8, 8, 7, RowMajorWithSum>::Pack(
   5632     const uint8_t* in, const RowMajorWithSum& params, uint8_t* out) {
   5633 #ifdef DEBUG
   5634 #ifdef DEBUG_METAGEMM_VERBOSE
   5635   std::cout << __FILE__ << "(" << __LINE__
   5636             << ") RowMajorWithSum<uint8_t, 8, 8, 7, RowMajorWithSum>::Pack()"
   5637             << std::endl
   5638             << std::flush;
   5639 #endif
   5640 #endif
   5641   int params_count_copy = params.count;
   5642   asm volatile(
   5643       "add r0, %[in], %[stride]\n"
   5644       "add r1, r0, %[stride]\n"
   5645       "add r2, r1, %[stride]\n"
   5646       "add r3, r2, %[stride]\n"
   5647       "add r4, r3, %[stride]\n"
   5648       "add r5, r4, %[stride]\n"
   5649       "add r6, r5, %[stride]\n"
   5650       "vmov.i16 q8, #0\n"
   5651       "vmov.i16 q9, #0\n"
   5652       "vmov.i16 q10, #0\n"
   5653       "vmov.i16 q11, #0\n"
   5654       "vmov.i16 q12, #0\n"
   5655       "vmov.i16 q13, #0\n"
   5656       "vmov.i16 q14, #0\n"
   5657       "vmov.i16 q15, #0\n"
   5658 
   5659       // Reduce count by leftovers.
   5660       "subs %[count], %[count], #7\n"
   5661       "beq 2f\n"
   5662 
   5663       "1:"
   5664       "subs %[count], %[count], #8\n"
   5665 
   5666       // Load Aggregate Store: 8x8.
   5667       "vld1.32 {d0}, [%[in]]!\n"
   5668       "vld1.32 {d1}, [r0]!\n"
   5669       "vld1.32 {d2}, [r1]!\n"
   5670       "vld1.32 {d3}, [r2]!\n"
   5671       "vld1.32 {d4}, [r3]!\n"
   5672       "vld1.32 {d5}, [r4]!\n"
   5673       "vld1.32 {d6}, [r5]!\n"
   5674       "vld1.32 {d7}, [r6]!\n"
   5675       "vaddw.u8 q8, q8, d0\n"
   5676       "vaddw.u8 q9, q9, d1\n"
   5677       "vaddw.u8 q10, q10, d2\n"
   5678       "vaddw.u8 q11, q11, d3\n"
   5679       "vaddw.u8 q12, q12, d4\n"
   5680       "vaddw.u8 q13, q13, d5\n"
   5681       "vaddw.u8 q14, q14, d6\n"
   5682       "vaddw.u8 q15, q15, d7\n"
   5683       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5684       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5685 
   5686       "bne 1b\n"
   5687 
   5688       "2:"
   5689 
   5690       // Load Aggregate Store: 8x7.
   5691       "vmov.i8 d0, #0\n"
   5692       "vmov.i8 d1, #0\n"
   5693       "vmov.i8 d2, #0\n"
   5694       "vmov.i8 d3, #0\n"
   5695       "vmov.i8 d4, #0\n"
   5696       "vmov.i8 d5, #0\n"
   5697       "vmov.i8 d6, #0\n"
   5698       "vmov.i8 d7, #0\n"
   5699       "vld1.32 {d0[0]}, [%[in]]!\n"
   5700       "vld1.16 {d0[2]}, [%[in]]!\n"
   5701       "vld1.8 {d0[6]}, [%[in]]!\n"
   5702       "vld1.32 {d1[0]}, [r0]!\n"
   5703       "vld1.16 {d1[2]}, [r0]!\n"
   5704       "vld1.8 {d1[6]}, [r0]!\n"
   5705       "vld1.32 {d2[0]}, [r1]!\n"
   5706       "vld1.16 {d2[2]}, [r1]!\n"
   5707       "vld1.8 {d2[6]}, [r1]!\n"
   5708       "vld1.32 {d3[0]}, [r2]!\n"
   5709       "vld1.16 {d3[2]}, [r2]!\n"
   5710       "vld1.8 {d3[6]}, [r2]!\n"
   5711       "vld1.32 {d4[0]}, [r3]!\n"
   5712       "vld1.16 {d4[2]}, [r3]!\n"
   5713       "vld1.8 {d4[6]}, [r3]!\n"
   5714       "vld1.32 {d5[0]}, [r4]!\n"
   5715       "vld1.16 {d5[2]}, [r4]!\n"
   5716       "vld1.8 {d5[6]}, [r4]!\n"
   5717       "vld1.32 {d6[0]}, [r5]!\n"
   5718       "vld1.16 {d6[2]}, [r5]!\n"
   5719       "vld1.8 {d6[6]}, [r5]!\n"
   5720       "vld1.32 {d7[0]}, [r6]!\n"
   5721       "vld1.16 {d7[2]}, [r6]!\n"
   5722       "vld1.8 {d7[6]}, [r6]!\n"
   5723       "vaddw.u8 q8, q8, d0\n"
   5724       "vaddw.u8 q9, q9, d1\n"
   5725       "vaddw.u8 q10, q10, d2\n"
   5726       "vaddw.u8 q11, q11, d3\n"
   5727       "vaddw.u8 q12, q12, d4\n"
   5728       "vaddw.u8 q13, q13, d5\n"
   5729       "vaddw.u8 q14, q14, d6\n"
   5730       "vaddw.u8 q15, q15, d7\n"
   5731       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   5732       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   5733 
   5734       // Aggregator Reduction.
   5735       "ldr r0, %[multiplicative_sum_offset]\n"
   5736       "ldr r1, %[additive_sum_offset]\n"
   5737       "vmov.32 d0[0], r0\n"
   5738       "vdup.32 q1, r1\n"
   5739       "vpaddl.u16 q8, q8\n"
   5740       "vpaddl.u16 q9, q9\n"
   5741       "vpaddl.u16 q10, q10\n"
   5742       "vpaddl.u16 q11, q11\n"
   5743       "vpaddl.u16 q12, q12\n"
   5744       "vpaddl.u16 q13, q13\n"
   5745       "vpaddl.u16 q14, q14\n"
   5746       "vpaddl.u16 q15, q15\n"
   5747       "vpadd.u32 d16, d16, d17\n"
   5748       "vpadd.u32 d18, d18, d19\n"
   5749       "vpadd.u32 d20, d20, d21\n"
   5750       "vpadd.u32 d22, d22, d23\n"
   5751       "vpadd.u32 d24, d24, d25\n"
   5752       "vpadd.u32 d26, d26, d27\n"
   5753       "vpadd.u32 d28, d28, d29\n"
   5754       "vpadd.u32 d30, d30, d31\n"
   5755       "vpadd.u32 d16, d16, d18\n"
   5756       "vpadd.u32 d17, d20, d22\n"
   5757       "vpadd.u32 d18, d24, d26\n"
   5758       "vpadd.u32 d19, d28, d30\n"
   5759       "vmul.i32 q8, q8, d0[0]\n"
   5760       "vmul.i32 q9, q9, d0[0]\n"
   5761       "vadd.i32 q8, q8, q1\n"
   5762       "vadd.i32 q9, q9, q1\n"
   5763       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   5764       : [count] "+r"(params_count_copy), [in] "+r"(in), [out] "+r"(out)
   5765       : [stride] "r"(params.stride),
   5766         [multiplicative_sum_offset] "m"(params.multiplicative_sum_offset),
   5767         [additive_sum_offset] "m"(params.additive_sum_offset)
   5768       : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "d0", "d1", "d2", "d3", "d4",
   5769         "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   5770         "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "cc",
   5771         "memory");
   5772 }
   5773 
   5774 template <>
   5775 inline void Stream<uint8_t, 1, 8, 0, ColumnMajorWithSum>::Pack(
   5776     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   5777 #ifdef DEBUG
   5778 #ifdef DEBUG_METAGEMM_VERBOSE
   5779   std::cout
   5780       << __FILE__ << "(" << __LINE__
   5781       << ") ColumnMajorWithSum<uint8_t, 1, 8, 0, ColumnMajorWithSum>::Pack()"
   5782       << std::endl
   5783       << std::flush;
   5784 #endif
   5785 #endif
   5786   int params_count_copy = params.count;
   5787   int params_stride_copy = params.stride;
   5788   asm volatile(
   5789       "vmov.i16 q8, #0\n"
   5790 
   5791       "1:"
   5792       "subs %[count], %[count], #8\n"
   5793 
   5794       // Load Aggregate Store - column major 1x8
   5795       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5796       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5797       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   5798       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   5799       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   5800       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   5801       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   5802       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   5803       "pld [%[in]]\n"
   5804       "vaddw.u8 q8, q8, d0\n"
   5805       "vst1.32 {d0}, [%[out]:64]!\n"
   5806 
   5807       "bne 1b\n"
   5808 
   5809       // Aggregator Reduction.
   5810       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   5811       "vdup.32 q1, %[additive_sum_offset]\n"
   5812       "vpaddl.u16 q8, q8\n"
   5813       "vpadd.u32 d16, d16, d17\n"
   5814       "vpadd.u32 d16, d16, d16\n"
   5815       "vmul.i32 q8, q8, d0[0]\n"
   5816       "vadd.i32 q8, q8, q1\n"
   5817       "vst1.32 {d16, d17}, [%[out]:64]\n"
   5818       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   5819         [out] "+r"(out), [in] "+r"(in)
   5820       : [additive_sum_offset] "r"(params.additive_sum_offset),
   5821         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   5822       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   5823 }
   5824 
   5825 template <>
   5826 inline void Stream<uint8_t, 1, 8, 1, ColumnMajorWithSum>::Pack(
   5827     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   5828 #ifdef DEBUG
   5829 #ifdef DEBUG_METAGEMM_VERBOSE
   5830   std::cout
   5831       << __FILE__ << "(" << __LINE__
   5832       << ") ColumnMajorWithSum<uint8_t, 1, 8, 1, ColumnMajorWithSum>::Pack()"
   5833       << std::endl
   5834       << std::flush;
   5835 #endif
   5836 #endif
   5837   int params_count_copy = params.count;
   5838   int params_stride_copy = params.stride;
   5839   asm volatile(
   5840       "vmov.i16 q8, #0\n"
   5841 
   5842       // Reduce count by leftovers.
   5843       "subs %[count], %[count], #1\n"
   5844       "beq 2f\n"
   5845 
   5846       "1:"
   5847       "subs %[count], %[count], #8\n"
   5848 
   5849       // Load Aggregate Store - column major 1x8
   5850       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5851       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5852       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   5853       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   5854       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   5855       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   5856       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   5857       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   5858       "pld [%[in]]\n"
   5859       "vaddw.u8 q8, q8, d0\n"
   5860       "vst1.32 {d0}, [%[out]:64]!\n"
   5861 
   5862       "bne 1b\n"
   5863 
   5864       "2:"
   5865 
   5866       // Load Aggregate Store - column major 1x1
   5867       "vmov.i8 d0, #0\n"
   5868       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5869       "pld [%[in]]\n"
   5870       "vaddw.u8 q8, q8, d0\n"
   5871       "vst1.32 {d0}, [%[out]:64]!\n"
   5872 
   5873       // Aggregator Reduction.
   5874       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   5875       "vdup.32 q1, %[additive_sum_offset]\n"
   5876       "vpaddl.u16 q8, q8\n"
   5877       "vpadd.u32 d16, d16, d17\n"
   5878       "vpadd.u32 d16, d16, d16\n"
   5879       "vmul.i32 q8, q8, d0[0]\n"
   5880       "vadd.i32 q8, q8, q1\n"
   5881       "vst1.32 {d16, d17}, [%[out]:64]\n"
   5882       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   5883         [out] "+r"(out), [in] "+r"(in)
   5884       : [additive_sum_offset] "r"(params.additive_sum_offset),
   5885         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   5886       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   5887 }
   5888 
   5889 template <>
   5890 inline void Stream<uint8_t, 1, 8, 2, ColumnMajorWithSum>::Pack(
   5891     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   5892 #ifdef DEBUG
   5893 #ifdef DEBUG_METAGEMM_VERBOSE
   5894   std::cout
   5895       << __FILE__ << "(" << __LINE__
   5896       << ") ColumnMajorWithSum<uint8_t, 1, 8, 2, ColumnMajorWithSum>::Pack()"
   5897       << std::endl
   5898       << std::flush;
   5899 #endif
   5900 #endif
   5901   int params_count_copy = params.count;
   5902   int params_stride_copy = params.stride;
   5903   asm volatile(
   5904       "vmov.i16 q8, #0\n"
   5905 
   5906       // Reduce count by leftovers.
   5907       "subs %[count], %[count], #2\n"
   5908       "beq 2f\n"
   5909 
   5910       "1:"
   5911       "subs %[count], %[count], #8\n"
   5912 
   5913       // Load Aggregate Store - column major 1x8
   5914       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5915       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5916       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   5917       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   5918       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   5919       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   5920       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   5921       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   5922       "pld [%[in]]\n"
   5923       "vaddw.u8 q8, q8, d0\n"
   5924       "vst1.32 {d0}, [%[out]:64]!\n"
   5925 
   5926       "bne 1b\n"
   5927 
   5928       "2:"
   5929 
   5930       // Load Aggregate Store - column major 1x2
   5931       "vmov.i8 d0, #0\n"
   5932       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5933       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5934       "pld [%[in]]\n"
   5935       "vaddw.u8 q8, q8, d0\n"
   5936       "vst1.32 {d0}, [%[out]:64]!\n"
   5937 
   5938       // Aggregator Reduction.
   5939       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   5940       "vdup.32 q1, %[additive_sum_offset]\n"
   5941       "vpaddl.u16 q8, q8\n"
   5942       "vpadd.u32 d16, d16, d17\n"
   5943       "vpadd.u32 d16, d16, d16\n"
   5944       "vmul.i32 q8, q8, d0[0]\n"
   5945       "vadd.i32 q8, q8, q1\n"
   5946       "vst1.32 {d16, d17}, [%[out]:64]\n"
   5947       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   5948         [out] "+r"(out), [in] "+r"(in)
   5949       : [additive_sum_offset] "r"(params.additive_sum_offset),
   5950         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   5951       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   5952 }
   5953 
   5954 template <>
   5955 inline void Stream<uint8_t, 1, 8, 3, ColumnMajorWithSum>::Pack(
   5956     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   5957 #ifdef DEBUG
   5958 #ifdef DEBUG_METAGEMM_VERBOSE
   5959   std::cout
   5960       << __FILE__ << "(" << __LINE__
   5961       << ") ColumnMajorWithSum<uint8_t, 1, 8, 3, ColumnMajorWithSum>::Pack()"
   5962       << std::endl
   5963       << std::flush;
   5964 #endif
   5965 #endif
   5966   int params_count_copy = params.count;
   5967   int params_stride_copy = params.stride;
   5968   asm volatile(
   5969       "vmov.i16 q8, #0\n"
   5970 
   5971       // Reduce count by leftovers.
   5972       "subs %[count], %[count], #3\n"
   5973       "beq 2f\n"
   5974 
   5975       "1:"
   5976       "subs %[count], %[count], #8\n"
   5977 
   5978       // Load Aggregate Store - column major 1x8
   5979       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5980       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5981       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   5982       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   5983       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   5984       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   5985       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   5986       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   5987       "pld [%[in]]\n"
   5988       "vaddw.u8 q8, q8, d0\n"
   5989       "vst1.32 {d0}, [%[out]:64]!\n"
   5990 
   5991       "bne 1b\n"
   5992 
   5993       "2:"
   5994 
   5995       // Load Aggregate Store - column major 1x3
   5996       "vmov.i8 d0, #0\n"
   5997       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   5998       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   5999       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6000       "pld [%[in]]\n"
   6001       "vaddw.u8 q8, q8, d0\n"
   6002       "vst1.32 {d0}, [%[out]:64]!\n"
   6003 
   6004       // Aggregator Reduction.
   6005       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6006       "vdup.32 q1, %[additive_sum_offset]\n"
   6007       "vpaddl.u16 q8, q8\n"
   6008       "vpadd.u32 d16, d16, d17\n"
   6009       "vpadd.u32 d16, d16, d16\n"
   6010       "vmul.i32 q8, q8, d0[0]\n"
   6011       "vadd.i32 q8, q8, q1\n"
   6012       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6013       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6014         [out] "+r"(out), [in] "+r"(in)
   6015       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6016         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6017       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   6018 }
   6019 
   6020 template <>
   6021 inline void Stream<uint8_t, 1, 8, 4, ColumnMajorWithSum>::Pack(
   6022     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6023 #ifdef DEBUG
   6024 #ifdef DEBUG_METAGEMM_VERBOSE
   6025   std::cout
   6026       << __FILE__ << "(" << __LINE__
   6027       << ") ColumnMajorWithSum<uint8_t, 1, 8, 4, ColumnMajorWithSum>::Pack()"
   6028       << std::endl
   6029       << std::flush;
   6030 #endif
   6031 #endif
   6032   int params_count_copy = params.count;
   6033   int params_stride_copy = params.stride;
   6034   asm volatile(
   6035       "vmov.i16 q8, #0\n"
   6036 
   6037       // Reduce count by leftovers.
   6038       "subs %[count], %[count], #4\n"
   6039       "beq 2f\n"
   6040 
   6041       "1:"
   6042       "subs %[count], %[count], #8\n"
   6043 
   6044       // Load Aggregate Store - column major 1x8
   6045       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6046       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6047       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6048       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6049       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6050       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6051       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   6052       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   6053       "pld [%[in]]\n"
   6054       "vaddw.u8 q8, q8, d0\n"
   6055       "vst1.32 {d0}, [%[out]:64]!\n"
   6056 
   6057       "bne 1b\n"
   6058 
   6059       "2:"
   6060 
   6061       // Load Aggregate Store - column major 1x4
   6062       "vmov.i8 d0, #0\n"
   6063       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6064       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6065       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6066       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6067       "pld [%[in]]\n"
   6068       "vaddw.u8 q8, q8, d0\n"
   6069       "vst1.32 {d0}, [%[out]:64]!\n"
   6070 
   6071       // Aggregator Reduction.
   6072       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6073       "vdup.32 q1, %[additive_sum_offset]\n"
   6074       "vpaddl.u16 q8, q8\n"
   6075       "vpadd.u32 d16, d16, d17\n"
   6076       "vpadd.u32 d16, d16, d16\n"
   6077       "vmul.i32 q8, q8, d0[0]\n"
   6078       "vadd.i32 q8, q8, q1\n"
   6079       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6080       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6081         [out] "+r"(out), [in] "+r"(in)
   6082       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6083         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6084       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   6085 }
   6086 
   6087 template <>
   6088 inline void Stream<uint8_t, 1, 8, 5, ColumnMajorWithSum>::Pack(
   6089     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6090 #ifdef DEBUG
   6091 #ifdef DEBUG_METAGEMM_VERBOSE
   6092   std::cout
   6093       << __FILE__ << "(" << __LINE__
   6094       << ") ColumnMajorWithSum<uint8_t, 1, 8, 5, ColumnMajorWithSum>::Pack()"
   6095       << std::endl
   6096       << std::flush;
   6097 #endif
   6098 #endif
   6099   int params_count_copy = params.count;
   6100   int params_stride_copy = params.stride;
   6101   asm volatile(
   6102       "vmov.i16 q8, #0\n"
   6103 
   6104       // Reduce count by leftovers.
   6105       "subs %[count], %[count], #5\n"
   6106       "beq 2f\n"
   6107 
   6108       "1:"
   6109       "subs %[count], %[count], #8\n"
   6110 
   6111       // Load Aggregate Store - column major 1x8
   6112       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6113       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6114       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6115       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6116       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6117       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6118       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   6119       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   6120       "pld [%[in]]\n"
   6121       "vaddw.u8 q8, q8, d0\n"
   6122       "vst1.32 {d0}, [%[out]:64]!\n"
   6123 
   6124       "bne 1b\n"
   6125 
   6126       "2:"
   6127 
   6128       // Load Aggregate Store - column major 1x5
   6129       "vmov.i8 d0, #0\n"
   6130       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6131       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6132       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6133       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6134       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6135       "pld [%[in]]\n"
   6136       "vaddw.u8 q8, q8, d0\n"
   6137       "vst1.32 {d0}, [%[out]:64]!\n"
   6138 
   6139       // Aggregator Reduction.
   6140       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6141       "vdup.32 q1, %[additive_sum_offset]\n"
   6142       "vpaddl.u16 q8, q8\n"
   6143       "vpadd.u32 d16, d16, d17\n"
   6144       "vpadd.u32 d16, d16, d16\n"
   6145       "vmul.i32 q8, q8, d0[0]\n"
   6146       "vadd.i32 q8, q8, q1\n"
   6147       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6148       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6149         [out] "+r"(out), [in] "+r"(in)
   6150       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6151         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6152       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   6153 }
   6154 
   6155 template <>
   6156 inline void Stream<uint8_t, 1, 8, 6, ColumnMajorWithSum>::Pack(
   6157     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6158 #ifdef DEBUG
   6159 #ifdef DEBUG_METAGEMM_VERBOSE
   6160   std::cout
   6161       << __FILE__ << "(" << __LINE__
   6162       << ") ColumnMajorWithSum<uint8_t, 1, 8, 6, ColumnMajorWithSum>::Pack()"
   6163       << std::endl
   6164       << std::flush;
   6165 #endif
   6166 #endif
   6167   int params_count_copy = params.count;
   6168   int params_stride_copy = params.stride;
   6169   asm volatile(
   6170       "vmov.i16 q8, #0\n"
   6171 
   6172       // Reduce count by leftovers.
   6173       "subs %[count], %[count], #6\n"
   6174       "beq 2f\n"
   6175 
   6176       "1:"
   6177       "subs %[count], %[count], #8\n"
   6178 
   6179       // Load Aggregate Store - column major 1x8
   6180       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6181       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6182       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6183       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6184       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6185       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6186       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   6187       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   6188       "pld [%[in]]\n"
   6189       "vaddw.u8 q8, q8, d0\n"
   6190       "vst1.32 {d0}, [%[out]:64]!\n"
   6191 
   6192       "bne 1b\n"
   6193 
   6194       "2:"
   6195 
   6196       // Load Aggregate Store - column major 1x6
   6197       "vmov.i8 d0, #0\n"
   6198       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6199       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6200       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6201       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6202       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6203       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6204       "pld [%[in]]\n"
   6205       "vaddw.u8 q8, q8, d0\n"
   6206       "vst1.32 {d0}, [%[out]:64]!\n"
   6207 
   6208       // Aggregator Reduction.
   6209       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6210       "vdup.32 q1, %[additive_sum_offset]\n"
   6211       "vpaddl.u16 q8, q8\n"
   6212       "vpadd.u32 d16, d16, d17\n"
   6213       "vpadd.u32 d16, d16, d16\n"
   6214       "vmul.i32 q8, q8, d0[0]\n"
   6215       "vadd.i32 q8, q8, q1\n"
   6216       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6217       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6218         [out] "+r"(out), [in] "+r"(in)
   6219       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6220         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6221       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   6222 }
   6223 
   6224 template <>
   6225 inline void Stream<uint8_t, 1, 8, 7, ColumnMajorWithSum>::Pack(
   6226     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6227 #ifdef DEBUG
   6228 #ifdef DEBUG_METAGEMM_VERBOSE
   6229   std::cout
   6230       << __FILE__ << "(" << __LINE__
   6231       << ") ColumnMajorWithSum<uint8_t, 1, 8, 7, ColumnMajorWithSum>::Pack()"
   6232       << std::endl
   6233       << std::flush;
   6234 #endif
   6235 #endif
   6236   int params_count_copy = params.count;
   6237   int params_stride_copy = params.stride;
   6238   asm volatile(
   6239       "vmov.i16 q8, #0\n"
   6240 
   6241       // Reduce count by leftovers.
   6242       "subs %[count], %[count], #7\n"
   6243       "beq 2f\n"
   6244 
   6245       "1:"
   6246       "subs %[count], %[count], #8\n"
   6247 
   6248       // Load Aggregate Store - column major 1x8
   6249       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6250       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6251       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6252       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6253       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6254       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6255       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   6256       "vld1.8 {d0[7]}, [%[in]], %[stride]\n"
   6257       "pld [%[in]]\n"
   6258       "vaddw.u8 q8, q8, d0\n"
   6259       "vst1.32 {d0}, [%[out]:64]!\n"
   6260 
   6261       "bne 1b\n"
   6262 
   6263       "2:"
   6264 
   6265       // Load Aggregate Store - column major 1x7
   6266       "vmov.i8 d0, #0\n"
   6267       "vld1.8 {d0[0]}, [%[in]], %[stride]\n"
   6268       "vld1.8 {d0[1]}, [%[in]], %[stride]\n"
   6269       "vld1.8 {d0[2]}, [%[in]], %[stride]\n"
   6270       "vld1.8 {d0[3]}, [%[in]], %[stride]\n"
   6271       "vld1.8 {d0[4]}, [%[in]], %[stride]\n"
   6272       "vld1.8 {d0[5]}, [%[in]], %[stride]\n"
   6273       "vld1.8 {d0[6]}, [%[in]], %[stride]\n"
   6274       "pld [%[in]]\n"
   6275       "vaddw.u8 q8, q8, d0\n"
   6276       "vst1.32 {d0}, [%[out]:64]!\n"
   6277 
   6278       // Aggregator Reduction.
   6279       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6280       "vdup.32 q1, %[additive_sum_offset]\n"
   6281       "vpaddl.u16 q8, q8\n"
   6282       "vpadd.u32 d16, d16, d17\n"
   6283       "vpadd.u32 d16, d16, d16\n"
   6284       "vmul.i32 q8, q8, d0[0]\n"
   6285       "vadd.i32 q8, q8, q1\n"
   6286       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6287       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6288         [out] "+r"(out), [in] "+r"(in)
   6289       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6290         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6291       : "d0", "d2", "d3", "d16", "d17", "cc", "memory");
   6292 }
   6293 
   6294 template <>
   6295 inline void Stream<uint8_t, 2, 8, 0, ColumnMajorWithSum>::Pack(
   6296     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6297 #ifdef DEBUG
   6298 #ifdef DEBUG_METAGEMM_VERBOSE
   6299   std::cout
   6300       << __FILE__ << "(" << __LINE__
   6301       << ") ColumnMajorWithSum<uint8_t, 2, 8, 0, ColumnMajorWithSum>::Pack()"
   6302       << std::endl
   6303       << std::flush;
   6304 #endif
   6305 #endif
   6306   int params_count_copy = params.count;
   6307   int params_stride_copy = params.stride;
   6308   asm volatile(
   6309       "vmov.i16 q8, #0\n"
   6310       "vmov.i16 q9, #0\n"
   6311 
   6312       "1:"
   6313       "subs %[count], %[count], #8\n"
   6314 
   6315       // Load Aggregate Store - column major 2x8
   6316       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6317       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6318       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6319       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6320       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6321       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6322       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6323       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6324       "pld [%[in]]\n"
   6325       "vuzp.8 d0, d1\n"
   6326       "vaddw.u8 q8, q8, d0\n"
   6327       "vaddw.u8 q9, q9, d1\n"
   6328       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6329 
   6330       "bne 1b\n"
   6331 
   6332       // Aggregator Reduction.
   6333       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6334       "vdup.32 q1, %[additive_sum_offset]\n"
   6335       "vpaddl.u16 q8, q8\n"
   6336       "vpaddl.u16 q9, q9\n"
   6337       "vpadd.u32 d16, d16, d17\n"
   6338       "vpadd.u32 d18, d18, d19\n"
   6339       "vpadd.u32 d16, d16, d18\n"
   6340       "vmul.i32 q8, q8, d0[0]\n"
   6341       "vadd.i32 q8, q8, q1\n"
   6342       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6343       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6344         [out] "+r"(out), [in] "+r"(in)
   6345       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6346         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6347       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6348 }
   6349 
   6350 template <>
   6351 inline void Stream<uint8_t, 2, 8, 1, ColumnMajorWithSum>::Pack(
   6352     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6353 #ifdef DEBUG
   6354 #ifdef DEBUG_METAGEMM_VERBOSE
   6355   std::cout
   6356       << __FILE__ << "(" << __LINE__
   6357       << ") ColumnMajorWithSum<uint8_t, 2, 8, 1, ColumnMajorWithSum>::Pack()"
   6358       << std::endl
   6359       << std::flush;
   6360 #endif
   6361 #endif
   6362   int params_count_copy = params.count;
   6363   int params_stride_copy = params.stride;
   6364   asm volatile(
   6365       "vmov.i16 q8, #0\n"
   6366       "vmov.i16 q9, #0\n"
   6367 
   6368       // Reduce count by leftovers.
   6369       "subs %[count], %[count], #1\n"
   6370       "beq 2f\n"
   6371 
   6372       "1:"
   6373       "subs %[count], %[count], #8\n"
   6374 
   6375       // Load Aggregate Store - column major 2x8
   6376       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6377       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6378       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6379       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6380       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6381       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6382       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6383       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6384       "pld [%[in]]\n"
   6385       "vuzp.8 d0, d1\n"
   6386       "vaddw.u8 q8, q8, d0\n"
   6387       "vaddw.u8 q9, q9, d1\n"
   6388       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6389 
   6390       "bne 1b\n"
   6391 
   6392       "2:"
   6393 
   6394       // Load Aggregate Store - column major 2x1
   6395       "vmov.i8 d0, #0\n"
   6396       "vmov.i8 d1, #0\n"
   6397       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6398       "pld [%[in]]\n"
   6399       "vuzp.8 d0, d1\n"
   6400       "vaddw.u8 q8, q8, d0\n"
   6401       "vaddw.u8 q9, q9, d1\n"
   6402       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6403 
   6404       // Aggregator Reduction.
   6405       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6406       "vdup.32 q1, %[additive_sum_offset]\n"
   6407       "vpaddl.u16 q8, q8\n"
   6408       "vpaddl.u16 q9, q9\n"
   6409       "vpadd.u32 d16, d16, d17\n"
   6410       "vpadd.u32 d18, d18, d19\n"
   6411       "vpadd.u32 d16, d16, d18\n"
   6412       "vmul.i32 q8, q8, d0[0]\n"
   6413       "vadd.i32 q8, q8, q1\n"
   6414       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6415       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6416         [out] "+r"(out), [in] "+r"(in)
   6417       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6418         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6419       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6420 }
   6421 
   6422 template <>
   6423 inline void Stream<uint8_t, 2, 8, 2, ColumnMajorWithSum>::Pack(
   6424     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6425 #ifdef DEBUG
   6426 #ifdef DEBUG_METAGEMM_VERBOSE
   6427   std::cout
   6428       << __FILE__ << "(" << __LINE__
   6429       << ") ColumnMajorWithSum<uint8_t, 2, 8, 2, ColumnMajorWithSum>::Pack()"
   6430       << std::endl
   6431       << std::flush;
   6432 #endif
   6433 #endif
   6434   int params_count_copy = params.count;
   6435   int params_stride_copy = params.stride;
   6436   asm volatile(
   6437       "vmov.i16 q8, #0\n"
   6438       "vmov.i16 q9, #0\n"
   6439 
   6440       // Reduce count by leftovers.
   6441       "subs %[count], %[count], #2\n"
   6442       "beq 2f\n"
   6443 
   6444       "1:"
   6445       "subs %[count], %[count], #8\n"
   6446 
   6447       // Load Aggregate Store - column major 2x8
   6448       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6449       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6450       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6451       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6452       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6453       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6454       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6455       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6456       "pld [%[in]]\n"
   6457       "vuzp.8 d0, d1\n"
   6458       "vaddw.u8 q8, q8, d0\n"
   6459       "vaddw.u8 q9, q9, d1\n"
   6460       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6461 
   6462       "bne 1b\n"
   6463 
   6464       "2:"
   6465 
   6466       // Load Aggregate Store - column major 2x2
   6467       "vmov.i8 d0, #0\n"
   6468       "vmov.i8 d1, #0\n"
   6469       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6470       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6471       "pld [%[in]]\n"
   6472       "vuzp.8 d0, d1\n"
   6473       "vaddw.u8 q8, q8, d0\n"
   6474       "vaddw.u8 q9, q9, d1\n"
   6475       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6476 
   6477       // Aggregator Reduction.
   6478       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6479       "vdup.32 q1, %[additive_sum_offset]\n"
   6480       "vpaddl.u16 q8, q8\n"
   6481       "vpaddl.u16 q9, q9\n"
   6482       "vpadd.u32 d16, d16, d17\n"
   6483       "vpadd.u32 d18, d18, d19\n"
   6484       "vpadd.u32 d16, d16, d18\n"
   6485       "vmul.i32 q8, q8, d0[0]\n"
   6486       "vadd.i32 q8, q8, q1\n"
   6487       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6488       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6489         [out] "+r"(out), [in] "+r"(in)
   6490       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6491         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6492       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6493 }
   6494 
   6495 template <>
   6496 inline void Stream<uint8_t, 2, 8, 3, ColumnMajorWithSum>::Pack(
   6497     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6498 #ifdef DEBUG
   6499 #ifdef DEBUG_METAGEMM_VERBOSE
   6500   std::cout
   6501       << __FILE__ << "(" << __LINE__
   6502       << ") ColumnMajorWithSum<uint8_t, 2, 8, 3, ColumnMajorWithSum>::Pack()"
   6503       << std::endl
   6504       << std::flush;
   6505 #endif
   6506 #endif
   6507   int params_count_copy = params.count;
   6508   int params_stride_copy = params.stride;
   6509   asm volatile(
   6510       "vmov.i16 q8, #0\n"
   6511       "vmov.i16 q9, #0\n"
   6512 
   6513       // Reduce count by leftovers.
   6514       "subs %[count], %[count], #3\n"
   6515       "beq 2f\n"
   6516 
   6517       "1:"
   6518       "subs %[count], %[count], #8\n"
   6519 
   6520       // Load Aggregate Store - column major 2x8
   6521       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6522       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6523       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6524       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6525       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6526       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6527       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6528       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6529       "pld [%[in]]\n"
   6530       "vuzp.8 d0, d1\n"
   6531       "vaddw.u8 q8, q8, d0\n"
   6532       "vaddw.u8 q9, q9, d1\n"
   6533       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6534 
   6535       "bne 1b\n"
   6536 
   6537       "2:"
   6538 
   6539       // Load Aggregate Store - column major 2x3
   6540       "vmov.i8 d0, #0\n"
   6541       "vmov.i8 d1, #0\n"
   6542       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6543       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6544       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6545       "pld [%[in]]\n"
   6546       "vuzp.8 d0, d1\n"
   6547       "vaddw.u8 q8, q8, d0\n"
   6548       "vaddw.u8 q9, q9, d1\n"
   6549       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6550 
   6551       // Aggregator Reduction.
   6552       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6553       "vdup.32 q1, %[additive_sum_offset]\n"
   6554       "vpaddl.u16 q8, q8\n"
   6555       "vpaddl.u16 q9, q9\n"
   6556       "vpadd.u32 d16, d16, d17\n"
   6557       "vpadd.u32 d18, d18, d19\n"
   6558       "vpadd.u32 d16, d16, d18\n"
   6559       "vmul.i32 q8, q8, d0[0]\n"
   6560       "vadd.i32 q8, q8, q1\n"
   6561       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6562       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6563         [out] "+r"(out), [in] "+r"(in)
   6564       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6565         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6566       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6567 }
   6568 
   6569 template <>
   6570 inline void Stream<uint8_t, 2, 8, 4, ColumnMajorWithSum>::Pack(
   6571     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6572 #ifdef DEBUG
   6573 #ifdef DEBUG_METAGEMM_VERBOSE
   6574   std::cout
   6575       << __FILE__ << "(" << __LINE__
   6576       << ") ColumnMajorWithSum<uint8_t, 2, 8, 4, ColumnMajorWithSum>::Pack()"
   6577       << std::endl
   6578       << std::flush;
   6579 #endif
   6580 #endif
   6581   int params_count_copy = params.count;
   6582   int params_stride_copy = params.stride;
   6583   asm volatile(
   6584       "vmov.i16 q8, #0\n"
   6585       "vmov.i16 q9, #0\n"
   6586 
   6587       // Reduce count by leftovers.
   6588       "subs %[count], %[count], #4\n"
   6589       "beq 2f\n"
   6590 
   6591       "1:"
   6592       "subs %[count], %[count], #8\n"
   6593 
   6594       // Load Aggregate Store - column major 2x8
   6595       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6596       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6597       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6598       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6599       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6600       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6601       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6602       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6603       "pld [%[in]]\n"
   6604       "vuzp.8 d0, d1\n"
   6605       "vaddw.u8 q8, q8, d0\n"
   6606       "vaddw.u8 q9, q9, d1\n"
   6607       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6608 
   6609       "bne 1b\n"
   6610 
   6611       "2:"
   6612 
   6613       // Load Aggregate Store - column major 2x4
   6614       "vmov.i8 d0, #0\n"
   6615       "vmov.i8 d1, #0\n"
   6616       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6617       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6618       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6619       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6620       "pld [%[in]]\n"
   6621       "vuzp.8 d0, d1\n"
   6622       "vaddw.u8 q8, q8, d0\n"
   6623       "vaddw.u8 q9, q9, d1\n"
   6624       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6625 
   6626       // Aggregator Reduction.
   6627       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6628       "vdup.32 q1, %[additive_sum_offset]\n"
   6629       "vpaddl.u16 q8, q8\n"
   6630       "vpaddl.u16 q9, q9\n"
   6631       "vpadd.u32 d16, d16, d17\n"
   6632       "vpadd.u32 d18, d18, d19\n"
   6633       "vpadd.u32 d16, d16, d18\n"
   6634       "vmul.i32 q8, q8, d0[0]\n"
   6635       "vadd.i32 q8, q8, q1\n"
   6636       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6637       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6638         [out] "+r"(out), [in] "+r"(in)
   6639       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6640         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6641       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6642 }
   6643 
   6644 template <>
   6645 inline void Stream<uint8_t, 2, 8, 5, ColumnMajorWithSum>::Pack(
   6646     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6647 #ifdef DEBUG
   6648 #ifdef DEBUG_METAGEMM_VERBOSE
   6649   std::cout
   6650       << __FILE__ << "(" << __LINE__
   6651       << ") ColumnMajorWithSum<uint8_t, 2, 8, 5, ColumnMajorWithSum>::Pack()"
   6652       << std::endl
   6653       << std::flush;
   6654 #endif
   6655 #endif
   6656   int params_count_copy = params.count;
   6657   int params_stride_copy = params.stride;
   6658   asm volatile(
   6659       "vmov.i16 q8, #0\n"
   6660       "vmov.i16 q9, #0\n"
   6661 
   6662       // Reduce count by leftovers.
   6663       "subs %[count], %[count], #5\n"
   6664       "beq 2f\n"
   6665 
   6666       "1:"
   6667       "subs %[count], %[count], #8\n"
   6668 
   6669       // Load Aggregate Store - column major 2x8
   6670       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6671       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6672       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6673       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6674       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6675       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6676       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6677       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6678       "pld [%[in]]\n"
   6679       "vuzp.8 d0, d1\n"
   6680       "vaddw.u8 q8, q8, d0\n"
   6681       "vaddw.u8 q9, q9, d1\n"
   6682       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6683 
   6684       "bne 1b\n"
   6685 
   6686       "2:"
   6687 
   6688       // Load Aggregate Store - column major 2x5
   6689       "vmov.i8 d0, #0\n"
   6690       "vmov.i8 d1, #0\n"
   6691       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6692       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6693       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6694       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6695       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6696       "pld [%[in]]\n"
   6697       "vuzp.8 d0, d1\n"
   6698       "vaddw.u8 q8, q8, d0\n"
   6699       "vaddw.u8 q9, q9, d1\n"
   6700       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6701 
   6702       // Aggregator Reduction.
   6703       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6704       "vdup.32 q1, %[additive_sum_offset]\n"
   6705       "vpaddl.u16 q8, q8\n"
   6706       "vpaddl.u16 q9, q9\n"
   6707       "vpadd.u32 d16, d16, d17\n"
   6708       "vpadd.u32 d18, d18, d19\n"
   6709       "vpadd.u32 d16, d16, d18\n"
   6710       "vmul.i32 q8, q8, d0[0]\n"
   6711       "vadd.i32 q8, q8, q1\n"
   6712       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6713       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6714         [out] "+r"(out), [in] "+r"(in)
   6715       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6716         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6717       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6718 }
   6719 
   6720 template <>
   6721 inline void Stream<uint8_t, 2, 8, 6, ColumnMajorWithSum>::Pack(
   6722     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6723 #ifdef DEBUG
   6724 #ifdef DEBUG_METAGEMM_VERBOSE
   6725   std::cout
   6726       << __FILE__ << "(" << __LINE__
   6727       << ") ColumnMajorWithSum<uint8_t, 2, 8, 6, ColumnMajorWithSum>::Pack()"
   6728       << std::endl
   6729       << std::flush;
   6730 #endif
   6731 #endif
   6732   int params_count_copy = params.count;
   6733   int params_stride_copy = params.stride;
   6734   asm volatile(
   6735       "vmov.i16 q8, #0\n"
   6736       "vmov.i16 q9, #0\n"
   6737 
   6738       // Reduce count by leftovers.
   6739       "subs %[count], %[count], #6\n"
   6740       "beq 2f\n"
   6741 
   6742       "1:"
   6743       "subs %[count], %[count], #8\n"
   6744 
   6745       // Load Aggregate Store - column major 2x8
   6746       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6747       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6748       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6749       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6750       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6751       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6752       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6753       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6754       "pld [%[in]]\n"
   6755       "vuzp.8 d0, d1\n"
   6756       "vaddw.u8 q8, q8, d0\n"
   6757       "vaddw.u8 q9, q9, d1\n"
   6758       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6759 
   6760       "bne 1b\n"
   6761 
   6762       "2:"
   6763 
   6764       // Load Aggregate Store - column major 2x6
   6765       "vmov.i8 d0, #0\n"
   6766       "vmov.i8 d1, #0\n"
   6767       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6768       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6769       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6770       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6771       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6772       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6773       "pld [%[in]]\n"
   6774       "vuzp.8 d0, d1\n"
   6775       "vaddw.u8 q8, q8, d0\n"
   6776       "vaddw.u8 q9, q9, d1\n"
   6777       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6778 
   6779       // Aggregator Reduction.
   6780       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6781       "vdup.32 q1, %[additive_sum_offset]\n"
   6782       "vpaddl.u16 q8, q8\n"
   6783       "vpaddl.u16 q9, q9\n"
   6784       "vpadd.u32 d16, d16, d17\n"
   6785       "vpadd.u32 d18, d18, d19\n"
   6786       "vpadd.u32 d16, d16, d18\n"
   6787       "vmul.i32 q8, q8, d0[0]\n"
   6788       "vadd.i32 q8, q8, q1\n"
   6789       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6790       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6791         [out] "+r"(out), [in] "+r"(in)
   6792       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6793         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6794       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6795 }
   6796 
   6797 template <>
   6798 inline void Stream<uint8_t, 2, 8, 7, ColumnMajorWithSum>::Pack(
   6799     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6800 #ifdef DEBUG
   6801 #ifdef DEBUG_METAGEMM_VERBOSE
   6802   std::cout
   6803       << __FILE__ << "(" << __LINE__
   6804       << ") ColumnMajorWithSum<uint8_t, 2, 8, 7, ColumnMajorWithSum>::Pack()"
   6805       << std::endl
   6806       << std::flush;
   6807 #endif
   6808 #endif
   6809   int params_count_copy = params.count;
   6810   int params_stride_copy = params.stride;
   6811   asm volatile(
   6812       "vmov.i16 q8, #0\n"
   6813       "vmov.i16 q9, #0\n"
   6814 
   6815       // Reduce count by leftovers.
   6816       "subs %[count], %[count], #7\n"
   6817       "beq 2f\n"
   6818 
   6819       "1:"
   6820       "subs %[count], %[count], #8\n"
   6821 
   6822       // Load Aggregate Store - column major 2x8
   6823       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6824       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6825       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6826       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6827       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6828       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6829       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6830       "vld1.16 {d1[3]}, [%[in]], %[stride]\n"
   6831       "pld [%[in]]\n"
   6832       "vuzp.8 d0, d1\n"
   6833       "vaddw.u8 q8, q8, d0\n"
   6834       "vaddw.u8 q9, q9, d1\n"
   6835       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6836 
   6837       "bne 1b\n"
   6838 
   6839       "2:"
   6840 
   6841       // Load Aggregate Store - column major 2x7
   6842       "vmov.i8 d0, #0\n"
   6843       "vmov.i8 d1, #0\n"
   6844       "vld1.16 {d0[0]}, [%[in]], %[stride]\n"
   6845       "vld1.16 {d0[1]}, [%[in]], %[stride]\n"
   6846       "vld1.16 {d0[2]}, [%[in]], %[stride]\n"
   6847       "vld1.16 {d0[3]}, [%[in]], %[stride]\n"
   6848       "vld1.16 {d1[0]}, [%[in]], %[stride]\n"
   6849       "vld1.16 {d1[1]}, [%[in]], %[stride]\n"
   6850       "vld1.16 {d1[2]}, [%[in]], %[stride]\n"
   6851       "pld [%[in]]\n"
   6852       "vuzp.8 d0, d1\n"
   6853       "vaddw.u8 q8, q8, d0\n"
   6854       "vaddw.u8 q9, q9, d1\n"
   6855       "vst1.32 {d0, d1}, [%[out]:128]!\n"
   6856 
   6857       // Aggregator Reduction.
   6858       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6859       "vdup.32 q1, %[additive_sum_offset]\n"
   6860       "vpaddl.u16 q8, q8\n"
   6861       "vpaddl.u16 q9, q9\n"
   6862       "vpadd.u32 d16, d16, d17\n"
   6863       "vpadd.u32 d18, d18, d19\n"
   6864       "vpadd.u32 d16, d16, d18\n"
   6865       "vmul.i32 q8, q8, d0[0]\n"
   6866       "vadd.i32 q8, q8, q1\n"
   6867       "vst1.32 {d16, d17}, [%[out]:128]\n"
   6868       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6869         [out] "+r"(out), [in] "+r"(in)
   6870       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6871         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6872       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "cc", "memory");
   6873 }
   6874 
   6875 template <>
   6876 inline void Stream<uint8_t, 3, 8, 0, ColumnMajorWithSum>::Pack(
   6877     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6878 #ifdef DEBUG
   6879 #ifdef DEBUG_METAGEMM_VERBOSE
   6880   std::cout
   6881       << __FILE__ << "(" << __LINE__
   6882       << ") ColumnMajorWithSum<uint8_t, 3, 8, 0, ColumnMajorWithSum>::Pack()"
   6883       << std::endl
   6884       << std::flush;
   6885 #endif
   6886 #endif
   6887   int params_count_copy = params.count;
   6888   int params_stride_copy = params.stride;
   6889   asm volatile(
   6890       "vmov.i16 q8, #0\n"
   6891       "vmov.i16 q9, #0\n"
   6892       "vmov.i16 q10, #0\n"
   6893 
   6894       "1:"
   6895       "subs %[count], %[count], #8\n"
   6896 
   6897       // Load Aggregate Store - column major 3x8
   6898       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   6899       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   6900       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   6901       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   6902       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   6903       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   6904       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   6905       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   6906       "vaddw.u8 q8, q8, d0\n"
   6907       "vaddw.u8 q9, q9, d1\n"
   6908       "vaddw.u8 q10, q10, d2\n"
   6909       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   6910 
   6911       "bne 1b\n"
   6912 
   6913       // Aggregator Reduction.
   6914       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6915       "vdup.32 q1, %[additive_sum_offset]\n"
   6916       "vpaddl.u16 q8, q8\n"
   6917       "vpaddl.u16 q9, q9\n"
   6918       "vpaddl.u16 q10, q10\n"
   6919       "vpadd.u32 d16, d16, d17\n"
   6920       "vpadd.u32 d18, d18, d19\n"
   6921       "vpadd.u32 d20, d20, d21\n"
   6922       "vpadd.u32 d16, d16, d18\n"
   6923       "vpadd.u32 d17, d20, d20\n"
   6924       "vmul.i32 q8, q8, d0[0]\n"
   6925       "vadd.i32 q8, q8, q1\n"
   6926       "vst1.32 {d16, d17}, [%[out]:64]\n"
   6927       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   6928         [out] "+r"(out), [in] "+r"(in)
   6929       : [additive_sum_offset] "r"(params.additive_sum_offset),
   6930         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   6931       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   6932         "memory");
   6933 }
   6934 
   6935 template <>
   6936 inline void Stream<uint8_t, 3, 8, 1, ColumnMajorWithSum>::Pack(
   6937     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   6938 #ifdef DEBUG
   6939 #ifdef DEBUG_METAGEMM_VERBOSE
   6940   std::cout
   6941       << __FILE__ << "(" << __LINE__
   6942       << ") ColumnMajorWithSum<uint8_t, 3, 8, 1, ColumnMajorWithSum>::Pack()"
   6943       << std::endl
   6944       << std::flush;
   6945 #endif
   6946 #endif
   6947   int params_count_copy = params.count;
   6948   int params_stride_copy = params.stride;
   6949   asm volatile(
   6950       "vmov.i16 q8, #0\n"
   6951       "vmov.i16 q9, #0\n"
   6952       "vmov.i16 q10, #0\n"
   6953 
   6954       // Reduce count by leftovers.
   6955       "subs %[count], %[count], #1\n"
   6956       "beq 2f\n"
   6957 
   6958       "1:"
   6959       "subs %[count], %[count], #8\n"
   6960 
   6961       // Load Aggregate Store - column major 3x8
   6962       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   6963       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   6964       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   6965       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   6966       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   6967       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   6968       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   6969       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   6970       "vaddw.u8 q8, q8, d0\n"
   6971       "vaddw.u8 q9, q9, d1\n"
   6972       "vaddw.u8 q10, q10, d2\n"
   6973       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   6974 
   6975       "bne 1b\n"
   6976 
   6977       "2:"
   6978 
   6979       // Load Aggregate Store - column major 3x1
   6980       "vmov.i8 d0, #0\n"
   6981       "vmov.i8 d1, #0\n"
   6982       "vmov.i8 d2, #0\n"
   6983       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   6984       "vaddw.u8 q8, q8, d0\n"
   6985       "vaddw.u8 q9, q9, d1\n"
   6986       "vaddw.u8 q10, q10, d2\n"
   6987       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   6988 
   6989       // Aggregator Reduction.
   6990       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   6991       "vdup.32 q1, %[additive_sum_offset]\n"
   6992       "vpaddl.u16 q8, q8\n"
   6993       "vpaddl.u16 q9, q9\n"
   6994       "vpaddl.u16 q10, q10\n"
   6995       "vpadd.u32 d16, d16, d17\n"
   6996       "vpadd.u32 d18, d18, d19\n"
   6997       "vpadd.u32 d20, d20, d21\n"
   6998       "vpadd.u32 d16, d16, d18\n"
   6999       "vpadd.u32 d17, d20, d20\n"
   7000       "vmul.i32 q8, q8, d0[0]\n"
   7001       "vadd.i32 q8, q8, q1\n"
   7002       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7003       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7004         [out] "+r"(out), [in] "+r"(in)
   7005       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7006         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7007       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7008         "memory");
   7009 }
   7010 
   7011 template <>
   7012 inline void Stream<uint8_t, 3, 8, 2, ColumnMajorWithSum>::Pack(
   7013     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7014 #ifdef DEBUG
   7015 #ifdef DEBUG_METAGEMM_VERBOSE
   7016   std::cout
   7017       << __FILE__ << "(" << __LINE__
   7018       << ") ColumnMajorWithSum<uint8_t, 3, 8, 2, ColumnMajorWithSum>::Pack()"
   7019       << std::endl
   7020       << std::flush;
   7021 #endif
   7022 #endif
   7023   int params_count_copy = params.count;
   7024   int params_stride_copy = params.stride;
   7025   asm volatile(
   7026       "vmov.i16 q8, #0\n"
   7027       "vmov.i16 q9, #0\n"
   7028       "vmov.i16 q10, #0\n"
   7029 
   7030       // Reduce count by leftovers.
   7031       "subs %[count], %[count], #2\n"
   7032       "beq 2f\n"
   7033 
   7034       "1:"
   7035       "subs %[count], %[count], #8\n"
   7036 
   7037       // Load Aggregate Store - column major 3x8
   7038       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7039       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7040       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7041       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7042       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7043       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7044       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7045       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7046       "vaddw.u8 q8, q8, d0\n"
   7047       "vaddw.u8 q9, q9, d1\n"
   7048       "vaddw.u8 q10, q10, d2\n"
   7049       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7050 
   7051       "bne 1b\n"
   7052 
   7053       "2:"
   7054 
   7055       // Load Aggregate Store - column major 3x2
   7056       "vmov.i8 d0, #0\n"
   7057       "vmov.i8 d1, #0\n"
   7058       "vmov.i8 d2, #0\n"
   7059       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7060       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7061       "vaddw.u8 q8, q8, d0\n"
   7062       "vaddw.u8 q9, q9, d1\n"
   7063       "vaddw.u8 q10, q10, d2\n"
   7064       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7065 
   7066       // Aggregator Reduction.
   7067       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7068       "vdup.32 q1, %[additive_sum_offset]\n"
   7069       "vpaddl.u16 q8, q8\n"
   7070       "vpaddl.u16 q9, q9\n"
   7071       "vpaddl.u16 q10, q10\n"
   7072       "vpadd.u32 d16, d16, d17\n"
   7073       "vpadd.u32 d18, d18, d19\n"
   7074       "vpadd.u32 d20, d20, d21\n"
   7075       "vpadd.u32 d16, d16, d18\n"
   7076       "vpadd.u32 d17, d20, d20\n"
   7077       "vmul.i32 q8, q8, d0[0]\n"
   7078       "vadd.i32 q8, q8, q1\n"
   7079       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7080       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7081         [out] "+r"(out), [in] "+r"(in)
   7082       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7083         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7084       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7085         "memory");
   7086 }
   7087 
   7088 template <>
   7089 inline void Stream<uint8_t, 3, 8, 3, ColumnMajorWithSum>::Pack(
   7090     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7091 #ifdef DEBUG
   7092 #ifdef DEBUG_METAGEMM_VERBOSE
   7093   std::cout
   7094       << __FILE__ << "(" << __LINE__
   7095       << ") ColumnMajorWithSum<uint8_t, 3, 8, 3, ColumnMajorWithSum>::Pack()"
   7096       << std::endl
   7097       << std::flush;
   7098 #endif
   7099 #endif
   7100   int params_count_copy = params.count;
   7101   int params_stride_copy = params.stride;
   7102   asm volatile(
   7103       "vmov.i16 q8, #0\n"
   7104       "vmov.i16 q9, #0\n"
   7105       "vmov.i16 q10, #0\n"
   7106 
   7107       // Reduce count by leftovers.
   7108       "subs %[count], %[count], #3\n"
   7109       "beq 2f\n"
   7110 
   7111       "1:"
   7112       "subs %[count], %[count], #8\n"
   7113 
   7114       // Load Aggregate Store - column major 3x8
   7115       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7116       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7117       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7118       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7119       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7120       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7121       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7122       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7123       "vaddw.u8 q8, q8, d0\n"
   7124       "vaddw.u8 q9, q9, d1\n"
   7125       "vaddw.u8 q10, q10, d2\n"
   7126       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7127 
   7128       "bne 1b\n"
   7129 
   7130       "2:"
   7131 
   7132       // Load Aggregate Store - column major 3x3
   7133       "vmov.i8 d0, #0\n"
   7134       "vmov.i8 d1, #0\n"
   7135       "vmov.i8 d2, #0\n"
   7136       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7137       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7138       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7139       "vaddw.u8 q8, q8, d0\n"
   7140       "vaddw.u8 q9, q9, d1\n"
   7141       "vaddw.u8 q10, q10, d2\n"
   7142       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7143 
   7144       // Aggregator Reduction.
   7145       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7146       "vdup.32 q1, %[additive_sum_offset]\n"
   7147       "vpaddl.u16 q8, q8\n"
   7148       "vpaddl.u16 q9, q9\n"
   7149       "vpaddl.u16 q10, q10\n"
   7150       "vpadd.u32 d16, d16, d17\n"
   7151       "vpadd.u32 d18, d18, d19\n"
   7152       "vpadd.u32 d20, d20, d21\n"
   7153       "vpadd.u32 d16, d16, d18\n"
   7154       "vpadd.u32 d17, d20, d20\n"
   7155       "vmul.i32 q8, q8, d0[0]\n"
   7156       "vadd.i32 q8, q8, q1\n"
   7157       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7158       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7159         [out] "+r"(out), [in] "+r"(in)
   7160       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7161         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7162       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7163         "memory");
   7164 }
   7165 
   7166 template <>
   7167 inline void Stream<uint8_t, 3, 8, 4, ColumnMajorWithSum>::Pack(
   7168     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7169 #ifdef DEBUG
   7170 #ifdef DEBUG_METAGEMM_VERBOSE
   7171   std::cout
   7172       << __FILE__ << "(" << __LINE__
   7173       << ") ColumnMajorWithSum<uint8_t, 3, 8, 4, ColumnMajorWithSum>::Pack()"
   7174       << std::endl
   7175       << std::flush;
   7176 #endif
   7177 #endif
   7178   int params_count_copy = params.count;
   7179   int params_stride_copy = params.stride;
   7180   asm volatile(
   7181       "vmov.i16 q8, #0\n"
   7182       "vmov.i16 q9, #0\n"
   7183       "vmov.i16 q10, #0\n"
   7184 
   7185       // Reduce count by leftovers.
   7186       "subs %[count], %[count], #4\n"
   7187       "beq 2f\n"
   7188 
   7189       "1:"
   7190       "subs %[count], %[count], #8\n"
   7191 
   7192       // Load Aggregate Store - column major 3x8
   7193       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7194       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7195       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7196       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7197       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7198       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7199       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7200       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7201       "vaddw.u8 q8, q8, d0\n"
   7202       "vaddw.u8 q9, q9, d1\n"
   7203       "vaddw.u8 q10, q10, d2\n"
   7204       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7205 
   7206       "bne 1b\n"
   7207 
   7208       "2:"
   7209 
   7210       // Load Aggregate Store - column major 3x4
   7211       "vmov.i8 d0, #0\n"
   7212       "vmov.i8 d1, #0\n"
   7213       "vmov.i8 d2, #0\n"
   7214       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7215       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7216       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7217       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7218       "vaddw.u8 q8, q8, d0\n"
   7219       "vaddw.u8 q9, q9, d1\n"
   7220       "vaddw.u8 q10, q10, d2\n"
   7221       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7222 
   7223       // Aggregator Reduction.
   7224       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7225       "vdup.32 q1, %[additive_sum_offset]\n"
   7226       "vpaddl.u16 q8, q8\n"
   7227       "vpaddl.u16 q9, q9\n"
   7228       "vpaddl.u16 q10, q10\n"
   7229       "vpadd.u32 d16, d16, d17\n"
   7230       "vpadd.u32 d18, d18, d19\n"
   7231       "vpadd.u32 d20, d20, d21\n"
   7232       "vpadd.u32 d16, d16, d18\n"
   7233       "vpadd.u32 d17, d20, d20\n"
   7234       "vmul.i32 q8, q8, d0[0]\n"
   7235       "vadd.i32 q8, q8, q1\n"
   7236       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7237       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7238         [out] "+r"(out), [in] "+r"(in)
   7239       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7240         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7241       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7242         "memory");
   7243 }
   7244 
   7245 template <>
   7246 inline void Stream<uint8_t, 3, 8, 5, ColumnMajorWithSum>::Pack(
   7247     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7248 #ifdef DEBUG
   7249 #ifdef DEBUG_METAGEMM_VERBOSE
   7250   std::cout
   7251       << __FILE__ << "(" << __LINE__
   7252       << ") ColumnMajorWithSum<uint8_t, 3, 8, 5, ColumnMajorWithSum>::Pack()"
   7253       << std::endl
   7254       << std::flush;
   7255 #endif
   7256 #endif
   7257   int params_count_copy = params.count;
   7258   int params_stride_copy = params.stride;
   7259   asm volatile(
   7260       "vmov.i16 q8, #0\n"
   7261       "vmov.i16 q9, #0\n"
   7262       "vmov.i16 q10, #0\n"
   7263 
   7264       // Reduce count by leftovers.
   7265       "subs %[count], %[count], #5\n"
   7266       "beq 2f\n"
   7267 
   7268       "1:"
   7269       "subs %[count], %[count], #8\n"
   7270 
   7271       // Load Aggregate Store - column major 3x8
   7272       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7273       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7274       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7275       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7276       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7277       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7278       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7279       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7280       "vaddw.u8 q8, q8, d0\n"
   7281       "vaddw.u8 q9, q9, d1\n"
   7282       "vaddw.u8 q10, q10, d2\n"
   7283       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7284 
   7285       "bne 1b\n"
   7286 
   7287       "2:"
   7288 
   7289       // Load Aggregate Store - column major 3x5
   7290       "vmov.i8 d0, #0\n"
   7291       "vmov.i8 d1, #0\n"
   7292       "vmov.i8 d2, #0\n"
   7293       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7294       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7295       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7296       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7297       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7298       "vaddw.u8 q8, q8, d0\n"
   7299       "vaddw.u8 q9, q9, d1\n"
   7300       "vaddw.u8 q10, q10, d2\n"
   7301       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7302 
   7303       // Aggregator Reduction.
   7304       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7305       "vdup.32 q1, %[additive_sum_offset]\n"
   7306       "vpaddl.u16 q8, q8\n"
   7307       "vpaddl.u16 q9, q9\n"
   7308       "vpaddl.u16 q10, q10\n"
   7309       "vpadd.u32 d16, d16, d17\n"
   7310       "vpadd.u32 d18, d18, d19\n"
   7311       "vpadd.u32 d20, d20, d21\n"
   7312       "vpadd.u32 d16, d16, d18\n"
   7313       "vpadd.u32 d17, d20, d20\n"
   7314       "vmul.i32 q8, q8, d0[0]\n"
   7315       "vadd.i32 q8, q8, q1\n"
   7316       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7317       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7318         [out] "+r"(out), [in] "+r"(in)
   7319       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7320         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7321       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7322         "memory");
   7323 }
   7324 
   7325 template <>
   7326 inline void Stream<uint8_t, 3, 8, 6, ColumnMajorWithSum>::Pack(
   7327     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7328 #ifdef DEBUG
   7329 #ifdef DEBUG_METAGEMM_VERBOSE
   7330   std::cout
   7331       << __FILE__ << "(" << __LINE__
   7332       << ") ColumnMajorWithSum<uint8_t, 3, 8, 6, ColumnMajorWithSum>::Pack()"
   7333       << std::endl
   7334       << std::flush;
   7335 #endif
   7336 #endif
   7337   int params_count_copy = params.count;
   7338   int params_stride_copy = params.stride;
   7339   asm volatile(
   7340       "vmov.i16 q8, #0\n"
   7341       "vmov.i16 q9, #0\n"
   7342       "vmov.i16 q10, #0\n"
   7343 
   7344       // Reduce count by leftovers.
   7345       "subs %[count], %[count], #6\n"
   7346       "beq 2f\n"
   7347 
   7348       "1:"
   7349       "subs %[count], %[count], #8\n"
   7350 
   7351       // Load Aggregate Store - column major 3x8
   7352       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7353       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7354       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7355       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7356       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7357       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7358       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7359       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7360       "vaddw.u8 q8, q8, d0\n"
   7361       "vaddw.u8 q9, q9, d1\n"
   7362       "vaddw.u8 q10, q10, d2\n"
   7363       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7364 
   7365       "bne 1b\n"
   7366 
   7367       "2:"
   7368 
   7369       // Load Aggregate Store - column major 3x6
   7370       "vmov.i8 d0, #0\n"
   7371       "vmov.i8 d1, #0\n"
   7372       "vmov.i8 d2, #0\n"
   7373       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7374       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7375       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7376       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7377       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7378       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7379       "vaddw.u8 q8, q8, d0\n"
   7380       "vaddw.u8 q9, q9, d1\n"
   7381       "vaddw.u8 q10, q10, d2\n"
   7382       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7383 
   7384       // Aggregator Reduction.
   7385       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7386       "vdup.32 q1, %[additive_sum_offset]\n"
   7387       "vpaddl.u16 q8, q8\n"
   7388       "vpaddl.u16 q9, q9\n"
   7389       "vpaddl.u16 q10, q10\n"
   7390       "vpadd.u32 d16, d16, d17\n"
   7391       "vpadd.u32 d18, d18, d19\n"
   7392       "vpadd.u32 d20, d20, d21\n"
   7393       "vpadd.u32 d16, d16, d18\n"
   7394       "vpadd.u32 d17, d20, d20\n"
   7395       "vmul.i32 q8, q8, d0[0]\n"
   7396       "vadd.i32 q8, q8, q1\n"
   7397       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7398       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7399         [out] "+r"(out), [in] "+r"(in)
   7400       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7401         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7402       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7403         "memory");
   7404 }
   7405 
   7406 template <>
   7407 inline void Stream<uint8_t, 3, 8, 7, ColumnMajorWithSum>::Pack(
   7408     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7409 #ifdef DEBUG
   7410 #ifdef DEBUG_METAGEMM_VERBOSE
   7411   std::cout
   7412       << __FILE__ << "(" << __LINE__
   7413       << ") ColumnMajorWithSum<uint8_t, 3, 8, 7, ColumnMajorWithSum>::Pack()"
   7414       << std::endl
   7415       << std::flush;
   7416 #endif
   7417 #endif
   7418   int params_count_copy = params.count;
   7419   int params_stride_copy = params.stride;
   7420   asm volatile(
   7421       "vmov.i16 q8, #0\n"
   7422       "vmov.i16 q9, #0\n"
   7423       "vmov.i16 q10, #0\n"
   7424 
   7425       // Reduce count by leftovers.
   7426       "subs %[count], %[count], #7\n"
   7427       "beq 2f\n"
   7428 
   7429       "1:"
   7430       "subs %[count], %[count], #8\n"
   7431 
   7432       // Load Aggregate Store - column major 3x8
   7433       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7434       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7435       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7436       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7437       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7438       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7439       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7440       "vld3.8 {d0[7], d1[7], d2[7]}, [%[in]], %[stride]\n"
   7441       "vaddw.u8 q8, q8, d0\n"
   7442       "vaddw.u8 q9, q9, d1\n"
   7443       "vaddw.u8 q10, q10, d2\n"
   7444       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7445 
   7446       "bne 1b\n"
   7447 
   7448       "2:"
   7449 
   7450       // Load Aggregate Store - column major 3x7
   7451       "vmov.i8 d0, #0\n"
   7452       "vmov.i8 d1, #0\n"
   7453       "vmov.i8 d2, #0\n"
   7454       "vld3.8 {d0[0], d1[0], d2[0]}, [%[in]], %[stride]\n"
   7455       "vld3.8 {d0[1], d1[1], d2[1]}, [%[in]], %[stride]\n"
   7456       "vld3.8 {d0[2], d1[2], d2[2]}, [%[in]], %[stride]\n"
   7457       "vld3.8 {d0[3], d1[3], d2[3]}, [%[in]], %[stride]\n"
   7458       "vld3.8 {d0[4], d1[4], d2[4]}, [%[in]], %[stride]\n"
   7459       "vld3.8 {d0[5], d1[5], d2[5]}, [%[in]], %[stride]\n"
   7460       "vld3.8 {d0[6], d1[6], d2[6]}, [%[in]], %[stride]\n"
   7461       "vaddw.u8 q8, q8, d0\n"
   7462       "vaddw.u8 q9, q9, d1\n"
   7463       "vaddw.u8 q10, q10, d2\n"
   7464       "vst1.32 {d0, d1, d2}, [%[out]:64]!\n"
   7465 
   7466       // Aggregator Reduction.
   7467       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7468       "vdup.32 q1, %[additive_sum_offset]\n"
   7469       "vpaddl.u16 q8, q8\n"
   7470       "vpaddl.u16 q9, q9\n"
   7471       "vpaddl.u16 q10, q10\n"
   7472       "vpadd.u32 d16, d16, d17\n"
   7473       "vpadd.u32 d18, d18, d19\n"
   7474       "vpadd.u32 d20, d20, d21\n"
   7475       "vpadd.u32 d16, d16, d18\n"
   7476       "vpadd.u32 d17, d20, d20\n"
   7477       "vmul.i32 q8, q8, d0[0]\n"
   7478       "vadd.i32 q8, q8, q1\n"
   7479       "vst1.32 {d16, d17}, [%[out]:64]\n"
   7480       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7481         [out] "+r"(out), [in] "+r"(in)
   7482       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7483         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7484       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "cc",
   7485         "memory");
   7486 }
   7487 
   7488 template <>
   7489 inline void Stream<uint8_t, 4, 8, 0, ColumnMajorWithSum>::Pack(
   7490     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7491 #ifdef DEBUG
   7492 #ifdef DEBUG_METAGEMM_VERBOSE
   7493   std::cout
   7494       << __FILE__ << "(" << __LINE__
   7495       << ") ColumnMajorWithSum<uint8_t, 4, 8, 0, ColumnMajorWithSum>::Pack()"
   7496       << std::endl
   7497       << std::flush;
   7498 #endif
   7499 #endif
   7500   int params_count_copy = params.count;
   7501   int params_stride_copy = params.stride;
   7502   asm volatile(
   7503       "vmov.i16 q8, #0\n"
   7504       "vmov.i16 q9, #0\n"
   7505       "vmov.i16 q10, #0\n"
   7506       "vmov.i16 q11, #0\n"
   7507 
   7508       "1:"
   7509       "subs %[count], %[count], #8\n"
   7510 
   7511       // Load Aggregate Store - column major 4x8
   7512       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7513       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7514       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7515       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7516       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7517       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7518       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7519       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7520       "pld [%[in]]\n"
   7521       "vtrn.16 d0, d2\n"
   7522       "vtrn.16 d1, d3\n"
   7523       "vtrn.8 d0, d1\n"
   7524       "vtrn.8 d2, d3\n"
   7525       "vaddw.u8 q8, q8, d0\n"
   7526       "vaddw.u8 q9, q9, d1\n"
   7527       "vaddw.u8 q10, q10, d2\n"
   7528       "vaddw.u8 q11, q11, d3\n"
   7529       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7530 
   7531       "bne 1b\n"
   7532 
   7533       // Aggregator Reduction.
   7534       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7535       "vdup.32 q1, %[additive_sum_offset]\n"
   7536       "vpaddl.u16 q8, q8\n"
   7537       "vpaddl.u16 q9, q9\n"
   7538       "vpaddl.u16 q10, q10\n"
   7539       "vpaddl.u16 q11, q11\n"
   7540       "vpadd.u32 d16, d16, d17\n"
   7541       "vpadd.u32 d18, d18, d19\n"
   7542       "vpadd.u32 d20, d20, d21\n"
   7543       "vpadd.u32 d22, d22, d23\n"
   7544       "vpadd.u32 d16, d16, d18\n"
   7545       "vpadd.u32 d17, d20, d22\n"
   7546       "vmul.i32 q8, q8, d0[0]\n"
   7547       "vadd.i32 q8, q8, q1\n"
   7548       "vst1.32 {d16, d17}, [%[out]:128]\n"
   7549       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7550         [out] "+r"(out), [in] "+r"(in)
   7551       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7552         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7553       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   7554         "d23", "cc", "memory");
   7555 }
   7556 
   7557 template <>
   7558 inline void Stream<uint8_t, 4, 8, 1, ColumnMajorWithSum>::Pack(
   7559     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7560 #ifdef DEBUG
   7561 #ifdef DEBUG_METAGEMM_VERBOSE
   7562   std::cout
   7563       << __FILE__ << "(" << __LINE__
   7564       << ") ColumnMajorWithSum<uint8_t, 4, 8, 1, ColumnMajorWithSum>::Pack()"
   7565       << std::endl
   7566       << std::flush;
   7567 #endif
   7568 #endif
   7569   int params_count_copy = params.count;
   7570   int params_stride_copy = params.stride;
   7571   asm volatile(
   7572       "vmov.i16 q8, #0\n"
   7573       "vmov.i16 q9, #0\n"
   7574       "vmov.i16 q10, #0\n"
   7575       "vmov.i16 q11, #0\n"
   7576 
   7577       // Reduce count by leftovers.
   7578       "subs %[count], %[count], #1\n"
   7579       "beq 2f\n"
   7580 
   7581       "1:"
   7582       "subs %[count], %[count], #8\n"
   7583 
   7584       // Load Aggregate Store - column major 4x8
   7585       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7586       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7587       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7588       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7589       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7590       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7591       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7592       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7593       "pld [%[in]]\n"
   7594       "vtrn.16 d0, d2\n"
   7595       "vtrn.16 d1, d3\n"
   7596       "vtrn.8 d0, d1\n"
   7597       "vtrn.8 d2, d3\n"
   7598       "vaddw.u8 q8, q8, d0\n"
   7599       "vaddw.u8 q9, q9, d1\n"
   7600       "vaddw.u8 q10, q10, d2\n"
   7601       "vaddw.u8 q11, q11, d3\n"
   7602       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7603 
   7604       "bne 1b\n"
   7605 
   7606       "2:"
   7607 
   7608       // Load Aggregate Store - column major 4x1
   7609       "vmov.i8 d0, #0\n"
   7610       "vmov.i8 d1, #0\n"
   7611       "vmov.i8 d2, #0\n"
   7612       "vmov.i8 d3, #0\n"
   7613       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7614       "pld [%[in]]\n"
   7615       "vtrn.16 d0, d2\n"
   7616       "vtrn.16 d1, d3\n"
   7617       "vtrn.8 d0, d1\n"
   7618       "vtrn.8 d2, d3\n"
   7619       "vaddw.u8 q8, q8, d0\n"
   7620       "vaddw.u8 q9, q9, d1\n"
   7621       "vaddw.u8 q10, q10, d2\n"
   7622       "vaddw.u8 q11, q11, d3\n"
   7623       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7624 
   7625       // Aggregator Reduction.
   7626       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7627       "vdup.32 q1, %[additive_sum_offset]\n"
   7628       "vpaddl.u16 q8, q8\n"
   7629       "vpaddl.u16 q9, q9\n"
   7630       "vpaddl.u16 q10, q10\n"
   7631       "vpaddl.u16 q11, q11\n"
   7632       "vpadd.u32 d16, d16, d17\n"
   7633       "vpadd.u32 d18, d18, d19\n"
   7634       "vpadd.u32 d20, d20, d21\n"
   7635       "vpadd.u32 d22, d22, d23\n"
   7636       "vpadd.u32 d16, d16, d18\n"
   7637       "vpadd.u32 d17, d20, d22\n"
   7638       "vmul.i32 q8, q8, d0[0]\n"
   7639       "vadd.i32 q8, q8, q1\n"
   7640       "vst1.32 {d16, d17}, [%[out]:128]\n"
   7641       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7642         [out] "+r"(out), [in] "+r"(in)
   7643       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7644         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7645       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   7646         "d23", "cc", "memory");
   7647 }
   7648 
   7649 template <>
   7650 inline void Stream<uint8_t, 4, 8, 2, ColumnMajorWithSum>::Pack(
   7651     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7652 #ifdef DEBUG
   7653 #ifdef DEBUG_METAGEMM_VERBOSE
   7654   std::cout
   7655       << __FILE__ << "(" << __LINE__
   7656       << ") ColumnMajorWithSum<uint8_t, 4, 8, 2, ColumnMajorWithSum>::Pack()"
   7657       << std::endl
   7658       << std::flush;
   7659 #endif
   7660 #endif
   7661   int params_count_copy = params.count;
   7662   int params_stride_copy = params.stride;
   7663   asm volatile(
   7664       "vmov.i16 q8, #0\n"
   7665       "vmov.i16 q9, #0\n"
   7666       "vmov.i16 q10, #0\n"
   7667       "vmov.i16 q11, #0\n"
   7668 
   7669       // Reduce count by leftovers.
   7670       "subs %[count], %[count], #2\n"
   7671       "beq 2f\n"
   7672 
   7673       "1:"
   7674       "subs %[count], %[count], #8\n"
   7675 
   7676       // Load Aggregate Store - column major 4x8
   7677       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7678       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7679       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7680       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7681       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7682       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7683       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7684       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7685       "pld [%[in]]\n"
   7686       "vtrn.16 d0, d2\n"
   7687       "vtrn.16 d1, d3\n"
   7688       "vtrn.8 d0, d1\n"
   7689       "vtrn.8 d2, d3\n"
   7690       "vaddw.u8 q8, q8, d0\n"
   7691       "vaddw.u8 q9, q9, d1\n"
   7692       "vaddw.u8 q10, q10, d2\n"
   7693       "vaddw.u8 q11, q11, d3\n"
   7694       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7695 
   7696       "bne 1b\n"
   7697 
   7698       "2:"
   7699 
   7700       // Load Aggregate Store - column major 4x2
   7701       "vmov.i8 d0, #0\n"
   7702       "vmov.i8 d1, #0\n"
   7703       "vmov.i8 d2, #0\n"
   7704       "vmov.i8 d3, #0\n"
   7705       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7706       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7707       "pld [%[in]]\n"
   7708       "vtrn.16 d0, d2\n"
   7709       "vtrn.16 d1, d3\n"
   7710       "vtrn.8 d0, d1\n"
   7711       "vtrn.8 d2, d3\n"
   7712       "vaddw.u8 q8, q8, d0\n"
   7713       "vaddw.u8 q9, q9, d1\n"
   7714       "vaddw.u8 q10, q10, d2\n"
   7715       "vaddw.u8 q11, q11, d3\n"
   7716       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7717 
   7718       // Aggregator Reduction.
   7719       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7720       "vdup.32 q1, %[additive_sum_offset]\n"
   7721       "vpaddl.u16 q8, q8\n"
   7722       "vpaddl.u16 q9, q9\n"
   7723       "vpaddl.u16 q10, q10\n"
   7724       "vpaddl.u16 q11, q11\n"
   7725       "vpadd.u32 d16, d16, d17\n"
   7726       "vpadd.u32 d18, d18, d19\n"
   7727       "vpadd.u32 d20, d20, d21\n"
   7728       "vpadd.u32 d22, d22, d23\n"
   7729       "vpadd.u32 d16, d16, d18\n"
   7730       "vpadd.u32 d17, d20, d22\n"
   7731       "vmul.i32 q8, q8, d0[0]\n"
   7732       "vadd.i32 q8, q8, q1\n"
   7733       "vst1.32 {d16, d17}, [%[out]:128]\n"
   7734       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7735         [out] "+r"(out), [in] "+r"(in)
   7736       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7737         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7738       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   7739         "d23", "cc", "memory");
   7740 }
   7741 
   7742 template <>
   7743 inline void Stream<uint8_t, 4, 8, 3, ColumnMajorWithSum>::Pack(
   7744     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7745 #ifdef DEBUG
   7746 #ifdef DEBUG_METAGEMM_VERBOSE
   7747   std::cout
   7748       << __FILE__ << "(" << __LINE__
   7749       << ") ColumnMajorWithSum<uint8_t, 4, 8, 3, ColumnMajorWithSum>::Pack()"
   7750       << std::endl
   7751       << std::flush;
   7752 #endif
   7753 #endif
   7754   int params_count_copy = params.count;
   7755   int params_stride_copy = params.stride;
   7756   asm volatile(
   7757       "vmov.i16 q8, #0\n"
   7758       "vmov.i16 q9, #0\n"
   7759       "vmov.i16 q10, #0\n"
   7760       "vmov.i16 q11, #0\n"
   7761 
   7762       // Reduce count by leftovers.
   7763       "subs %[count], %[count], #3\n"
   7764       "beq 2f\n"
   7765 
   7766       "1:"
   7767       "subs %[count], %[count], #8\n"
   7768 
   7769       // Load Aggregate Store - column major 4x8
   7770       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7771       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7772       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7773       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7774       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7775       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7776       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7777       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7778       "pld [%[in]]\n"
   7779       "vtrn.16 d0, d2\n"
   7780       "vtrn.16 d1, d3\n"
   7781       "vtrn.8 d0, d1\n"
   7782       "vtrn.8 d2, d3\n"
   7783       "vaddw.u8 q8, q8, d0\n"
   7784       "vaddw.u8 q9, q9, d1\n"
   7785       "vaddw.u8 q10, q10, d2\n"
   7786       "vaddw.u8 q11, q11, d3\n"
   7787       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7788 
   7789       "bne 1b\n"
   7790 
   7791       "2:"
   7792 
   7793       // Load Aggregate Store - column major 4x3
   7794       "vmov.i8 d0, #0\n"
   7795       "vmov.i8 d1, #0\n"
   7796       "vmov.i8 d2, #0\n"
   7797       "vmov.i8 d3, #0\n"
   7798       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7799       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7800       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7801       "pld [%[in]]\n"
   7802       "vtrn.16 d0, d2\n"
   7803       "vtrn.16 d1, d3\n"
   7804       "vtrn.8 d0, d1\n"
   7805       "vtrn.8 d2, d3\n"
   7806       "vaddw.u8 q8, q8, d0\n"
   7807       "vaddw.u8 q9, q9, d1\n"
   7808       "vaddw.u8 q10, q10, d2\n"
   7809       "vaddw.u8 q11, q11, d3\n"
   7810       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7811 
   7812       // Aggregator Reduction.
   7813       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7814       "vdup.32 q1, %[additive_sum_offset]\n"
   7815       "vpaddl.u16 q8, q8\n"
   7816       "vpaddl.u16 q9, q9\n"
   7817       "vpaddl.u16 q10, q10\n"
   7818       "vpaddl.u16 q11, q11\n"
   7819       "vpadd.u32 d16, d16, d17\n"
   7820       "vpadd.u32 d18, d18, d19\n"
   7821       "vpadd.u32 d20, d20, d21\n"
   7822       "vpadd.u32 d22, d22, d23\n"
   7823       "vpadd.u32 d16, d16, d18\n"
   7824       "vpadd.u32 d17, d20, d22\n"
   7825       "vmul.i32 q8, q8, d0[0]\n"
   7826       "vadd.i32 q8, q8, q1\n"
   7827       "vst1.32 {d16, d17}, [%[out]:128]\n"
   7828       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7829         [out] "+r"(out), [in] "+r"(in)
   7830       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7831         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7832       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   7833         "d23", "cc", "memory");
   7834 }
   7835 
   7836 template <>
   7837 inline void Stream<uint8_t, 4, 8, 4, ColumnMajorWithSum>::Pack(
   7838     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7839 #ifdef DEBUG
   7840 #ifdef DEBUG_METAGEMM_VERBOSE
   7841   std::cout
   7842       << __FILE__ << "(" << __LINE__
   7843       << ") ColumnMajorWithSum<uint8_t, 4, 8, 4, ColumnMajorWithSum>::Pack()"
   7844       << std::endl
   7845       << std::flush;
   7846 #endif
   7847 #endif
   7848   int params_count_copy = params.count;
   7849   int params_stride_copy = params.stride;
   7850   asm volatile(
   7851       "vmov.i16 q8, #0\n"
   7852       "vmov.i16 q9, #0\n"
   7853       "vmov.i16 q10, #0\n"
   7854       "vmov.i16 q11, #0\n"
   7855 
   7856       // Reduce count by leftovers.
   7857       "subs %[count], %[count], #4\n"
   7858       "beq 2f\n"
   7859 
   7860       "1:"
   7861       "subs %[count], %[count], #8\n"
   7862 
   7863       // Load Aggregate Store - column major 4x8
   7864       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7865       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7866       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7867       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7868       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7869       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7870       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7871       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7872       "pld [%[in]]\n"
   7873       "vtrn.16 d0, d2\n"
   7874       "vtrn.16 d1, d3\n"
   7875       "vtrn.8 d0, d1\n"
   7876       "vtrn.8 d2, d3\n"
   7877       "vaddw.u8 q8, q8, d0\n"
   7878       "vaddw.u8 q9, q9, d1\n"
   7879       "vaddw.u8 q10, q10, d2\n"
   7880       "vaddw.u8 q11, q11, d3\n"
   7881       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7882 
   7883       "bne 1b\n"
   7884 
   7885       "2:"
   7886 
   7887       // Load Aggregate Store - column major 4x4
   7888       "vmov.i8 d0, #0\n"
   7889       "vmov.i8 d1, #0\n"
   7890       "vmov.i8 d2, #0\n"
   7891       "vmov.i8 d3, #0\n"
   7892       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7893       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7894       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7895       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7896       "pld [%[in]]\n"
   7897       "vtrn.16 d0, d2\n"
   7898       "vtrn.16 d1, d3\n"
   7899       "vtrn.8 d0, d1\n"
   7900       "vtrn.8 d2, d3\n"
   7901       "vaddw.u8 q8, q8, d0\n"
   7902       "vaddw.u8 q9, q9, d1\n"
   7903       "vaddw.u8 q10, q10, d2\n"
   7904       "vaddw.u8 q11, q11, d3\n"
   7905       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7906 
   7907       // Aggregator Reduction.
   7908       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   7909       "vdup.32 q1, %[additive_sum_offset]\n"
   7910       "vpaddl.u16 q8, q8\n"
   7911       "vpaddl.u16 q9, q9\n"
   7912       "vpaddl.u16 q10, q10\n"
   7913       "vpaddl.u16 q11, q11\n"
   7914       "vpadd.u32 d16, d16, d17\n"
   7915       "vpadd.u32 d18, d18, d19\n"
   7916       "vpadd.u32 d20, d20, d21\n"
   7917       "vpadd.u32 d22, d22, d23\n"
   7918       "vpadd.u32 d16, d16, d18\n"
   7919       "vpadd.u32 d17, d20, d22\n"
   7920       "vmul.i32 q8, q8, d0[0]\n"
   7921       "vadd.i32 q8, q8, q1\n"
   7922       "vst1.32 {d16, d17}, [%[out]:128]\n"
   7923       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   7924         [out] "+r"(out), [in] "+r"(in)
   7925       : [additive_sum_offset] "r"(params.additive_sum_offset),
   7926         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   7927       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   7928         "d23", "cc", "memory");
   7929 }
   7930 
   7931 template <>
   7932 inline void Stream<uint8_t, 4, 8, 5, ColumnMajorWithSum>::Pack(
   7933     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   7934 #ifdef DEBUG
   7935 #ifdef DEBUG_METAGEMM_VERBOSE
   7936   std::cout
   7937       << __FILE__ << "(" << __LINE__
   7938       << ") ColumnMajorWithSum<uint8_t, 4, 8, 5, ColumnMajorWithSum>::Pack()"
   7939       << std::endl
   7940       << std::flush;
   7941 #endif
   7942 #endif
   7943   int params_count_copy = params.count;
   7944   int params_stride_copy = params.stride;
   7945   asm volatile(
   7946       "vmov.i16 q8, #0\n"
   7947       "vmov.i16 q9, #0\n"
   7948       "vmov.i16 q10, #0\n"
   7949       "vmov.i16 q11, #0\n"
   7950 
   7951       // Reduce count by leftovers.
   7952       "subs %[count], %[count], #5\n"
   7953       "beq 2f\n"
   7954 
   7955       "1:"
   7956       "subs %[count], %[count], #8\n"
   7957 
   7958       // Load Aggregate Store - column major 4x8
   7959       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7960       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7961       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7962       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7963       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7964       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   7965       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   7966       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   7967       "pld [%[in]]\n"
   7968       "vtrn.16 d0, d2\n"
   7969       "vtrn.16 d1, d3\n"
   7970       "vtrn.8 d0, d1\n"
   7971       "vtrn.8 d2, d3\n"
   7972       "vaddw.u8 q8, q8, d0\n"
   7973       "vaddw.u8 q9, q9, d1\n"
   7974       "vaddw.u8 q10, q10, d2\n"
   7975       "vaddw.u8 q11, q11, d3\n"
   7976       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   7977 
   7978       "bne 1b\n"
   7979 
   7980       "2:"
   7981 
   7982       // Load Aggregate Store - column major 4x5
   7983       "vmov.i8 d0, #0\n"
   7984       "vmov.i8 d1, #0\n"
   7985       "vmov.i8 d2, #0\n"
   7986       "vmov.i8 d3, #0\n"
   7987       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   7988       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   7989       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   7990       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   7991       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   7992       "pld [%[in]]\n"
   7993       "vtrn.16 d0, d2\n"
   7994       "vtrn.16 d1, d3\n"
   7995       "vtrn.8 d0, d1\n"
   7996       "vtrn.8 d2, d3\n"
   7997       "vaddw.u8 q8, q8, d0\n"
   7998       "vaddw.u8 q9, q9, d1\n"
   7999       "vaddw.u8 q10, q10, d2\n"
   8000       "vaddw.u8 q11, q11, d3\n"
   8001       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   8002 
   8003       // Aggregator Reduction.
   8004       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8005       "vdup.32 q1, %[additive_sum_offset]\n"
   8006       "vpaddl.u16 q8, q8\n"
   8007       "vpaddl.u16 q9, q9\n"
   8008       "vpaddl.u16 q10, q10\n"
   8009       "vpaddl.u16 q11, q11\n"
   8010       "vpadd.u32 d16, d16, d17\n"
   8011       "vpadd.u32 d18, d18, d19\n"
   8012       "vpadd.u32 d20, d20, d21\n"
   8013       "vpadd.u32 d22, d22, d23\n"
   8014       "vpadd.u32 d16, d16, d18\n"
   8015       "vpadd.u32 d17, d20, d22\n"
   8016       "vmul.i32 q8, q8, d0[0]\n"
   8017       "vadd.i32 q8, q8, q1\n"
   8018       "vst1.32 {d16, d17}, [%[out]:128]\n"
   8019       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8020         [out] "+r"(out), [in] "+r"(in)
   8021       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8022         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8023       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   8024         "d23", "cc", "memory");
   8025 }
   8026 
   8027 template <>
   8028 inline void Stream<uint8_t, 4, 8, 6, ColumnMajorWithSum>::Pack(
   8029     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8030 #ifdef DEBUG
   8031 #ifdef DEBUG_METAGEMM_VERBOSE
   8032   std::cout
   8033       << __FILE__ << "(" << __LINE__
   8034       << ") ColumnMajorWithSum<uint8_t, 4, 8, 6, ColumnMajorWithSum>::Pack()"
   8035       << std::endl
   8036       << std::flush;
   8037 #endif
   8038 #endif
   8039   int params_count_copy = params.count;
   8040   int params_stride_copy = params.stride;
   8041   asm volatile(
   8042       "vmov.i16 q8, #0\n"
   8043       "vmov.i16 q9, #0\n"
   8044       "vmov.i16 q10, #0\n"
   8045       "vmov.i16 q11, #0\n"
   8046 
   8047       // Reduce count by leftovers.
   8048       "subs %[count], %[count], #6\n"
   8049       "beq 2f\n"
   8050 
   8051       "1:"
   8052       "subs %[count], %[count], #8\n"
   8053 
   8054       // Load Aggregate Store - column major 4x8
   8055       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   8056       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   8057       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   8058       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   8059       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   8060       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   8061       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   8062       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   8063       "pld [%[in]]\n"
   8064       "vtrn.16 d0, d2\n"
   8065       "vtrn.16 d1, d3\n"
   8066       "vtrn.8 d0, d1\n"
   8067       "vtrn.8 d2, d3\n"
   8068       "vaddw.u8 q8, q8, d0\n"
   8069       "vaddw.u8 q9, q9, d1\n"
   8070       "vaddw.u8 q10, q10, d2\n"
   8071       "vaddw.u8 q11, q11, d3\n"
   8072       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   8073 
   8074       "bne 1b\n"
   8075 
   8076       "2:"
   8077 
   8078       // Load Aggregate Store - column major 4x6
   8079       "vmov.i8 d0, #0\n"
   8080       "vmov.i8 d1, #0\n"
   8081       "vmov.i8 d2, #0\n"
   8082       "vmov.i8 d3, #0\n"
   8083       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   8084       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   8085       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   8086       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   8087       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   8088       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   8089       "pld [%[in]]\n"
   8090       "vtrn.16 d0, d2\n"
   8091       "vtrn.16 d1, d3\n"
   8092       "vtrn.8 d0, d1\n"
   8093       "vtrn.8 d2, d3\n"
   8094       "vaddw.u8 q8, q8, d0\n"
   8095       "vaddw.u8 q9, q9, d1\n"
   8096       "vaddw.u8 q10, q10, d2\n"
   8097       "vaddw.u8 q11, q11, d3\n"
   8098       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   8099 
   8100       // Aggregator Reduction.
   8101       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8102       "vdup.32 q1, %[additive_sum_offset]\n"
   8103       "vpaddl.u16 q8, q8\n"
   8104       "vpaddl.u16 q9, q9\n"
   8105       "vpaddl.u16 q10, q10\n"
   8106       "vpaddl.u16 q11, q11\n"
   8107       "vpadd.u32 d16, d16, d17\n"
   8108       "vpadd.u32 d18, d18, d19\n"
   8109       "vpadd.u32 d20, d20, d21\n"
   8110       "vpadd.u32 d22, d22, d23\n"
   8111       "vpadd.u32 d16, d16, d18\n"
   8112       "vpadd.u32 d17, d20, d22\n"
   8113       "vmul.i32 q8, q8, d0[0]\n"
   8114       "vadd.i32 q8, q8, q1\n"
   8115       "vst1.32 {d16, d17}, [%[out]:128]\n"
   8116       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8117         [out] "+r"(out), [in] "+r"(in)
   8118       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8119         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8120       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   8121         "d23", "cc", "memory");
   8122 }
   8123 
   8124 template <>
   8125 inline void Stream<uint8_t, 4, 8, 7, ColumnMajorWithSum>::Pack(
   8126     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8127 #ifdef DEBUG
   8128 #ifdef DEBUG_METAGEMM_VERBOSE
   8129   std::cout
   8130       << __FILE__ << "(" << __LINE__
   8131       << ") ColumnMajorWithSum<uint8_t, 4, 8, 7, ColumnMajorWithSum>::Pack()"
   8132       << std::endl
   8133       << std::flush;
   8134 #endif
   8135 #endif
   8136   int params_count_copy = params.count;
   8137   int params_stride_copy = params.stride;
   8138   asm volatile(
   8139       "vmov.i16 q8, #0\n"
   8140       "vmov.i16 q9, #0\n"
   8141       "vmov.i16 q10, #0\n"
   8142       "vmov.i16 q11, #0\n"
   8143 
   8144       // Reduce count by leftovers.
   8145       "subs %[count], %[count], #7\n"
   8146       "beq 2f\n"
   8147 
   8148       "1:"
   8149       "subs %[count], %[count], #8\n"
   8150 
   8151       // Load Aggregate Store - column major 4x8
   8152       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   8153       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   8154       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   8155       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   8156       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   8157       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   8158       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   8159       "vld1.32 {d3[1]}, [%[in]], %[stride]\n"
   8160       "pld [%[in]]\n"
   8161       "vtrn.16 d0, d2\n"
   8162       "vtrn.16 d1, d3\n"
   8163       "vtrn.8 d0, d1\n"
   8164       "vtrn.8 d2, d3\n"
   8165       "vaddw.u8 q8, q8, d0\n"
   8166       "vaddw.u8 q9, q9, d1\n"
   8167       "vaddw.u8 q10, q10, d2\n"
   8168       "vaddw.u8 q11, q11, d3\n"
   8169       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   8170 
   8171       "bne 1b\n"
   8172 
   8173       "2:"
   8174 
   8175       // Load Aggregate Store - column major 4x7
   8176       "vmov.i8 d0, #0\n"
   8177       "vmov.i8 d1, #0\n"
   8178       "vmov.i8 d2, #0\n"
   8179       "vmov.i8 d3, #0\n"
   8180       "vld1.32 {d0[0]}, [%[in]], %[stride]\n"
   8181       "vld1.32 {d1[0]}, [%[in]], %[stride]\n"
   8182       "vld1.32 {d2[0]}, [%[in]], %[stride]\n"
   8183       "vld1.32 {d3[0]}, [%[in]], %[stride]\n"
   8184       "vld1.32 {d0[1]}, [%[in]], %[stride]\n"
   8185       "vld1.32 {d1[1]}, [%[in]], %[stride]\n"
   8186       "vld1.32 {d2[1]}, [%[in]], %[stride]\n"
   8187       "pld [%[in]]\n"
   8188       "vtrn.16 d0, d2\n"
   8189       "vtrn.16 d1, d3\n"
   8190       "vtrn.8 d0, d1\n"
   8191       "vtrn.8 d2, d3\n"
   8192       "vaddw.u8 q8, q8, d0\n"
   8193       "vaddw.u8 q9, q9, d1\n"
   8194       "vaddw.u8 q10, q10, d2\n"
   8195       "vaddw.u8 q11, q11, d3\n"
   8196       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   8197 
   8198       // Aggregator Reduction.
   8199       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8200       "vdup.32 q1, %[additive_sum_offset]\n"
   8201       "vpaddl.u16 q8, q8\n"
   8202       "vpaddl.u16 q9, q9\n"
   8203       "vpaddl.u16 q10, q10\n"
   8204       "vpaddl.u16 q11, q11\n"
   8205       "vpadd.u32 d16, d16, d17\n"
   8206       "vpadd.u32 d18, d18, d19\n"
   8207       "vpadd.u32 d20, d20, d21\n"
   8208       "vpadd.u32 d22, d22, d23\n"
   8209       "vpadd.u32 d16, d16, d18\n"
   8210       "vpadd.u32 d17, d20, d22\n"
   8211       "vmul.i32 q8, q8, d0[0]\n"
   8212       "vadd.i32 q8, q8, q1\n"
   8213       "vst1.32 {d16, d17}, [%[out]:128]\n"
   8214       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8215         [out] "+r"(out), [in] "+r"(in)
   8216       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8217         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8218       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
   8219         "d23", "cc", "memory");
   8220 }
   8221 
   8222 template <>
   8223 inline void Stream<uint8_t, 5, 8, 0, ColumnMajorWithSum>::Pack(
   8224     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8225 #ifdef DEBUG
   8226 #ifdef DEBUG_METAGEMM_VERBOSE
   8227   std::cout
   8228       << __FILE__ << "(" << __LINE__
   8229       << ") ColumnMajorWithSum<uint8_t, 5, 8, 0, ColumnMajorWithSum>::Pack()"
   8230       << std::endl
   8231       << std::flush;
   8232 #endif
   8233 #endif
   8234   int params_count_copy = params.count;
   8235   int params_stride_copy = params.stride;
   8236   asm volatile(
   8237       "sub %[stride], %[stride], #4\n"
   8238       "vmov.i16 q8, #0\n"
   8239       "vmov.i16 q9, #0\n"
   8240       "vmov.i16 q10, #0\n"
   8241       "vmov.i16 q11, #0\n"
   8242       "vmov.i16 q12, #0\n"
   8243 
   8244       "1:"
   8245       "subs %[count], %[count], #8\n"
   8246 
   8247       // Load Aggregate Store - column major 5x8
   8248       "vld1.32 {d0[0]}, [%[in]]!\n"
   8249       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8250       "vld1.32 {d1[0]}, [%[in]]!\n"
   8251       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8252       "vld1.32 {d2[0]}, [%[in]]!\n"
   8253       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8254       "vld1.32 {d3[0]}, [%[in]]!\n"
   8255       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8256       "vld1.32 {d0[1]}, [%[in]]!\n"
   8257       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8258       "vld1.32 {d1[1]}, [%[in]]!\n"
   8259       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8260       "vld1.32 {d2[1]}, [%[in]]!\n"
   8261       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8262       "vld1.32 {d3[1]}, [%[in]]!\n"
   8263       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8264       "pld [%[in]]\n"
   8265       "vtrn.16 d0, d2\n"
   8266       "vtrn.16 d1, d3\n"
   8267       "vtrn.8 d0, d1\n"
   8268       "vtrn.8 d2, d3\n"
   8269       "vaddw.u8 q8, q8, d0\n"
   8270       "vaddw.u8 q9, q9, d1\n"
   8271       "vaddw.u8 q10, q10, d2\n"
   8272       "vaddw.u8 q11, q11, d3\n"
   8273       "vaddw.u8 q12, q12, d4\n"
   8274       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8275       "vst1.32 {d4}, [%[out]:64]!\n"
   8276 
   8277       "bne 1b\n"
   8278 
   8279       // Aggregator Reduction.
   8280       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8281       "vdup.32 q1, %[additive_sum_offset]\n"
   8282       "vpaddl.u16 q8, q8\n"
   8283       "vpaddl.u16 q9, q9\n"
   8284       "vpaddl.u16 q10, q10\n"
   8285       "vpaddl.u16 q11, q11\n"
   8286       "vpaddl.u16 q12, q12\n"
   8287       "vpadd.u32 d16, d16, d17\n"
   8288       "vpadd.u32 d18, d18, d19\n"
   8289       "vpadd.u32 d20, d20, d21\n"
   8290       "vpadd.u32 d22, d22, d23\n"
   8291       "vpadd.u32 d24, d24, d25\n"
   8292       "vpadd.u32 d16, d16, d18\n"
   8293       "vpadd.u32 d17, d20, d22\n"
   8294       "vpadd.u32 d18, d24, d24\n"
   8295       "vmul.i32 q8, q8, d0[0]\n"
   8296       "vmul.i32 q9, q9, d0[0]\n"
   8297       "vadd.i32 q8, q8, q1\n"
   8298       "vadd.i32 q9, q9, q1\n"
   8299       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8300       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8301         [out] "+r"(out), [in] "+r"(in)
   8302       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8303         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8304       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8305         "d22", "d23", "d24", "d25", "cc", "memory");
   8306 }
   8307 
   8308 template <>
   8309 inline void Stream<uint8_t, 5, 8, 1, ColumnMajorWithSum>::Pack(
   8310     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8311 #ifdef DEBUG
   8312 #ifdef DEBUG_METAGEMM_VERBOSE
   8313   std::cout
   8314       << __FILE__ << "(" << __LINE__
   8315       << ") ColumnMajorWithSum<uint8_t, 5, 8, 1, ColumnMajorWithSum>::Pack()"
   8316       << std::endl
   8317       << std::flush;
   8318 #endif
   8319 #endif
   8320   int params_count_copy = params.count;
   8321   int params_stride_copy = params.stride;
   8322   asm volatile(
   8323       "sub %[stride], %[stride], #4\n"
   8324       "vmov.i16 q8, #0\n"
   8325       "vmov.i16 q9, #0\n"
   8326       "vmov.i16 q10, #0\n"
   8327       "vmov.i16 q11, #0\n"
   8328       "vmov.i16 q12, #0\n"
   8329 
   8330       // Reduce count by leftovers.
   8331       "subs %[count], %[count], #1\n"
   8332       "beq 2f\n"
   8333 
   8334       "1:"
   8335       "subs %[count], %[count], #8\n"
   8336 
   8337       // Load Aggregate Store - column major 5x8
   8338       "vld1.32 {d0[0]}, [%[in]]!\n"
   8339       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8340       "vld1.32 {d1[0]}, [%[in]]!\n"
   8341       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8342       "vld1.32 {d2[0]}, [%[in]]!\n"
   8343       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8344       "vld1.32 {d3[0]}, [%[in]]!\n"
   8345       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8346       "vld1.32 {d0[1]}, [%[in]]!\n"
   8347       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8348       "vld1.32 {d1[1]}, [%[in]]!\n"
   8349       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8350       "vld1.32 {d2[1]}, [%[in]]!\n"
   8351       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8352       "vld1.32 {d3[1]}, [%[in]]!\n"
   8353       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8354       "pld [%[in]]\n"
   8355       "vtrn.16 d0, d2\n"
   8356       "vtrn.16 d1, d3\n"
   8357       "vtrn.8 d0, d1\n"
   8358       "vtrn.8 d2, d3\n"
   8359       "vaddw.u8 q8, q8, d0\n"
   8360       "vaddw.u8 q9, q9, d1\n"
   8361       "vaddw.u8 q10, q10, d2\n"
   8362       "vaddw.u8 q11, q11, d3\n"
   8363       "vaddw.u8 q12, q12, d4\n"
   8364       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8365       "vst1.32 {d4}, [%[out]:64]!\n"
   8366 
   8367       "bne 1b\n"
   8368 
   8369       "2:"
   8370 
   8371       // Load Aggregate Store - column major 5x1
   8372       "vmov.i8 d0, #0\n"
   8373       "vmov.i8 d1, #0\n"
   8374       "vmov.i8 d2, #0\n"
   8375       "vmov.i8 d3, #0\n"
   8376       "vmov.i8 d4, #0\n"
   8377       "vld1.32 {d0[0]}, [%[in]]!\n"
   8378       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8379       "pld [%[in]]\n"
   8380       "vtrn.16 d0, d2\n"
   8381       "vtrn.16 d1, d3\n"
   8382       "vtrn.8 d0, d1\n"
   8383       "vtrn.8 d2, d3\n"
   8384       "vaddw.u8 q8, q8, d0\n"
   8385       "vaddw.u8 q9, q9, d1\n"
   8386       "vaddw.u8 q10, q10, d2\n"
   8387       "vaddw.u8 q11, q11, d3\n"
   8388       "vaddw.u8 q12, q12, d4\n"
   8389       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8390       "vst1.32 {d4}, [%[out]:64]!\n"
   8391 
   8392       // Aggregator Reduction.
   8393       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8394       "vdup.32 q1, %[additive_sum_offset]\n"
   8395       "vpaddl.u16 q8, q8\n"
   8396       "vpaddl.u16 q9, q9\n"
   8397       "vpaddl.u16 q10, q10\n"
   8398       "vpaddl.u16 q11, q11\n"
   8399       "vpaddl.u16 q12, q12\n"
   8400       "vpadd.u32 d16, d16, d17\n"
   8401       "vpadd.u32 d18, d18, d19\n"
   8402       "vpadd.u32 d20, d20, d21\n"
   8403       "vpadd.u32 d22, d22, d23\n"
   8404       "vpadd.u32 d24, d24, d25\n"
   8405       "vpadd.u32 d16, d16, d18\n"
   8406       "vpadd.u32 d17, d20, d22\n"
   8407       "vpadd.u32 d18, d24, d24\n"
   8408       "vmul.i32 q8, q8, d0[0]\n"
   8409       "vmul.i32 q9, q9, d0[0]\n"
   8410       "vadd.i32 q8, q8, q1\n"
   8411       "vadd.i32 q9, q9, q1\n"
   8412       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8413       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8414         [out] "+r"(out), [in] "+r"(in)
   8415       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8416         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8417       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8418         "d22", "d23", "d24", "d25", "cc", "memory");
   8419 }
   8420 
   8421 template <>
   8422 inline void Stream<uint8_t, 5, 8, 2, ColumnMajorWithSum>::Pack(
   8423     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8424 #ifdef DEBUG
   8425 #ifdef DEBUG_METAGEMM_VERBOSE
   8426   std::cout
   8427       << __FILE__ << "(" << __LINE__
   8428       << ") ColumnMajorWithSum<uint8_t, 5, 8, 2, ColumnMajorWithSum>::Pack()"
   8429       << std::endl
   8430       << std::flush;
   8431 #endif
   8432 #endif
   8433   int params_count_copy = params.count;
   8434   int params_stride_copy = params.stride;
   8435   asm volatile(
   8436       "sub %[stride], %[stride], #4\n"
   8437       "vmov.i16 q8, #0\n"
   8438       "vmov.i16 q9, #0\n"
   8439       "vmov.i16 q10, #0\n"
   8440       "vmov.i16 q11, #0\n"
   8441       "vmov.i16 q12, #0\n"
   8442 
   8443       // Reduce count by leftovers.
   8444       "subs %[count], %[count], #2\n"
   8445       "beq 2f\n"
   8446 
   8447       "1:"
   8448       "subs %[count], %[count], #8\n"
   8449 
   8450       // Load Aggregate Store - column major 5x8
   8451       "vld1.32 {d0[0]}, [%[in]]!\n"
   8452       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8453       "vld1.32 {d1[0]}, [%[in]]!\n"
   8454       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8455       "vld1.32 {d2[0]}, [%[in]]!\n"
   8456       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8457       "vld1.32 {d3[0]}, [%[in]]!\n"
   8458       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8459       "vld1.32 {d0[1]}, [%[in]]!\n"
   8460       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8461       "vld1.32 {d1[1]}, [%[in]]!\n"
   8462       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8463       "vld1.32 {d2[1]}, [%[in]]!\n"
   8464       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8465       "vld1.32 {d3[1]}, [%[in]]!\n"
   8466       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8467       "pld [%[in]]\n"
   8468       "vtrn.16 d0, d2\n"
   8469       "vtrn.16 d1, d3\n"
   8470       "vtrn.8 d0, d1\n"
   8471       "vtrn.8 d2, d3\n"
   8472       "vaddw.u8 q8, q8, d0\n"
   8473       "vaddw.u8 q9, q9, d1\n"
   8474       "vaddw.u8 q10, q10, d2\n"
   8475       "vaddw.u8 q11, q11, d3\n"
   8476       "vaddw.u8 q12, q12, d4\n"
   8477       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8478       "vst1.32 {d4}, [%[out]:64]!\n"
   8479 
   8480       "bne 1b\n"
   8481 
   8482       "2:"
   8483 
   8484       // Load Aggregate Store - column major 5x2
   8485       "vmov.i8 d0, #0\n"
   8486       "vmov.i8 d1, #0\n"
   8487       "vmov.i8 d2, #0\n"
   8488       "vmov.i8 d3, #0\n"
   8489       "vmov.i8 d4, #0\n"
   8490       "vld1.32 {d0[0]}, [%[in]]!\n"
   8491       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8492       "vld1.32 {d1[0]}, [%[in]]!\n"
   8493       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8494       "pld [%[in]]\n"
   8495       "vtrn.16 d0, d2\n"
   8496       "vtrn.16 d1, d3\n"
   8497       "vtrn.8 d0, d1\n"
   8498       "vtrn.8 d2, d3\n"
   8499       "vaddw.u8 q8, q8, d0\n"
   8500       "vaddw.u8 q9, q9, d1\n"
   8501       "vaddw.u8 q10, q10, d2\n"
   8502       "vaddw.u8 q11, q11, d3\n"
   8503       "vaddw.u8 q12, q12, d4\n"
   8504       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8505       "vst1.32 {d4}, [%[out]:64]!\n"
   8506 
   8507       // Aggregator Reduction.
   8508       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8509       "vdup.32 q1, %[additive_sum_offset]\n"
   8510       "vpaddl.u16 q8, q8\n"
   8511       "vpaddl.u16 q9, q9\n"
   8512       "vpaddl.u16 q10, q10\n"
   8513       "vpaddl.u16 q11, q11\n"
   8514       "vpaddl.u16 q12, q12\n"
   8515       "vpadd.u32 d16, d16, d17\n"
   8516       "vpadd.u32 d18, d18, d19\n"
   8517       "vpadd.u32 d20, d20, d21\n"
   8518       "vpadd.u32 d22, d22, d23\n"
   8519       "vpadd.u32 d24, d24, d25\n"
   8520       "vpadd.u32 d16, d16, d18\n"
   8521       "vpadd.u32 d17, d20, d22\n"
   8522       "vpadd.u32 d18, d24, d24\n"
   8523       "vmul.i32 q8, q8, d0[0]\n"
   8524       "vmul.i32 q9, q9, d0[0]\n"
   8525       "vadd.i32 q8, q8, q1\n"
   8526       "vadd.i32 q9, q9, q1\n"
   8527       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8528       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8529         [out] "+r"(out), [in] "+r"(in)
   8530       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8531         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8532       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8533         "d22", "d23", "d24", "d25", "cc", "memory");
   8534 }
   8535 
   8536 template <>
   8537 inline void Stream<uint8_t, 5, 8, 3, ColumnMajorWithSum>::Pack(
   8538     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8539 #ifdef DEBUG
   8540 #ifdef DEBUG_METAGEMM_VERBOSE
   8541   std::cout
   8542       << __FILE__ << "(" << __LINE__
   8543       << ") ColumnMajorWithSum<uint8_t, 5, 8, 3, ColumnMajorWithSum>::Pack()"
   8544       << std::endl
   8545       << std::flush;
   8546 #endif
   8547 #endif
   8548   int params_count_copy = params.count;
   8549   int params_stride_copy = params.stride;
   8550   asm volatile(
   8551       "sub %[stride], %[stride], #4\n"
   8552       "vmov.i16 q8, #0\n"
   8553       "vmov.i16 q9, #0\n"
   8554       "vmov.i16 q10, #0\n"
   8555       "vmov.i16 q11, #0\n"
   8556       "vmov.i16 q12, #0\n"
   8557 
   8558       // Reduce count by leftovers.
   8559       "subs %[count], %[count], #3\n"
   8560       "beq 2f\n"
   8561 
   8562       "1:"
   8563       "subs %[count], %[count], #8\n"
   8564 
   8565       // Load Aggregate Store - column major 5x8
   8566       "vld1.32 {d0[0]}, [%[in]]!\n"
   8567       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8568       "vld1.32 {d1[0]}, [%[in]]!\n"
   8569       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8570       "vld1.32 {d2[0]}, [%[in]]!\n"
   8571       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8572       "vld1.32 {d3[0]}, [%[in]]!\n"
   8573       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8574       "vld1.32 {d0[1]}, [%[in]]!\n"
   8575       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8576       "vld1.32 {d1[1]}, [%[in]]!\n"
   8577       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8578       "vld1.32 {d2[1]}, [%[in]]!\n"
   8579       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8580       "vld1.32 {d3[1]}, [%[in]]!\n"
   8581       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8582       "pld [%[in]]\n"
   8583       "vtrn.16 d0, d2\n"
   8584       "vtrn.16 d1, d3\n"
   8585       "vtrn.8 d0, d1\n"
   8586       "vtrn.8 d2, d3\n"
   8587       "vaddw.u8 q8, q8, d0\n"
   8588       "vaddw.u8 q9, q9, d1\n"
   8589       "vaddw.u8 q10, q10, d2\n"
   8590       "vaddw.u8 q11, q11, d3\n"
   8591       "vaddw.u8 q12, q12, d4\n"
   8592       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8593       "vst1.32 {d4}, [%[out]:64]!\n"
   8594 
   8595       "bne 1b\n"
   8596 
   8597       "2:"
   8598 
   8599       // Load Aggregate Store - column major 5x3
   8600       "vmov.i8 d0, #0\n"
   8601       "vmov.i8 d1, #0\n"
   8602       "vmov.i8 d2, #0\n"
   8603       "vmov.i8 d3, #0\n"
   8604       "vmov.i8 d4, #0\n"
   8605       "vld1.32 {d0[0]}, [%[in]]!\n"
   8606       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8607       "vld1.32 {d1[0]}, [%[in]]!\n"
   8608       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8609       "vld1.32 {d2[0]}, [%[in]]!\n"
   8610       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8611       "pld [%[in]]\n"
   8612       "vtrn.16 d0, d2\n"
   8613       "vtrn.16 d1, d3\n"
   8614       "vtrn.8 d0, d1\n"
   8615       "vtrn.8 d2, d3\n"
   8616       "vaddw.u8 q8, q8, d0\n"
   8617       "vaddw.u8 q9, q9, d1\n"
   8618       "vaddw.u8 q10, q10, d2\n"
   8619       "vaddw.u8 q11, q11, d3\n"
   8620       "vaddw.u8 q12, q12, d4\n"
   8621       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8622       "vst1.32 {d4}, [%[out]:64]!\n"
   8623 
   8624       // Aggregator Reduction.
   8625       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8626       "vdup.32 q1, %[additive_sum_offset]\n"
   8627       "vpaddl.u16 q8, q8\n"
   8628       "vpaddl.u16 q9, q9\n"
   8629       "vpaddl.u16 q10, q10\n"
   8630       "vpaddl.u16 q11, q11\n"
   8631       "vpaddl.u16 q12, q12\n"
   8632       "vpadd.u32 d16, d16, d17\n"
   8633       "vpadd.u32 d18, d18, d19\n"
   8634       "vpadd.u32 d20, d20, d21\n"
   8635       "vpadd.u32 d22, d22, d23\n"
   8636       "vpadd.u32 d24, d24, d25\n"
   8637       "vpadd.u32 d16, d16, d18\n"
   8638       "vpadd.u32 d17, d20, d22\n"
   8639       "vpadd.u32 d18, d24, d24\n"
   8640       "vmul.i32 q8, q8, d0[0]\n"
   8641       "vmul.i32 q9, q9, d0[0]\n"
   8642       "vadd.i32 q8, q8, q1\n"
   8643       "vadd.i32 q9, q9, q1\n"
   8644       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8645       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8646         [out] "+r"(out), [in] "+r"(in)
   8647       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8648         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8649       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8650         "d22", "d23", "d24", "d25", "cc", "memory");
   8651 }
   8652 
   8653 template <>
   8654 inline void Stream<uint8_t, 5, 8, 4, ColumnMajorWithSum>::Pack(
   8655     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8656 #ifdef DEBUG
   8657 #ifdef DEBUG_METAGEMM_VERBOSE
   8658   std::cout
   8659       << __FILE__ << "(" << __LINE__
   8660       << ") ColumnMajorWithSum<uint8_t, 5, 8, 4, ColumnMajorWithSum>::Pack()"
   8661       << std::endl
   8662       << std::flush;
   8663 #endif
   8664 #endif
   8665   int params_count_copy = params.count;
   8666   int params_stride_copy = params.stride;
   8667   asm volatile(
   8668       "sub %[stride], %[stride], #4\n"
   8669       "vmov.i16 q8, #0\n"
   8670       "vmov.i16 q9, #0\n"
   8671       "vmov.i16 q10, #0\n"
   8672       "vmov.i16 q11, #0\n"
   8673       "vmov.i16 q12, #0\n"
   8674 
   8675       // Reduce count by leftovers.
   8676       "subs %[count], %[count], #4\n"
   8677       "beq 2f\n"
   8678 
   8679       "1:"
   8680       "subs %[count], %[count], #8\n"
   8681 
   8682       // Load Aggregate Store - column major 5x8
   8683       "vld1.32 {d0[0]}, [%[in]]!\n"
   8684       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8685       "vld1.32 {d1[0]}, [%[in]]!\n"
   8686       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8687       "vld1.32 {d2[0]}, [%[in]]!\n"
   8688       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8689       "vld1.32 {d3[0]}, [%[in]]!\n"
   8690       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8691       "vld1.32 {d0[1]}, [%[in]]!\n"
   8692       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8693       "vld1.32 {d1[1]}, [%[in]]!\n"
   8694       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8695       "vld1.32 {d2[1]}, [%[in]]!\n"
   8696       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8697       "vld1.32 {d3[1]}, [%[in]]!\n"
   8698       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8699       "pld [%[in]]\n"
   8700       "vtrn.16 d0, d2\n"
   8701       "vtrn.16 d1, d3\n"
   8702       "vtrn.8 d0, d1\n"
   8703       "vtrn.8 d2, d3\n"
   8704       "vaddw.u8 q8, q8, d0\n"
   8705       "vaddw.u8 q9, q9, d1\n"
   8706       "vaddw.u8 q10, q10, d2\n"
   8707       "vaddw.u8 q11, q11, d3\n"
   8708       "vaddw.u8 q12, q12, d4\n"
   8709       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8710       "vst1.32 {d4}, [%[out]:64]!\n"
   8711 
   8712       "bne 1b\n"
   8713 
   8714       "2:"
   8715 
   8716       // Load Aggregate Store - column major 5x4
   8717       "vmov.i8 d0, #0\n"
   8718       "vmov.i8 d1, #0\n"
   8719       "vmov.i8 d2, #0\n"
   8720       "vmov.i8 d3, #0\n"
   8721       "vmov.i8 d4, #0\n"
   8722       "vld1.32 {d0[0]}, [%[in]]!\n"
   8723       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8724       "vld1.32 {d1[0]}, [%[in]]!\n"
   8725       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8726       "vld1.32 {d2[0]}, [%[in]]!\n"
   8727       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8728       "vld1.32 {d3[0]}, [%[in]]!\n"
   8729       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8730       "pld [%[in]]\n"
   8731       "vtrn.16 d0, d2\n"
   8732       "vtrn.16 d1, d3\n"
   8733       "vtrn.8 d0, d1\n"
   8734       "vtrn.8 d2, d3\n"
   8735       "vaddw.u8 q8, q8, d0\n"
   8736       "vaddw.u8 q9, q9, d1\n"
   8737       "vaddw.u8 q10, q10, d2\n"
   8738       "vaddw.u8 q11, q11, d3\n"
   8739       "vaddw.u8 q12, q12, d4\n"
   8740       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8741       "vst1.32 {d4}, [%[out]:64]!\n"
   8742 
   8743       // Aggregator Reduction.
   8744       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8745       "vdup.32 q1, %[additive_sum_offset]\n"
   8746       "vpaddl.u16 q8, q8\n"
   8747       "vpaddl.u16 q9, q9\n"
   8748       "vpaddl.u16 q10, q10\n"
   8749       "vpaddl.u16 q11, q11\n"
   8750       "vpaddl.u16 q12, q12\n"
   8751       "vpadd.u32 d16, d16, d17\n"
   8752       "vpadd.u32 d18, d18, d19\n"
   8753       "vpadd.u32 d20, d20, d21\n"
   8754       "vpadd.u32 d22, d22, d23\n"
   8755       "vpadd.u32 d24, d24, d25\n"
   8756       "vpadd.u32 d16, d16, d18\n"
   8757       "vpadd.u32 d17, d20, d22\n"
   8758       "vpadd.u32 d18, d24, d24\n"
   8759       "vmul.i32 q8, q8, d0[0]\n"
   8760       "vmul.i32 q9, q9, d0[0]\n"
   8761       "vadd.i32 q8, q8, q1\n"
   8762       "vadd.i32 q9, q9, q1\n"
   8763       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8764       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8765         [out] "+r"(out), [in] "+r"(in)
   8766       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8767         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8768       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8769         "d22", "d23", "d24", "d25", "cc", "memory");
   8770 }
   8771 
   8772 template <>
   8773 inline void Stream<uint8_t, 5, 8, 5, ColumnMajorWithSum>::Pack(
   8774     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8775 #ifdef DEBUG
   8776 #ifdef DEBUG_METAGEMM_VERBOSE
   8777   std::cout
   8778       << __FILE__ << "(" << __LINE__
   8779       << ") ColumnMajorWithSum<uint8_t, 5, 8, 5, ColumnMajorWithSum>::Pack()"
   8780       << std::endl
   8781       << std::flush;
   8782 #endif
   8783 #endif
   8784   int params_count_copy = params.count;
   8785   int params_stride_copy = params.stride;
   8786   asm volatile(
   8787       "sub %[stride], %[stride], #4\n"
   8788       "vmov.i16 q8, #0\n"
   8789       "vmov.i16 q9, #0\n"
   8790       "vmov.i16 q10, #0\n"
   8791       "vmov.i16 q11, #0\n"
   8792       "vmov.i16 q12, #0\n"
   8793 
   8794       // Reduce count by leftovers.
   8795       "subs %[count], %[count], #5\n"
   8796       "beq 2f\n"
   8797 
   8798       "1:"
   8799       "subs %[count], %[count], #8\n"
   8800 
   8801       // Load Aggregate Store - column major 5x8
   8802       "vld1.32 {d0[0]}, [%[in]]!\n"
   8803       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8804       "vld1.32 {d1[0]}, [%[in]]!\n"
   8805       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8806       "vld1.32 {d2[0]}, [%[in]]!\n"
   8807       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8808       "vld1.32 {d3[0]}, [%[in]]!\n"
   8809       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8810       "vld1.32 {d0[1]}, [%[in]]!\n"
   8811       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8812       "vld1.32 {d1[1]}, [%[in]]!\n"
   8813       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8814       "vld1.32 {d2[1]}, [%[in]]!\n"
   8815       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8816       "vld1.32 {d3[1]}, [%[in]]!\n"
   8817       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8818       "pld [%[in]]\n"
   8819       "vtrn.16 d0, d2\n"
   8820       "vtrn.16 d1, d3\n"
   8821       "vtrn.8 d0, d1\n"
   8822       "vtrn.8 d2, d3\n"
   8823       "vaddw.u8 q8, q8, d0\n"
   8824       "vaddw.u8 q9, q9, d1\n"
   8825       "vaddw.u8 q10, q10, d2\n"
   8826       "vaddw.u8 q11, q11, d3\n"
   8827       "vaddw.u8 q12, q12, d4\n"
   8828       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8829       "vst1.32 {d4}, [%[out]:64]!\n"
   8830 
   8831       "bne 1b\n"
   8832 
   8833       "2:"
   8834 
   8835       // Load Aggregate Store - column major 5x5
   8836       "vmov.i8 d0, #0\n"
   8837       "vmov.i8 d1, #0\n"
   8838       "vmov.i8 d2, #0\n"
   8839       "vmov.i8 d3, #0\n"
   8840       "vmov.i8 d4, #0\n"
   8841       "vld1.32 {d0[0]}, [%[in]]!\n"
   8842       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8843       "vld1.32 {d1[0]}, [%[in]]!\n"
   8844       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8845       "vld1.32 {d2[0]}, [%[in]]!\n"
   8846       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8847       "vld1.32 {d3[0]}, [%[in]]!\n"
   8848       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8849       "vld1.32 {d0[1]}, [%[in]]!\n"
   8850       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8851       "pld [%[in]]\n"
   8852       "vtrn.16 d0, d2\n"
   8853       "vtrn.16 d1, d3\n"
   8854       "vtrn.8 d0, d1\n"
   8855       "vtrn.8 d2, d3\n"
   8856       "vaddw.u8 q8, q8, d0\n"
   8857       "vaddw.u8 q9, q9, d1\n"
   8858       "vaddw.u8 q10, q10, d2\n"
   8859       "vaddw.u8 q11, q11, d3\n"
   8860       "vaddw.u8 q12, q12, d4\n"
   8861       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8862       "vst1.32 {d4}, [%[out]:64]!\n"
   8863 
   8864       // Aggregator Reduction.
   8865       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8866       "vdup.32 q1, %[additive_sum_offset]\n"
   8867       "vpaddl.u16 q8, q8\n"
   8868       "vpaddl.u16 q9, q9\n"
   8869       "vpaddl.u16 q10, q10\n"
   8870       "vpaddl.u16 q11, q11\n"
   8871       "vpaddl.u16 q12, q12\n"
   8872       "vpadd.u32 d16, d16, d17\n"
   8873       "vpadd.u32 d18, d18, d19\n"
   8874       "vpadd.u32 d20, d20, d21\n"
   8875       "vpadd.u32 d22, d22, d23\n"
   8876       "vpadd.u32 d24, d24, d25\n"
   8877       "vpadd.u32 d16, d16, d18\n"
   8878       "vpadd.u32 d17, d20, d22\n"
   8879       "vpadd.u32 d18, d24, d24\n"
   8880       "vmul.i32 q8, q8, d0[0]\n"
   8881       "vmul.i32 q9, q9, d0[0]\n"
   8882       "vadd.i32 q8, q8, q1\n"
   8883       "vadd.i32 q9, q9, q1\n"
   8884       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   8885       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   8886         [out] "+r"(out), [in] "+r"(in)
   8887       : [additive_sum_offset] "r"(params.additive_sum_offset),
   8888         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   8889       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   8890         "d22", "d23", "d24", "d25", "cc", "memory");
   8891 }
   8892 
   8893 template <>
   8894 inline void Stream<uint8_t, 5, 8, 6, ColumnMajorWithSum>::Pack(
   8895     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   8896 #ifdef DEBUG
   8897 #ifdef DEBUG_METAGEMM_VERBOSE
   8898   std::cout
   8899       << __FILE__ << "(" << __LINE__
   8900       << ") ColumnMajorWithSum<uint8_t, 5, 8, 6, ColumnMajorWithSum>::Pack()"
   8901       << std::endl
   8902       << std::flush;
   8903 #endif
   8904 #endif
   8905   int params_count_copy = params.count;
   8906   int params_stride_copy = params.stride;
   8907   asm volatile(
   8908       "sub %[stride], %[stride], #4\n"
   8909       "vmov.i16 q8, #0\n"
   8910       "vmov.i16 q9, #0\n"
   8911       "vmov.i16 q10, #0\n"
   8912       "vmov.i16 q11, #0\n"
   8913       "vmov.i16 q12, #0\n"
   8914 
   8915       // Reduce count by leftovers.
   8916       "subs %[count], %[count], #6\n"
   8917       "beq 2f\n"
   8918 
   8919       "1:"
   8920       "subs %[count], %[count], #8\n"
   8921 
   8922       // Load Aggregate Store - column major 5x8
   8923       "vld1.32 {d0[0]}, [%[in]]!\n"
   8924       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8925       "vld1.32 {d1[0]}, [%[in]]!\n"
   8926       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8927       "vld1.32 {d2[0]}, [%[in]]!\n"
   8928       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8929       "vld1.32 {d3[0]}, [%[in]]!\n"
   8930       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8931       "vld1.32 {d0[1]}, [%[in]]!\n"
   8932       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8933       "vld1.32 {d1[1]}, [%[in]]!\n"
   8934       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8935       "vld1.32 {d2[1]}, [%[in]]!\n"
   8936       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   8937       "vld1.32 {d3[1]}, [%[in]]!\n"
   8938       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   8939       "pld [%[in]]\n"
   8940       "vtrn.16 d0, d2\n"
   8941       "vtrn.16 d1, d3\n"
   8942       "vtrn.8 d0, d1\n"
   8943       "vtrn.8 d2, d3\n"
   8944       "vaddw.u8 q8, q8, d0\n"
   8945       "vaddw.u8 q9, q9, d1\n"
   8946       "vaddw.u8 q10, q10, d2\n"
   8947       "vaddw.u8 q11, q11, d3\n"
   8948       "vaddw.u8 q12, q12, d4\n"
   8949       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8950       "vst1.32 {d4}, [%[out]:64]!\n"
   8951 
   8952       "bne 1b\n"
   8953 
   8954       "2:"
   8955 
   8956       // Load Aggregate Store - column major 5x6
   8957       "vmov.i8 d0, #0\n"
   8958       "vmov.i8 d1, #0\n"
   8959       "vmov.i8 d2, #0\n"
   8960       "vmov.i8 d3, #0\n"
   8961       "vmov.i8 d4, #0\n"
   8962       "vld1.32 {d0[0]}, [%[in]]!\n"
   8963       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   8964       "vld1.32 {d1[0]}, [%[in]]!\n"
   8965       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   8966       "vld1.32 {d2[0]}, [%[in]]!\n"
   8967       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   8968       "vld1.32 {d3[0]}, [%[in]]!\n"
   8969       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   8970       "vld1.32 {d0[1]}, [%[in]]!\n"
   8971       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   8972       "vld1.32 {d1[1]}, [%[in]]!\n"
   8973       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   8974       "pld [%[in]]\n"
   8975       "vtrn.16 d0, d2\n"
   8976       "vtrn.16 d1, d3\n"
   8977       "vtrn.8 d0, d1\n"
   8978       "vtrn.8 d2, d3\n"
   8979       "vaddw.u8 q8, q8, d0\n"
   8980       "vaddw.u8 q9, q9, d1\n"
   8981       "vaddw.u8 q10, q10, d2\n"
   8982       "vaddw.u8 q11, q11, d3\n"
   8983       "vaddw.u8 q12, q12, d4\n"
   8984       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   8985       "vst1.32 {d4}, [%[out]:64]!\n"
   8986 
   8987       // Aggregator Reduction.
   8988       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   8989       "vdup.32 q1, %[additive_sum_offset]\n"
   8990       "vpaddl.u16 q8, q8\n"
   8991       "vpaddl.u16 q9, q9\n"
   8992       "vpaddl.u16 q10, q10\n"
   8993       "vpaddl.u16 q11, q11\n"
   8994       "vpaddl.u16 q12, q12\n"
   8995       "vpadd.u32 d16, d16, d17\n"
   8996       "vpadd.u32 d18, d18, d19\n"
   8997       "vpadd.u32 d20, d20, d21\n"
   8998       "vpadd.u32 d22, d22, d23\n"
   8999       "vpadd.u32 d24, d24, d25\n"
   9000       "vpadd.u32 d16, d16, d18\n"
   9001       "vpadd.u32 d17, d20, d22\n"
   9002       "vpadd.u32 d18, d24, d24\n"
   9003       "vmul.i32 q8, q8, d0[0]\n"
   9004       "vmul.i32 q9, q9, d0[0]\n"
   9005       "vadd.i32 q8, q8, q1\n"
   9006       "vadd.i32 q9, q9, q1\n"
   9007       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   9008       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9009         [out] "+r"(out), [in] "+r"(in)
   9010       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9011         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9012       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   9013         "d22", "d23", "d24", "d25", "cc", "memory");
   9014 }
   9015 
   9016 template <>
   9017 inline void Stream<uint8_t, 5, 8, 7, ColumnMajorWithSum>::Pack(
   9018     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9019 #ifdef DEBUG
   9020 #ifdef DEBUG_METAGEMM_VERBOSE
   9021   std::cout
   9022       << __FILE__ << "(" << __LINE__
   9023       << ") ColumnMajorWithSum<uint8_t, 5, 8, 7, ColumnMajorWithSum>::Pack()"
   9024       << std::endl
   9025       << std::flush;
   9026 #endif
   9027 #endif
   9028   int params_count_copy = params.count;
   9029   int params_stride_copy = params.stride;
   9030   asm volatile(
   9031       "sub %[stride], %[stride], #4\n"
   9032       "vmov.i16 q8, #0\n"
   9033       "vmov.i16 q9, #0\n"
   9034       "vmov.i16 q10, #0\n"
   9035       "vmov.i16 q11, #0\n"
   9036       "vmov.i16 q12, #0\n"
   9037 
   9038       // Reduce count by leftovers.
   9039       "subs %[count], %[count], #7\n"
   9040       "beq 2f\n"
   9041 
   9042       "1:"
   9043       "subs %[count], %[count], #8\n"
   9044 
   9045       // Load Aggregate Store - column major 5x8
   9046       "vld1.32 {d0[0]}, [%[in]]!\n"
   9047       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   9048       "vld1.32 {d1[0]}, [%[in]]!\n"
   9049       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   9050       "vld1.32 {d2[0]}, [%[in]]!\n"
   9051       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   9052       "vld1.32 {d3[0]}, [%[in]]!\n"
   9053       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   9054       "vld1.32 {d0[1]}, [%[in]]!\n"
   9055       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   9056       "vld1.32 {d1[1]}, [%[in]]!\n"
   9057       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   9058       "vld1.32 {d2[1]}, [%[in]]!\n"
   9059       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   9060       "vld1.32 {d3[1]}, [%[in]]!\n"
   9061       "vld1.8 {d4[7]}, [%[in]], %[stride]\n"
   9062       "pld [%[in]]\n"
   9063       "vtrn.16 d0, d2\n"
   9064       "vtrn.16 d1, d3\n"
   9065       "vtrn.8 d0, d1\n"
   9066       "vtrn.8 d2, d3\n"
   9067       "vaddw.u8 q8, q8, d0\n"
   9068       "vaddw.u8 q9, q9, d1\n"
   9069       "vaddw.u8 q10, q10, d2\n"
   9070       "vaddw.u8 q11, q11, d3\n"
   9071       "vaddw.u8 q12, q12, d4\n"
   9072       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   9073       "vst1.32 {d4}, [%[out]:64]!\n"
   9074 
   9075       "bne 1b\n"
   9076 
   9077       "2:"
   9078 
   9079       // Load Aggregate Store - column major 5x7
   9080       "vmov.i8 d0, #0\n"
   9081       "vmov.i8 d1, #0\n"
   9082       "vmov.i8 d2, #0\n"
   9083       "vmov.i8 d3, #0\n"
   9084       "vmov.i8 d4, #0\n"
   9085       "vld1.32 {d0[0]}, [%[in]]!\n"
   9086       "vld1.8 {d4[0]}, [%[in]], %[stride]\n"
   9087       "vld1.32 {d1[0]}, [%[in]]!\n"
   9088       "vld1.8 {d4[1]}, [%[in]], %[stride]\n"
   9089       "vld1.32 {d2[0]}, [%[in]]!\n"
   9090       "vld1.8 {d4[2]}, [%[in]], %[stride]\n"
   9091       "vld1.32 {d3[0]}, [%[in]]!\n"
   9092       "vld1.8 {d4[3]}, [%[in]], %[stride]\n"
   9093       "vld1.32 {d0[1]}, [%[in]]!\n"
   9094       "vld1.8 {d4[4]}, [%[in]], %[stride]\n"
   9095       "vld1.32 {d1[1]}, [%[in]]!\n"
   9096       "vld1.8 {d4[5]}, [%[in]], %[stride]\n"
   9097       "vld1.32 {d2[1]}, [%[in]]!\n"
   9098       "vld1.8 {d4[6]}, [%[in]], %[stride]\n"
   9099       "pld [%[in]]\n"
   9100       "vtrn.16 d0, d2\n"
   9101       "vtrn.16 d1, d3\n"
   9102       "vtrn.8 d0, d1\n"
   9103       "vtrn.8 d2, d3\n"
   9104       "vaddw.u8 q8, q8, d0\n"
   9105       "vaddw.u8 q9, q9, d1\n"
   9106       "vaddw.u8 q10, q10, d2\n"
   9107       "vaddw.u8 q11, q11, d3\n"
   9108       "vaddw.u8 q12, q12, d4\n"
   9109       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   9110       "vst1.32 {d4}, [%[out]:64]!\n"
   9111 
   9112       // Aggregator Reduction.
   9113       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9114       "vdup.32 q1, %[additive_sum_offset]\n"
   9115       "vpaddl.u16 q8, q8\n"
   9116       "vpaddl.u16 q9, q9\n"
   9117       "vpaddl.u16 q10, q10\n"
   9118       "vpaddl.u16 q11, q11\n"
   9119       "vpaddl.u16 q12, q12\n"
   9120       "vpadd.u32 d16, d16, d17\n"
   9121       "vpadd.u32 d18, d18, d19\n"
   9122       "vpadd.u32 d20, d20, d21\n"
   9123       "vpadd.u32 d22, d22, d23\n"
   9124       "vpadd.u32 d24, d24, d25\n"
   9125       "vpadd.u32 d16, d16, d18\n"
   9126       "vpadd.u32 d17, d20, d22\n"
   9127       "vpadd.u32 d18, d24, d24\n"
   9128       "vmul.i32 q8, q8, d0[0]\n"
   9129       "vmul.i32 q9, q9, d0[0]\n"
   9130       "vadd.i32 q8, q8, q1\n"
   9131       "vadd.i32 q9, q9, q1\n"
   9132       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   9133       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9134         [out] "+r"(out), [in] "+r"(in)
   9135       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9136         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9137       : "d0", "d1", "d2", "d3", "d4", "d16", "d17", "d18", "d19", "d20", "d21",
   9138         "d22", "d23", "d24", "d25", "cc", "memory");
   9139 }
   9140 
   9141 template <>
   9142 inline void Stream<uint8_t, 6, 8, 0, ColumnMajorWithSum>::Pack(
   9143     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9144 #ifdef DEBUG
   9145 #ifdef DEBUG_METAGEMM_VERBOSE
   9146   std::cout
   9147       << __FILE__ << "(" << __LINE__
   9148       << ") ColumnMajorWithSum<uint8_t, 6, 8, 0, ColumnMajorWithSum>::Pack()"
   9149       << std::endl
   9150       << std::flush;
   9151 #endif
   9152 #endif
   9153   int params_count_copy = params.count;
   9154   int params_stride_copy = params.stride;
   9155   asm volatile(
   9156       "sub %[stride], %[stride], #4\n"
   9157       "vmov.i16 q8, #0\n"
   9158       "vmov.i16 q9, #0\n"
   9159       "vmov.i16 q10, #0\n"
   9160       "vmov.i16 q11, #0\n"
   9161       "vmov.i16 q12, #0\n"
   9162       "vmov.i16 q13, #0\n"
   9163 
   9164       "1:"
   9165       "subs %[count], %[count], #8\n"
   9166 
   9167       // Load Aggregate Store - column major 6x8
   9168       "vld1.32 {d0[0]}, [%[in]]!\n"
   9169       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9170       "vld1.32 {d1[0]}, [%[in]]!\n"
   9171       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9172       "vld1.32 {d2[0]}, [%[in]]!\n"
   9173       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9174       "vld1.32 {d3[0]}, [%[in]]!\n"
   9175       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9176       "vld1.32 {d0[1]}, [%[in]]!\n"
   9177       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9178       "vld1.32 {d1[1]}, [%[in]]!\n"
   9179       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9180       "vld1.32 {d2[1]}, [%[in]]!\n"
   9181       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9182       "vld1.32 {d3[1]}, [%[in]]!\n"
   9183       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9184       "pld [%[in]]\n"
   9185       "vtrn.16 d0, d2\n"
   9186       "vtrn.16 d1, d3\n"
   9187       "vuzp.8 d4, d5\n"
   9188       "vtrn.8 d0, d1\n"
   9189       "vtrn.8 d2, d3\n"
   9190       "vaddw.u8 q8, q8, d0\n"
   9191       "vaddw.u8 q9, q9, d1\n"
   9192       "vaddw.u8 q10, q10, d2\n"
   9193       "vaddw.u8 q11, q11, d3\n"
   9194       "vaddw.u8 q12, q12, d4\n"
   9195       "vaddw.u8 q13, q13, d5\n"
   9196       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9197       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9198 
   9199       "bne 1b\n"
   9200 
   9201       // Aggregator Reduction.
   9202       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9203       "vdup.32 q1, %[additive_sum_offset]\n"
   9204       "vpaddl.u16 q8, q8\n"
   9205       "vpaddl.u16 q9, q9\n"
   9206       "vpaddl.u16 q10, q10\n"
   9207       "vpaddl.u16 q11, q11\n"
   9208       "vpaddl.u16 q12, q12\n"
   9209       "vpaddl.u16 q13, q13\n"
   9210       "vpadd.u32 d16, d16, d17\n"
   9211       "vpadd.u32 d18, d18, d19\n"
   9212       "vpadd.u32 d20, d20, d21\n"
   9213       "vpadd.u32 d22, d22, d23\n"
   9214       "vpadd.u32 d24, d24, d25\n"
   9215       "vpadd.u32 d26, d26, d27\n"
   9216       "vpadd.u32 d16, d16, d18\n"
   9217       "vpadd.u32 d17, d20, d22\n"
   9218       "vpadd.u32 d18, d24, d26\n"
   9219       "vmul.i32 q8, q8, d0[0]\n"
   9220       "vmul.i32 q9, q9, d0[0]\n"
   9221       "vadd.i32 q8, q8, q1\n"
   9222       "vadd.i32 q9, q9, q1\n"
   9223       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9224       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9225         [out] "+r"(out), [in] "+r"(in)
   9226       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9227         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9228       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9229         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9230 }
   9231 
   9232 template <>
   9233 inline void Stream<uint8_t, 6, 8, 1, ColumnMajorWithSum>::Pack(
   9234     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9235 #ifdef DEBUG
   9236 #ifdef DEBUG_METAGEMM_VERBOSE
   9237   std::cout
   9238       << __FILE__ << "(" << __LINE__
   9239       << ") ColumnMajorWithSum<uint8_t, 6, 8, 1, ColumnMajorWithSum>::Pack()"
   9240       << std::endl
   9241       << std::flush;
   9242 #endif
   9243 #endif
   9244   int params_count_copy = params.count;
   9245   int params_stride_copy = params.stride;
   9246   asm volatile(
   9247       "sub %[stride], %[stride], #4\n"
   9248       "vmov.i16 q8, #0\n"
   9249       "vmov.i16 q9, #0\n"
   9250       "vmov.i16 q10, #0\n"
   9251       "vmov.i16 q11, #0\n"
   9252       "vmov.i16 q12, #0\n"
   9253       "vmov.i16 q13, #0\n"
   9254 
   9255       // Reduce count by leftovers.
   9256       "subs %[count], %[count], #1\n"
   9257       "beq 2f\n"
   9258 
   9259       "1:"
   9260       "subs %[count], %[count], #8\n"
   9261 
   9262       // Load Aggregate Store - column major 6x8
   9263       "vld1.32 {d0[0]}, [%[in]]!\n"
   9264       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9265       "vld1.32 {d1[0]}, [%[in]]!\n"
   9266       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9267       "vld1.32 {d2[0]}, [%[in]]!\n"
   9268       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9269       "vld1.32 {d3[0]}, [%[in]]!\n"
   9270       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9271       "vld1.32 {d0[1]}, [%[in]]!\n"
   9272       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9273       "vld1.32 {d1[1]}, [%[in]]!\n"
   9274       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9275       "vld1.32 {d2[1]}, [%[in]]!\n"
   9276       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9277       "vld1.32 {d3[1]}, [%[in]]!\n"
   9278       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9279       "pld [%[in]]\n"
   9280       "vtrn.16 d0, d2\n"
   9281       "vtrn.16 d1, d3\n"
   9282       "vuzp.8 d4, d5\n"
   9283       "vtrn.8 d0, d1\n"
   9284       "vtrn.8 d2, d3\n"
   9285       "vaddw.u8 q8, q8, d0\n"
   9286       "vaddw.u8 q9, q9, d1\n"
   9287       "vaddw.u8 q10, q10, d2\n"
   9288       "vaddw.u8 q11, q11, d3\n"
   9289       "vaddw.u8 q12, q12, d4\n"
   9290       "vaddw.u8 q13, q13, d5\n"
   9291       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9292       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9293 
   9294       "bne 1b\n"
   9295 
   9296       "2:"
   9297 
   9298       // Load Aggregate Store - column major 6x1
   9299       "vmov.i8 d0, #0\n"
   9300       "vmov.i8 d1, #0\n"
   9301       "vmov.i8 d2, #0\n"
   9302       "vmov.i8 d3, #0\n"
   9303       "vmov.i8 d4, #0\n"
   9304       "vmov.i8 d5, #0\n"
   9305       "vld1.32 {d0[0]}, [%[in]]!\n"
   9306       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9307       "pld [%[in]]\n"
   9308       "vtrn.16 d0, d2\n"
   9309       "vtrn.16 d1, d3\n"
   9310       "vuzp.8 d4, d5\n"
   9311       "vtrn.8 d0, d1\n"
   9312       "vtrn.8 d2, d3\n"
   9313       "vaddw.u8 q8, q8, d0\n"
   9314       "vaddw.u8 q9, q9, d1\n"
   9315       "vaddw.u8 q10, q10, d2\n"
   9316       "vaddw.u8 q11, q11, d3\n"
   9317       "vaddw.u8 q12, q12, d4\n"
   9318       "vaddw.u8 q13, q13, d5\n"
   9319       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9320       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9321 
   9322       // Aggregator Reduction.
   9323       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9324       "vdup.32 q1, %[additive_sum_offset]\n"
   9325       "vpaddl.u16 q8, q8\n"
   9326       "vpaddl.u16 q9, q9\n"
   9327       "vpaddl.u16 q10, q10\n"
   9328       "vpaddl.u16 q11, q11\n"
   9329       "vpaddl.u16 q12, q12\n"
   9330       "vpaddl.u16 q13, q13\n"
   9331       "vpadd.u32 d16, d16, d17\n"
   9332       "vpadd.u32 d18, d18, d19\n"
   9333       "vpadd.u32 d20, d20, d21\n"
   9334       "vpadd.u32 d22, d22, d23\n"
   9335       "vpadd.u32 d24, d24, d25\n"
   9336       "vpadd.u32 d26, d26, d27\n"
   9337       "vpadd.u32 d16, d16, d18\n"
   9338       "vpadd.u32 d17, d20, d22\n"
   9339       "vpadd.u32 d18, d24, d26\n"
   9340       "vmul.i32 q8, q8, d0[0]\n"
   9341       "vmul.i32 q9, q9, d0[0]\n"
   9342       "vadd.i32 q8, q8, q1\n"
   9343       "vadd.i32 q9, q9, q1\n"
   9344       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9345       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9346         [out] "+r"(out), [in] "+r"(in)
   9347       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9348         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9349       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9350         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9351 }
   9352 
   9353 template <>
   9354 inline void Stream<uint8_t, 6, 8, 2, ColumnMajorWithSum>::Pack(
   9355     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9356 #ifdef DEBUG
   9357 #ifdef DEBUG_METAGEMM_VERBOSE
   9358   std::cout
   9359       << __FILE__ << "(" << __LINE__
   9360       << ") ColumnMajorWithSum<uint8_t, 6, 8, 2, ColumnMajorWithSum>::Pack()"
   9361       << std::endl
   9362       << std::flush;
   9363 #endif
   9364 #endif
   9365   int params_count_copy = params.count;
   9366   int params_stride_copy = params.stride;
   9367   asm volatile(
   9368       "sub %[stride], %[stride], #4\n"
   9369       "vmov.i16 q8, #0\n"
   9370       "vmov.i16 q9, #0\n"
   9371       "vmov.i16 q10, #0\n"
   9372       "vmov.i16 q11, #0\n"
   9373       "vmov.i16 q12, #0\n"
   9374       "vmov.i16 q13, #0\n"
   9375 
   9376       // Reduce count by leftovers.
   9377       "subs %[count], %[count], #2\n"
   9378       "beq 2f\n"
   9379 
   9380       "1:"
   9381       "subs %[count], %[count], #8\n"
   9382 
   9383       // Load Aggregate Store - column major 6x8
   9384       "vld1.32 {d0[0]}, [%[in]]!\n"
   9385       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9386       "vld1.32 {d1[0]}, [%[in]]!\n"
   9387       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9388       "vld1.32 {d2[0]}, [%[in]]!\n"
   9389       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9390       "vld1.32 {d3[0]}, [%[in]]!\n"
   9391       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9392       "vld1.32 {d0[1]}, [%[in]]!\n"
   9393       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9394       "vld1.32 {d1[1]}, [%[in]]!\n"
   9395       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9396       "vld1.32 {d2[1]}, [%[in]]!\n"
   9397       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9398       "vld1.32 {d3[1]}, [%[in]]!\n"
   9399       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9400       "pld [%[in]]\n"
   9401       "vtrn.16 d0, d2\n"
   9402       "vtrn.16 d1, d3\n"
   9403       "vuzp.8 d4, d5\n"
   9404       "vtrn.8 d0, d1\n"
   9405       "vtrn.8 d2, d3\n"
   9406       "vaddw.u8 q8, q8, d0\n"
   9407       "vaddw.u8 q9, q9, d1\n"
   9408       "vaddw.u8 q10, q10, d2\n"
   9409       "vaddw.u8 q11, q11, d3\n"
   9410       "vaddw.u8 q12, q12, d4\n"
   9411       "vaddw.u8 q13, q13, d5\n"
   9412       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9413       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9414 
   9415       "bne 1b\n"
   9416 
   9417       "2:"
   9418 
   9419       // Load Aggregate Store - column major 6x2
   9420       "vmov.i8 d0, #0\n"
   9421       "vmov.i8 d1, #0\n"
   9422       "vmov.i8 d2, #0\n"
   9423       "vmov.i8 d3, #0\n"
   9424       "vmov.i8 d4, #0\n"
   9425       "vmov.i8 d5, #0\n"
   9426       "vld1.32 {d0[0]}, [%[in]]!\n"
   9427       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9428       "vld1.32 {d1[0]}, [%[in]]!\n"
   9429       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9430       "pld [%[in]]\n"
   9431       "vtrn.16 d0, d2\n"
   9432       "vtrn.16 d1, d3\n"
   9433       "vuzp.8 d4, d5\n"
   9434       "vtrn.8 d0, d1\n"
   9435       "vtrn.8 d2, d3\n"
   9436       "vaddw.u8 q8, q8, d0\n"
   9437       "vaddw.u8 q9, q9, d1\n"
   9438       "vaddw.u8 q10, q10, d2\n"
   9439       "vaddw.u8 q11, q11, d3\n"
   9440       "vaddw.u8 q12, q12, d4\n"
   9441       "vaddw.u8 q13, q13, d5\n"
   9442       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9443       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9444 
   9445       // Aggregator Reduction.
   9446       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9447       "vdup.32 q1, %[additive_sum_offset]\n"
   9448       "vpaddl.u16 q8, q8\n"
   9449       "vpaddl.u16 q9, q9\n"
   9450       "vpaddl.u16 q10, q10\n"
   9451       "vpaddl.u16 q11, q11\n"
   9452       "vpaddl.u16 q12, q12\n"
   9453       "vpaddl.u16 q13, q13\n"
   9454       "vpadd.u32 d16, d16, d17\n"
   9455       "vpadd.u32 d18, d18, d19\n"
   9456       "vpadd.u32 d20, d20, d21\n"
   9457       "vpadd.u32 d22, d22, d23\n"
   9458       "vpadd.u32 d24, d24, d25\n"
   9459       "vpadd.u32 d26, d26, d27\n"
   9460       "vpadd.u32 d16, d16, d18\n"
   9461       "vpadd.u32 d17, d20, d22\n"
   9462       "vpadd.u32 d18, d24, d26\n"
   9463       "vmul.i32 q8, q8, d0[0]\n"
   9464       "vmul.i32 q9, q9, d0[0]\n"
   9465       "vadd.i32 q8, q8, q1\n"
   9466       "vadd.i32 q9, q9, q1\n"
   9467       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9468       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9469         [out] "+r"(out), [in] "+r"(in)
   9470       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9471         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9472       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9473         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9474 }
   9475 
   9476 template <>
   9477 inline void Stream<uint8_t, 6, 8, 3, ColumnMajorWithSum>::Pack(
   9478     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9479 #ifdef DEBUG
   9480 #ifdef DEBUG_METAGEMM_VERBOSE
   9481   std::cout
   9482       << __FILE__ << "(" << __LINE__
   9483       << ") ColumnMajorWithSum<uint8_t, 6, 8, 3, ColumnMajorWithSum>::Pack()"
   9484       << std::endl
   9485       << std::flush;
   9486 #endif
   9487 #endif
   9488   int params_count_copy = params.count;
   9489   int params_stride_copy = params.stride;
   9490   asm volatile(
   9491       "sub %[stride], %[stride], #4\n"
   9492       "vmov.i16 q8, #0\n"
   9493       "vmov.i16 q9, #0\n"
   9494       "vmov.i16 q10, #0\n"
   9495       "vmov.i16 q11, #0\n"
   9496       "vmov.i16 q12, #0\n"
   9497       "vmov.i16 q13, #0\n"
   9498 
   9499       // Reduce count by leftovers.
   9500       "subs %[count], %[count], #3\n"
   9501       "beq 2f\n"
   9502 
   9503       "1:"
   9504       "subs %[count], %[count], #8\n"
   9505 
   9506       // Load Aggregate Store - column major 6x8
   9507       "vld1.32 {d0[0]}, [%[in]]!\n"
   9508       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9509       "vld1.32 {d1[0]}, [%[in]]!\n"
   9510       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9511       "vld1.32 {d2[0]}, [%[in]]!\n"
   9512       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9513       "vld1.32 {d3[0]}, [%[in]]!\n"
   9514       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9515       "vld1.32 {d0[1]}, [%[in]]!\n"
   9516       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9517       "vld1.32 {d1[1]}, [%[in]]!\n"
   9518       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9519       "vld1.32 {d2[1]}, [%[in]]!\n"
   9520       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9521       "vld1.32 {d3[1]}, [%[in]]!\n"
   9522       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9523       "pld [%[in]]\n"
   9524       "vtrn.16 d0, d2\n"
   9525       "vtrn.16 d1, d3\n"
   9526       "vuzp.8 d4, d5\n"
   9527       "vtrn.8 d0, d1\n"
   9528       "vtrn.8 d2, d3\n"
   9529       "vaddw.u8 q8, q8, d0\n"
   9530       "vaddw.u8 q9, q9, d1\n"
   9531       "vaddw.u8 q10, q10, d2\n"
   9532       "vaddw.u8 q11, q11, d3\n"
   9533       "vaddw.u8 q12, q12, d4\n"
   9534       "vaddw.u8 q13, q13, d5\n"
   9535       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9536       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9537 
   9538       "bne 1b\n"
   9539 
   9540       "2:"
   9541 
   9542       // Load Aggregate Store - column major 6x3
   9543       "vmov.i8 d0, #0\n"
   9544       "vmov.i8 d1, #0\n"
   9545       "vmov.i8 d2, #0\n"
   9546       "vmov.i8 d3, #0\n"
   9547       "vmov.i8 d4, #0\n"
   9548       "vmov.i8 d5, #0\n"
   9549       "vld1.32 {d0[0]}, [%[in]]!\n"
   9550       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9551       "vld1.32 {d1[0]}, [%[in]]!\n"
   9552       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9553       "vld1.32 {d2[0]}, [%[in]]!\n"
   9554       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9555       "pld [%[in]]\n"
   9556       "vtrn.16 d0, d2\n"
   9557       "vtrn.16 d1, d3\n"
   9558       "vuzp.8 d4, d5\n"
   9559       "vtrn.8 d0, d1\n"
   9560       "vtrn.8 d2, d3\n"
   9561       "vaddw.u8 q8, q8, d0\n"
   9562       "vaddw.u8 q9, q9, d1\n"
   9563       "vaddw.u8 q10, q10, d2\n"
   9564       "vaddw.u8 q11, q11, d3\n"
   9565       "vaddw.u8 q12, q12, d4\n"
   9566       "vaddw.u8 q13, q13, d5\n"
   9567       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9568       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9569 
   9570       // Aggregator Reduction.
   9571       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9572       "vdup.32 q1, %[additive_sum_offset]\n"
   9573       "vpaddl.u16 q8, q8\n"
   9574       "vpaddl.u16 q9, q9\n"
   9575       "vpaddl.u16 q10, q10\n"
   9576       "vpaddl.u16 q11, q11\n"
   9577       "vpaddl.u16 q12, q12\n"
   9578       "vpaddl.u16 q13, q13\n"
   9579       "vpadd.u32 d16, d16, d17\n"
   9580       "vpadd.u32 d18, d18, d19\n"
   9581       "vpadd.u32 d20, d20, d21\n"
   9582       "vpadd.u32 d22, d22, d23\n"
   9583       "vpadd.u32 d24, d24, d25\n"
   9584       "vpadd.u32 d26, d26, d27\n"
   9585       "vpadd.u32 d16, d16, d18\n"
   9586       "vpadd.u32 d17, d20, d22\n"
   9587       "vpadd.u32 d18, d24, d26\n"
   9588       "vmul.i32 q8, q8, d0[0]\n"
   9589       "vmul.i32 q9, q9, d0[0]\n"
   9590       "vadd.i32 q8, q8, q1\n"
   9591       "vadd.i32 q9, q9, q1\n"
   9592       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9593       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9594         [out] "+r"(out), [in] "+r"(in)
   9595       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9596         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9597       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9598         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9599 }
   9600 
   9601 template <>
   9602 inline void Stream<uint8_t, 6, 8, 4, ColumnMajorWithSum>::Pack(
   9603     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9604 #ifdef DEBUG
   9605 #ifdef DEBUG_METAGEMM_VERBOSE
   9606   std::cout
   9607       << __FILE__ << "(" << __LINE__
   9608       << ") ColumnMajorWithSum<uint8_t, 6, 8, 4, ColumnMajorWithSum>::Pack()"
   9609       << std::endl
   9610       << std::flush;
   9611 #endif
   9612 #endif
   9613   int params_count_copy = params.count;
   9614   int params_stride_copy = params.stride;
   9615   asm volatile(
   9616       "sub %[stride], %[stride], #4\n"
   9617       "vmov.i16 q8, #0\n"
   9618       "vmov.i16 q9, #0\n"
   9619       "vmov.i16 q10, #0\n"
   9620       "vmov.i16 q11, #0\n"
   9621       "vmov.i16 q12, #0\n"
   9622       "vmov.i16 q13, #0\n"
   9623 
   9624       // Reduce count by leftovers.
   9625       "subs %[count], %[count], #4\n"
   9626       "beq 2f\n"
   9627 
   9628       "1:"
   9629       "subs %[count], %[count], #8\n"
   9630 
   9631       // Load Aggregate Store - column major 6x8
   9632       "vld1.32 {d0[0]}, [%[in]]!\n"
   9633       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9634       "vld1.32 {d1[0]}, [%[in]]!\n"
   9635       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9636       "vld1.32 {d2[0]}, [%[in]]!\n"
   9637       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9638       "vld1.32 {d3[0]}, [%[in]]!\n"
   9639       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9640       "vld1.32 {d0[1]}, [%[in]]!\n"
   9641       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9642       "vld1.32 {d1[1]}, [%[in]]!\n"
   9643       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9644       "vld1.32 {d2[1]}, [%[in]]!\n"
   9645       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9646       "vld1.32 {d3[1]}, [%[in]]!\n"
   9647       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9648       "pld [%[in]]\n"
   9649       "vtrn.16 d0, d2\n"
   9650       "vtrn.16 d1, d3\n"
   9651       "vuzp.8 d4, d5\n"
   9652       "vtrn.8 d0, d1\n"
   9653       "vtrn.8 d2, d3\n"
   9654       "vaddw.u8 q8, q8, d0\n"
   9655       "vaddw.u8 q9, q9, d1\n"
   9656       "vaddw.u8 q10, q10, d2\n"
   9657       "vaddw.u8 q11, q11, d3\n"
   9658       "vaddw.u8 q12, q12, d4\n"
   9659       "vaddw.u8 q13, q13, d5\n"
   9660       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9661       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9662 
   9663       "bne 1b\n"
   9664 
   9665       "2:"
   9666 
   9667       // Load Aggregate Store - column major 6x4
   9668       "vmov.i8 d0, #0\n"
   9669       "vmov.i8 d1, #0\n"
   9670       "vmov.i8 d2, #0\n"
   9671       "vmov.i8 d3, #0\n"
   9672       "vmov.i8 d4, #0\n"
   9673       "vmov.i8 d5, #0\n"
   9674       "vld1.32 {d0[0]}, [%[in]]!\n"
   9675       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9676       "vld1.32 {d1[0]}, [%[in]]!\n"
   9677       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9678       "vld1.32 {d2[0]}, [%[in]]!\n"
   9679       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9680       "vld1.32 {d3[0]}, [%[in]]!\n"
   9681       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9682       "pld [%[in]]\n"
   9683       "vtrn.16 d0, d2\n"
   9684       "vtrn.16 d1, d3\n"
   9685       "vuzp.8 d4, d5\n"
   9686       "vtrn.8 d0, d1\n"
   9687       "vtrn.8 d2, d3\n"
   9688       "vaddw.u8 q8, q8, d0\n"
   9689       "vaddw.u8 q9, q9, d1\n"
   9690       "vaddw.u8 q10, q10, d2\n"
   9691       "vaddw.u8 q11, q11, d3\n"
   9692       "vaddw.u8 q12, q12, d4\n"
   9693       "vaddw.u8 q13, q13, d5\n"
   9694       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9695       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9696 
   9697       // Aggregator Reduction.
   9698       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9699       "vdup.32 q1, %[additive_sum_offset]\n"
   9700       "vpaddl.u16 q8, q8\n"
   9701       "vpaddl.u16 q9, q9\n"
   9702       "vpaddl.u16 q10, q10\n"
   9703       "vpaddl.u16 q11, q11\n"
   9704       "vpaddl.u16 q12, q12\n"
   9705       "vpaddl.u16 q13, q13\n"
   9706       "vpadd.u32 d16, d16, d17\n"
   9707       "vpadd.u32 d18, d18, d19\n"
   9708       "vpadd.u32 d20, d20, d21\n"
   9709       "vpadd.u32 d22, d22, d23\n"
   9710       "vpadd.u32 d24, d24, d25\n"
   9711       "vpadd.u32 d26, d26, d27\n"
   9712       "vpadd.u32 d16, d16, d18\n"
   9713       "vpadd.u32 d17, d20, d22\n"
   9714       "vpadd.u32 d18, d24, d26\n"
   9715       "vmul.i32 q8, q8, d0[0]\n"
   9716       "vmul.i32 q9, q9, d0[0]\n"
   9717       "vadd.i32 q8, q8, q1\n"
   9718       "vadd.i32 q9, q9, q1\n"
   9719       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9720       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9721         [out] "+r"(out), [in] "+r"(in)
   9722       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9723         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9724       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9725         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9726 }
   9727 
   9728 template <>
   9729 inline void Stream<uint8_t, 6, 8, 5, ColumnMajorWithSum>::Pack(
   9730     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9731 #ifdef DEBUG
   9732 #ifdef DEBUG_METAGEMM_VERBOSE
   9733   std::cout
   9734       << __FILE__ << "(" << __LINE__
   9735       << ") ColumnMajorWithSum<uint8_t, 6, 8, 5, ColumnMajorWithSum>::Pack()"
   9736       << std::endl
   9737       << std::flush;
   9738 #endif
   9739 #endif
   9740   int params_count_copy = params.count;
   9741   int params_stride_copy = params.stride;
   9742   asm volatile(
   9743       "sub %[stride], %[stride], #4\n"
   9744       "vmov.i16 q8, #0\n"
   9745       "vmov.i16 q9, #0\n"
   9746       "vmov.i16 q10, #0\n"
   9747       "vmov.i16 q11, #0\n"
   9748       "vmov.i16 q12, #0\n"
   9749       "vmov.i16 q13, #0\n"
   9750 
   9751       // Reduce count by leftovers.
   9752       "subs %[count], %[count], #5\n"
   9753       "beq 2f\n"
   9754 
   9755       "1:"
   9756       "subs %[count], %[count], #8\n"
   9757 
   9758       // Load Aggregate Store - column major 6x8
   9759       "vld1.32 {d0[0]}, [%[in]]!\n"
   9760       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9761       "vld1.32 {d1[0]}, [%[in]]!\n"
   9762       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9763       "vld1.32 {d2[0]}, [%[in]]!\n"
   9764       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9765       "vld1.32 {d3[0]}, [%[in]]!\n"
   9766       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9767       "vld1.32 {d0[1]}, [%[in]]!\n"
   9768       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9769       "vld1.32 {d1[1]}, [%[in]]!\n"
   9770       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9771       "vld1.32 {d2[1]}, [%[in]]!\n"
   9772       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9773       "vld1.32 {d3[1]}, [%[in]]!\n"
   9774       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9775       "pld [%[in]]\n"
   9776       "vtrn.16 d0, d2\n"
   9777       "vtrn.16 d1, d3\n"
   9778       "vuzp.8 d4, d5\n"
   9779       "vtrn.8 d0, d1\n"
   9780       "vtrn.8 d2, d3\n"
   9781       "vaddw.u8 q8, q8, d0\n"
   9782       "vaddw.u8 q9, q9, d1\n"
   9783       "vaddw.u8 q10, q10, d2\n"
   9784       "vaddw.u8 q11, q11, d3\n"
   9785       "vaddw.u8 q12, q12, d4\n"
   9786       "vaddw.u8 q13, q13, d5\n"
   9787       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9788       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9789 
   9790       "bne 1b\n"
   9791 
   9792       "2:"
   9793 
   9794       // Load Aggregate Store - column major 6x5
   9795       "vmov.i8 d0, #0\n"
   9796       "vmov.i8 d1, #0\n"
   9797       "vmov.i8 d2, #0\n"
   9798       "vmov.i8 d3, #0\n"
   9799       "vmov.i8 d4, #0\n"
   9800       "vmov.i8 d5, #0\n"
   9801       "vld1.32 {d0[0]}, [%[in]]!\n"
   9802       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9803       "vld1.32 {d1[0]}, [%[in]]!\n"
   9804       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9805       "vld1.32 {d2[0]}, [%[in]]!\n"
   9806       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9807       "vld1.32 {d3[0]}, [%[in]]!\n"
   9808       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9809       "vld1.32 {d0[1]}, [%[in]]!\n"
   9810       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9811       "pld [%[in]]\n"
   9812       "vtrn.16 d0, d2\n"
   9813       "vtrn.16 d1, d3\n"
   9814       "vuzp.8 d4, d5\n"
   9815       "vtrn.8 d0, d1\n"
   9816       "vtrn.8 d2, d3\n"
   9817       "vaddw.u8 q8, q8, d0\n"
   9818       "vaddw.u8 q9, q9, d1\n"
   9819       "vaddw.u8 q10, q10, d2\n"
   9820       "vaddw.u8 q11, q11, d3\n"
   9821       "vaddw.u8 q12, q12, d4\n"
   9822       "vaddw.u8 q13, q13, d5\n"
   9823       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9824       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9825 
   9826       // Aggregator Reduction.
   9827       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9828       "vdup.32 q1, %[additive_sum_offset]\n"
   9829       "vpaddl.u16 q8, q8\n"
   9830       "vpaddl.u16 q9, q9\n"
   9831       "vpaddl.u16 q10, q10\n"
   9832       "vpaddl.u16 q11, q11\n"
   9833       "vpaddl.u16 q12, q12\n"
   9834       "vpaddl.u16 q13, q13\n"
   9835       "vpadd.u32 d16, d16, d17\n"
   9836       "vpadd.u32 d18, d18, d19\n"
   9837       "vpadd.u32 d20, d20, d21\n"
   9838       "vpadd.u32 d22, d22, d23\n"
   9839       "vpadd.u32 d24, d24, d25\n"
   9840       "vpadd.u32 d26, d26, d27\n"
   9841       "vpadd.u32 d16, d16, d18\n"
   9842       "vpadd.u32 d17, d20, d22\n"
   9843       "vpadd.u32 d18, d24, d26\n"
   9844       "vmul.i32 q8, q8, d0[0]\n"
   9845       "vmul.i32 q9, q9, d0[0]\n"
   9846       "vadd.i32 q8, q8, q1\n"
   9847       "vadd.i32 q9, q9, q1\n"
   9848       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9849       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9850         [out] "+r"(out), [in] "+r"(in)
   9851       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9852         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9853       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9854         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9855 }
   9856 
   9857 template <>
   9858 inline void Stream<uint8_t, 6, 8, 6, ColumnMajorWithSum>::Pack(
   9859     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9860 #ifdef DEBUG
   9861 #ifdef DEBUG_METAGEMM_VERBOSE
   9862   std::cout
   9863       << __FILE__ << "(" << __LINE__
   9864       << ") ColumnMajorWithSum<uint8_t, 6, 8, 6, ColumnMajorWithSum>::Pack()"
   9865       << std::endl
   9866       << std::flush;
   9867 #endif
   9868 #endif
   9869   int params_count_copy = params.count;
   9870   int params_stride_copy = params.stride;
   9871   asm volatile(
   9872       "sub %[stride], %[stride], #4\n"
   9873       "vmov.i16 q8, #0\n"
   9874       "vmov.i16 q9, #0\n"
   9875       "vmov.i16 q10, #0\n"
   9876       "vmov.i16 q11, #0\n"
   9877       "vmov.i16 q12, #0\n"
   9878       "vmov.i16 q13, #0\n"
   9879 
   9880       // Reduce count by leftovers.
   9881       "subs %[count], %[count], #6\n"
   9882       "beq 2f\n"
   9883 
   9884       "1:"
   9885       "subs %[count], %[count], #8\n"
   9886 
   9887       // Load Aggregate Store - column major 6x8
   9888       "vld1.32 {d0[0]}, [%[in]]!\n"
   9889       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9890       "vld1.32 {d1[0]}, [%[in]]!\n"
   9891       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9892       "vld1.32 {d2[0]}, [%[in]]!\n"
   9893       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9894       "vld1.32 {d3[0]}, [%[in]]!\n"
   9895       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9896       "vld1.32 {d0[1]}, [%[in]]!\n"
   9897       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9898       "vld1.32 {d1[1]}, [%[in]]!\n"
   9899       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9900       "vld1.32 {d2[1]}, [%[in]]!\n"
   9901       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   9902       "vld1.32 {d3[1]}, [%[in]]!\n"
   9903       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   9904       "pld [%[in]]\n"
   9905       "vtrn.16 d0, d2\n"
   9906       "vtrn.16 d1, d3\n"
   9907       "vuzp.8 d4, d5\n"
   9908       "vtrn.8 d0, d1\n"
   9909       "vtrn.8 d2, d3\n"
   9910       "vaddw.u8 q8, q8, d0\n"
   9911       "vaddw.u8 q9, q9, d1\n"
   9912       "vaddw.u8 q10, q10, d2\n"
   9913       "vaddw.u8 q11, q11, d3\n"
   9914       "vaddw.u8 q12, q12, d4\n"
   9915       "vaddw.u8 q13, q13, d5\n"
   9916       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9917       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9918 
   9919       "bne 1b\n"
   9920 
   9921       "2:"
   9922 
   9923       // Load Aggregate Store - column major 6x6
   9924       "vmov.i8 d0, #0\n"
   9925       "vmov.i8 d1, #0\n"
   9926       "vmov.i8 d2, #0\n"
   9927       "vmov.i8 d3, #0\n"
   9928       "vmov.i8 d4, #0\n"
   9929       "vmov.i8 d5, #0\n"
   9930       "vld1.32 {d0[0]}, [%[in]]!\n"
   9931       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   9932       "vld1.32 {d1[0]}, [%[in]]!\n"
   9933       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   9934       "vld1.32 {d2[0]}, [%[in]]!\n"
   9935       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   9936       "vld1.32 {d3[0]}, [%[in]]!\n"
   9937       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   9938       "vld1.32 {d0[1]}, [%[in]]!\n"
   9939       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   9940       "vld1.32 {d1[1]}, [%[in]]!\n"
   9941       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   9942       "pld [%[in]]\n"
   9943       "vtrn.16 d0, d2\n"
   9944       "vtrn.16 d1, d3\n"
   9945       "vuzp.8 d4, d5\n"
   9946       "vtrn.8 d0, d1\n"
   9947       "vtrn.8 d2, d3\n"
   9948       "vaddw.u8 q8, q8, d0\n"
   9949       "vaddw.u8 q9, q9, d1\n"
   9950       "vaddw.u8 q10, q10, d2\n"
   9951       "vaddw.u8 q11, q11, d3\n"
   9952       "vaddw.u8 q12, q12, d4\n"
   9953       "vaddw.u8 q13, q13, d5\n"
   9954       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   9955       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   9956 
   9957       // Aggregator Reduction.
   9958       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   9959       "vdup.32 q1, %[additive_sum_offset]\n"
   9960       "vpaddl.u16 q8, q8\n"
   9961       "vpaddl.u16 q9, q9\n"
   9962       "vpaddl.u16 q10, q10\n"
   9963       "vpaddl.u16 q11, q11\n"
   9964       "vpaddl.u16 q12, q12\n"
   9965       "vpaddl.u16 q13, q13\n"
   9966       "vpadd.u32 d16, d16, d17\n"
   9967       "vpadd.u32 d18, d18, d19\n"
   9968       "vpadd.u32 d20, d20, d21\n"
   9969       "vpadd.u32 d22, d22, d23\n"
   9970       "vpadd.u32 d24, d24, d25\n"
   9971       "vpadd.u32 d26, d26, d27\n"
   9972       "vpadd.u32 d16, d16, d18\n"
   9973       "vpadd.u32 d17, d20, d22\n"
   9974       "vpadd.u32 d18, d24, d26\n"
   9975       "vmul.i32 q8, q8, d0[0]\n"
   9976       "vmul.i32 q9, q9, d0[0]\n"
   9977       "vadd.i32 q8, q8, q1\n"
   9978       "vadd.i32 q9, q9, q1\n"
   9979       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   9980       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   9981         [out] "+r"(out), [in] "+r"(in)
   9982       : [additive_sum_offset] "r"(params.additive_sum_offset),
   9983         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   9984       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   9985         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   9986 }
   9987 
   9988 template <>
   9989 inline void Stream<uint8_t, 6, 8, 7, ColumnMajorWithSum>::Pack(
   9990     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   9991 #ifdef DEBUG
   9992 #ifdef DEBUG_METAGEMM_VERBOSE
   9993   std::cout
   9994       << __FILE__ << "(" << __LINE__
   9995       << ") ColumnMajorWithSum<uint8_t, 6, 8, 7, ColumnMajorWithSum>::Pack()"
   9996       << std::endl
   9997       << std::flush;
   9998 #endif
   9999 #endif
   10000   int params_count_copy = params.count;
   10001   int params_stride_copy = params.stride;
   10002   asm volatile(
   10003       "sub %[stride], %[stride], #4\n"
   10004       "vmov.i16 q8, #0\n"
   10005       "vmov.i16 q9, #0\n"
   10006       "vmov.i16 q10, #0\n"
   10007       "vmov.i16 q11, #0\n"
   10008       "vmov.i16 q12, #0\n"
   10009       "vmov.i16 q13, #0\n"
   10010 
   10011       // Reduce count by leftovers.
   10012       "subs %[count], %[count], #7\n"
   10013       "beq 2f\n"
   10014 
   10015       "1:"
   10016       "subs %[count], %[count], #8\n"
   10017 
   10018       // Load Aggregate Store - column major 6x8
   10019       "vld1.32 {d0[0]}, [%[in]]!\n"
   10020       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   10021       "vld1.32 {d1[0]}, [%[in]]!\n"
   10022       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   10023       "vld1.32 {d2[0]}, [%[in]]!\n"
   10024       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   10025       "vld1.32 {d3[0]}, [%[in]]!\n"
   10026       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   10027       "vld1.32 {d0[1]}, [%[in]]!\n"
   10028       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   10029       "vld1.32 {d1[1]}, [%[in]]!\n"
   10030       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   10031       "vld1.32 {d2[1]}, [%[in]]!\n"
   10032       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   10033       "vld1.32 {d3[1]}, [%[in]]!\n"
   10034       "vld1.16 {d5[3]}, [%[in]], %[stride]\n"
   10035       "pld [%[in]]\n"
   10036       "vtrn.16 d0, d2\n"
   10037       "vtrn.16 d1, d3\n"
   10038       "vuzp.8 d4, d5\n"
   10039       "vtrn.8 d0, d1\n"
   10040       "vtrn.8 d2, d3\n"
   10041       "vaddw.u8 q8, q8, d0\n"
   10042       "vaddw.u8 q9, q9, d1\n"
   10043       "vaddw.u8 q10, q10, d2\n"
   10044       "vaddw.u8 q11, q11, d3\n"
   10045       "vaddw.u8 q12, q12, d4\n"
   10046       "vaddw.u8 q13, q13, d5\n"
   10047       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   10048       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   10049 
   10050       "bne 1b\n"
   10051 
   10052       "2:"
   10053 
   10054       // Load Aggregate Store - column major 6x7
   10055       "vmov.i8 d0, #0\n"
   10056       "vmov.i8 d1, #0\n"
   10057       "vmov.i8 d2, #0\n"
   10058       "vmov.i8 d3, #0\n"
   10059       "vmov.i8 d4, #0\n"
   10060       "vmov.i8 d5, #0\n"
   10061       "vld1.32 {d0[0]}, [%[in]]!\n"
   10062       "vld1.16 {d4[0]}, [%[in]], %[stride]\n"
   10063       "vld1.32 {d1[0]}, [%[in]]!\n"
   10064       "vld1.16 {d4[1]}, [%[in]], %[stride]\n"
   10065       "vld1.32 {d2[0]}, [%[in]]!\n"
   10066       "vld1.16 {d4[2]}, [%[in]], %[stride]\n"
   10067       "vld1.32 {d3[0]}, [%[in]]!\n"
   10068       "vld1.16 {d4[3]}, [%[in]], %[stride]\n"
   10069       "vld1.32 {d0[1]}, [%[in]]!\n"
   10070       "vld1.16 {d5[0]}, [%[in]], %[stride]\n"
   10071       "vld1.32 {d1[1]}, [%[in]]!\n"
   10072       "vld1.16 {d5[1]}, [%[in]], %[stride]\n"
   10073       "vld1.32 {d2[1]}, [%[in]]!\n"
   10074       "vld1.16 {d5[2]}, [%[in]], %[stride]\n"
   10075       "pld [%[in]]\n"
   10076       "vtrn.16 d0, d2\n"
   10077       "vtrn.16 d1, d3\n"
   10078       "vuzp.8 d4, d5\n"
   10079       "vtrn.8 d0, d1\n"
   10080       "vtrn.8 d2, d3\n"
   10081       "vaddw.u8 q8, q8, d0\n"
   10082       "vaddw.u8 q9, q9, d1\n"
   10083       "vaddw.u8 q10, q10, d2\n"
   10084       "vaddw.u8 q11, q11, d3\n"
   10085       "vaddw.u8 q12, q12, d4\n"
   10086       "vaddw.u8 q13, q13, d5\n"
   10087       "vst1.32 {d0, d1, d2, d3}, [%[out]:128]!\n"
   10088       "vst1.32 {d4, d5}, [%[out]:128]!\n"
   10089 
   10090       // Aggregator Reduction.
   10091       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10092       "vdup.32 q1, %[additive_sum_offset]\n"
   10093       "vpaddl.u16 q8, q8\n"
   10094       "vpaddl.u16 q9, q9\n"
   10095       "vpaddl.u16 q10, q10\n"
   10096       "vpaddl.u16 q11, q11\n"
   10097       "vpaddl.u16 q12, q12\n"
   10098       "vpaddl.u16 q13, q13\n"
   10099       "vpadd.u32 d16, d16, d17\n"
   10100       "vpadd.u32 d18, d18, d19\n"
   10101       "vpadd.u32 d20, d20, d21\n"
   10102       "vpadd.u32 d22, d22, d23\n"
   10103       "vpadd.u32 d24, d24, d25\n"
   10104       "vpadd.u32 d26, d26, d27\n"
   10105       "vpadd.u32 d16, d16, d18\n"
   10106       "vpadd.u32 d17, d20, d22\n"
   10107       "vpadd.u32 d18, d24, d26\n"
   10108       "vmul.i32 q8, q8, d0[0]\n"
   10109       "vmul.i32 q9, q9, d0[0]\n"
   10110       "vadd.i32 q8, q8, q1\n"
   10111       "vadd.i32 q9, q9, q1\n"
   10112       "vst1.32 {d16, d17, d18, d19}, [%[out]:128]\n"
   10113       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10114         [out] "+r"(out), [in] "+r"(in)
   10115       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10116         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10117       : "d0", "d1", "d2", "d3", "d4", "d5", "d16", "d17", "d18", "d19", "d20",
   10118         "d21", "d22", "d23", "d24", "d25", "d26", "d27", "cc", "memory");
   10119 }
   10120 
   10121 template <>
   10122 inline void Stream<uint8_t, 7, 8, 0, ColumnMajorWithSum>::Pack(
   10123     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10124 #ifdef DEBUG
   10125 #ifdef DEBUG_METAGEMM_VERBOSE
   10126   std::cout
   10127       << __FILE__ << "(" << __LINE__
   10128       << ") ColumnMajorWithSum<uint8_t, 7, 8, 0, ColumnMajorWithSum>::Pack()"
   10129       << std::endl
   10130       << std::flush;
   10131 #endif
   10132 #endif
   10133   int params_count_copy = params.count;
   10134   int params_stride_copy = params.stride;
   10135   asm volatile(
   10136       "sub %[stride], %[stride], #4\n"
   10137       "vmov.i16 q8, #0\n"
   10138       "vmov.i16 q9, #0\n"
   10139       "vmov.i16 q10, #0\n"
   10140       "vmov.i16 q11, #0\n"
   10141       "vmov.i16 q12, #0\n"
   10142       "vmov.i16 q13, #0\n"
   10143       "vmov.i16 q14, #0\n"
   10144 
   10145       "1:"
   10146       "subs %[count], %[count], #8\n"
   10147 
   10148       // Load Aggregate Store - column major 7x8
   10149       "vld1.32 {d0[0]}, [%[in]]!\n"
   10150       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10151       "vld1.32 {d1[0]}, [%[in]]!\n"
   10152       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10153       "vld1.32 {d2[0]}, [%[in]]!\n"
   10154       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10155       "vld1.32 {d3[0]}, [%[in]]!\n"
   10156       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10157       "vld1.32 {d0[1]}, [%[in]]!\n"
   10158       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10159       "vld1.32 {d1[1]}, [%[in]]!\n"
   10160       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10161       "vld1.32 {d2[1]}, [%[in]]!\n"
   10162       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10163       "vld1.32 {d3[1]}, [%[in]]!\n"
   10164       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10165       "pld [%[in]]\n"
   10166       "vtrn.16 d0, d2\n"
   10167       "vtrn.16 d1, d3\n"
   10168       "vtrn.8 d0, d1\n"
   10169       "vtrn.8 d2, d3\n"
   10170       "vaddw.u8 q8, q8, d0\n"
   10171       "vaddw.u8 q9, q9, d1\n"
   10172       "vaddw.u8 q10, q10, d2\n"
   10173       "vaddw.u8 q11, q11, d3\n"
   10174       "vaddw.u8 q12, q12, d4\n"
   10175       "vaddw.u8 q13, q13, d5\n"
   10176       "vaddw.u8 q14, q14, d6\n"
   10177       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10178       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10179 
   10180       "bne 1b\n"
   10181 
   10182       // Aggregator Reduction.
   10183       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10184       "vdup.32 q1, %[additive_sum_offset]\n"
   10185       "vpaddl.u16 q8, q8\n"
   10186       "vpaddl.u16 q9, q9\n"
   10187       "vpaddl.u16 q10, q10\n"
   10188       "vpaddl.u16 q11, q11\n"
   10189       "vpaddl.u16 q12, q12\n"
   10190       "vpaddl.u16 q13, q13\n"
   10191       "vpaddl.u16 q14, q14\n"
   10192       "vpadd.u32 d16, d16, d17\n"
   10193       "vpadd.u32 d18, d18, d19\n"
   10194       "vpadd.u32 d20, d20, d21\n"
   10195       "vpadd.u32 d22, d22, d23\n"
   10196       "vpadd.u32 d24, d24, d25\n"
   10197       "vpadd.u32 d26, d26, d27\n"
   10198       "vpadd.u32 d28, d28, d29\n"
   10199       "vpadd.u32 d16, d16, d18\n"
   10200       "vpadd.u32 d17, d20, d22\n"
   10201       "vpadd.u32 d18, d24, d26\n"
   10202       "vpadd.u32 d19, d28, d28\n"
   10203       "vmul.i32 q8, q8, d0[0]\n"
   10204       "vmul.i32 q9, q9, d0[0]\n"
   10205       "vadd.i32 q8, q8, q1\n"
   10206       "vadd.i32 q9, q9, q1\n"
   10207       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10208       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10209         [out] "+r"(out), [in] "+r"(in)
   10210       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10211         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10212       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10213         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10214         "cc", "memory");
   10215 }
   10216 
   10217 template <>
   10218 inline void Stream<uint8_t, 7, 8, 1, ColumnMajorWithSum>::Pack(
   10219     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10220 #ifdef DEBUG
   10221 #ifdef DEBUG_METAGEMM_VERBOSE
   10222   std::cout
   10223       << __FILE__ << "(" << __LINE__
   10224       << ") ColumnMajorWithSum<uint8_t, 7, 8, 1, ColumnMajorWithSum>::Pack()"
   10225       << std::endl
   10226       << std::flush;
   10227 #endif
   10228 #endif
   10229   int params_count_copy = params.count;
   10230   int params_stride_copy = params.stride;
   10231   asm volatile(
   10232       "sub %[stride], %[stride], #4\n"
   10233       "vmov.i16 q8, #0\n"
   10234       "vmov.i16 q9, #0\n"
   10235       "vmov.i16 q10, #0\n"
   10236       "vmov.i16 q11, #0\n"
   10237       "vmov.i16 q12, #0\n"
   10238       "vmov.i16 q13, #0\n"
   10239       "vmov.i16 q14, #0\n"
   10240 
   10241       // Reduce count by leftovers.
   10242       "subs %[count], %[count], #1\n"
   10243       "beq 2f\n"
   10244 
   10245       "1:"
   10246       "subs %[count], %[count], #8\n"
   10247 
   10248       // Load Aggregate Store - column major 7x8
   10249       "vld1.32 {d0[0]}, [%[in]]!\n"
   10250       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10251       "vld1.32 {d1[0]}, [%[in]]!\n"
   10252       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10253       "vld1.32 {d2[0]}, [%[in]]!\n"
   10254       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10255       "vld1.32 {d3[0]}, [%[in]]!\n"
   10256       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10257       "vld1.32 {d0[1]}, [%[in]]!\n"
   10258       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10259       "vld1.32 {d1[1]}, [%[in]]!\n"
   10260       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10261       "vld1.32 {d2[1]}, [%[in]]!\n"
   10262       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10263       "vld1.32 {d3[1]}, [%[in]]!\n"
   10264       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10265       "pld [%[in]]\n"
   10266       "vtrn.16 d0, d2\n"
   10267       "vtrn.16 d1, d3\n"
   10268       "vtrn.8 d0, d1\n"
   10269       "vtrn.8 d2, d3\n"
   10270       "vaddw.u8 q8, q8, d0\n"
   10271       "vaddw.u8 q9, q9, d1\n"
   10272       "vaddw.u8 q10, q10, d2\n"
   10273       "vaddw.u8 q11, q11, d3\n"
   10274       "vaddw.u8 q12, q12, d4\n"
   10275       "vaddw.u8 q13, q13, d5\n"
   10276       "vaddw.u8 q14, q14, d6\n"
   10277       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10278       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10279 
   10280       "bne 1b\n"
   10281 
   10282       "2:"
   10283 
   10284       // Load Aggregate Store - column major 7x1
   10285       "vmov.i8 d0, #0\n"
   10286       "vmov.i8 d1, #0\n"
   10287       "vmov.i8 d2, #0\n"
   10288       "vmov.i8 d3, #0\n"
   10289       "vmov.i8 d4, #0\n"
   10290       "vmov.i8 d5, #0\n"
   10291       "vmov.i8 d6, #0\n"
   10292       "vld1.32 {d0[0]}, [%[in]]!\n"
   10293       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10294       "pld [%[in]]\n"
   10295       "vtrn.16 d0, d2\n"
   10296       "vtrn.16 d1, d3\n"
   10297       "vtrn.8 d0, d1\n"
   10298       "vtrn.8 d2, d3\n"
   10299       "vaddw.u8 q8, q8, d0\n"
   10300       "vaddw.u8 q9, q9, d1\n"
   10301       "vaddw.u8 q10, q10, d2\n"
   10302       "vaddw.u8 q11, q11, d3\n"
   10303       "vaddw.u8 q12, q12, d4\n"
   10304       "vaddw.u8 q13, q13, d5\n"
   10305       "vaddw.u8 q14, q14, d6\n"
   10306       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10307       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10308 
   10309       // Aggregator Reduction.
   10310       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10311       "vdup.32 q1, %[additive_sum_offset]\n"
   10312       "vpaddl.u16 q8, q8\n"
   10313       "vpaddl.u16 q9, q9\n"
   10314       "vpaddl.u16 q10, q10\n"
   10315       "vpaddl.u16 q11, q11\n"
   10316       "vpaddl.u16 q12, q12\n"
   10317       "vpaddl.u16 q13, q13\n"
   10318       "vpaddl.u16 q14, q14\n"
   10319       "vpadd.u32 d16, d16, d17\n"
   10320       "vpadd.u32 d18, d18, d19\n"
   10321       "vpadd.u32 d20, d20, d21\n"
   10322       "vpadd.u32 d22, d22, d23\n"
   10323       "vpadd.u32 d24, d24, d25\n"
   10324       "vpadd.u32 d26, d26, d27\n"
   10325       "vpadd.u32 d28, d28, d29\n"
   10326       "vpadd.u32 d16, d16, d18\n"
   10327       "vpadd.u32 d17, d20, d22\n"
   10328       "vpadd.u32 d18, d24, d26\n"
   10329       "vpadd.u32 d19, d28, d28\n"
   10330       "vmul.i32 q8, q8, d0[0]\n"
   10331       "vmul.i32 q9, q9, d0[0]\n"
   10332       "vadd.i32 q8, q8, q1\n"
   10333       "vadd.i32 q9, q9, q1\n"
   10334       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10335       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10336         [out] "+r"(out), [in] "+r"(in)
   10337       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10338         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10339       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10340         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10341         "cc", "memory");
   10342 }
   10343 
   10344 template <>
   10345 inline void Stream<uint8_t, 7, 8, 2, ColumnMajorWithSum>::Pack(
   10346     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10347 #ifdef DEBUG
   10348 #ifdef DEBUG_METAGEMM_VERBOSE
   10349   std::cout
   10350       << __FILE__ << "(" << __LINE__
   10351       << ") ColumnMajorWithSum<uint8_t, 7, 8, 2, ColumnMajorWithSum>::Pack()"
   10352       << std::endl
   10353       << std::flush;
   10354 #endif
   10355 #endif
   10356   int params_count_copy = params.count;
   10357   int params_stride_copy = params.stride;
   10358   asm volatile(
   10359       "sub %[stride], %[stride], #4\n"
   10360       "vmov.i16 q8, #0\n"
   10361       "vmov.i16 q9, #0\n"
   10362       "vmov.i16 q10, #0\n"
   10363       "vmov.i16 q11, #0\n"
   10364       "vmov.i16 q12, #0\n"
   10365       "vmov.i16 q13, #0\n"
   10366       "vmov.i16 q14, #0\n"
   10367 
   10368       // Reduce count by leftovers.
   10369       "subs %[count], %[count], #2\n"
   10370       "beq 2f\n"
   10371 
   10372       "1:"
   10373       "subs %[count], %[count], #8\n"
   10374 
   10375       // Load Aggregate Store - column major 7x8
   10376       "vld1.32 {d0[0]}, [%[in]]!\n"
   10377       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10378       "vld1.32 {d1[0]}, [%[in]]!\n"
   10379       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10380       "vld1.32 {d2[0]}, [%[in]]!\n"
   10381       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10382       "vld1.32 {d3[0]}, [%[in]]!\n"
   10383       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10384       "vld1.32 {d0[1]}, [%[in]]!\n"
   10385       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10386       "vld1.32 {d1[1]}, [%[in]]!\n"
   10387       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10388       "vld1.32 {d2[1]}, [%[in]]!\n"
   10389       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10390       "vld1.32 {d3[1]}, [%[in]]!\n"
   10391       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10392       "pld [%[in]]\n"
   10393       "vtrn.16 d0, d2\n"
   10394       "vtrn.16 d1, d3\n"
   10395       "vtrn.8 d0, d1\n"
   10396       "vtrn.8 d2, d3\n"
   10397       "vaddw.u8 q8, q8, d0\n"
   10398       "vaddw.u8 q9, q9, d1\n"
   10399       "vaddw.u8 q10, q10, d2\n"
   10400       "vaddw.u8 q11, q11, d3\n"
   10401       "vaddw.u8 q12, q12, d4\n"
   10402       "vaddw.u8 q13, q13, d5\n"
   10403       "vaddw.u8 q14, q14, d6\n"
   10404       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10405       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10406 
   10407       "bne 1b\n"
   10408 
   10409       "2:"
   10410 
   10411       // Load Aggregate Store - column major 7x2
   10412       "vmov.i8 d0, #0\n"
   10413       "vmov.i8 d1, #0\n"
   10414       "vmov.i8 d2, #0\n"
   10415       "vmov.i8 d3, #0\n"
   10416       "vmov.i8 d4, #0\n"
   10417       "vmov.i8 d5, #0\n"
   10418       "vmov.i8 d6, #0\n"
   10419       "vld1.32 {d0[0]}, [%[in]]!\n"
   10420       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10421       "vld1.32 {d1[0]}, [%[in]]!\n"
   10422       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10423       "pld [%[in]]\n"
   10424       "vtrn.16 d0, d2\n"
   10425       "vtrn.16 d1, d3\n"
   10426       "vtrn.8 d0, d1\n"
   10427       "vtrn.8 d2, d3\n"
   10428       "vaddw.u8 q8, q8, d0\n"
   10429       "vaddw.u8 q9, q9, d1\n"
   10430       "vaddw.u8 q10, q10, d2\n"
   10431       "vaddw.u8 q11, q11, d3\n"
   10432       "vaddw.u8 q12, q12, d4\n"
   10433       "vaddw.u8 q13, q13, d5\n"
   10434       "vaddw.u8 q14, q14, d6\n"
   10435       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10436       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10437 
   10438       // Aggregator Reduction.
   10439       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10440       "vdup.32 q1, %[additive_sum_offset]\n"
   10441       "vpaddl.u16 q8, q8\n"
   10442       "vpaddl.u16 q9, q9\n"
   10443       "vpaddl.u16 q10, q10\n"
   10444       "vpaddl.u16 q11, q11\n"
   10445       "vpaddl.u16 q12, q12\n"
   10446       "vpaddl.u16 q13, q13\n"
   10447       "vpaddl.u16 q14, q14\n"
   10448       "vpadd.u32 d16, d16, d17\n"
   10449       "vpadd.u32 d18, d18, d19\n"
   10450       "vpadd.u32 d20, d20, d21\n"
   10451       "vpadd.u32 d22, d22, d23\n"
   10452       "vpadd.u32 d24, d24, d25\n"
   10453       "vpadd.u32 d26, d26, d27\n"
   10454       "vpadd.u32 d28, d28, d29\n"
   10455       "vpadd.u32 d16, d16, d18\n"
   10456       "vpadd.u32 d17, d20, d22\n"
   10457       "vpadd.u32 d18, d24, d26\n"
   10458       "vpadd.u32 d19, d28, d28\n"
   10459       "vmul.i32 q8, q8, d0[0]\n"
   10460       "vmul.i32 q9, q9, d0[0]\n"
   10461       "vadd.i32 q8, q8, q1\n"
   10462       "vadd.i32 q9, q9, q1\n"
   10463       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10464       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10465         [out] "+r"(out), [in] "+r"(in)
   10466       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10467         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10468       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10469         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10470         "cc", "memory");
   10471 }
   10472 
   10473 template <>
   10474 inline void Stream<uint8_t, 7, 8, 3, ColumnMajorWithSum>::Pack(
   10475     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10476 #ifdef DEBUG
   10477 #ifdef DEBUG_METAGEMM_VERBOSE
   10478   std::cout
   10479       << __FILE__ << "(" << __LINE__
   10480       << ") ColumnMajorWithSum<uint8_t, 7, 8, 3, ColumnMajorWithSum>::Pack()"
   10481       << std::endl
   10482       << std::flush;
   10483 #endif
   10484 #endif
   10485   int params_count_copy = params.count;
   10486   int params_stride_copy = params.stride;
   10487   asm volatile(
   10488       "sub %[stride], %[stride], #4\n"
   10489       "vmov.i16 q8, #0\n"
   10490       "vmov.i16 q9, #0\n"
   10491       "vmov.i16 q10, #0\n"
   10492       "vmov.i16 q11, #0\n"
   10493       "vmov.i16 q12, #0\n"
   10494       "vmov.i16 q13, #0\n"
   10495       "vmov.i16 q14, #0\n"
   10496 
   10497       // Reduce count by leftovers.
   10498       "subs %[count], %[count], #3\n"
   10499       "beq 2f\n"
   10500 
   10501       "1:"
   10502       "subs %[count], %[count], #8\n"
   10503 
   10504       // Load Aggregate Store - column major 7x8
   10505       "vld1.32 {d0[0]}, [%[in]]!\n"
   10506       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10507       "vld1.32 {d1[0]}, [%[in]]!\n"
   10508       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10509       "vld1.32 {d2[0]}, [%[in]]!\n"
   10510       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10511       "vld1.32 {d3[0]}, [%[in]]!\n"
   10512       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10513       "vld1.32 {d0[1]}, [%[in]]!\n"
   10514       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10515       "vld1.32 {d1[1]}, [%[in]]!\n"
   10516       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10517       "vld1.32 {d2[1]}, [%[in]]!\n"
   10518       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10519       "vld1.32 {d3[1]}, [%[in]]!\n"
   10520       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10521       "pld [%[in]]\n"
   10522       "vtrn.16 d0, d2\n"
   10523       "vtrn.16 d1, d3\n"
   10524       "vtrn.8 d0, d1\n"
   10525       "vtrn.8 d2, d3\n"
   10526       "vaddw.u8 q8, q8, d0\n"
   10527       "vaddw.u8 q9, q9, d1\n"
   10528       "vaddw.u8 q10, q10, d2\n"
   10529       "vaddw.u8 q11, q11, d3\n"
   10530       "vaddw.u8 q12, q12, d4\n"
   10531       "vaddw.u8 q13, q13, d5\n"
   10532       "vaddw.u8 q14, q14, d6\n"
   10533       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10534       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10535 
   10536       "bne 1b\n"
   10537 
   10538       "2:"
   10539 
   10540       // Load Aggregate Store - column major 7x3
   10541       "vmov.i8 d0, #0\n"
   10542       "vmov.i8 d1, #0\n"
   10543       "vmov.i8 d2, #0\n"
   10544       "vmov.i8 d3, #0\n"
   10545       "vmov.i8 d4, #0\n"
   10546       "vmov.i8 d5, #0\n"
   10547       "vmov.i8 d6, #0\n"
   10548       "vld1.32 {d0[0]}, [%[in]]!\n"
   10549       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10550       "vld1.32 {d1[0]}, [%[in]]!\n"
   10551       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10552       "vld1.32 {d2[0]}, [%[in]]!\n"
   10553       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10554       "pld [%[in]]\n"
   10555       "vtrn.16 d0, d2\n"
   10556       "vtrn.16 d1, d3\n"
   10557       "vtrn.8 d0, d1\n"
   10558       "vtrn.8 d2, d3\n"
   10559       "vaddw.u8 q8, q8, d0\n"
   10560       "vaddw.u8 q9, q9, d1\n"
   10561       "vaddw.u8 q10, q10, d2\n"
   10562       "vaddw.u8 q11, q11, d3\n"
   10563       "vaddw.u8 q12, q12, d4\n"
   10564       "vaddw.u8 q13, q13, d5\n"
   10565       "vaddw.u8 q14, q14, d6\n"
   10566       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10567       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10568 
   10569       // Aggregator Reduction.
   10570       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10571       "vdup.32 q1, %[additive_sum_offset]\n"
   10572       "vpaddl.u16 q8, q8\n"
   10573       "vpaddl.u16 q9, q9\n"
   10574       "vpaddl.u16 q10, q10\n"
   10575       "vpaddl.u16 q11, q11\n"
   10576       "vpaddl.u16 q12, q12\n"
   10577       "vpaddl.u16 q13, q13\n"
   10578       "vpaddl.u16 q14, q14\n"
   10579       "vpadd.u32 d16, d16, d17\n"
   10580       "vpadd.u32 d18, d18, d19\n"
   10581       "vpadd.u32 d20, d20, d21\n"
   10582       "vpadd.u32 d22, d22, d23\n"
   10583       "vpadd.u32 d24, d24, d25\n"
   10584       "vpadd.u32 d26, d26, d27\n"
   10585       "vpadd.u32 d28, d28, d29\n"
   10586       "vpadd.u32 d16, d16, d18\n"
   10587       "vpadd.u32 d17, d20, d22\n"
   10588       "vpadd.u32 d18, d24, d26\n"
   10589       "vpadd.u32 d19, d28, d28\n"
   10590       "vmul.i32 q8, q8, d0[0]\n"
   10591       "vmul.i32 q9, q9, d0[0]\n"
   10592       "vadd.i32 q8, q8, q1\n"
   10593       "vadd.i32 q9, q9, q1\n"
   10594       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10595       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10596         [out] "+r"(out), [in] "+r"(in)
   10597       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10598         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10599       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10600         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10601         "cc", "memory");
   10602 }
   10603 
   10604 template <>
   10605 inline void Stream<uint8_t, 7, 8, 4, ColumnMajorWithSum>::Pack(
   10606     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10607 #ifdef DEBUG
   10608 #ifdef DEBUG_METAGEMM_VERBOSE
   10609   std::cout
   10610       << __FILE__ << "(" << __LINE__
   10611       << ") ColumnMajorWithSum<uint8_t, 7, 8, 4, ColumnMajorWithSum>::Pack()"
   10612       << std::endl
   10613       << std::flush;
   10614 #endif
   10615 #endif
   10616   int params_count_copy = params.count;
   10617   int params_stride_copy = params.stride;
   10618   asm volatile(
   10619       "sub %[stride], %[stride], #4\n"
   10620       "vmov.i16 q8, #0\n"
   10621       "vmov.i16 q9, #0\n"
   10622       "vmov.i16 q10, #0\n"
   10623       "vmov.i16 q11, #0\n"
   10624       "vmov.i16 q12, #0\n"
   10625       "vmov.i16 q13, #0\n"
   10626       "vmov.i16 q14, #0\n"
   10627 
   10628       // Reduce count by leftovers.
   10629       "subs %[count], %[count], #4\n"
   10630       "beq 2f\n"
   10631 
   10632       "1:"
   10633       "subs %[count], %[count], #8\n"
   10634 
   10635       // Load Aggregate Store - column major 7x8
   10636       "vld1.32 {d0[0]}, [%[in]]!\n"
   10637       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10638       "vld1.32 {d1[0]}, [%[in]]!\n"
   10639       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10640       "vld1.32 {d2[0]}, [%[in]]!\n"
   10641       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10642       "vld1.32 {d3[0]}, [%[in]]!\n"
   10643       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10644       "vld1.32 {d0[1]}, [%[in]]!\n"
   10645       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10646       "vld1.32 {d1[1]}, [%[in]]!\n"
   10647       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10648       "vld1.32 {d2[1]}, [%[in]]!\n"
   10649       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10650       "vld1.32 {d3[1]}, [%[in]]!\n"
   10651       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10652       "pld [%[in]]\n"
   10653       "vtrn.16 d0, d2\n"
   10654       "vtrn.16 d1, d3\n"
   10655       "vtrn.8 d0, d1\n"
   10656       "vtrn.8 d2, d3\n"
   10657       "vaddw.u8 q8, q8, d0\n"
   10658       "vaddw.u8 q9, q9, d1\n"
   10659       "vaddw.u8 q10, q10, d2\n"
   10660       "vaddw.u8 q11, q11, d3\n"
   10661       "vaddw.u8 q12, q12, d4\n"
   10662       "vaddw.u8 q13, q13, d5\n"
   10663       "vaddw.u8 q14, q14, d6\n"
   10664       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10665       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10666 
   10667       "bne 1b\n"
   10668 
   10669       "2:"
   10670 
   10671       // Load Aggregate Store - column major 7x4
   10672       "vmov.i8 d0, #0\n"
   10673       "vmov.i8 d1, #0\n"
   10674       "vmov.i8 d2, #0\n"
   10675       "vmov.i8 d3, #0\n"
   10676       "vmov.i8 d4, #0\n"
   10677       "vmov.i8 d5, #0\n"
   10678       "vmov.i8 d6, #0\n"
   10679       "vld1.32 {d0[0]}, [%[in]]!\n"
   10680       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10681       "vld1.32 {d1[0]}, [%[in]]!\n"
   10682       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10683       "vld1.32 {d2[0]}, [%[in]]!\n"
   10684       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10685       "vld1.32 {d3[0]}, [%[in]]!\n"
   10686       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10687       "pld [%[in]]\n"
   10688       "vtrn.16 d0, d2\n"
   10689       "vtrn.16 d1, d3\n"
   10690       "vtrn.8 d0, d1\n"
   10691       "vtrn.8 d2, d3\n"
   10692       "vaddw.u8 q8, q8, d0\n"
   10693       "vaddw.u8 q9, q9, d1\n"
   10694       "vaddw.u8 q10, q10, d2\n"
   10695       "vaddw.u8 q11, q11, d3\n"
   10696       "vaddw.u8 q12, q12, d4\n"
   10697       "vaddw.u8 q13, q13, d5\n"
   10698       "vaddw.u8 q14, q14, d6\n"
   10699       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10700       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10701 
   10702       // Aggregator Reduction.
   10703       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10704       "vdup.32 q1, %[additive_sum_offset]\n"
   10705       "vpaddl.u16 q8, q8\n"
   10706       "vpaddl.u16 q9, q9\n"
   10707       "vpaddl.u16 q10, q10\n"
   10708       "vpaddl.u16 q11, q11\n"
   10709       "vpaddl.u16 q12, q12\n"
   10710       "vpaddl.u16 q13, q13\n"
   10711       "vpaddl.u16 q14, q14\n"
   10712       "vpadd.u32 d16, d16, d17\n"
   10713       "vpadd.u32 d18, d18, d19\n"
   10714       "vpadd.u32 d20, d20, d21\n"
   10715       "vpadd.u32 d22, d22, d23\n"
   10716       "vpadd.u32 d24, d24, d25\n"
   10717       "vpadd.u32 d26, d26, d27\n"
   10718       "vpadd.u32 d28, d28, d29\n"
   10719       "vpadd.u32 d16, d16, d18\n"
   10720       "vpadd.u32 d17, d20, d22\n"
   10721       "vpadd.u32 d18, d24, d26\n"
   10722       "vpadd.u32 d19, d28, d28\n"
   10723       "vmul.i32 q8, q8, d0[0]\n"
   10724       "vmul.i32 q9, q9, d0[0]\n"
   10725       "vadd.i32 q8, q8, q1\n"
   10726       "vadd.i32 q9, q9, q1\n"
   10727       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10728       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10729         [out] "+r"(out), [in] "+r"(in)
   10730       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10731         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10732       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10733         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10734         "cc", "memory");
   10735 }
   10736 
   10737 template <>
   10738 inline void Stream<uint8_t, 7, 8, 5, ColumnMajorWithSum>::Pack(
   10739     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10740 #ifdef DEBUG
   10741 #ifdef DEBUG_METAGEMM_VERBOSE
   10742   std::cout
   10743       << __FILE__ << "(" << __LINE__
   10744       << ") ColumnMajorWithSum<uint8_t, 7, 8, 5, ColumnMajorWithSum>::Pack()"
   10745       << std::endl
   10746       << std::flush;
   10747 #endif
   10748 #endif
   10749   int params_count_copy = params.count;
   10750   int params_stride_copy = params.stride;
   10751   asm volatile(
   10752       "sub %[stride], %[stride], #4\n"
   10753       "vmov.i16 q8, #0\n"
   10754       "vmov.i16 q9, #0\n"
   10755       "vmov.i16 q10, #0\n"
   10756       "vmov.i16 q11, #0\n"
   10757       "vmov.i16 q12, #0\n"
   10758       "vmov.i16 q13, #0\n"
   10759       "vmov.i16 q14, #0\n"
   10760 
   10761       // Reduce count by leftovers.
   10762       "subs %[count], %[count], #5\n"
   10763       "beq 2f\n"
   10764 
   10765       "1:"
   10766       "subs %[count], %[count], #8\n"
   10767 
   10768       // Load Aggregate Store - column major 7x8
   10769       "vld1.32 {d0[0]}, [%[in]]!\n"
   10770       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10771       "vld1.32 {d1[0]}, [%[in]]!\n"
   10772       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10773       "vld1.32 {d2[0]}, [%[in]]!\n"
   10774       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10775       "vld1.32 {d3[0]}, [%[in]]!\n"
   10776       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10777       "vld1.32 {d0[1]}, [%[in]]!\n"
   10778       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10779       "vld1.32 {d1[1]}, [%[in]]!\n"
   10780       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10781       "vld1.32 {d2[1]}, [%[in]]!\n"
   10782       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10783       "vld1.32 {d3[1]}, [%[in]]!\n"
   10784       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10785       "pld [%[in]]\n"
   10786       "vtrn.16 d0, d2\n"
   10787       "vtrn.16 d1, d3\n"
   10788       "vtrn.8 d0, d1\n"
   10789       "vtrn.8 d2, d3\n"
   10790       "vaddw.u8 q8, q8, d0\n"
   10791       "vaddw.u8 q9, q9, d1\n"
   10792       "vaddw.u8 q10, q10, d2\n"
   10793       "vaddw.u8 q11, q11, d3\n"
   10794       "vaddw.u8 q12, q12, d4\n"
   10795       "vaddw.u8 q13, q13, d5\n"
   10796       "vaddw.u8 q14, q14, d6\n"
   10797       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10798       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10799 
   10800       "bne 1b\n"
   10801 
   10802       "2:"
   10803 
   10804       // Load Aggregate Store - column major 7x5
   10805       "vmov.i8 d0, #0\n"
   10806       "vmov.i8 d1, #0\n"
   10807       "vmov.i8 d2, #0\n"
   10808       "vmov.i8 d3, #0\n"
   10809       "vmov.i8 d4, #0\n"
   10810       "vmov.i8 d5, #0\n"
   10811       "vmov.i8 d6, #0\n"
   10812       "vld1.32 {d0[0]}, [%[in]]!\n"
   10813       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10814       "vld1.32 {d1[0]}, [%[in]]!\n"
   10815       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10816       "vld1.32 {d2[0]}, [%[in]]!\n"
   10817       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10818       "vld1.32 {d3[0]}, [%[in]]!\n"
   10819       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10820       "vld1.32 {d0[1]}, [%[in]]!\n"
   10821       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10822       "pld [%[in]]\n"
   10823       "vtrn.16 d0, d2\n"
   10824       "vtrn.16 d1, d3\n"
   10825       "vtrn.8 d0, d1\n"
   10826       "vtrn.8 d2, d3\n"
   10827       "vaddw.u8 q8, q8, d0\n"
   10828       "vaddw.u8 q9, q9, d1\n"
   10829       "vaddw.u8 q10, q10, d2\n"
   10830       "vaddw.u8 q11, q11, d3\n"
   10831       "vaddw.u8 q12, q12, d4\n"
   10832       "vaddw.u8 q13, q13, d5\n"
   10833       "vaddw.u8 q14, q14, d6\n"
   10834       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10835       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10836 
   10837       // Aggregator Reduction.
   10838       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10839       "vdup.32 q1, %[additive_sum_offset]\n"
   10840       "vpaddl.u16 q8, q8\n"
   10841       "vpaddl.u16 q9, q9\n"
   10842       "vpaddl.u16 q10, q10\n"
   10843       "vpaddl.u16 q11, q11\n"
   10844       "vpaddl.u16 q12, q12\n"
   10845       "vpaddl.u16 q13, q13\n"
   10846       "vpaddl.u16 q14, q14\n"
   10847       "vpadd.u32 d16, d16, d17\n"
   10848       "vpadd.u32 d18, d18, d19\n"
   10849       "vpadd.u32 d20, d20, d21\n"
   10850       "vpadd.u32 d22, d22, d23\n"
   10851       "vpadd.u32 d24, d24, d25\n"
   10852       "vpadd.u32 d26, d26, d27\n"
   10853       "vpadd.u32 d28, d28, d29\n"
   10854       "vpadd.u32 d16, d16, d18\n"
   10855       "vpadd.u32 d17, d20, d22\n"
   10856       "vpadd.u32 d18, d24, d26\n"
   10857       "vpadd.u32 d19, d28, d28\n"
   10858       "vmul.i32 q8, q8, d0[0]\n"
   10859       "vmul.i32 q9, q9, d0[0]\n"
   10860       "vadd.i32 q8, q8, q1\n"
   10861       "vadd.i32 q9, q9, q1\n"
   10862       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   10863       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   10864         [out] "+r"(out), [in] "+r"(in)
   10865       : [additive_sum_offset] "r"(params.additive_sum_offset),
   10866         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   10867       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   10868         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   10869         "cc", "memory");
   10870 }
   10871 
   10872 template <>
   10873 inline void Stream<uint8_t, 7, 8, 6, ColumnMajorWithSum>::Pack(
   10874     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   10875 #ifdef DEBUG
   10876 #ifdef DEBUG_METAGEMM_VERBOSE
   10877   std::cout
   10878       << __FILE__ << "(" << __LINE__
   10879       << ") ColumnMajorWithSum<uint8_t, 7, 8, 6, ColumnMajorWithSum>::Pack()"
   10880       << std::endl
   10881       << std::flush;
   10882 #endif
   10883 #endif
   10884   int params_count_copy = params.count;
   10885   int params_stride_copy = params.stride;
   10886   asm volatile(
   10887       "sub %[stride], %[stride], #4\n"
   10888       "vmov.i16 q8, #0\n"
   10889       "vmov.i16 q9, #0\n"
   10890       "vmov.i16 q10, #0\n"
   10891       "vmov.i16 q11, #0\n"
   10892       "vmov.i16 q12, #0\n"
   10893       "vmov.i16 q13, #0\n"
   10894       "vmov.i16 q14, #0\n"
   10895 
   10896       // Reduce count by leftovers.
   10897       "subs %[count], %[count], #6\n"
   10898       "beq 2f\n"
   10899 
   10900       "1:"
   10901       "subs %[count], %[count], #8\n"
   10902 
   10903       // Load Aggregate Store - column major 7x8
   10904       "vld1.32 {d0[0]}, [%[in]]!\n"
   10905       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10906       "vld1.32 {d1[0]}, [%[in]]!\n"
   10907       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10908       "vld1.32 {d2[0]}, [%[in]]!\n"
   10909       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10910       "vld1.32 {d3[0]}, [%[in]]!\n"
   10911       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10912       "vld1.32 {d0[1]}, [%[in]]!\n"
   10913       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10914       "vld1.32 {d1[1]}, [%[in]]!\n"
   10915       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10916       "vld1.32 {d2[1]}, [%[in]]!\n"
   10917       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   10918       "vld1.32 {d3[1]}, [%[in]]!\n"
   10919       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   10920       "pld [%[in]]\n"
   10921       "vtrn.16 d0, d2\n"
   10922       "vtrn.16 d1, d3\n"
   10923       "vtrn.8 d0, d1\n"
   10924       "vtrn.8 d2, d3\n"
   10925       "vaddw.u8 q8, q8, d0\n"
   10926       "vaddw.u8 q9, q9, d1\n"
   10927       "vaddw.u8 q10, q10, d2\n"
   10928       "vaddw.u8 q11, q11, d3\n"
   10929       "vaddw.u8 q12, q12, d4\n"
   10930       "vaddw.u8 q13, q13, d5\n"
   10931       "vaddw.u8 q14, q14, d6\n"
   10932       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10933       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10934 
   10935       "bne 1b\n"
   10936 
   10937       "2:"
   10938 
   10939       // Load Aggregate Store - column major 7x6
   10940       "vmov.i8 d0, #0\n"
   10941       "vmov.i8 d1, #0\n"
   10942       "vmov.i8 d2, #0\n"
   10943       "vmov.i8 d3, #0\n"
   10944       "vmov.i8 d4, #0\n"
   10945       "vmov.i8 d5, #0\n"
   10946       "vmov.i8 d6, #0\n"
   10947       "vld1.32 {d0[0]}, [%[in]]!\n"
   10948       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   10949       "vld1.32 {d1[0]}, [%[in]]!\n"
   10950       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   10951       "vld1.32 {d2[0]}, [%[in]]!\n"
   10952       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   10953       "vld1.32 {d3[0]}, [%[in]]!\n"
   10954       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   10955       "vld1.32 {d0[1]}, [%[in]]!\n"
   10956       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   10957       "vld1.32 {d1[1]}, [%[in]]!\n"
   10958       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   10959       "pld [%[in]]\n"
   10960       "vtrn.16 d0, d2\n"
   10961       "vtrn.16 d1, d3\n"
   10962       "vtrn.8 d0, d1\n"
   10963       "vtrn.8 d2, d3\n"
   10964       "vaddw.u8 q8, q8, d0\n"
   10965       "vaddw.u8 q9, q9, d1\n"
   10966       "vaddw.u8 q10, q10, d2\n"
   10967       "vaddw.u8 q11, q11, d3\n"
   10968       "vaddw.u8 q12, q12, d4\n"
   10969       "vaddw.u8 q13, q13, d5\n"
   10970       "vaddw.u8 q14, q14, d6\n"
   10971       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   10972       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   10973 
   10974       // Aggregator Reduction.
   10975       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   10976       "vdup.32 q1, %[additive_sum_offset]\n"
   10977       "vpaddl.u16 q8, q8\n"
   10978       "vpaddl.u16 q9, q9\n"
   10979       "vpaddl.u16 q10, q10\n"
   10980       "vpaddl.u16 q11, q11\n"
   10981       "vpaddl.u16 q12, q12\n"
   10982       "vpaddl.u16 q13, q13\n"
   10983       "vpaddl.u16 q14, q14\n"
   10984       "vpadd.u32 d16, d16, d17\n"
   10985       "vpadd.u32 d18, d18, d19\n"
   10986       "vpadd.u32 d20, d20, d21\n"
   10987       "vpadd.u32 d22, d22, d23\n"
   10988       "vpadd.u32 d24, d24, d25\n"
   10989       "vpadd.u32 d26, d26, d27\n"
   10990       "vpadd.u32 d28, d28, d29\n"
   10991       "vpadd.u32 d16, d16, d18\n"
   10992       "vpadd.u32 d17, d20, d22\n"
   10993       "vpadd.u32 d18, d24, d26\n"
   10994       "vpadd.u32 d19, d28, d28\n"
   10995       "vmul.i32 q8, q8, d0[0]\n"
   10996       "vmul.i32 q9, q9, d0[0]\n"
   10997       "vadd.i32 q8, q8, q1\n"
   10998       "vadd.i32 q9, q9, q1\n"
   10999       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   11000       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11001         [out] "+r"(out), [in] "+r"(in)
   11002       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11003         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11004       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   11005         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   11006         "cc", "memory");
   11007 }
   11008 
   11009 template <>
   11010 inline void Stream<uint8_t, 7, 8, 7, ColumnMajorWithSum>::Pack(
   11011     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11012 #ifdef DEBUG
   11013 #ifdef DEBUG_METAGEMM_VERBOSE
   11014   std::cout
   11015       << __FILE__ << "(" << __LINE__
   11016       << ") ColumnMajorWithSum<uint8_t, 7, 8, 7, ColumnMajorWithSum>::Pack()"
   11017       << std::endl
   11018       << std::flush;
   11019 #endif
   11020 #endif
   11021   int params_count_copy = params.count;
   11022   int params_stride_copy = params.stride;
   11023   asm volatile(
   11024       "sub %[stride], %[stride], #4\n"
   11025       "vmov.i16 q8, #0\n"
   11026       "vmov.i16 q9, #0\n"
   11027       "vmov.i16 q10, #0\n"
   11028       "vmov.i16 q11, #0\n"
   11029       "vmov.i16 q12, #0\n"
   11030       "vmov.i16 q13, #0\n"
   11031       "vmov.i16 q14, #0\n"
   11032 
   11033       // Reduce count by leftovers.
   11034       "subs %[count], %[count], #7\n"
   11035       "beq 2f\n"
   11036 
   11037       "1:"
   11038       "subs %[count], %[count], #8\n"
   11039 
   11040       // Load Aggregate Store - column major 7x8
   11041       "vld1.32 {d0[0]}, [%[in]]!\n"
   11042       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   11043       "vld1.32 {d1[0]}, [%[in]]!\n"
   11044       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   11045       "vld1.32 {d2[0]}, [%[in]]!\n"
   11046       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   11047       "vld1.32 {d3[0]}, [%[in]]!\n"
   11048       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   11049       "vld1.32 {d0[1]}, [%[in]]!\n"
   11050       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   11051       "vld1.32 {d1[1]}, [%[in]]!\n"
   11052       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   11053       "vld1.32 {d2[1]}, [%[in]]!\n"
   11054       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   11055       "vld1.32 {d3[1]}, [%[in]]!\n"
   11056       "vld3.8 {d4[7], d5[7], d6[7]}, [%[in]], %[stride]\n"
   11057       "pld [%[in]]\n"
   11058       "vtrn.16 d0, d2\n"
   11059       "vtrn.16 d1, d3\n"
   11060       "vtrn.8 d0, d1\n"
   11061       "vtrn.8 d2, d3\n"
   11062       "vaddw.u8 q8, q8, d0\n"
   11063       "vaddw.u8 q9, q9, d1\n"
   11064       "vaddw.u8 q10, q10, d2\n"
   11065       "vaddw.u8 q11, q11, d3\n"
   11066       "vaddw.u8 q12, q12, d4\n"
   11067       "vaddw.u8 q13, q13, d5\n"
   11068       "vaddw.u8 q14, q14, d6\n"
   11069       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   11070       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   11071 
   11072       "bne 1b\n"
   11073 
   11074       "2:"
   11075 
   11076       // Load Aggregate Store - column major 7x7
   11077       "vmov.i8 d0, #0\n"
   11078       "vmov.i8 d1, #0\n"
   11079       "vmov.i8 d2, #0\n"
   11080       "vmov.i8 d3, #0\n"
   11081       "vmov.i8 d4, #0\n"
   11082       "vmov.i8 d5, #0\n"
   11083       "vmov.i8 d6, #0\n"
   11084       "vld1.32 {d0[0]}, [%[in]]!\n"
   11085       "vld3.8 {d4[0], d5[0], d6[0]}, [%[in]], %[stride]\n"
   11086       "vld1.32 {d1[0]}, [%[in]]!\n"
   11087       "vld3.8 {d4[1], d5[1], d6[1]}, [%[in]], %[stride]\n"
   11088       "vld1.32 {d2[0]}, [%[in]]!\n"
   11089       "vld3.8 {d4[2], d5[2], d6[2]}, [%[in]], %[stride]\n"
   11090       "vld1.32 {d3[0]}, [%[in]]!\n"
   11091       "vld3.8 {d4[3], d5[3], d6[3]}, [%[in]], %[stride]\n"
   11092       "vld1.32 {d0[1]}, [%[in]]!\n"
   11093       "vld3.8 {d4[4], d5[4], d6[4]}, [%[in]], %[stride]\n"
   11094       "vld1.32 {d1[1]}, [%[in]]!\n"
   11095       "vld3.8 {d4[5], d5[5], d6[5]}, [%[in]], %[stride]\n"
   11096       "vld1.32 {d2[1]}, [%[in]]!\n"
   11097       "vld3.8 {d4[6], d5[6], d6[6]}, [%[in]], %[stride]\n"
   11098       "pld [%[in]]\n"
   11099       "vtrn.16 d0, d2\n"
   11100       "vtrn.16 d1, d3\n"
   11101       "vtrn.8 d0, d1\n"
   11102       "vtrn.8 d2, d3\n"
   11103       "vaddw.u8 q8, q8, d0\n"
   11104       "vaddw.u8 q9, q9, d1\n"
   11105       "vaddw.u8 q10, q10, d2\n"
   11106       "vaddw.u8 q11, q11, d3\n"
   11107       "vaddw.u8 q12, q12, d4\n"
   11108       "vaddw.u8 q13, q13, d5\n"
   11109       "vaddw.u8 q14, q14, d6\n"
   11110       "vst1.32 {d0, d1, d2, d3}, [%[out]:64]!\n"
   11111       "vst1.32 {d4, d5, d6}, [%[out]:64]!\n"
   11112 
   11113       // Aggregator Reduction.
   11114       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11115       "vdup.32 q1, %[additive_sum_offset]\n"
   11116       "vpaddl.u16 q8, q8\n"
   11117       "vpaddl.u16 q9, q9\n"
   11118       "vpaddl.u16 q10, q10\n"
   11119       "vpaddl.u16 q11, q11\n"
   11120       "vpaddl.u16 q12, q12\n"
   11121       "vpaddl.u16 q13, q13\n"
   11122       "vpaddl.u16 q14, q14\n"
   11123       "vpadd.u32 d16, d16, d17\n"
   11124       "vpadd.u32 d18, d18, d19\n"
   11125       "vpadd.u32 d20, d20, d21\n"
   11126       "vpadd.u32 d22, d22, d23\n"
   11127       "vpadd.u32 d24, d24, d25\n"
   11128       "vpadd.u32 d26, d26, d27\n"
   11129       "vpadd.u32 d28, d28, d29\n"
   11130       "vpadd.u32 d16, d16, d18\n"
   11131       "vpadd.u32 d17, d20, d22\n"
   11132       "vpadd.u32 d18, d24, d26\n"
   11133       "vpadd.u32 d19, d28, d28\n"
   11134       "vmul.i32 q8, q8, d0[0]\n"
   11135       "vmul.i32 q9, q9, d0[0]\n"
   11136       "vadd.i32 q8, q8, q1\n"
   11137       "vadd.i32 q9, q9, q1\n"
   11138       "vst1.32 {d16, d17, d18, d19}, [%[out]:64]\n"
   11139       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11140         [out] "+r"(out), [in] "+r"(in)
   11141       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11142         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11143       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d16", "d17", "d18", "d19",
   11144         "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29",
   11145         "cc", "memory");
   11146 }
   11147 
   11148 template <>
   11149 inline void Stream<uint8_t, 8, 8, 0, ColumnMajorWithSum>::Pack(
   11150     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11151 #ifdef DEBUG
   11152 #ifdef DEBUG_METAGEMM_VERBOSE
   11153   std::cout
   11154       << __FILE__ << "(" << __LINE__
   11155       << ") ColumnMajorWithSum<uint8_t, 8, 8, 0, ColumnMajorWithSum>::Pack()"
   11156       << std::endl
   11157       << std::flush;
   11158 #endif
   11159 #endif
   11160   int params_count_copy = params.count;
   11161   int params_stride_copy = params.stride;
   11162   asm volatile(
   11163       "vmov.i16 q8, #0\n"
   11164       "vmov.i16 q9, #0\n"
   11165       "vmov.i16 q10, #0\n"
   11166       "vmov.i16 q11, #0\n"
   11167       "vmov.i16 q12, #0\n"
   11168       "vmov.i16 q13, #0\n"
   11169       "vmov.i16 q14, #0\n"
   11170       "vmov.i16 q15, #0\n"
   11171 
   11172       "1:"
   11173       "subs %[count], %[count], #8\n"
   11174 
   11175       // Load Aggregate Store - column major 8x8
   11176       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11177       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11178       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11179       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11180       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11181       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11182       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11183       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11184       "pld [%[in]]\n"
   11185       "vtrn.8 d0, d1\n"
   11186       "vtrn.8 d2, d3\n"
   11187       "vtrn.8 d4, d5\n"
   11188       "vtrn.8 d6, d7\n"
   11189       "vtrn.16 d0, d2\n"
   11190       "vtrn.16 d1, d3\n"
   11191       "vtrn.16 d4, d6\n"
   11192       "vtrn.16 d5, d7\n"
   11193       "vtrn.32 d0, d4\n"
   11194       "vtrn.32 d1, d5\n"
   11195       "vtrn.32 d2, d6\n"
   11196       "vtrn.32 d3, d7\n"
   11197       "vaddw.u8 q8, q8, d0\n"
   11198       "vaddw.u8 q9, q9, d1\n"
   11199       "vaddw.u8 q10, q10, d2\n"
   11200       "vaddw.u8 q11, q11, d3\n"
   11201       "vaddw.u8 q12, q12, d4\n"
   11202       "vaddw.u8 q13, q13, d5\n"
   11203       "vaddw.u8 q14, q14, d6\n"
   11204       "vaddw.u8 q15, q15, d7\n"
   11205       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11206       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11207 
   11208       "bne 1b\n"
   11209 
   11210       // Aggregator Reduction.
   11211       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11212       "vdup.32 q1, %[additive_sum_offset]\n"
   11213       "vpaddl.u16 q8, q8\n"
   11214       "vpaddl.u16 q9, q9\n"
   11215       "vpaddl.u16 q10, q10\n"
   11216       "vpaddl.u16 q11, q11\n"
   11217       "vpaddl.u16 q12, q12\n"
   11218       "vpaddl.u16 q13, q13\n"
   11219       "vpaddl.u16 q14, q14\n"
   11220       "vpaddl.u16 q15, q15\n"
   11221       "vpadd.u32 d16, d16, d17\n"
   11222       "vpadd.u32 d18, d18, d19\n"
   11223       "vpadd.u32 d20, d20, d21\n"
   11224       "vpadd.u32 d22, d22, d23\n"
   11225       "vpadd.u32 d24, d24, d25\n"
   11226       "vpadd.u32 d26, d26, d27\n"
   11227       "vpadd.u32 d28, d28, d29\n"
   11228       "vpadd.u32 d30, d30, d31\n"
   11229       "vpadd.u32 d16, d16, d18\n"
   11230       "vpadd.u32 d17, d20, d22\n"
   11231       "vpadd.u32 d18, d24, d26\n"
   11232       "vpadd.u32 d19, d28, d30\n"
   11233       "vmul.i32 q8, q8, d0[0]\n"
   11234       "vmul.i32 q9, q9, d0[0]\n"
   11235       "vadd.i32 q8, q8, q1\n"
   11236       "vadd.i32 q9, q9, q1\n"
   11237       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11238       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11239         [out] "+r"(out), [in] "+r"(in)
   11240       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11241         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11242       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11243         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11244         "d29", "d30", "d31", "cc", "memory");
   11245 }
   11246 
   11247 template <>
   11248 inline void Stream<uint8_t, 8, 8, 1, ColumnMajorWithSum>::Pack(
   11249     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11250 #ifdef DEBUG
   11251 #ifdef DEBUG_METAGEMM_VERBOSE
   11252   std::cout
   11253       << __FILE__ << "(" << __LINE__
   11254       << ") ColumnMajorWithSum<uint8_t, 8, 8, 1, ColumnMajorWithSum>::Pack()"
   11255       << std::endl
   11256       << std::flush;
   11257 #endif
   11258 #endif
   11259   int params_count_copy = params.count;
   11260   int params_stride_copy = params.stride;
   11261   asm volatile(
   11262       "vmov.i16 q8, #0\n"
   11263       "vmov.i16 q9, #0\n"
   11264       "vmov.i16 q10, #0\n"
   11265       "vmov.i16 q11, #0\n"
   11266       "vmov.i16 q12, #0\n"
   11267       "vmov.i16 q13, #0\n"
   11268       "vmov.i16 q14, #0\n"
   11269       "vmov.i16 q15, #0\n"
   11270 
   11271       // Reduce count by leftovers.
   11272       "subs %[count], %[count], #1\n"
   11273       "beq 2f\n"
   11274 
   11275       "1:"
   11276       "subs %[count], %[count], #8\n"
   11277 
   11278       // Load Aggregate Store - column major 8x8
   11279       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11280       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11281       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11282       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11283       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11284       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11285       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11286       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11287       "pld [%[in]]\n"
   11288       "vtrn.8 d0, d1\n"
   11289       "vtrn.8 d2, d3\n"
   11290       "vtrn.8 d4, d5\n"
   11291       "vtrn.8 d6, d7\n"
   11292       "vtrn.16 d0, d2\n"
   11293       "vtrn.16 d1, d3\n"
   11294       "vtrn.16 d4, d6\n"
   11295       "vtrn.16 d5, d7\n"
   11296       "vtrn.32 d0, d4\n"
   11297       "vtrn.32 d1, d5\n"
   11298       "vtrn.32 d2, d6\n"
   11299       "vtrn.32 d3, d7\n"
   11300       "vaddw.u8 q8, q8, d0\n"
   11301       "vaddw.u8 q9, q9, d1\n"
   11302       "vaddw.u8 q10, q10, d2\n"
   11303       "vaddw.u8 q11, q11, d3\n"
   11304       "vaddw.u8 q12, q12, d4\n"
   11305       "vaddw.u8 q13, q13, d5\n"
   11306       "vaddw.u8 q14, q14, d6\n"
   11307       "vaddw.u8 q15, q15, d7\n"
   11308       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11309       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11310 
   11311       "bne 1b\n"
   11312 
   11313       "2:"
   11314 
   11315       // Load Aggregate Store - column major 8x1
   11316       "vmov.i8 d0, #0\n"
   11317       "vmov.i8 d1, #0\n"
   11318       "vmov.i8 d2, #0\n"
   11319       "vmov.i8 d3, #0\n"
   11320       "vmov.i8 d4, #0\n"
   11321       "vmov.i8 d5, #0\n"
   11322       "vmov.i8 d6, #0\n"
   11323       "vmov.i8 d7, #0\n"
   11324       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11325       "pld [%[in]]\n"
   11326       "vtrn.8 d0, d1\n"
   11327       "vtrn.8 d2, d3\n"
   11328       "vtrn.8 d4, d5\n"
   11329       "vtrn.8 d6, d7\n"
   11330       "vtrn.16 d0, d2\n"
   11331       "vtrn.16 d1, d3\n"
   11332       "vtrn.16 d4, d6\n"
   11333       "vtrn.16 d5, d7\n"
   11334       "vtrn.32 d0, d4\n"
   11335       "vtrn.32 d1, d5\n"
   11336       "vtrn.32 d2, d6\n"
   11337       "vtrn.32 d3, d7\n"
   11338       "vaddw.u8 q8, q8, d0\n"
   11339       "vaddw.u8 q9, q9, d1\n"
   11340       "vaddw.u8 q10, q10, d2\n"
   11341       "vaddw.u8 q11, q11, d3\n"
   11342       "vaddw.u8 q12, q12, d4\n"
   11343       "vaddw.u8 q13, q13, d5\n"
   11344       "vaddw.u8 q14, q14, d6\n"
   11345       "vaddw.u8 q15, q15, d7\n"
   11346       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11347       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11348 
   11349       // Aggregator Reduction.
   11350       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11351       "vdup.32 q1, %[additive_sum_offset]\n"
   11352       "vpaddl.u16 q8, q8\n"
   11353       "vpaddl.u16 q9, q9\n"
   11354       "vpaddl.u16 q10, q10\n"
   11355       "vpaddl.u16 q11, q11\n"
   11356       "vpaddl.u16 q12, q12\n"
   11357       "vpaddl.u16 q13, q13\n"
   11358       "vpaddl.u16 q14, q14\n"
   11359       "vpaddl.u16 q15, q15\n"
   11360       "vpadd.u32 d16, d16, d17\n"
   11361       "vpadd.u32 d18, d18, d19\n"
   11362       "vpadd.u32 d20, d20, d21\n"
   11363       "vpadd.u32 d22, d22, d23\n"
   11364       "vpadd.u32 d24, d24, d25\n"
   11365       "vpadd.u32 d26, d26, d27\n"
   11366       "vpadd.u32 d28, d28, d29\n"
   11367       "vpadd.u32 d30, d30, d31\n"
   11368       "vpadd.u32 d16, d16, d18\n"
   11369       "vpadd.u32 d17, d20, d22\n"
   11370       "vpadd.u32 d18, d24, d26\n"
   11371       "vpadd.u32 d19, d28, d30\n"
   11372       "vmul.i32 q8, q8, d0[0]\n"
   11373       "vmul.i32 q9, q9, d0[0]\n"
   11374       "vadd.i32 q8, q8, q1\n"
   11375       "vadd.i32 q9, q9, q1\n"
   11376       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11377       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11378         [out] "+r"(out), [in] "+r"(in)
   11379       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11380         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11381       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11382         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11383         "d29", "d30", "d31", "cc", "memory");
   11384 }
   11385 
   11386 template <>
   11387 inline void Stream<uint8_t, 8, 8, 2, ColumnMajorWithSum>::Pack(
   11388     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11389 #ifdef DEBUG
   11390 #ifdef DEBUG_METAGEMM_VERBOSE
   11391   std::cout
   11392       << __FILE__ << "(" << __LINE__
   11393       << ") ColumnMajorWithSum<uint8_t, 8, 8, 2, ColumnMajorWithSum>::Pack()"
   11394       << std::endl
   11395       << std::flush;
   11396 #endif
   11397 #endif
   11398   int params_count_copy = params.count;
   11399   int params_stride_copy = params.stride;
   11400   asm volatile(
   11401       "vmov.i16 q8, #0\n"
   11402       "vmov.i16 q9, #0\n"
   11403       "vmov.i16 q10, #0\n"
   11404       "vmov.i16 q11, #0\n"
   11405       "vmov.i16 q12, #0\n"
   11406       "vmov.i16 q13, #0\n"
   11407       "vmov.i16 q14, #0\n"
   11408       "vmov.i16 q15, #0\n"
   11409 
   11410       // Reduce count by leftovers.
   11411       "subs %[count], %[count], #2\n"
   11412       "beq 2f\n"
   11413 
   11414       "1:"
   11415       "subs %[count], %[count], #8\n"
   11416 
   11417       // Load Aggregate Store - column major 8x8
   11418       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11419       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11420       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11421       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11422       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11423       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11424       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11425       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11426       "pld [%[in]]\n"
   11427       "vtrn.8 d0, d1\n"
   11428       "vtrn.8 d2, d3\n"
   11429       "vtrn.8 d4, d5\n"
   11430       "vtrn.8 d6, d7\n"
   11431       "vtrn.16 d0, d2\n"
   11432       "vtrn.16 d1, d3\n"
   11433       "vtrn.16 d4, d6\n"
   11434       "vtrn.16 d5, d7\n"
   11435       "vtrn.32 d0, d4\n"
   11436       "vtrn.32 d1, d5\n"
   11437       "vtrn.32 d2, d6\n"
   11438       "vtrn.32 d3, d7\n"
   11439       "vaddw.u8 q8, q8, d0\n"
   11440       "vaddw.u8 q9, q9, d1\n"
   11441       "vaddw.u8 q10, q10, d2\n"
   11442       "vaddw.u8 q11, q11, d3\n"
   11443       "vaddw.u8 q12, q12, d4\n"
   11444       "vaddw.u8 q13, q13, d5\n"
   11445       "vaddw.u8 q14, q14, d6\n"
   11446       "vaddw.u8 q15, q15, d7\n"
   11447       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11448       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11449 
   11450       "bne 1b\n"
   11451 
   11452       "2:"
   11453 
   11454       // Load Aggregate Store - column major 8x2
   11455       "vmov.i8 d0, #0\n"
   11456       "vmov.i8 d1, #0\n"
   11457       "vmov.i8 d2, #0\n"
   11458       "vmov.i8 d3, #0\n"
   11459       "vmov.i8 d4, #0\n"
   11460       "vmov.i8 d5, #0\n"
   11461       "vmov.i8 d6, #0\n"
   11462       "vmov.i8 d7, #0\n"
   11463       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11464       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11465       "pld [%[in]]\n"
   11466       "vtrn.8 d0, d1\n"
   11467       "vtrn.8 d2, d3\n"
   11468       "vtrn.8 d4, d5\n"
   11469       "vtrn.8 d6, d7\n"
   11470       "vtrn.16 d0, d2\n"
   11471       "vtrn.16 d1, d3\n"
   11472       "vtrn.16 d4, d6\n"
   11473       "vtrn.16 d5, d7\n"
   11474       "vtrn.32 d0, d4\n"
   11475       "vtrn.32 d1, d5\n"
   11476       "vtrn.32 d2, d6\n"
   11477       "vtrn.32 d3, d7\n"
   11478       "vaddw.u8 q8, q8, d0\n"
   11479       "vaddw.u8 q9, q9, d1\n"
   11480       "vaddw.u8 q10, q10, d2\n"
   11481       "vaddw.u8 q11, q11, d3\n"
   11482       "vaddw.u8 q12, q12, d4\n"
   11483       "vaddw.u8 q13, q13, d5\n"
   11484       "vaddw.u8 q14, q14, d6\n"
   11485       "vaddw.u8 q15, q15, d7\n"
   11486       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11487       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11488 
   11489       // Aggregator Reduction.
   11490       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11491       "vdup.32 q1, %[additive_sum_offset]\n"
   11492       "vpaddl.u16 q8, q8\n"
   11493       "vpaddl.u16 q9, q9\n"
   11494       "vpaddl.u16 q10, q10\n"
   11495       "vpaddl.u16 q11, q11\n"
   11496       "vpaddl.u16 q12, q12\n"
   11497       "vpaddl.u16 q13, q13\n"
   11498       "vpaddl.u16 q14, q14\n"
   11499       "vpaddl.u16 q15, q15\n"
   11500       "vpadd.u32 d16, d16, d17\n"
   11501       "vpadd.u32 d18, d18, d19\n"
   11502       "vpadd.u32 d20, d20, d21\n"
   11503       "vpadd.u32 d22, d22, d23\n"
   11504       "vpadd.u32 d24, d24, d25\n"
   11505       "vpadd.u32 d26, d26, d27\n"
   11506       "vpadd.u32 d28, d28, d29\n"
   11507       "vpadd.u32 d30, d30, d31\n"
   11508       "vpadd.u32 d16, d16, d18\n"
   11509       "vpadd.u32 d17, d20, d22\n"
   11510       "vpadd.u32 d18, d24, d26\n"
   11511       "vpadd.u32 d19, d28, d30\n"
   11512       "vmul.i32 q8, q8, d0[0]\n"
   11513       "vmul.i32 q9, q9, d0[0]\n"
   11514       "vadd.i32 q8, q8, q1\n"
   11515       "vadd.i32 q9, q9, q1\n"
   11516       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11517       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11518         [out] "+r"(out), [in] "+r"(in)
   11519       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11520         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11521       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11522         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11523         "d29", "d30", "d31", "cc", "memory");
   11524 }
   11525 
   11526 template <>
   11527 inline void Stream<uint8_t, 8, 8, 3, ColumnMajorWithSum>::Pack(
   11528     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11529 #ifdef DEBUG
   11530 #ifdef DEBUG_METAGEMM_VERBOSE
   11531   std::cout
   11532       << __FILE__ << "(" << __LINE__
   11533       << ") ColumnMajorWithSum<uint8_t, 8, 8, 3, ColumnMajorWithSum>::Pack()"
   11534       << std::endl
   11535       << std::flush;
   11536 #endif
   11537 #endif
   11538   int params_count_copy = params.count;
   11539   int params_stride_copy = params.stride;
   11540   asm volatile(
   11541       "vmov.i16 q8, #0\n"
   11542       "vmov.i16 q9, #0\n"
   11543       "vmov.i16 q10, #0\n"
   11544       "vmov.i16 q11, #0\n"
   11545       "vmov.i16 q12, #0\n"
   11546       "vmov.i16 q13, #0\n"
   11547       "vmov.i16 q14, #0\n"
   11548       "vmov.i16 q15, #0\n"
   11549 
   11550       // Reduce count by leftovers.
   11551       "subs %[count], %[count], #3\n"
   11552       "beq 2f\n"
   11553 
   11554       "1:"
   11555       "subs %[count], %[count], #8\n"
   11556 
   11557       // Load Aggregate Store - column major 8x8
   11558       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11559       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11560       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11561       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11562       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11563       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11564       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11565       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11566       "pld [%[in]]\n"
   11567       "vtrn.8 d0, d1\n"
   11568       "vtrn.8 d2, d3\n"
   11569       "vtrn.8 d4, d5\n"
   11570       "vtrn.8 d6, d7\n"
   11571       "vtrn.16 d0, d2\n"
   11572       "vtrn.16 d1, d3\n"
   11573       "vtrn.16 d4, d6\n"
   11574       "vtrn.16 d5, d7\n"
   11575       "vtrn.32 d0, d4\n"
   11576       "vtrn.32 d1, d5\n"
   11577       "vtrn.32 d2, d6\n"
   11578       "vtrn.32 d3, d7\n"
   11579       "vaddw.u8 q8, q8, d0\n"
   11580       "vaddw.u8 q9, q9, d1\n"
   11581       "vaddw.u8 q10, q10, d2\n"
   11582       "vaddw.u8 q11, q11, d3\n"
   11583       "vaddw.u8 q12, q12, d4\n"
   11584       "vaddw.u8 q13, q13, d5\n"
   11585       "vaddw.u8 q14, q14, d6\n"
   11586       "vaddw.u8 q15, q15, d7\n"
   11587       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11588       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11589 
   11590       "bne 1b\n"
   11591 
   11592       "2:"
   11593 
   11594       // Load Aggregate Store - column major 8x3
   11595       "vmov.i8 d0, #0\n"
   11596       "vmov.i8 d1, #0\n"
   11597       "vmov.i8 d2, #0\n"
   11598       "vmov.i8 d3, #0\n"
   11599       "vmov.i8 d4, #0\n"
   11600       "vmov.i8 d5, #0\n"
   11601       "vmov.i8 d6, #0\n"
   11602       "vmov.i8 d7, #0\n"
   11603       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11604       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11605       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11606       "pld [%[in]]\n"
   11607       "vtrn.8 d0, d1\n"
   11608       "vtrn.8 d2, d3\n"
   11609       "vtrn.8 d4, d5\n"
   11610       "vtrn.8 d6, d7\n"
   11611       "vtrn.16 d0, d2\n"
   11612       "vtrn.16 d1, d3\n"
   11613       "vtrn.16 d4, d6\n"
   11614       "vtrn.16 d5, d7\n"
   11615       "vtrn.32 d0, d4\n"
   11616       "vtrn.32 d1, d5\n"
   11617       "vtrn.32 d2, d6\n"
   11618       "vtrn.32 d3, d7\n"
   11619       "vaddw.u8 q8, q8, d0\n"
   11620       "vaddw.u8 q9, q9, d1\n"
   11621       "vaddw.u8 q10, q10, d2\n"
   11622       "vaddw.u8 q11, q11, d3\n"
   11623       "vaddw.u8 q12, q12, d4\n"
   11624       "vaddw.u8 q13, q13, d5\n"
   11625       "vaddw.u8 q14, q14, d6\n"
   11626       "vaddw.u8 q15, q15, d7\n"
   11627       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11628       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11629 
   11630       // Aggregator Reduction.
   11631       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11632       "vdup.32 q1, %[additive_sum_offset]\n"
   11633       "vpaddl.u16 q8, q8\n"
   11634       "vpaddl.u16 q9, q9\n"
   11635       "vpaddl.u16 q10, q10\n"
   11636       "vpaddl.u16 q11, q11\n"
   11637       "vpaddl.u16 q12, q12\n"
   11638       "vpaddl.u16 q13, q13\n"
   11639       "vpaddl.u16 q14, q14\n"
   11640       "vpaddl.u16 q15, q15\n"
   11641       "vpadd.u32 d16, d16, d17\n"
   11642       "vpadd.u32 d18, d18, d19\n"
   11643       "vpadd.u32 d20, d20, d21\n"
   11644       "vpadd.u32 d22, d22, d23\n"
   11645       "vpadd.u32 d24, d24, d25\n"
   11646       "vpadd.u32 d26, d26, d27\n"
   11647       "vpadd.u32 d28, d28, d29\n"
   11648       "vpadd.u32 d30, d30, d31\n"
   11649       "vpadd.u32 d16, d16, d18\n"
   11650       "vpadd.u32 d17, d20, d22\n"
   11651       "vpadd.u32 d18, d24, d26\n"
   11652       "vpadd.u32 d19, d28, d30\n"
   11653       "vmul.i32 q8, q8, d0[0]\n"
   11654       "vmul.i32 q9, q9, d0[0]\n"
   11655       "vadd.i32 q8, q8, q1\n"
   11656       "vadd.i32 q9, q9, q1\n"
   11657       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11658       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11659         [out] "+r"(out), [in] "+r"(in)
   11660       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11661         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11662       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11663         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11664         "d29", "d30", "d31", "cc", "memory");
   11665 }
   11666 
   11667 template <>
   11668 inline void Stream<uint8_t, 8, 8, 4, ColumnMajorWithSum>::Pack(
   11669     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11670 #ifdef DEBUG
   11671 #ifdef DEBUG_METAGEMM_VERBOSE
   11672   std::cout
   11673       << __FILE__ << "(" << __LINE__
   11674       << ") ColumnMajorWithSum<uint8_t, 8, 8, 4, ColumnMajorWithSum>::Pack()"
   11675       << std::endl
   11676       << std::flush;
   11677 #endif
   11678 #endif
   11679   int params_count_copy = params.count;
   11680   int params_stride_copy = params.stride;
   11681   asm volatile(
   11682       "vmov.i16 q8, #0\n"
   11683       "vmov.i16 q9, #0\n"
   11684       "vmov.i16 q10, #0\n"
   11685       "vmov.i16 q11, #0\n"
   11686       "vmov.i16 q12, #0\n"
   11687       "vmov.i16 q13, #0\n"
   11688       "vmov.i16 q14, #0\n"
   11689       "vmov.i16 q15, #0\n"
   11690 
   11691       // Reduce count by leftovers.
   11692       "subs %[count], %[count], #4\n"
   11693       "beq 2f\n"
   11694 
   11695       "1:"
   11696       "subs %[count], %[count], #8\n"
   11697 
   11698       // Load Aggregate Store - column major 8x8
   11699       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11700       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11701       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11702       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11703       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11704       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11705       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11706       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11707       "pld [%[in]]\n"
   11708       "vtrn.8 d0, d1\n"
   11709       "vtrn.8 d2, d3\n"
   11710       "vtrn.8 d4, d5\n"
   11711       "vtrn.8 d6, d7\n"
   11712       "vtrn.16 d0, d2\n"
   11713       "vtrn.16 d1, d3\n"
   11714       "vtrn.16 d4, d6\n"
   11715       "vtrn.16 d5, d7\n"
   11716       "vtrn.32 d0, d4\n"
   11717       "vtrn.32 d1, d5\n"
   11718       "vtrn.32 d2, d6\n"
   11719       "vtrn.32 d3, d7\n"
   11720       "vaddw.u8 q8, q8, d0\n"
   11721       "vaddw.u8 q9, q9, d1\n"
   11722       "vaddw.u8 q10, q10, d2\n"
   11723       "vaddw.u8 q11, q11, d3\n"
   11724       "vaddw.u8 q12, q12, d4\n"
   11725       "vaddw.u8 q13, q13, d5\n"
   11726       "vaddw.u8 q14, q14, d6\n"
   11727       "vaddw.u8 q15, q15, d7\n"
   11728       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11729       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11730 
   11731       "bne 1b\n"
   11732 
   11733       "2:"
   11734 
   11735       // Load Aggregate Store - column major 8x4
   11736       "vmov.i8 d0, #0\n"
   11737       "vmov.i8 d1, #0\n"
   11738       "vmov.i8 d2, #0\n"
   11739       "vmov.i8 d3, #0\n"
   11740       "vmov.i8 d4, #0\n"
   11741       "vmov.i8 d5, #0\n"
   11742       "vmov.i8 d6, #0\n"
   11743       "vmov.i8 d7, #0\n"
   11744       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11745       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11746       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11747       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11748       "pld [%[in]]\n"
   11749       "vtrn.8 d0, d1\n"
   11750       "vtrn.8 d2, d3\n"
   11751       "vtrn.8 d4, d5\n"
   11752       "vtrn.8 d6, d7\n"
   11753       "vtrn.16 d0, d2\n"
   11754       "vtrn.16 d1, d3\n"
   11755       "vtrn.16 d4, d6\n"
   11756       "vtrn.16 d5, d7\n"
   11757       "vtrn.32 d0, d4\n"
   11758       "vtrn.32 d1, d5\n"
   11759       "vtrn.32 d2, d6\n"
   11760       "vtrn.32 d3, d7\n"
   11761       "vaddw.u8 q8, q8, d0\n"
   11762       "vaddw.u8 q9, q9, d1\n"
   11763       "vaddw.u8 q10, q10, d2\n"
   11764       "vaddw.u8 q11, q11, d3\n"
   11765       "vaddw.u8 q12, q12, d4\n"
   11766       "vaddw.u8 q13, q13, d5\n"
   11767       "vaddw.u8 q14, q14, d6\n"
   11768       "vaddw.u8 q15, q15, d7\n"
   11769       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11770       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11771 
   11772       // Aggregator Reduction.
   11773       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11774       "vdup.32 q1, %[additive_sum_offset]\n"
   11775       "vpaddl.u16 q8, q8\n"
   11776       "vpaddl.u16 q9, q9\n"
   11777       "vpaddl.u16 q10, q10\n"
   11778       "vpaddl.u16 q11, q11\n"
   11779       "vpaddl.u16 q12, q12\n"
   11780       "vpaddl.u16 q13, q13\n"
   11781       "vpaddl.u16 q14, q14\n"
   11782       "vpaddl.u16 q15, q15\n"
   11783       "vpadd.u32 d16, d16, d17\n"
   11784       "vpadd.u32 d18, d18, d19\n"
   11785       "vpadd.u32 d20, d20, d21\n"
   11786       "vpadd.u32 d22, d22, d23\n"
   11787       "vpadd.u32 d24, d24, d25\n"
   11788       "vpadd.u32 d26, d26, d27\n"
   11789       "vpadd.u32 d28, d28, d29\n"
   11790       "vpadd.u32 d30, d30, d31\n"
   11791       "vpadd.u32 d16, d16, d18\n"
   11792       "vpadd.u32 d17, d20, d22\n"
   11793       "vpadd.u32 d18, d24, d26\n"
   11794       "vpadd.u32 d19, d28, d30\n"
   11795       "vmul.i32 q8, q8, d0[0]\n"
   11796       "vmul.i32 q9, q9, d0[0]\n"
   11797       "vadd.i32 q8, q8, q1\n"
   11798       "vadd.i32 q9, q9, q1\n"
   11799       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11800       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11801         [out] "+r"(out), [in] "+r"(in)
   11802       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11803         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11804       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11805         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11806         "d29", "d30", "d31", "cc", "memory");
   11807 }
   11808 
   11809 template <>
   11810 inline void Stream<uint8_t, 8, 8, 5, ColumnMajorWithSum>::Pack(
   11811     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11812 #ifdef DEBUG
   11813 #ifdef DEBUG_METAGEMM_VERBOSE
   11814   std::cout
   11815       << __FILE__ << "(" << __LINE__
   11816       << ") ColumnMajorWithSum<uint8_t, 8, 8, 5, ColumnMajorWithSum>::Pack()"
   11817       << std::endl
   11818       << std::flush;
   11819 #endif
   11820 #endif
   11821   int params_count_copy = params.count;
   11822   int params_stride_copy = params.stride;
   11823   asm volatile(
   11824       "vmov.i16 q8, #0\n"
   11825       "vmov.i16 q9, #0\n"
   11826       "vmov.i16 q10, #0\n"
   11827       "vmov.i16 q11, #0\n"
   11828       "vmov.i16 q12, #0\n"
   11829       "vmov.i16 q13, #0\n"
   11830       "vmov.i16 q14, #0\n"
   11831       "vmov.i16 q15, #0\n"
   11832 
   11833       // Reduce count by leftovers.
   11834       "subs %[count], %[count], #5\n"
   11835       "beq 2f\n"
   11836 
   11837       "1:"
   11838       "subs %[count], %[count], #8\n"
   11839 
   11840       // Load Aggregate Store - column major 8x8
   11841       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11842       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11843       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11844       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11845       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11846       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11847       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11848       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11849       "pld [%[in]]\n"
   11850       "vtrn.8 d0, d1\n"
   11851       "vtrn.8 d2, d3\n"
   11852       "vtrn.8 d4, d5\n"
   11853       "vtrn.8 d6, d7\n"
   11854       "vtrn.16 d0, d2\n"
   11855       "vtrn.16 d1, d3\n"
   11856       "vtrn.16 d4, d6\n"
   11857       "vtrn.16 d5, d7\n"
   11858       "vtrn.32 d0, d4\n"
   11859       "vtrn.32 d1, d5\n"
   11860       "vtrn.32 d2, d6\n"
   11861       "vtrn.32 d3, d7\n"
   11862       "vaddw.u8 q8, q8, d0\n"
   11863       "vaddw.u8 q9, q9, d1\n"
   11864       "vaddw.u8 q10, q10, d2\n"
   11865       "vaddw.u8 q11, q11, d3\n"
   11866       "vaddw.u8 q12, q12, d4\n"
   11867       "vaddw.u8 q13, q13, d5\n"
   11868       "vaddw.u8 q14, q14, d6\n"
   11869       "vaddw.u8 q15, q15, d7\n"
   11870       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11871       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11872 
   11873       "bne 1b\n"
   11874 
   11875       "2:"
   11876 
   11877       // Load Aggregate Store - column major 8x5
   11878       "vmov.i8 d0, #0\n"
   11879       "vmov.i8 d1, #0\n"
   11880       "vmov.i8 d2, #0\n"
   11881       "vmov.i8 d3, #0\n"
   11882       "vmov.i8 d4, #0\n"
   11883       "vmov.i8 d5, #0\n"
   11884       "vmov.i8 d6, #0\n"
   11885       "vmov.i8 d7, #0\n"
   11886       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11887       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11888       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11889       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11890       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11891       "pld [%[in]]\n"
   11892       "vtrn.8 d0, d1\n"
   11893       "vtrn.8 d2, d3\n"
   11894       "vtrn.8 d4, d5\n"
   11895       "vtrn.8 d6, d7\n"
   11896       "vtrn.16 d0, d2\n"
   11897       "vtrn.16 d1, d3\n"
   11898       "vtrn.16 d4, d6\n"
   11899       "vtrn.16 d5, d7\n"
   11900       "vtrn.32 d0, d4\n"
   11901       "vtrn.32 d1, d5\n"
   11902       "vtrn.32 d2, d6\n"
   11903       "vtrn.32 d3, d7\n"
   11904       "vaddw.u8 q8, q8, d0\n"
   11905       "vaddw.u8 q9, q9, d1\n"
   11906       "vaddw.u8 q10, q10, d2\n"
   11907       "vaddw.u8 q11, q11, d3\n"
   11908       "vaddw.u8 q12, q12, d4\n"
   11909       "vaddw.u8 q13, q13, d5\n"
   11910       "vaddw.u8 q14, q14, d6\n"
   11911       "vaddw.u8 q15, q15, d7\n"
   11912       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   11913       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   11914 
   11915       // Aggregator Reduction.
   11916       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   11917       "vdup.32 q1, %[additive_sum_offset]\n"
   11918       "vpaddl.u16 q8, q8\n"
   11919       "vpaddl.u16 q9, q9\n"
   11920       "vpaddl.u16 q10, q10\n"
   11921       "vpaddl.u16 q11, q11\n"
   11922       "vpaddl.u16 q12, q12\n"
   11923       "vpaddl.u16 q13, q13\n"
   11924       "vpaddl.u16 q14, q14\n"
   11925       "vpaddl.u16 q15, q15\n"
   11926       "vpadd.u32 d16, d16, d17\n"
   11927       "vpadd.u32 d18, d18, d19\n"
   11928       "vpadd.u32 d20, d20, d21\n"
   11929       "vpadd.u32 d22, d22, d23\n"
   11930       "vpadd.u32 d24, d24, d25\n"
   11931       "vpadd.u32 d26, d26, d27\n"
   11932       "vpadd.u32 d28, d28, d29\n"
   11933       "vpadd.u32 d30, d30, d31\n"
   11934       "vpadd.u32 d16, d16, d18\n"
   11935       "vpadd.u32 d17, d20, d22\n"
   11936       "vpadd.u32 d18, d24, d26\n"
   11937       "vpadd.u32 d19, d28, d30\n"
   11938       "vmul.i32 q8, q8, d0[0]\n"
   11939       "vmul.i32 q9, q9, d0[0]\n"
   11940       "vadd.i32 q8, q8, q1\n"
   11941       "vadd.i32 q9, q9, q1\n"
   11942       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   11943       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   11944         [out] "+r"(out), [in] "+r"(in)
   11945       : [additive_sum_offset] "r"(params.additive_sum_offset),
   11946         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   11947       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   11948         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   11949         "d29", "d30", "d31", "cc", "memory");
   11950 }
   11951 
   11952 template <>
   11953 inline void Stream<uint8_t, 8, 8, 6, ColumnMajorWithSum>::Pack(
   11954     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   11955 #ifdef DEBUG
   11956 #ifdef DEBUG_METAGEMM_VERBOSE
   11957   std::cout
   11958       << __FILE__ << "(" << __LINE__
   11959       << ") ColumnMajorWithSum<uint8_t, 8, 8, 6, ColumnMajorWithSum>::Pack()"
   11960       << std::endl
   11961       << std::flush;
   11962 #endif
   11963 #endif
   11964   int params_count_copy = params.count;
   11965   int params_stride_copy = params.stride;
   11966   asm volatile(
   11967       "vmov.i16 q8, #0\n"
   11968       "vmov.i16 q9, #0\n"
   11969       "vmov.i16 q10, #0\n"
   11970       "vmov.i16 q11, #0\n"
   11971       "vmov.i16 q12, #0\n"
   11972       "vmov.i16 q13, #0\n"
   11973       "vmov.i16 q14, #0\n"
   11974       "vmov.i16 q15, #0\n"
   11975 
   11976       // Reduce count by leftovers.
   11977       "subs %[count], %[count], #6\n"
   11978       "beq 2f\n"
   11979 
   11980       "1:"
   11981       "subs %[count], %[count], #8\n"
   11982 
   11983       // Load Aggregate Store - column major 8x8
   11984       "vld1.32 {d0}, [%[in]], %[stride]\n"
   11985       "vld1.32 {d1}, [%[in]], %[stride]\n"
   11986       "vld1.32 {d2}, [%[in]], %[stride]\n"
   11987       "vld1.32 {d3}, [%[in]], %[stride]\n"
   11988       "vld1.32 {d4}, [%[in]], %[stride]\n"
   11989       "vld1.32 {d5}, [%[in]], %[stride]\n"
   11990       "vld1.32 {d6}, [%[in]], %[stride]\n"
   11991       "vld1.32 {d7}, [%[in]], %[stride]\n"
   11992       "pld [%[in]]\n"
   11993       "vtrn.8 d0, d1\n"
   11994       "vtrn.8 d2, d3\n"
   11995       "vtrn.8 d4, d5\n"
   11996       "vtrn.8 d6, d7\n"
   11997       "vtrn.16 d0, d2\n"
   11998       "vtrn.16 d1, d3\n"
   11999       "vtrn.16 d4, d6\n"
   12000       "vtrn.16 d5, d7\n"
   12001       "vtrn.32 d0, d4\n"
   12002       "vtrn.32 d1, d5\n"
   12003       "vtrn.32 d2, d6\n"
   12004       "vtrn.32 d3, d7\n"
   12005       "vaddw.u8 q8, q8, d0\n"
   12006       "vaddw.u8 q9, q9, d1\n"
   12007       "vaddw.u8 q10, q10, d2\n"
   12008       "vaddw.u8 q11, q11, d3\n"
   12009       "vaddw.u8 q12, q12, d4\n"
   12010       "vaddw.u8 q13, q13, d5\n"
   12011       "vaddw.u8 q14, q14, d6\n"
   12012       "vaddw.u8 q15, q15, d7\n"
   12013       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   12014       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   12015 
   12016       "bne 1b\n"
   12017 
   12018       "2:"
   12019 
   12020       // Load Aggregate Store - column major 8x6
   12021       "vmov.i8 d0, #0\n"
   12022       "vmov.i8 d1, #0\n"
   12023       "vmov.i8 d2, #0\n"
   12024       "vmov.i8 d3, #0\n"
   12025       "vmov.i8 d4, #0\n"
   12026       "vmov.i8 d5, #0\n"
   12027       "vmov.i8 d6, #0\n"
   12028       "vmov.i8 d7, #0\n"
   12029       "vld1.32 {d0}, [%[in]], %[stride]\n"
   12030       "vld1.32 {d1}, [%[in]], %[stride]\n"
   12031       "vld1.32 {d2}, [%[in]], %[stride]\n"
   12032       "vld1.32 {d3}, [%[in]], %[stride]\n"
   12033       "vld1.32 {d4}, [%[in]], %[stride]\n"
   12034       "vld1.32 {d5}, [%[in]], %[stride]\n"
   12035       "pld [%[in]]\n"
   12036       "vtrn.8 d0, d1\n"
   12037       "vtrn.8 d2, d3\n"
   12038       "vtrn.8 d4, d5\n"
   12039       "vtrn.8 d6, d7\n"
   12040       "vtrn.16 d0, d2\n"
   12041       "vtrn.16 d1, d3\n"
   12042       "vtrn.16 d4, d6\n"
   12043       "vtrn.16 d5, d7\n"
   12044       "vtrn.32 d0, d4\n"
   12045       "vtrn.32 d1, d5\n"
   12046       "vtrn.32 d2, d6\n"
   12047       "vtrn.32 d3, d7\n"
   12048       "vaddw.u8 q8, q8, d0\n"
   12049       "vaddw.u8 q9, q9, d1\n"
   12050       "vaddw.u8 q10, q10, d2\n"
   12051       "vaddw.u8 q11, q11, d3\n"
   12052       "vaddw.u8 q12, q12, d4\n"
   12053       "vaddw.u8 q13, q13, d5\n"
   12054       "vaddw.u8 q14, q14, d6\n"
   12055       "vaddw.u8 q15, q15, d7\n"
   12056       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   12057       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   12058 
   12059       // Aggregator Reduction.
   12060       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   12061       "vdup.32 q1, %[additive_sum_offset]\n"
   12062       "vpaddl.u16 q8, q8\n"
   12063       "vpaddl.u16 q9, q9\n"
   12064       "vpaddl.u16 q10, q10\n"
   12065       "vpaddl.u16 q11, q11\n"
   12066       "vpaddl.u16 q12, q12\n"
   12067       "vpaddl.u16 q13, q13\n"
   12068       "vpaddl.u16 q14, q14\n"
   12069       "vpaddl.u16 q15, q15\n"
   12070       "vpadd.u32 d16, d16, d17\n"
   12071       "vpadd.u32 d18, d18, d19\n"
   12072       "vpadd.u32 d20, d20, d21\n"
   12073       "vpadd.u32 d22, d22, d23\n"
   12074       "vpadd.u32 d24, d24, d25\n"
   12075       "vpadd.u32 d26, d26, d27\n"
   12076       "vpadd.u32 d28, d28, d29\n"
   12077       "vpadd.u32 d30, d30, d31\n"
   12078       "vpadd.u32 d16, d16, d18\n"
   12079       "vpadd.u32 d17, d20, d22\n"
   12080       "vpadd.u32 d18, d24, d26\n"
   12081       "vpadd.u32 d19, d28, d30\n"
   12082       "vmul.i32 q8, q8, d0[0]\n"
   12083       "vmul.i32 q9, q9, d0[0]\n"
   12084       "vadd.i32 q8, q8, q1\n"
   12085       "vadd.i32 q9, q9, q1\n"
   12086       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   12087       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   12088         [out] "+r"(out), [in] "+r"(in)
   12089       : [additive_sum_offset] "r"(params.additive_sum_offset),
   12090         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   12091       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   12092         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   12093         "d29", "d30", "d31", "cc", "memory");
   12094 }
   12095 
   12096 template <>
   12097 inline void Stream<uint8_t, 8, 8, 7, ColumnMajorWithSum>::Pack(
   12098     const uint8_t* in, const ColumnMajorWithSum& params, uint8_t* out) {
   12099 #ifdef DEBUG
   12100 #ifdef DEBUG_METAGEMM_VERBOSE
   12101   std::cout
   12102       << __FILE__ << "(" << __LINE__
   12103       << ") ColumnMajorWithSum<uint8_t, 8, 8, 7, ColumnMajorWithSum>::Pack()"
   12104       << std::endl
   12105       << std::flush;
   12106 #endif
   12107 #endif
   12108   int params_count_copy = params.count;
   12109   int params_stride_copy = params.stride;
   12110   asm volatile(
   12111       "vmov.i16 q8, #0\n"
   12112       "vmov.i16 q9, #0\n"
   12113       "vmov.i16 q10, #0\n"
   12114       "vmov.i16 q11, #0\n"
   12115       "vmov.i16 q12, #0\n"
   12116       "vmov.i16 q13, #0\n"
   12117       "vmov.i16 q14, #0\n"
   12118       "vmov.i16 q15, #0\n"
   12119 
   12120       // Reduce count by leftovers.
   12121       "subs %[count], %[count], #7\n"
   12122       "beq 2f\n"
   12123 
   12124       "1:"
   12125       "subs %[count], %[count], #8\n"
   12126 
   12127       // Load Aggregate Store - column major 8x8
   12128       "vld1.32 {d0}, [%[in]], %[stride]\n"
   12129       "vld1.32 {d1}, [%[in]], %[stride]\n"
   12130       "vld1.32 {d2}, [%[in]], %[stride]\n"
   12131       "vld1.32 {d3}, [%[in]], %[stride]\n"
   12132       "vld1.32 {d4}, [%[in]], %[stride]\n"
   12133       "vld1.32 {d5}, [%[in]], %[stride]\n"
   12134       "vld1.32 {d6}, [%[in]], %[stride]\n"
   12135       "vld1.32 {d7}, [%[in]], %[stride]\n"
   12136       "pld [%[in]]\n"
   12137       "vtrn.8 d0, d1\n"
   12138       "vtrn.8 d2, d3\n"
   12139       "vtrn.8 d4, d5\n"
   12140       "vtrn.8 d6, d7\n"
   12141       "vtrn.16 d0, d2\n"
   12142       "vtrn.16 d1, d3\n"
   12143       "vtrn.16 d4, d6\n"
   12144       "vtrn.16 d5, d7\n"
   12145       "vtrn.32 d0, d4\n"
   12146       "vtrn.32 d1, d5\n"
   12147       "vtrn.32 d2, d6\n"
   12148       "vtrn.32 d3, d7\n"
   12149       "vaddw.u8 q8, q8, d0\n"
   12150       "vaddw.u8 q9, q9, d1\n"
   12151       "vaddw.u8 q10, q10, d2\n"
   12152       "vaddw.u8 q11, q11, d3\n"
   12153       "vaddw.u8 q12, q12, d4\n"
   12154       "vaddw.u8 q13, q13, d5\n"
   12155       "vaddw.u8 q14, q14, d6\n"
   12156       "vaddw.u8 q15, q15, d7\n"
   12157       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   12158       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   12159 
   12160       "bne 1b\n"
   12161 
   12162       "2:"
   12163 
   12164       // Load Aggregate Store - column major 8x7
   12165       "vmov.i8 d0, #0\n"
   12166       "vmov.i8 d1, #0\n"
   12167       "vmov.i8 d2, #0\n"
   12168       "vmov.i8 d3, #0\n"
   12169       "vmov.i8 d4, #0\n"
   12170       "vmov.i8 d5, #0\n"
   12171       "vmov.i8 d6, #0\n"
   12172       "vmov.i8 d7, #0\n"
   12173       "vld1.32 {d0}, [%[in]], %[stride]\n"
   12174       "vld1.32 {d1}, [%[in]], %[stride]\n"
   12175       "vld1.32 {d2}, [%[in]], %[stride]\n"
   12176       "vld1.32 {d3}, [%[in]], %[stride]\n"
   12177       "vld1.32 {d4}, [%[in]], %[stride]\n"
   12178       "vld1.32 {d5}, [%[in]], %[stride]\n"
   12179       "vld1.32 {d6}, [%[in]], %[stride]\n"
   12180       "pld [%[in]]\n"
   12181       "vtrn.8 d0, d1\n"
   12182       "vtrn.8 d2, d3\n"
   12183       "vtrn.8 d4, d5\n"
   12184       "vtrn.8 d6, d7\n"
   12185       "vtrn.16 d0, d2\n"
   12186       "vtrn.16 d1, d3\n"
   12187       "vtrn.16 d4, d6\n"
   12188       "vtrn.16 d5, d7\n"
   12189       "vtrn.32 d0, d4\n"
   12190       "vtrn.32 d1, d5\n"
   12191       "vtrn.32 d2, d6\n"
   12192       "vtrn.32 d3, d7\n"
   12193       "vaddw.u8 q8, q8, d0\n"
   12194       "vaddw.u8 q9, q9, d1\n"
   12195       "vaddw.u8 q10, q10, d2\n"
   12196       "vaddw.u8 q11, q11, d3\n"
   12197       "vaddw.u8 q12, q12, d4\n"
   12198       "vaddw.u8 q13, q13, d5\n"
   12199       "vaddw.u8 q14, q14, d6\n"
   12200       "vaddw.u8 q15, q15, d7\n"
   12201       "vst1.32 {d0, d1, d2, d3}, [%[out]:256]!\n"
   12202       "vst1.32 {d4, d5, d6, d7}, [%[out]:256]!\n"
   12203 
   12204       // Aggregator Reduction.
   12205       "vmov.32 d0[0], %[multiplicative_sum_offset]\n"
   12206       "vdup.32 q1, %[additive_sum_offset]\n"
   12207       "vpaddl.u16 q8, q8\n"
   12208       "vpaddl.u16 q9, q9\n"
   12209       "vpaddl.u16 q10, q10\n"
   12210       "vpaddl.u16 q11, q11\n"
   12211       "vpaddl.u16 q12, q12\n"
   12212       "vpaddl.u16 q13, q13\n"
   12213       "vpaddl.u16 q14, q14\n"
   12214       "vpaddl.u16 q15, q15\n"
   12215       "vpadd.u32 d16, d16, d17\n"
   12216       "vpadd.u32 d18, d18, d19\n"
   12217       "vpadd.u32 d20, d20, d21\n"
   12218       "vpadd.u32 d22, d22, d23\n"
   12219       "vpadd.u32 d24, d24, d25\n"
   12220       "vpadd.u32 d26, d26, d27\n"
   12221       "vpadd.u32 d28, d28, d29\n"
   12222       "vpadd.u32 d30, d30, d31\n"
   12223       "vpadd.u32 d16, d16, d18\n"
   12224       "vpadd.u32 d17, d20, d22\n"
   12225       "vpadd.u32 d18, d24, d26\n"
   12226       "vpadd.u32 d19, d28, d30\n"
   12227       "vmul.i32 q8, q8, d0[0]\n"
   12228       "vmul.i32 q9, q9, d0[0]\n"
   12229       "vadd.i32 q8, q8, q1\n"
   12230       "vadd.i32 q9, q9, q1\n"
   12231       "vst1.32 {d16, d17, d18, d19}, [%[out]:256]\n"
   12232       : [count] "+r"(params_count_copy), [stride] "+r"(params_stride_copy),
   12233         [out] "+r"(out), [in] "+r"(in)
   12234       : [additive_sum_offset] "r"(params.additive_sum_offset),
   12235         [multiplicative_sum_offset] "r"(params.multiplicative_sum_offset)
   12236       : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18",
   12237         "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28",
   12238         "d29", "d30", "d31", "cc", "memory");
   12239 }
   12240 
   12241 }  // namespace meta
   12242 }  // namespace gemmlowp
   12243 
   12244 #else
   12245 #warning "Meta gemm for arm32 requires: GEMMLOWP_NEON_32!"
   12246 #endif
   12247 
   12248 #endif  // GEMMLOWP_META_STREAMS_ARM_32_H_
   12249