KleidiAI Coverage Report


Directory: ./
File: kai/ukernels/matmul/pack/kai_rhs_pack_kxn_bf16p12x4biasf32_f16_neon.c
Date: 2025-10-20 13:18:31
Coverage Exec Excl Total
Lines: 86.2% 25 11 40
Functions: 66.7% 4 0 6
Branches: 100.0% 4 22 26

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_BF16_VECTOR_ARITHMETIC) || \
11 !defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
12 #error This file must be compiled for AArch64, FEAT_BF16, FEAT_FP16.
13 #else // Architectural features check.
14
15 #include "kai_rhs_pack_kxn_bf16p12x4biasf32_f16_neon.h"
16
17 #include <arm_neon.h>
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21
22 #include "kai/kai_common.h"
23
24 static const size_t kai_nr = 12;
25 static const size_t kai_kr = 4;
26
27 size_t kai_get_n_step_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(void) {
28 return kai_nr;
29 }
30
31 92 size_t kai_get_rhs_offset_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(size_t n_idx) {
32 KAI_ASSUME(n_idx % kai_nr == 0);
33
34 92 return n_idx * sizeof(uint16_t);
35 }
36
37 size_t kai_get_bias_offset_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(size_t n_idx) {
38 return n_idx * sizeof(uint32_t);
39 }
40
41 112 size_t kai_get_rhs_packed_offset_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(size_t n_idx, size_t k) {
42 KAI_ASSUME(n_idx % kai_nr == 0);
43
44 112 return n_idx * (sizeof(uint32_t) + kai_roundup(k, kai_kr) * sizeof(uint16_t));
45 }
46
47 112 size_t kai_get_rhs_packed_size_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(size_t n, size_t k) {
48 112 return kai_get_rhs_packed_offset_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(kai_roundup(n, kai_nr), k);
49 }
50
51 112 void kai_run_rhs_pack_kxn_bf16p12x4biasf32_f16_neon(
52 size_t num_groups, size_t n, size_t k, size_t nr, size_t kr, size_t sr, size_t rhs_stride, const void* rhs,
53 const void* bias, const void* scale, void* rhs_packed, size_t extra_bytes, const void* params) {
54 KAI_ASSUME(num_groups == 1);
55 KAI_ASSUME(nr == kai_nr);
56 KAI_ASSUME(kr == kai_kr);
57 KAI_ASSUME(sr == 1);
58 KAI_ASSUME(rhs != NULL);
59 KAI_ASSUME(scale == NULL);
60 KAI_ASSUME(rhs_packed != NULL);
61 KAI_ASSUME(extra_bytes == 0);
62 KAI_ASSUME(params == NULL);
63
64 112 size_t height = k;
65 112 const size_t width = n;
66 112 const void* in = rhs;
67 112 void* out = rhs_packed;
68 112 const size_t in_stride = rhs_stride;
69 112 const uint16_t* pad_row = rhs;
70
71 // Fill zeros if bias is nullptr
72 112 size_t bias_step = nr * sizeof(float);
73 112 uint8_t zero_bias[kai_nr * sizeof(float)];
74
75
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 if (bias == NULL) {
76 56 memset(zero_bias, 0, kai_nr * sizeof(float));
77 56 bias_step = 0;
78 56 }
79
80
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 const void* bias_ptr = bias == NULL ? (const void*)zero_bias : bias;
81
82 112 size_t out_stride = kai_nr * kai_roundup(height, kai_kr) * sizeof(uint16_t) + kai_nr * sizeof(uint32_t);
83
84 224 __asm__ __volatile__(
85 "mov x22, %x[width]\n"
86 "mov x21, %x[out]\n"
87 "cmp x22, #0xc\n"
88 "blt 2f\n"
89 "1:" // Bias: Full loop
90 "ldr q18, [%x[bias], #0x0]\n"
91 "ldr q17, [%x[bias], #0x10]\n"
92 "sub x22, x22, #0xc\n"
93 "ldr q16, [%x[bias], #0x20]\n"
94 "cmp x22, #0xc\n"
95 "add %x[bias], %x[bias], %x[bias_step]\n"
96 "str q18, [x21, #0x0]\n"
97 "str q17, [x21, #0x10]\n"
98 "str q16, [x21, #0x20]\n"
99 "add x21, x21, %x[out_stride]\n"
100 "bge 1b\n"
101 "cbz x22, 3f\n"
102 "2:" // Bias: Tail loop
103 "ldr w20, [%x[bias], #0x0]\n"
104 "sub x22, x22, #0x1\n"
105 "add %x[bias], %x[bias], #0x4\n"
106 "cmp x22, #0x0\n"
107 "str w20, [x21]\n"
108 "add x21, x21, #0x4\n"
109 "bgt 2b\n"
110 "3:" // Bias: Done
111 "cmp %x[height], #0x8\n"
112 "add %x[out], %x[out], #0x30\n"
113 "blt 12f\n"
114 "4:" // Main row loop: Head
115 "mov x9, %x[in]\n"
116 "mov x28, %x[width]\n"
117 "mov x27, %x[out]\n"
118 "sub %x[height], %x[height], #0x8\n"
119 "add x26, x9, %x[in_stride]\n"
120 "add x25, x26, %x[in_stride]\n"
121 "add x24, x25, %x[in_stride]\n"
122 "cmp x28, #0xc\n"
123 "add x23, x24, %x[in_stride]\n"
124 "add x22, x23, %x[in_stride]\n"
125 "add x21, x22, %x[in_stride]\n"
126 "add x20, x21, %x[in_stride]\n"
127 "add %x[in], x20, %x[in_stride]\n"
128 "blt 6f\n"
129 "5:" // Main row loop: Column loop
130 "ldr q23, [x9], #0x10\n"
131 "ldr q22, [x26], #0x10\n"
132 "sub x28, x28, #0xc\n"
133 "ldr q17, [x25], #0x10\n"
134 "ldr q16, [x24], #0x10\n"
135 "cmp x28, #0xc\n"
136 "ldr q1, [x23], #0x10\n"
137 "ldr q0, [x22], #0x10\n"
138 "ldr q21, [x21], #0x10\n"
139 "ldr q20, [x20], #0x10\n"
140 "ldr d31, [x9], #0x8\n"
141 "ldr d30, [x26], #0x8\n"
142 "zip1 v29.8h, v23.8h, v17.8h\n"
143 "zip1 v28.8h, v22.8h, v16.8h\n"
144 "ldr d19, [x25], #0x8\n"
145 "ldr d18, [x24], #0x8\n"
146 "zip2 v27.8h, v23.8h, v17.8h\n"
147 "zip2 v26.8h, v22.8h, v16.8h\n"
148 "ldr d25, [x23], #0x8\n"
149 "ldr d24, [x22], #0x8\n"
150 "zip1 v23.8h, v1.8h, v21.8h\n"
151 "zip1 v22.8h, v0.8h, v20.8h\n"
152 "ldr d17, [x21], #0x8\n"
153 "ldr d16, [x20], #0x8\n"
154 "zip2 v21.8h, v1.8h, v21.8h\n"
155 "zip2 v20.8h, v0.8h, v20.8h\n"
156 "zip1 v19.8h, v31.8h, v19.8h\n"
157 "zip1 v18.8h, v30.8h, v18.8h\n"
158 "zip1 v1.8h, v29.8h, v28.8h\n"
159 "zip2 v0.8h, v29.8h, v28.8h\n"
160 "zip1 v17.8h, v25.8h, v17.8h\n"
161 "zip1 v16.8h, v24.8h, v16.8h\n"
162 "zip1 v31.8h, v27.8h, v26.8h\n"
163 "zip2 v30.8h, v27.8h, v26.8h\n"
164 "zip1 v29.8h, v19.8h, v18.8h\n"
165 "zip2 v28.8h, v19.8h, v18.8h\n"
166 "zip1 v13.8h, v23.8h, v22.8h\n"
167 "zip2 v12.8h, v23.8h, v22.8h\n"
168 "zip1 v11.8h, v21.8h, v20.8h\n"
169 "zip2 v10.8h, v21.8h, v20.8h\n"
170 "zip1 v9.8h, v17.8h, v16.8h\n"
171 "zip2 v8.8h, v17.8h, v16.8h\n"
172 "fcvtl v27.4s, v1.4h\n"
173 "fcvtl v26.4s, v0.4h\n"
174 "fcvtl v25.4s, v31.4h\n"
175 "fcvtl v24.4s, v30.4h\n"
176 "fcvtl v23.4s, v29.4h\n"
177 "fcvtl v22.4s, v28.4h\n"
178 "fcvtl v21.4s, v13.4h\n"
179 "fcvtl v20.4s, v12.4h\n"
180 "fcvtl v19.4s, v11.4h\n"
181 "fcvtl v18.4s, v10.4h\n"
182 "fcvtl v17.4s, v9.4h\n"
183 "fcvtl v16.4s, v8.4h\n"
184 "fcvtl2 v7.4s, v1.8h\n"
185 ".inst 0x0ea16b66 // bfcvtn v6.4h, v27.4s\n"
186 "fcvtl2 v5.4s, v0.8h\n"
187 ".inst 0x0ea16b44 // bfcvtn v4.4h, v26.4s\n"
188 "fcvtl2 v3.4s, v31.8h\n"
189 ".inst 0x0ea16b22 // bfcvtn v2.4h, v25.4s\n"
190 "fcvtl2 v1.4s, v30.8h\n"
191 ".inst 0x0ea16b00 // bfcvtn v0.4h, v24.4s\n"
192 "fcvtl2 v31.4s, v29.8h\n"
193 ".inst 0x0ea16afe // bfcvtn v30.4h, v23.4s\n"
194 "fcvtl2 v29.4s, v28.8h\n"
195 ".inst 0x0ea16adc // bfcvtn v28.4h, v22.4s\n"
196 "fcvtl2 v27.4s, v13.8h\n"
197 ".inst 0x0ea16aba // bfcvtn v26.4h, v21.4s\n"
198 "fcvtl2 v25.4s, v12.8h\n"
199 ".inst 0x0ea16a98 // bfcvtn v24.4h, v20.4s\n"
200 "fcvtl2 v23.4s, v11.8h\n"
201 ".inst 0x0ea16a76 // bfcvtn v22.4h, v19.4s\n"
202 "fcvtl2 v21.4s, v10.8h\n"
203 ".inst 0x0ea16a54 // bfcvtn v20.4h, v18.4s\n"
204 "fcvtl2 v19.4s, v9.8h\n"
205 ".inst 0x0ea16a32 // bfcvtn v18.4h, v17.4s\n"
206 "fcvtl2 v17.4s, v8.8h\n"
207 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
208 ".inst 0x4ea168e6 // bfcvtn2 v6.8h, v7.4s\n"
209 ".inst 0x4ea168a4 // bfcvtn2 v4.8h, v5.4s\n"
210 ".inst 0x4ea16862 // bfcvtn2 v2.8h, v3.4s\n"
211 ".inst 0x4ea16820 // bfcvtn2 v0.8h, v1.4s\n"
212 ".inst 0x4ea16bfe // bfcvtn2 v30.8h, v31.4s\n"
213 ".inst 0x4ea16bbc // bfcvtn2 v28.8h, v29.4s\n"
214 ".inst 0x4ea16b7a // bfcvtn2 v26.8h, v27.4s\n"
215 ".inst 0x4ea16b38 // bfcvtn2 v24.8h, v25.4s\n"
216 "str q6, [x27, #0x0]\n"
217 ".inst 0x4ea16af6 // bfcvtn2 v22.8h, v23.4s\n"
218 ".inst 0x4ea16ab4 // bfcvtn2 v20.8h, v21.4s\n"
219 "str q4, [x27, #0x10]\n"
220 ".inst 0x4ea16a72 // bfcvtn2 v18.8h, v19.4s\n"
221 ".inst 0x4ea16a30 // bfcvtn2 v16.8h, v17.4s\n"
222 "str q2, [x27, #0x20]\n"
223 "str q0, [x27, #0x30]\n"
224 "str q30, [x27, #0x40]\n"
225 "str q28, [x27, #0x50]\n"
226 "str q26, [x27, #0x60]\n"
227 "str q24, [x27, #0x70]\n"
228 "str q22, [x27, #0x80]\n"
229 "str q20, [x27, #0x90]\n"
230 "str q18, [x27, #0xa0]\n"
231 "str q16, [x27, #0xb0]\n"
232 "add x27, x27, %x[out_stride]\n"
233 "bge 5b\n"
234 "6:" // Main row loop: Column loop skip
235 "cbz x28, 11f\n"
236 "cmp x28, #0x4\n"
237 "movi v16.16b, #0x0\n"
238 "str q16, [x27, #0x0]\n"
239 "str q16, [x27, #0x10]\n"
240 "str q16, [x27, #0x20]\n"
241 "str q16, [x27, #0x30]\n"
242 "str q16, [x27, #0x40]\n"
243 "str q16, [x27, #0x50]\n"
244 "str q16, [x27, #0x60]\n"
245 "str q16, [x27, #0x70]\n"
246 "str q16, [x27, #0x80]\n"
247 "str q16, [x27, #0x90]\n"
248 "str q16, [x27, #0xa0]\n"
249 "str q16, [x27, #0xb0]\n"
250 "blt 8f\n"
251 "7:" // Main row loop: width 4 loop: loop
252 "ldr d23, [x9], #0x8\n"
253 "ldr d22, [x26], #0x8\n"
254 "sub x28, x28, #0x4\n"
255 "ldr d20, [x25], #0x8\n"
256 "ldr d16, [x24], #0x8\n"
257 "cmp x28, #0x4\n"
258 "ldr d19, [x23], #0x8\n"
259 "ldr d21, [x22], #0x8\n"
260 "ldr d18, [x21], #0x8\n"
261 "ldr d17, [x20], #0x8\n"
262 "zip1 v20.8h, v23.8h, v20.8h\n"
263 "zip1 v16.8h, v22.8h, v16.8h\n"
264 "zip1 v19.8h, v19.8h, v18.8h\n"
265 "zip1 v18.8h, v21.8h, v17.8h\n"
266 "zip1 v17.8h, v20.8h, v16.8h\n"
267 "zip2 v16.8h, v20.8h, v16.8h\n"
268 "zip1 v25.8h, v19.8h, v18.8h\n"
269 "zip2 v24.8h, v19.8h, v18.8h\n"
270 "fcvtl v19.4s, v17.4h\n"
271 "fcvtl v18.4s, v16.4h\n"
272 "fcvtl2 v23.4s, v17.8h\n"
273 "fcvtl2 v22.4s, v16.8h\n"
274 "fcvtl v17.4s, v25.4h\n"
275 "fcvtl v16.4s, v24.4h\n"
276 ".inst 0x0ea16a75 // bfcvtn v21.4h, v19.4s\n"
277 ".inst 0x0ea16a54 // bfcvtn v20.4h, v18.4s\n"
278 "fcvtl2 v19.4s, v25.8h\n"
279 "fcvtl2 v18.4s, v24.8h\n"
280 ".inst 0x0ea16a31 // bfcvtn v17.4h, v17.4s\n"
281 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
282 ".inst 0x4ea16af5 // bfcvtn2 v21.8h, v23.4s\n"
283 ".inst 0x4ea16ad4 // bfcvtn2 v20.8h, v22.4s\n"
284 ".inst 0x4ea16a71 // bfcvtn2 v17.8h, v19.4s\n"
285 ".inst 0x4ea16a50 // bfcvtn2 v16.8h, v18.4s\n"
286 "str q21, [x27, #0x0]\n"
287 "str q20, [x27, #0x10]\n"
288 "str q17, [x27, #0x60]\n"
289 "str q16, [x27, #0x70]\n"
290 "add x27, x27, #0x20\n"
291 "bge 7b\n"
292 "8:" // Main row loop: width 4 loop: skip
293 "cmp x28, #0x1\n"
294 "blt 10f\n"
295 "9:" // Main row loop: width 1 loop: loop
296 "ldr h23, [x9], #0x2\n"
297 "ldr h22, [x26], #0x2\n"
298 "sub x28, x28, #0x1\n"
299 "ldr h19, [x25], #0x2\n"
300 "ldr h18, [x24], #0x2\n"
301 "cmp x28, #0x1\n"
302 "ldr h21, [x23], #0x2\n"
303 "ldr h20, [x22], #0x2\n"
304 "ldr h17, [x21], #0x2\n"
305 "ldr h16, [x20], #0x2\n"
306 "zip1 v19.8h, v23.8h, v19.8h\n"
307 "zip1 v18.8h, v22.8h, v18.8h\n"
308 "zip1 v17.8h, v21.8h, v17.8h\n"
309 "zip1 v16.8h, v20.8h, v16.8h\n"
310 "zip1 v19.8h, v19.8h, v18.8h\n"
311 "zip1 v18.8h, v17.8h, v16.8h\n"
312 "fcvtl v17.4s, v19.4h\n"
313 "fcvtl v16.4s, v18.4h\n"
314 "fcvtl2 v19.4s, v19.8h\n"
315 "fcvtl2 v18.4s, v18.8h\n"
316 ".inst 0x0ea16a31 // bfcvtn v17.4h, v17.4s\n"
317 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
318 ".inst 0x4ea16a71 // bfcvtn2 v17.8h, v19.4s\n"
319 ".inst 0x4ea16a50 // bfcvtn2 v16.8h, v18.4s\n"
320 "str d17, [x27, #0x0]\n"
321 "str d16, [x27, #0x60]\n"
322 "add x27, x27, #0x8\n"
323 "bge 9b\n"
324 "10:" // Main row loop: width 1 loop: skip
325 "11:" // Main row loop: odd col skip
326 "cmp %x[height], #0x8\n"
327 "add %x[out], %x[out], #0xc0\n"
328 "bge 4b\n"
329 "cbz %x[height], 21f\n"
330 "12:" // Main loop skip
331 "13:" // Tail row loop: Head
332 "mov x9, %x[in]\n"
333 "mov x20, %x[width]\n"
334 "cmp %x[height], #0x3\n"
335 "mov x27, %x[out]\n"
336 "add x26, x9, %x[in_stride]\n"
337 "add x25, x26, %x[in_stride]\n"
338 "add x24, x25, %x[in_stride]\n"
339 "csel x25, x25, %x[pad_row], GE\n"
340 "add %x[in], x24, %x[in_stride]\n"
341 "csel x24, x24, %x[pad_row], GT\n"
342 "cmp %x[height], #0x1\n"
343 "sub %x[height], %x[height], #0x4\n"
344 "csel x26, x26, %x[pad_row], GT\n"
345 "cmp x20, #0xc\n"
346 "blt 15f\n"
347 "14:" // Tail row loop: Column loop
348 "ldr q25, [x9], #0x10\n"
349 "ldr q24, [x26], #0x10\n"
350 "sub x20, x20, #0xc\n"
351 "ldr q19, [x25], #0x10\n"
352 "ldr q18, [x24], #0x10\n"
353 "cmp x20, #0xc\n"
354 "ldr d23, [x9], #0x8\n"
355 "ldr d22, [x26], #0x8\n"
356 "ldr d17, [x25], #0x8\n"
357 "ldr d16, [x24], #0x8\n"
358 "zip1 v21.8h, v25.8h, v19.8h\n"
359 "zip1 v20.8h, v24.8h, v18.8h\n"
360 "zip2 v19.8h, v25.8h, v19.8h\n"
361 "zip2 v18.8h, v24.8h, v18.8h\n"
362 "zip1 v17.8h, v23.8h, v17.8h\n"
363 "zip1 v16.8h, v22.8h, v16.8h\n"
364 "zip1 v24.8h, v21.8h, v20.8h\n"
365 "zip2 v23.8h, v21.8h, v20.8h\n"
366 "zip1 v22.8h, v19.8h, v18.8h\n"
367 "zip2 v30.8h, v19.8h, v18.8h\n"
368 "zip1 v29.8h, v17.8h, v16.8h\n"
369 "zip2 v28.8h, v17.8h, v16.8h\n"
370 "fcvtl v21.4s, v24.4h\n"
371 "fcvtl v20.4s, v23.4h\n"
372 "fcvtl v19.4s, v22.4h\n"
373 "fcvtl v18.4s, v30.4h\n"
374 "fcvtl v17.4s, v29.4h\n"
375 "fcvtl v16.4s, v28.4h\n"
376 "fcvtl2 v27.4s, v24.8h\n"
377 ".inst 0x0ea16aba // bfcvtn v26.4h, v21.4s\n"
378 "fcvtl2 v25.4s, v23.8h\n"
379 ".inst 0x0ea16a98 // bfcvtn v24.4h, v20.4s\n"
380 "fcvtl2 v23.4s, v22.8h\n"
381 ".inst 0x0ea16a76 // bfcvtn v22.4h, v19.4s\n"
382 "fcvtl2 v21.4s, v30.8h\n"
383 ".inst 0x0ea16a54 // bfcvtn v20.4h, v18.4s\n"
384 "fcvtl2 v19.4s, v29.8h\n"
385 ".inst 0x0ea16a32 // bfcvtn v18.4h, v17.4s\n"
386 "fcvtl2 v17.4s, v28.8h\n"
387 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
388 ".inst 0x4ea16b7a // bfcvtn2 v26.8h, v27.4s\n"
389 ".inst 0x4ea16b38 // bfcvtn2 v24.8h, v25.4s\n"
390 ".inst 0x4ea16af6 // bfcvtn2 v22.8h, v23.4s\n"
391 ".inst 0x4ea16ab4 // bfcvtn2 v20.8h, v21.4s\n"
392 ".inst 0x4ea16a72 // bfcvtn2 v18.8h, v19.4s\n"
393 ".inst 0x4ea16a30 // bfcvtn2 v16.8h, v17.4s\n"
394 "str q26, [x27, #0x0]\n"
395 "str q24, [x27, #0x10]\n"
396 "str q22, [x27, #0x20]\n"
397 "str q20, [x27, #0x30]\n"
398 "str q18, [x27, #0x40]\n"
399 "str q16, [x27, #0x50]\n"
400 "add x27, x27, %x[out_stride]\n"
401 "bge 14b\n"
402 "15:" // Tail row loop: Column loop skip
403 "cbz x20, 20f\n"
404 "cmp x20, #0x4\n"
405 "movi v16.16b, #0x0\n"
406 "str q16, [x27, #0x0]\n"
407 "str q16, [x27, #0x10]\n"
408 "str q16, [x27, #0x20]\n"
409 "str q16, [x27, #0x30]\n"
410 "str q16, [x27, #0x40]\n"
411 "str q16, [x27, #0x50]\n"
412 "blt 17f\n"
413 "16:" // Tail row loop: width 4 loop: loop
414 "ldr d18, [x9], #0x8\n"
415 "ldr d19, [x26], #0x8\n"
416 "sub x20, x20, #0x4\n"
417 "ldr d17, [x25], #0x8\n"
418 "ldr d16, [x24], #0x8\n"
419 "cmp x20, #0x4\n"
420 "zip1 v18.8h, v18.8h, v17.8h\n"
421 "zip1 v17.8h, v19.8h, v16.8h\n"
422 "zip1 v16.8h, v18.8h, v17.8h\n"
423 "zip2 v20.8h, v18.8h, v17.8h\n"
424 "fcvtl v17.4s, v16.4h\n"
425 "fcvtl2 v19.4s, v16.8h\n"
426 "fcvtl v16.4s, v20.4h\n"
427 ".inst 0x0ea16a32 // bfcvtn v18.4h, v17.4s\n"
428 "fcvtl2 v17.4s, v20.8h\n"
429 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
430 ".inst 0x4ea16a72 // bfcvtn2 v18.8h, v19.4s\n"
431 ".inst 0x4ea16a30 // bfcvtn2 v16.8h, v17.4s\n"
432 "str q18, [x27, #0x0]\n"
433 "str q16, [x27, #0x10]\n"
434 "add x27, x27, #0x20\n"
435 "bge 16b\n"
436 "17:" // Tail row loop: width 4 loop: skip
437 "cmp x20, #0x1\n"
438 "blt 19f\n"
439 "18:" // Tail row loop: width 1 loop: loop
440 "ldr h19, [x9], #0x2\n"
441 "ldr h18, [x26], #0x2\n"
442 "sub x20, x20, #0x1\n"
443 "ldr h17, [x25], #0x2\n"
444 "ldr h16, [x24], #0x2\n"
445 "cmp x20, #0x1\n"
446 "zip1 v17.8h, v19.8h, v17.8h\n"
447 "zip1 v16.8h, v18.8h, v16.8h\n"
448 "zip1 v17.8h, v17.8h, v16.8h\n"
449 "fcvtl v16.4s, v17.4h\n"
450 "fcvtl2 v17.4s, v17.8h\n"
451 ".inst 0x0ea16a10 // bfcvtn v16.4h, v16.4s\n"
452 ".inst 0x4ea16a30 // bfcvtn2 v16.8h, v17.4s\n"
453 "str d16, [x27, #0x0]\n"
454 "add x27, x27, #0x8\n"
455 "bge 18b\n"
456 "19:" // Tail row loop: width 1 loop: skip
457 "20:" // Tail row loop: odd col skip
458 "cmp %x[height], #0x1\n"
459 "add %x[out], %x[out], #0x60\n"
460 "bge 13b\n"
461 "21:" // Done
462 : [bias] "+&r"(bias_ptr), [height] "+&r"(height), [in] "+&r"(in), [out] "+&r"(out)
463 112 : [bias_step] "r"(bias_step), [in_stride] "r"(in_stride), [out_stride] "r"(out_stride), [pad_row] "r"(pad_row),
464 112 [width] "r"(width)
465 : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v16",
466 "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "x9",
467 "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28");
468 112 }
469
470 #endif // Architectural features check.
471