KleidiAI Coverage Report


Directory: ./
File: kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi8cxp/kai_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod.c
Date: 2025-10-20 13:18:31
Coverage Exec Excl Total
Lines: 97.8% 45 5 51
Functions: 100.0% 14 0 14
Branches: 50.0% 1 10 12

Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 //
4 // SPDX-License-Identifier: Apache-2.0
5 //
6
7 // Do not flag up inline assembly blocks
8 #pragma GCC diagnostic ignored "-Woverlength-strings"
9
10 #if !defined(__aarch64__) && !defined(__ARM_FEATURE_DOTPROD)
11 #error "Dotprod extension required to compile this micro-kernel"
12 #else // Architectural features check.
13
14 #include "kai_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod.h"
15
16 #include <stddef.h>
17 #include <stdint.h>
18
19 #include "kai/kai_common.h"
20
21 // Compute args
22 static const size_t kai_m_step = 16;
23 static const size_t kai_n_step = 4;
24 // Packing args
25 static const size_t kai_mr = 4;
26 static const size_t kai_nr = 4;
27 static const size_t kai_kr = 4;
28 static const size_t kai_sr = 1;
29 // LHS format args (num. bytes per value, multiplier, zero_point (if asymmetric))
30 static const size_t kai_num_bytes_qvalue_lhs = 1;
31 static const size_t kai_num_bytes_multiplier_lhs = 4;
32 static const size_t kai_num_bytes_zp_lhs = 4;
33 // RHS format args (num. bytes per value, multiplier, zero_point (if asymmetric), and reduction sum (if LHS is
34 // asymmetric))
35 static const size_t kai_num_bytes_qvalue_rhs = 1;
36 static const size_t kai_num_bytes_multiplier_rhs = 4;
37 static const size_t kai_num_bytes_rsum_rhs = 4;
38 // DST format args
39 static const size_t kai_num_bytes_dst_value = 4;
40 // Extra args
41 static const size_t kai_num_bytes_bias = 4;
42 static const size_t kai_k_multiple_of = 32;
43
44 617 inline static size_t kai_k_roundedup(size_t k) {
45 617 return kai_roundup(k, kai_k_multiple_of);
46 }
47
48 231 inline static size_t kai_lhs_packed_stride(size_t k) {
49 231 const size_t k_internal = kai_k_roundedup(k);
50 231 size_t lhs_packed_stride = kai_mr * ((k_internal * kai_num_bytes_qvalue_lhs) + kai_num_bytes_multiplier_lhs);
51 // Since the LHS matrix is asymmetric with per-row quantization, we must include the
52 // the number of bytes to hold the zero point value
53 231 lhs_packed_stride += kai_mr * kai_num_bytes_zp_lhs;
54
55 462 return lhs_packed_stride;
56 231 }
57
58 231 inline static size_t kai_rhs_packed_stride(size_t k) {
59 231 const size_t k_internal = kai_k_roundedup(k);
60 231 size_t rhs_packed_stride = kai_nr * (k_internal * kai_num_bytes_qvalue_rhs);
61 231 rhs_packed_stride += kai_nr * kai_num_bytes_multiplier_rhs;
62 // Since the LHS matrix is quantized asymmetric with per-row quantization, we also include
63 // the number of bytes for the reduction sum
64 231 rhs_packed_stride += kai_nr * kai_num_bytes_rsum_rhs;
65 // Since the bias is packed with the RHS matrix, the stride is adjusted with the number of bytes of the bias
66 231 rhs_packed_stride += kai_nr * kai_num_bytes_bias;
67
68 462 return rhs_packed_stride;
69 231 }
70
71 231 size_t kai_get_m_step_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
72 231 return kai_m_step;
73 }
74
75 231 size_t kai_get_n_step_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
76 231 return kai_n_step;
77 }
78
79 231 size_t kai_get_mr_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
80 231 return kai_mr;
81 }
82
83 231 size_t kai_get_nr_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
84 231 return kai_nr;
85 }
86
87 308 size_t kai_get_kr_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
88 308 return kai_kr;
89 }
90
91 308 size_t kai_get_sr_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(void) {
92 308 return kai_sr;
93 }
94
95 231 size_t kai_get_lhs_packed_offset_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(size_t m_idx, size_t k) {
96 KAI_ASSUME((m_idx % kai_m_step) == 0);
97
98 231 return (m_idx / kai_mr) * kai_lhs_packed_stride(k);
99 }
100
101 231 size_t kai_get_rhs_packed_offset_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(size_t n_idx, size_t k) {
102 KAI_ASSUME((n_idx % kai_n_step) == 0);
103
104 231 return (n_idx / kai_nr) * kai_rhs_packed_stride(k);
105 }
106
107 154 size_t kai_get_dst_offset_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(
108 size_t m_idx, size_t n_idx, size_t dst_stride) {
109 KAI_ASSUME((m_idx % kai_m_step) == 0);
110 KAI_ASSUME((n_idx % kai_n_step) == 0);
111
112 154 return (n_idx * kai_num_bytes_dst_value) + m_idx * dst_stride;
113 }
114
115 154 size_t kai_get_dst_size_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(size_t m, size_t n) {
116 154 return m * n * kai_num_bytes_dst_value;
117 }
118
119 155 void kai_run_matmul_clamp_f32_qai8dxp4x4_qsi8cxp4x4_16x4_neon_dotprod(
120 size_t m, //
121 size_t n, //
122 size_t k, //
123 const void* restrict lhs_packed, //
124 const void* restrict rhs_packed, //
125 float* restrict dst, // NOLINT(readability-non-const-parameter)
126 size_t dst_stride_row, //
127 size_t dst_stride_col, //
128 float scalar_min, //
129 float scalar_max) {
130 KAI_ASSUME(dst_stride_col == sizeof(float));
131
132
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
155 if (m == 0) {
133 return;
134 }
135
136 155 const size_t k_internal = kai_k_roundedup(k);
137 155 const size_t num_blocks = k_internal / kai_k_multiple_of;
138 155 const float clamp_vals[2] = {scalar_min, scalar_max};
139
140 310 __asm__ __volatile__(
141 "mov x13, %x[m]\n"
142 "mov x12, #0x80\n"
143 "mov x20, #0x20\n"
144 "cmp x13, #0x10\n"
145 "madd x12, %x[num_blocks], x12, x20\n"
146 "blt 14f\n"
147 "1:" // Row loop
148 "mov x11, %x[rhs_packed]\n"
149 "mov x10, %x[n]\n"
150 "add x9, %x[dst], %x[dst_stride_row], LSL #4\n"
151 "2:" // Column loop
152 "mov x27, %x[lhs_packed]\n"
153 "movi v31.4s, #0x0\n"
154 "movi v30.4s, #0x0\n"
155 "mov x23, %x[num_blocks]\n"
156 "movi v29.4s, #0x0\n"
157 "movi v28.4s, #0x0\n"
158 "movi v27.4s, #0x0\n"
159 "movi v26.4s, #0x0\n"
160 "add x22, x27, x12\n"
161 "add x21, x22, x12\n"
162 "add x20, x21, x12\n"
163 "movi v25.4s, #0x0\n"
164 "movi v24.4s, #0x0\n"
165 "movi v23.4s, #0x0\n"
166 "movi v22.4s, #0x0\n"
167 "movi v21.4s, #0x0\n"
168 "movi v20.4s, #0x0\n"
169 "movi v19.4s, #0x0\n"
170 "movi v18.4s, #0x0\n"
171 "movi v17.4s, #0x0\n"
172 "movi v16.4s, #0x0\n"
173 "3:" // Sub block loop
174 "ldr q15, [x11, #0x0]\n"
175 "ldr q7, [x27, #0x0]\n"
176 "subs x23, x23, #0x1\n"
177 "ldr q5, [x22, #0x0]\n"
178 "ldr q6, [x21, #0x0]\n"
179 "ldr q4, [x20, #0x0]\n"
180 "ldr q14, [x11, #0x10]\n"
181 "ldr q3, [x27, #0x10]\n"
182 "ldr q2, [x22, #0x10]\n"
183 ".inst 0x4f87e1ff // sdot v31.4s, v15.16b, v7.4b[0]\n"
184 ".inst 0x4fa7e1fe // sdot v30.4s, v15.16b, v7.4b[1]\n"
185 "ldr q1, [x21, #0x10]\n"
186 "ldr q0, [x20, #0x10]\n"
187 ".inst 0x4f87e9fd // sdot v29.4s, v15.16b, v7.4b[2]\n"
188 ".inst 0x4fa7e9fc // sdot v28.4s, v15.16b, v7.4b[3]\n"
189 "ldr q10, [x11, #0x20]\n"
190 "ldr q13, [x27, #0x20]\n"
191 ".inst 0x4f85e1fb // sdot v27.4s, v15.16b, v5.4b[0]\n"
192 ".inst 0x4fa5e1fa // sdot v26.4s, v15.16b, v5.4b[1]\n"
193 "ldr q12, [x22, #0x20]\n"
194 "ldr q11, [x21, #0x20]\n"
195 ".inst 0x4f85e9f9 // sdot v25.4s, v15.16b, v5.4b[2]\n"
196 ".inst 0x4fa5e9f8 // sdot v24.4s, v15.16b, v5.4b[3]\n"
197 "ldr q9, [x20, #0x20]\n"
198 "ldr q5, [x11, #0x30]\n"
199 ".inst 0x4f86e1f7 // sdot v23.4s, v15.16b, v6.4b[0]\n"
200 ".inst 0x4fa6e1f6 // sdot v22.4s, v15.16b, v6.4b[1]\n"
201 "ldr q8, [x27, #0x30]\n"
202 "ldr q7, [x22, #0x30]\n"
203 ".inst 0x4f86e9f5 // sdot v21.4s, v15.16b, v6.4b[2]\n"
204 ".inst 0x4fa6e9f4 // sdot v20.4s, v15.16b, v6.4b[3]\n"
205 "ldr q6, [x21, #0x30]\n"
206 ".inst 0x4f84e1f3 // sdot v19.4s, v15.16b, v4.4b[0]\n"
207 ".inst 0x4fa4e1f2 // sdot v18.4s, v15.16b, v4.4b[1]\n"
208 ".inst 0x4f84e9f1 // sdot v17.4s, v15.16b, v4.4b[2]\n"
209 ".inst 0x4fa4e9f0 // sdot v16.4s, v15.16b, v4.4b[3]\n"
210 "ldr q4, [x20, #0x30]\n"
211 "ldr q15, [x11, #0x40]\n"
212 ".inst 0x4f83e1df // sdot v31.4s, v14.16b, v3.4b[0]\n"
213 ".inst 0x4fa3e1de // sdot v30.4s, v14.16b, v3.4b[1]\n"
214 ".inst 0x4f83e9dd // sdot v29.4s, v14.16b, v3.4b[2]\n"
215 ".inst 0x4fa3e9dc // sdot v28.4s, v14.16b, v3.4b[3]\n"
216 "ldr q3, [x27, #0x40]\n"
217 ".inst 0x4f82e1db // sdot v27.4s, v14.16b, v2.4b[0]\n"
218 ".inst 0x4fa2e1da // sdot v26.4s, v14.16b, v2.4b[1]\n"
219 ".inst 0x4f82e9d9 // sdot v25.4s, v14.16b, v2.4b[2]\n"
220 ".inst 0x4fa2e9d8 // sdot v24.4s, v14.16b, v2.4b[3]\n"
221 "ldr q2, [x22, #0x40]\n"
222 ".inst 0x4f81e1d7 // sdot v23.4s, v14.16b, v1.4b[0]\n"
223 ".inst 0x4fa1e1d6 // sdot v22.4s, v14.16b, v1.4b[1]\n"
224 ".inst 0x4f81e9d5 // sdot v21.4s, v14.16b, v1.4b[2]\n"
225 ".inst 0x4fa1e9d4 // sdot v20.4s, v14.16b, v1.4b[3]\n"
226 "ldr q1, [x21, #0x40]\n"
227 ".inst 0x4f80e1d3 // sdot v19.4s, v14.16b, v0.4b[0]\n"
228 ".inst 0x4fa0e1d2 // sdot v18.4s, v14.16b, v0.4b[1]\n"
229 ".inst 0x4f80e9d1 // sdot v17.4s, v14.16b, v0.4b[2]\n"
230 ".inst 0x4fa0e9d0 // sdot v16.4s, v14.16b, v0.4b[3]\n"
231 "ldr q0, [x20, #0x40]\n"
232 "ldr q14, [x11, #0x50]\n"
233 ".inst 0x4f8de15f // sdot v31.4s, v10.16b, v13.4b[0]\n"
234 ".inst 0x4fade15e // sdot v30.4s, v10.16b, v13.4b[1]\n"
235 ".inst 0x4f8de95d // sdot v29.4s, v10.16b, v13.4b[2]\n"
236 ".inst 0x4fade95c // sdot v28.4s, v10.16b, v13.4b[3]\n"
237 "ldr q13, [x27, #0x50]\n"
238 ".inst 0x4f8ce15b // sdot v27.4s, v10.16b, v12.4b[0]\n"
239 ".inst 0x4face15a // sdot v26.4s, v10.16b, v12.4b[1]\n"
240 ".inst 0x4f8ce959 // sdot v25.4s, v10.16b, v12.4b[2]\n"
241 ".inst 0x4face958 // sdot v24.4s, v10.16b, v12.4b[3]\n"
242 "ldr q12, [x22, #0x50]\n"
243 ".inst 0x4f8be157 // sdot v23.4s, v10.16b, v11.4b[0]\n"
244 ".inst 0x4fabe156 // sdot v22.4s, v10.16b, v11.4b[1]\n"
245 ".inst 0x4f8be955 // sdot v21.4s, v10.16b, v11.4b[2]\n"
246 ".inst 0x4fabe954 // sdot v20.4s, v10.16b, v11.4b[3]\n"
247 "ldr q11, [x21, #0x50]\n"
248 ".inst 0x4f89e153 // sdot v19.4s, v10.16b, v9.4b[0]\n"
249 ".inst 0x4fa9e152 // sdot v18.4s, v10.16b, v9.4b[1]\n"
250 ".inst 0x4f89e951 // sdot v17.4s, v10.16b, v9.4b[2]\n"
251 ".inst 0x4fa9e950 // sdot v16.4s, v10.16b, v9.4b[3]\n"
252 "ldr q10, [x20, #0x50]\n"
253 "ldr q9, [x11, #0x60]\n"
254 ".inst 0x4f88e0bf // sdot v31.4s, v5.16b, v8.4b[0]\n"
255 ".inst 0x4fa8e0be // sdot v30.4s, v5.16b, v8.4b[1]\n"
256 ".inst 0x4f88e8bd // sdot v29.4s, v5.16b, v8.4b[2]\n"
257 ".inst 0x4fa8e8bc // sdot v28.4s, v5.16b, v8.4b[3]\n"
258 "ldr q8, [x27, #0x60]\n"
259 ".inst 0x4f87e0bb // sdot v27.4s, v5.16b, v7.4b[0]\n"
260 ".inst 0x4fa7e0ba // sdot v26.4s, v5.16b, v7.4b[1]\n"
261 ".inst 0x4f87e8b9 // sdot v25.4s, v5.16b, v7.4b[2]\n"
262 ".inst 0x4fa7e8b8 // sdot v24.4s, v5.16b, v7.4b[3]\n"
263 "ldr q7, [x22, #0x60]\n"
264 ".inst 0x4f86e0b7 // sdot v23.4s, v5.16b, v6.4b[0]\n"
265 ".inst 0x4fa6e0b6 // sdot v22.4s, v5.16b, v6.4b[1]\n"
266 ".inst 0x4f86e8b5 // sdot v21.4s, v5.16b, v6.4b[2]\n"
267 ".inst 0x4fa6e8b4 // sdot v20.4s, v5.16b, v6.4b[3]\n"
268 "ldr q6, [x21, #0x60]\n"
269 ".inst 0x4f84e0b3 // sdot v19.4s, v5.16b, v4.4b[0]\n"
270 ".inst 0x4fa4e0b2 // sdot v18.4s, v5.16b, v4.4b[1]\n"
271 ".inst 0x4f84e8b1 // sdot v17.4s, v5.16b, v4.4b[2]\n"
272 ".inst 0x4fa4e8b0 // sdot v16.4s, v5.16b, v4.4b[3]\n"
273 "ldr q5, [x20, #0x60]\n"
274 "ldr q4, [x11, #0x70]\n"
275 ".inst 0x4f83e1ff // sdot v31.4s, v15.16b, v3.4b[0]\n"
276 ".inst 0x4fa3e1fe // sdot v30.4s, v15.16b, v3.4b[1]\n"
277 "add x11, x11, #0x80\n"
278 ".inst 0x4f83e9fd // sdot v29.4s, v15.16b, v3.4b[2]\n"
279 ".inst 0x4fa3e9fc // sdot v28.4s, v15.16b, v3.4b[3]\n"
280 "ldr q3, [x27, #0x70]\n"
281 "add x27, x27, #0x80\n"
282 ".inst 0x4f82e1fb // sdot v27.4s, v15.16b, v2.4b[0]\n"
283 ".inst 0x4fa2e1fa // sdot v26.4s, v15.16b, v2.4b[1]\n"
284 ".inst 0x4f82e9f9 // sdot v25.4s, v15.16b, v2.4b[2]\n"
285 ".inst 0x4fa2e9f8 // sdot v24.4s, v15.16b, v2.4b[3]\n"
286 "ldr q2, [x22, #0x70]\n"
287 "add x22, x22, #0x80\n"
288 ".inst 0x4f81e1f7 // sdot v23.4s, v15.16b, v1.4b[0]\n"
289 ".inst 0x4fa1e1f6 // sdot v22.4s, v15.16b, v1.4b[1]\n"
290 ".inst 0x4f81e9f5 // sdot v21.4s, v15.16b, v1.4b[2]\n"
291 ".inst 0x4fa1e9f4 // sdot v20.4s, v15.16b, v1.4b[3]\n"
292 "ldr q1, [x21, #0x70]\n"
293 "add x21, x21, #0x80\n"
294 ".inst 0x4f80e1f3 // sdot v19.4s, v15.16b, v0.4b[0]\n"
295 ".inst 0x4fa0e1f2 // sdot v18.4s, v15.16b, v0.4b[1]\n"
296 ".inst 0x4f80e9f1 // sdot v17.4s, v15.16b, v0.4b[2]\n"
297 ".inst 0x4fa0e9f0 // sdot v16.4s, v15.16b, v0.4b[3]\n"
298 "ldr q0, [x20, #0x70]\n"
299 "add x20, x20, #0x80\n"
300 ".inst 0x4f8de1df // sdot v31.4s, v14.16b, v13.4b[0]\n"
301 ".inst 0x4fade1de // sdot v30.4s, v14.16b, v13.4b[1]\n"
302 ".inst 0x4f8de9dd // sdot v29.4s, v14.16b, v13.4b[2]\n"
303 ".inst 0x4fade9dc // sdot v28.4s, v14.16b, v13.4b[3]\n"
304 ".inst 0x4f8ce1db // sdot v27.4s, v14.16b, v12.4b[0]\n"
305 ".inst 0x4face1da // sdot v26.4s, v14.16b, v12.4b[1]\n"
306 ".inst 0x4f8ce9d9 // sdot v25.4s, v14.16b, v12.4b[2]\n"
307 ".inst 0x4face9d8 // sdot v24.4s, v14.16b, v12.4b[3]\n"
308 ".inst 0x4f8be1d7 // sdot v23.4s, v14.16b, v11.4b[0]\n"
309 ".inst 0x4fabe1d6 // sdot v22.4s, v14.16b, v11.4b[1]\n"
310 ".inst 0x4f8be9d5 // sdot v21.4s, v14.16b, v11.4b[2]\n"
311 ".inst 0x4fabe9d4 // sdot v20.4s, v14.16b, v11.4b[3]\n"
312 ".inst 0x4f8ae1d3 // sdot v19.4s, v14.16b, v10.4b[0]\n"
313 ".inst 0x4faae1d2 // sdot v18.4s, v14.16b, v10.4b[1]\n"
314 ".inst 0x4f8ae9d1 // sdot v17.4s, v14.16b, v10.4b[2]\n"
315 ".inst 0x4faae9d0 // sdot v16.4s, v14.16b, v10.4b[3]\n"
316 ".inst 0x4f88e13f // sdot v31.4s, v9.16b, v8.4b[0]\n"
317 ".inst 0x4fa8e13e // sdot v30.4s, v9.16b, v8.4b[1]\n"
318 ".inst 0x4f88e93d // sdot v29.4s, v9.16b, v8.4b[2]\n"
319 ".inst 0x4fa8e93c // sdot v28.4s, v9.16b, v8.4b[3]\n"
320 ".inst 0x4f87e13b // sdot v27.4s, v9.16b, v7.4b[0]\n"
321 ".inst 0x4fa7e13a // sdot v26.4s, v9.16b, v7.4b[1]\n"
322 ".inst 0x4f87e939 // sdot v25.4s, v9.16b, v7.4b[2]\n"
323 ".inst 0x4fa7e938 // sdot v24.4s, v9.16b, v7.4b[3]\n"
324 ".inst 0x4f86e137 // sdot v23.4s, v9.16b, v6.4b[0]\n"
325 ".inst 0x4fa6e136 // sdot v22.4s, v9.16b, v6.4b[1]\n"
326 ".inst 0x4f86e935 // sdot v21.4s, v9.16b, v6.4b[2]\n"
327 ".inst 0x4fa6e934 // sdot v20.4s, v9.16b, v6.4b[3]\n"
328 ".inst 0x4f85e133 // sdot v19.4s, v9.16b, v5.4b[0]\n"
329 ".inst 0x4fa5e132 // sdot v18.4s, v9.16b, v5.4b[1]\n"
330 ".inst 0x4f85e931 // sdot v17.4s, v9.16b, v5.4b[2]\n"
331 ".inst 0x4fa5e930 // sdot v16.4s, v9.16b, v5.4b[3]\n"
332 ".inst 0x4f83e09f // sdot v31.4s, v4.16b, v3.4b[0]\n"
333 ".inst 0x4fa3e09e // sdot v30.4s, v4.16b, v3.4b[1]\n"
334 ".inst 0x4f83e89d // sdot v29.4s, v4.16b, v3.4b[2]\n"
335 ".inst 0x4fa3e89c // sdot v28.4s, v4.16b, v3.4b[3]\n"
336 ".inst 0x4f82e09b // sdot v27.4s, v4.16b, v2.4b[0]\n"
337 ".inst 0x4fa2e09a // sdot v26.4s, v4.16b, v2.4b[1]\n"
338 ".inst 0x4f82e899 // sdot v25.4s, v4.16b, v2.4b[2]\n"
339 ".inst 0x4fa2e898 // sdot v24.4s, v4.16b, v2.4b[3]\n"
340 ".inst 0x4f81e097 // sdot v23.4s, v4.16b, v1.4b[0]\n"
341 ".inst 0x4fa1e096 // sdot v22.4s, v4.16b, v1.4b[1]\n"
342 ".inst 0x4f81e895 // sdot v21.4s, v4.16b, v1.4b[2]\n"
343 ".inst 0x4fa1e894 // sdot v20.4s, v4.16b, v1.4b[3]\n"
344 ".inst 0x4f80e093 // sdot v19.4s, v4.16b, v0.4b[0]\n"
345 ".inst 0x4fa0e092 // sdot v18.4s, v4.16b, v0.4b[1]\n"
346 ".inst 0x4f80e891 // sdot v17.4s, v4.16b, v0.4b[2]\n"
347 ".inst 0x4fa0e890 // sdot v16.4s, v4.16b, v0.4b[3]\n"
348 "bgt 3b\n"
349 "ldr q5, [x11, #0x0]\n"
350 "ld1 { v1.4s }, [x27]\n"
351 "add x27, x27, #0x10\n"
352 "ldr q4, [x11, #0x10]\n"
353 "ldr q0, [x27, #0x0]\n"
354 "add x11, x11, #0x20\n"
355 "mla v31.4s, v5.4s, v1.s[0]\n"
356 "mla v30.4s, v5.4s, v1.s[1]\n"
357 "mla v29.4s, v5.4s, v1.s[2]\n"
358 "mla v28.4s, v5.4s, v1.s[3]\n"
359 "fmul v3.4s, v4.4s, v0.s[0]\n"
360 "fmul v2.4s, v4.4s, v0.s[1]\n"
361 "fmul v1.4s, v4.4s, v0.s[2]\n"
362 "scvtf v31.4s, v31.4s\n"
363 "fmul v0.4s, v4.4s, v0.s[3]\n"
364 "scvtf v30.4s, v30.4s\n"
365 "scvtf v29.4s, v29.4s\n"
366 "scvtf v28.4s, v28.4s\n"
367 "fmul v31.4s, v31.4s, v3.4s\n"
368 "fmul v30.4s, v30.4s, v2.4s\n"
369 "fmul v29.4s, v29.4s, v1.4s\n"
370 "fmul v28.4s, v28.4s, v0.4s\n"
371 "ld1 { v1.4s }, [x22]\n"
372 "add x22, x22, #0x10\n"
373 "ldr q0, [x22, #0x0]\n"
374 "mla v27.4s, v5.4s, v1.s[0]\n"
375 "mla v26.4s, v5.4s, v1.s[1]\n"
376 "mla v25.4s, v5.4s, v1.s[2]\n"
377 "mla v24.4s, v5.4s, v1.s[3]\n"
378 "fmul v3.4s, v4.4s, v0.s[0]\n"
379 "fmul v2.4s, v4.4s, v0.s[1]\n"
380 "fmul v1.4s, v4.4s, v0.s[2]\n"
381 "scvtf v27.4s, v27.4s\n"
382 "fmul v0.4s, v4.4s, v0.s[3]\n"
383 "scvtf v26.4s, v26.4s\n"
384 "scvtf v25.4s, v25.4s\n"
385 "scvtf v24.4s, v24.4s\n"
386 "fmul v27.4s, v27.4s, v3.4s\n"
387 "fmul v26.4s, v26.4s, v2.4s\n"
388 "fmul v25.4s, v25.4s, v1.4s\n"
389 "fmul v24.4s, v24.4s, v0.4s\n"
390 "ld1 { v1.4s }, [x21]\n"
391 "add x21, x21, #0x10\n"
392 "ldr q0, [x21, #0x0]\n"
393 "mla v23.4s, v5.4s, v1.s[0]\n"
394 "mla v22.4s, v5.4s, v1.s[1]\n"
395 "mla v21.4s, v5.4s, v1.s[2]\n"
396 "mla v20.4s, v5.4s, v1.s[3]\n"
397 "fmul v3.4s, v4.4s, v0.s[0]\n"
398 "fmul v2.4s, v4.4s, v0.s[1]\n"
399 "fmul v1.4s, v4.4s, v0.s[2]\n"
400 "scvtf v23.4s, v23.4s\n"
401 "fmul v0.4s, v4.4s, v0.s[3]\n"
402 "scvtf v22.4s, v22.4s\n"
403 "scvtf v21.4s, v21.4s\n"
404 "scvtf v20.4s, v20.4s\n"
405 "fmul v23.4s, v23.4s, v3.4s\n"
406 "fmul v22.4s, v22.4s, v2.4s\n"
407 "fmul v21.4s, v21.4s, v1.4s\n"
408 "fmul v20.4s, v20.4s, v0.4s\n"
409 "ld1 { v1.4s }, [x20]\n"
410 "add x20, x20, #0x10\n"
411 "ldr q0, [x20, #0x0]\n"
412 "mla v19.4s, v5.4s, v1.s[0]\n"
413 "mla v18.4s, v5.4s, v1.s[1]\n"
414 "mla v17.4s, v5.4s, v1.s[2]\n"
415 "mla v16.4s, v5.4s, v1.s[3]\n"
416 "fmul v3.4s, v4.4s, v0.s[0]\n"
417 "fmul v2.4s, v4.4s, v0.s[1]\n"
418 "fmul v1.4s, v4.4s, v0.s[2]\n"
419 "scvtf v19.4s, v19.4s\n"
420 "fmul v0.4s, v4.4s, v0.s[3]\n"
421 "scvtf v18.4s, v18.4s\n"
422 "scvtf v17.4s, v17.4s\n"
423 "scvtf v16.4s, v16.4s\n"
424 "fmul v19.4s, v19.4s, v3.4s\n"
425 "fmul v18.4s, v18.4s, v2.4s\n"
426 "fmul v17.4s, v17.4s, v1.4s\n"
427 "fmul v16.4s, v16.4s, v0.4s\n"
428 "ldr q2, [x11, #0x0]\n"
429 "ld1r { v1.4s }, [%x[clamp_vals]]\n"
430 "add x20, %x[clamp_vals], #0x4\n"
431 "cmp x10, #0x4\n"
432 "ld1r { v0.4s }, [x20]\n"
433 "add x11, x11, #0x10\n"
434 "fadd v31.4s, v31.4s, v2.4s\n"
435 "fadd v30.4s, v30.4s, v2.4s\n"
436 "fadd v29.4s, v29.4s, v2.4s\n"
437 "fadd v28.4s, v28.4s, v2.4s\n"
438 "fadd v27.4s, v27.4s, v2.4s\n"
439 "fadd v26.4s, v26.4s, v2.4s\n"
440 "fadd v25.4s, v25.4s, v2.4s\n"
441 "fadd v24.4s, v24.4s, v2.4s\n"
442 "fadd v23.4s, v23.4s, v2.4s\n"
443 "fadd v22.4s, v22.4s, v2.4s\n"
444 "fadd v21.4s, v21.4s, v2.4s\n"
445 "fadd v20.4s, v20.4s, v2.4s\n"
446 "fadd v19.4s, v19.4s, v2.4s\n"
447 "fadd v18.4s, v18.4s, v2.4s\n"
448 "fadd v17.4s, v17.4s, v2.4s\n"
449 "fadd v16.4s, v16.4s, v2.4s\n"
450 "fmax v31.4s, v31.4s, v1.4s\n"
451 "fmax v30.4s, v30.4s, v1.4s\n"
452 "fmax v29.4s, v29.4s, v1.4s\n"
453 "fmax v28.4s, v28.4s, v1.4s\n"
454 "fmax v27.4s, v27.4s, v1.4s\n"
455 "fmax v26.4s, v26.4s, v1.4s\n"
456 "fmax v25.4s, v25.4s, v1.4s\n"
457 "fmax v24.4s, v24.4s, v1.4s\n"
458 "fmax v23.4s, v23.4s, v1.4s\n"
459 "fmax v22.4s, v22.4s, v1.4s\n"
460 "fmax v21.4s, v21.4s, v1.4s\n"
461 "fmax v20.4s, v20.4s, v1.4s\n"
462 "fmax v19.4s, v19.4s, v1.4s\n"
463 "fmax v18.4s, v18.4s, v1.4s\n"
464 "fmax v17.4s, v17.4s, v1.4s\n"
465 "fmax v16.4s, v16.4s, v1.4s\n"
466 "fmin v31.4s, v31.4s, v0.4s\n"
467 "fmin v30.4s, v30.4s, v0.4s\n"
468 "fmin v29.4s, v29.4s, v0.4s\n"
469 "fmin v28.4s, v28.4s, v0.4s\n"
470 "fmin v27.4s, v27.4s, v0.4s\n"
471 "fmin v26.4s, v26.4s, v0.4s\n"
472 "fmin v25.4s, v25.4s, v0.4s\n"
473 "fmin v24.4s, v24.4s, v0.4s\n"
474 "fmin v23.4s, v23.4s, v0.4s\n"
475 "fmin v22.4s, v22.4s, v0.4s\n"
476 "fmin v21.4s, v21.4s, v0.4s\n"
477 "fmin v20.4s, v20.4s, v0.4s\n"
478 "fmin v19.4s, v19.4s, v0.4s\n"
479 "fmin v18.4s, v18.4s, v0.4s\n"
480 "fmin v17.4s, v17.4s, v0.4s\n"
481 "fmin v16.4s, v16.4s, v0.4s\n"
482 "blt 8f\n"
483 "mov x20, %x[dst]\n"
484 "str q31, [x20, #0x0]\n"
485 "add x20, x20, %x[dst_stride_row]\n"
486 "str q30, [x20, #0x0]\n"
487 "add x20, x20, %x[dst_stride_row]\n"
488 "str q29, [x20, #0x0]\n"
489 "add x20, x20, %x[dst_stride_row]\n"
490 "str q28, [x20, #0x0]\n"
491 "add x20, x20, %x[dst_stride_row]\n"
492 "str q27, [x20, #0x0]\n"
493 "add x20, x20, %x[dst_stride_row]\n"
494 "str q26, [x20, #0x0]\n"
495 "add x20, x20, %x[dst_stride_row]\n"
496 "str q25, [x20, #0x0]\n"
497 "add x20, x20, %x[dst_stride_row]\n"
498 "str q24, [x20, #0x0]\n"
499 "add x20, x20, %x[dst_stride_row]\n"
500 "str q23, [x20, #0x0]\n"
501 "add x20, x20, %x[dst_stride_row]\n"
502 "str q22, [x20, #0x0]\n"
503 "add x20, x20, %x[dst_stride_row]\n"
504 "str q21, [x20, #0x0]\n"
505 "add x20, x20, %x[dst_stride_row]\n"
506 "str q20, [x20, #0x0]\n"
507 "add x20, x20, %x[dst_stride_row]\n"
508 "str q19, [x20, #0x0]\n"
509 "add x20, x20, %x[dst_stride_row]\n"
510 "str q18, [x20, #0x0]\n"
511 "add x20, x20, %x[dst_stride_row]\n"
512 "str q17, [x20, #0x0]\n"
513 "add x20, x20, %x[dst_stride_row]\n"
514 "str q16, [x20, #0x0]\n"
515 "b 13f\n"
516 "8:" // Partial output
517 "mov x28, %x[dst]\n"
518 "add x26, x28, %x[dst_stride_row], LSL #2\n"
519 "add x25, x26, %x[dst_stride_row], LSL #1\n"
520 "add x24, x26, %x[dst_stride_row]\n"
521 "add x23, x25, %x[dst_stride_row]\n"
522 "add x22, x28, %x[dst_stride_row], LSL #1\n"
523 "add x21, x28, %x[dst_stride_row]\n"
524 "add x20, x22, %x[dst_stride_row]\n"
525 "add x27, x23, %x[dst_stride_row]\n"
526 "tbz x10, #1, 9f\n"
527 "st1 { v24.d }[0], [x23], #0x8\n"
528 "st1 { v25.d }[0], [x25], #0x8\n"
529 "st1 { v26.d }[0], [x24], #0x8\n"
530 "st1 { v27.d }[0], [x26], #0x8\n"
531 "st1 { v28.d }[0], [x20], #0x8\n"
532 "st1 { v29.d }[0], [x22], #0x8\n"
533 "st1 { v30.d }[0], [x21], #0x8\n"
534 "st1 { v31.d }[0], [x28], #0x8\n"
535 "tbz x10, #0, 10f\n"
536 "st1 { v24.s }[2], [x23]\n"
537 "st1 { v25.s }[2], [x25]\n"
538 "st1 { v26.s }[2], [x24]\n"
539 "st1 { v27.s }[2], [x26]\n"
540 "st1 { v28.s }[2], [x20]\n"
541 "st1 { v29.s }[2], [x22]\n"
542 "st1 { v30.s }[2], [x21]\n"
543 "st1 { v31.s }[2], [x28]\n"
544 "b 10f\n"
545 "9:" // Output block 0: partial_1_0
546 "st1 { v24.s }[0], [x23]\n"
547 "st1 { v25.s }[0], [x25]\n"
548 "st1 { v26.s }[0], [x24]\n"
549 "st1 { v27.s }[0], [x26]\n"
550 "st1 { v28.s }[0], [x20]\n"
551 "st1 { v29.s }[0], [x22]\n"
552 "st1 { v30.s }[0], [x21]\n"
553 "st1 { v31.s }[0], [x28]\n"
554 "10:" // Output block 0: Done
555 "add x26, x27, %x[dst_stride_row], LSL #2\n"
556 "add x25, x27, %x[dst_stride_row], LSL #1\n"
557 "add x24, x26, %x[dst_stride_row], LSL #1\n"
558 "add x23, x27, %x[dst_stride_row]\n"
559 "add x22, x25, %x[dst_stride_row]\n"
560 "add x21, x26, %x[dst_stride_row]\n"
561 "add x20, x24, %x[dst_stride_row]\n"
562 "tbz x10, #1, 11f\n"
563 "st1 { v16.d }[0], [x20], #0x8\n"
564 "st1 { v17.d }[0], [x24], #0x8\n"
565 "st1 { v18.d }[0], [x21], #0x8\n"
566 "st1 { v19.d }[0], [x26], #0x8\n"
567 "st1 { v20.d }[0], [x22], #0x8\n"
568 "st1 { v21.d }[0], [x25], #0x8\n"
569 "st1 { v22.d }[0], [x23], #0x8\n"
570 "st1 { v23.d }[0], [x27], #0x8\n"
571 "tbz x10, #0, 12f\n"
572 "st1 { v16.s }[2], [x20]\n"
573 "st1 { v17.s }[2], [x24]\n"
574 "st1 { v18.s }[2], [x21]\n"
575 "st1 { v19.s }[2], [x26]\n"
576 "st1 { v20.s }[2], [x22]\n"
577 "st1 { v21.s }[2], [x25]\n"
578 "st1 { v22.s }[2], [x23]\n"
579 "st1 { v23.s }[2], [x27]\n"
580 "b 12f\n"
581 "11:" // Output block 1: partial_1_0
582 "st1 { v16.s }[0], [x20]\n"
583 "st1 { v17.s }[0], [x24]\n"
584 "st1 { v18.s }[0], [x21]\n"
585 "st1 { v19.s }[0], [x26]\n"
586 "st1 { v20.s }[0], [x22]\n"
587 "st1 { v21.s }[0], [x25]\n"
588 "st1 { v22.s }[0], [x23]\n"
589 "st1 { v23.s }[0], [x27]\n"
590 "12:" // Output block 1: Done
591 "13:" // Output stage exit
592 "subs x10, x10, #0x4\n"
593 "add %x[dst], %x[dst], #0x10\n"
594 "bgt 2b\n"
595 "mov x20, #0x4\n"
596 "sub x13, x13, #0x10\n"
597 "cmp x13, #0x10\n"
598 "mov %x[dst], x9\n"
599 "madd %x[lhs_packed], x20, x12, %x[lhs_packed]\n"
600 "bge 1b\n"
601 "14:" // Row loop skip
602 "cbz x13, 23f\n"
603 "15:" // Row tail: Row loop
604 "mov x26, %x[rhs_packed]\n"
605 "mov x25, %x[n]\n"
606 "add x24, %x[dst], %x[dst_stride_row], LSL #2\n"
607 "16:" // Row tail: Column loop
608 "mov x27, %x[lhs_packed]\n"
609 "movi v31.4s, #0x0\n"
610 "movi v30.4s, #0x0\n"
611 "mov x20, %x[num_blocks]\n"
612 "movi v29.4s, #0x0\n"
613 "movi v28.4s, #0x0\n"
614 "17:" // Row tail: Sub block loop
615 "ldr q17, [x26, #0x0]\n"
616 "ldr q16, [x27, #0x0]\n"
617 "subs x20, x20, #0x1\n"
618 "ldr q1, [x26, #0x10]\n"
619 "ldr q0, [x27, #0x10]\n"
620 "ldr q27, [x26, #0x20]\n"
621 "ldr q26, [x27, #0x20]\n"
622 "ldr q25, [x26, #0x30]\n"
623 "ldr q24, [x27, #0x30]\n"
624 ".inst 0x4f90e23f // sdot v31.4s, v17.16b, v16.4b[0]\n"
625 ".inst 0x4fb0e23e // sdot v30.4s, v17.16b, v16.4b[1]\n"
626 "ldr q23, [x26, #0x40]\n"
627 "ldr q22, [x27, #0x40]\n"
628 ".inst 0x4f90ea3d // sdot v29.4s, v17.16b, v16.4b[2]\n"
629 ".inst 0x4fb0ea3c // sdot v28.4s, v17.16b, v16.4b[3]\n"
630 "ldr q21, [x26, #0x50]\n"
631 "ldr q20, [x27, #0x50]\n"
632 "ldr q19, [x26, #0x60]\n"
633 "ldr q18, [x27, #0x60]\n"
634 "ldr q17, [x26, #0x70]\n"
635 "ldr q16, [x27, #0x70]\n"
636 ".inst 0x4f80e03f // sdot v31.4s, v1.16b, v0.4b[0]\n"
637 ".inst 0x4fa0e03e // sdot v30.4s, v1.16b, v0.4b[1]\n"
638 ".inst 0x4f80e83d // sdot v29.4s, v1.16b, v0.4b[2]\n"
639 ".inst 0x4fa0e83c // sdot v28.4s, v1.16b, v0.4b[3]\n"
640 "add x27, x27, #0x80\n"
641 "add x26, x26, #0x80\n"
642 ".inst 0x4f9ae37f // sdot v31.4s, v27.16b, v26.4b[0]\n"
643 ".inst 0x4fbae37e // sdot v30.4s, v27.16b, v26.4b[1]\n"
644 ".inst 0x4f9aeb7d // sdot v29.4s, v27.16b, v26.4b[2]\n"
645 ".inst 0x4fbaeb7c // sdot v28.4s, v27.16b, v26.4b[3]\n"
646 ".inst 0x4f98e33f // sdot v31.4s, v25.16b, v24.4b[0]\n"
647 ".inst 0x4fb8e33e // sdot v30.4s, v25.16b, v24.4b[1]\n"
648 ".inst 0x4f98eb3d // sdot v29.4s, v25.16b, v24.4b[2]\n"
649 ".inst 0x4fb8eb3c // sdot v28.4s, v25.16b, v24.4b[3]\n"
650 ".inst 0x4f96e2ff // sdot v31.4s, v23.16b, v22.4b[0]\n"
651 ".inst 0x4fb6e2fe // sdot v30.4s, v23.16b, v22.4b[1]\n"
652 ".inst 0x4f96eafd // sdot v29.4s, v23.16b, v22.4b[2]\n"
653 ".inst 0x4fb6eafc // sdot v28.4s, v23.16b, v22.4b[3]\n"
654 ".inst 0x4f94e2bf // sdot v31.4s, v21.16b, v20.4b[0]\n"
655 ".inst 0x4fb4e2be // sdot v30.4s, v21.16b, v20.4b[1]\n"
656 ".inst 0x4f94eabd // sdot v29.4s, v21.16b, v20.4b[2]\n"
657 ".inst 0x4fb4eabc // sdot v28.4s, v21.16b, v20.4b[3]\n"
658 ".inst 0x4f92e27f // sdot v31.4s, v19.16b, v18.4b[0]\n"
659 ".inst 0x4fb2e27e // sdot v30.4s, v19.16b, v18.4b[1]\n"
660 ".inst 0x4f92ea7d // sdot v29.4s, v19.16b, v18.4b[2]\n"
661 ".inst 0x4fb2ea7c // sdot v28.4s, v19.16b, v18.4b[3]\n"
662 ".inst 0x4f90e23f // sdot v31.4s, v17.16b, v16.4b[0]\n"
663 ".inst 0x4fb0e23e // sdot v30.4s, v17.16b, v16.4b[1]\n"
664 ".inst 0x4f90ea3d // sdot v29.4s, v17.16b, v16.4b[2]\n"
665 ".inst 0x4fb0ea3c // sdot v28.4s, v17.16b, v16.4b[3]\n"
666 "bgt 17b\n"
667 "ldr q18, [x26, #0x0]\n"
668 "ld1 { v17.4s }, [x27]\n"
669 "add x27, x27, #0x10\n"
670 "ldr q20, [x26, #0x10]\n"
671 "ldr q16, [x27, #0x0]\n"
672 "add x26, x26, #0x20\n"
673 "mla v31.4s, v18.4s, v17.s[0]\n"
674 "mla v30.4s, v18.4s, v17.s[1]\n"
675 "mla v29.4s, v18.4s, v17.s[2]\n"
676 "mla v28.4s, v18.4s, v17.s[3]\n"
677 "fmul v19.4s, v20.4s, v16.s[0]\n"
678 "fmul v18.4s, v20.4s, v16.s[1]\n"
679 "fmul v17.4s, v20.4s, v16.s[2]\n"
680 "scvtf v31.4s, v31.4s\n"
681 "fmul v16.4s, v20.4s, v16.s[3]\n"
682 "scvtf v30.4s, v30.4s\n"
683 "scvtf v29.4s, v29.4s\n"
684 "scvtf v28.4s, v28.4s\n"
685 "fmul v31.4s, v31.4s, v19.4s\n"
686 "fmul v30.4s, v30.4s, v18.4s\n"
687 "fmul v29.4s, v29.4s, v17.4s\n"
688 "fmul v28.4s, v28.4s, v16.4s\n"
689 "ldr q18, [x26, #0x0]\n"
690 "ld1r { v17.4s }, [%x[clamp_vals]]\n"
691 "add x20, %x[clamp_vals], #0x4\n"
692 "cmp x25, #0x4\n"
693 "ld1r { v16.4s }, [x20]\n"
694 "add x26, x26, #0x10\n"
695 "fadd v31.4s, v31.4s, v18.4s\n"
696 "fadd v30.4s, v30.4s, v18.4s\n"
697 "fadd v29.4s, v29.4s, v18.4s\n"
698 "fadd v28.4s, v28.4s, v18.4s\n"
699 "fmax v31.4s, v31.4s, v17.4s\n"
700 "fmax v30.4s, v30.4s, v17.4s\n"
701 "fmax v29.4s, v29.4s, v17.4s\n"
702 "fmax v28.4s, v28.4s, v17.4s\n"
703 "fmin v31.4s, v31.4s, v16.4s\n"
704 "fmin v30.4s, v30.4s, v16.4s\n"
705 "fmin v29.4s, v29.4s, v16.4s\n"
706 "fmin v28.4s, v28.4s, v16.4s\n"
707 "blt 19f\n"
708 "mov x20, %x[dst]\n"
709 "cmp x13, #0x1\n"
710 "str q31, [x20, #0x0]\n"
711 "add x20, x20, %x[dst_stride_row]\n"
712 "ble 22f\n"
713 "cmp x13, #0x2\n"
714 "str q30, [x20, #0x0]\n"
715 "add x20, x20, %x[dst_stride_row]\n"
716 "ble 22f\n"
717 "cmp x13, #0x3\n"
718 "str q29, [x20, #0x0]\n"
719 "add x20, x20, %x[dst_stride_row]\n"
720 "ble 22f\n"
721 "str q28, [x20, #0x0]\n"
722 "b 22f\n"
723 "19:" // Row tail: Partial output
724 "mov x23, %x[dst]\n"
725 "cmp x13, #0x1\n"
726 "add x22, x23, %x[dst_stride_row]\n"
727 "csel x22, x22, x23, GT\n"
728 "cmp x13, #0x2\n"
729 "add x21, x23, %x[dst_stride_row], LSL #1\n"
730 "csel x21, x21, x22, GT\n"
731 "cmp x13, #0x3\n"
732 "add x20, x21, %x[dst_stride_row]\n"
733 "csel x20, x20, x21, GT\n"
734 "tbz x25, #1, 20f\n"
735 "st1 { v28.d }[0], [x20], #0x8\n"
736 "st1 { v29.d }[0], [x21], #0x8\n"
737 "st1 { v30.d }[0], [x22], #0x8\n"
738 "st1 { v31.d }[0], [x23], #0x8\n"
739 "tbz x25, #0, 21f\n"
740 "st1 { v28.s }[2], [x20]\n"
741 "st1 { v29.s }[2], [x21]\n"
742 "st1 { v30.s }[2], [x22]\n"
743 "st1 { v31.s }[2], [x23]\n"
744 "b 21f\n"
745 "20:" // Row tail: Output block 0: partial_1_0
746 "st1 { v28.s }[0], [x20]\n"
747 "st1 { v29.s }[0], [x21]\n"
748 "st1 { v30.s }[0], [x22]\n"
749 "st1 { v31.s }[0], [x23]\n"
750 "21:" // Row tail: Output block 0: Done
751 "22:" // Row tail: Output stage exit
752 "subs x25, x25, #0x4\n"
753 "add %x[dst], %x[dst], #0x10\n"
754 "bgt 16b\n"
755 "subs x13, x13, #0x4\n"
756 "add %x[lhs_packed], %x[lhs_packed], x12\n"
757 "mov %x[dst], x24\n"
758 "bgt 15b\n"
759 "23:" // Row tail: Row loop skip
760 : [dst] "+&r"(dst), [lhs_packed] "+&r"(lhs_packed)
761 155 : [clamp_vals] "r"(clamp_vals), [dst_stride_row] "r"(dst_stride_row), [m] "r"(m), [n] "r"(n),
762 155 [num_blocks] "r"(num_blocks), [rhs_packed] "r"(rhs_packed)
763 : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14",
764 "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29",
765 "v30", "v31", "x9", "x10", "x11", "x12", "x13", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27",
766 "x28");
767 155 }
768
769 #endif // Architectural features check.
770