• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const RowMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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 <>
Pack(const uint8_t * in,const ColumnMajorWithSum & params,uint8_t * out)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