native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
neon.h
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2#pragma once
3#include "native/config.h"
4#include "native/attributes.h"
5#include <cstdint>
6#include <utility>
7#if NATIVE_HOST_NEON
8#include <arm_neon.h>
9
10namespace native::detail::arm_neon {
11 template<class V, std::size_t... I>
12 native_inline native_target("neon") V register_order(V value,
13 std::index_sequence<I...>) noexcept {
14#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
15 // Clang maps a 128-bit inline-asm vector operand as bytes on big endian.
16 // Cancel that whole-register byte permutation, independently of lane width.
17 // Its 64-bit asm operands already use the ACLE register representation.
18 if constexpr (sizeof(V) == 16) {
19 auto raw = __builtin_bit_cast(uint8x16_t, value);
20 return __builtin_bit_cast(
21 V, __builtin_shufflevector(raw, raw, (15 - I)...));
22 }
23#endif
24 return value;
25 }
26
27 template<class V> native_inline native_target("neon") V register_order(V value) noexcept {
28 return register_order(value, std::make_index_sequence<16>{});
29 }
30
31 // The narrowing-high instruction overwrites the upper 64 register bits.
32 // Duplicate the low vector on BE so widening needs no constant-table shuffle.
33 template<class V, std::size_t... I>
34 native_inline native_target("neon") auto low_register(V low, std::index_sequence<I...>) noexcept {
35#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
36 using result_type = decltype(__builtin_shufflevector(low, low, I...));
37 result_type result;
38 asm("dup %0.2d, %1.d[0]" : "=w"(result) : "w"(low));
39 return result;
40#else
41 return register_order(__builtin_shufflevector(low, V{}, I...));
42#endif
43 }
44
45 template<class V> native_inline native_target("neon") auto low_register(V low) noexcept {
46 return low_register(low, std::make_index_sequence<2 * sizeof(V) / sizeof(low[0])>{});
47 }
48
49 template<class R, class V> native_inline native_target("neon") R to_register(V value) noexcept {
50 if constexpr (sizeof(R) == sizeof(typename V::native_type))
51 return __builtin_bit_cast(R, value.to_native());
52 else {
53 auto bytes = __builtin_bit_cast(uint8x16_t, value.to_native());
54 return __builtin_bit_cast(R, __builtin_shufflevector(bytes, bytes, 0, 1, 2, 3, 4, 5, 6, 7));
55 }
56 }
57
58 template<class V, class R>
59 native_inline native_target("neon") V from_register(R value) noexcept {
60 if constexpr (sizeof(R) == sizeof(typename V::native_type))
61 return V::from_native(__builtin_bit_cast(typename V::native_type, value));
62 else {
63 auto bytes = __builtin_bit_cast(uint8x8_t, value);
64 return V::from_native(__builtin_bit_cast(
65 typename V::native_type, __builtin_shufflevector(bytes, uint8x8_t{}, 0, 1, 2, 3, 4, 5, 6,
66 7, 8, 9, 10, 11, 12, 13, 14, 15)));
67 }
68 }
69
70 native_inline native_target("neon") int8x8_t sqadd(int8x8_t a, int8x8_t b) noexcept {
71 auto left = register_order(a);
72 auto right = register_order(b);
73 int8x8_t result;
74 asm volatile("sqadd %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
75 return register_order(result);
76 }
77
78 native_inline native_target("neon") int8x16_t sqadd(int8x16_t a, int8x16_t b) noexcept {
79 auto left = register_order(a);
80 auto right = register_order(b);
81 int8x16_t result;
82 asm volatile("sqadd %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
83 return register_order(result);
84 }
85
86 native_inline native_target("neon") int16x4_t sqadd(int16x4_t a, int16x4_t b) noexcept {
87 auto left = register_order(a);
88 auto right = register_order(b);
89 int16x4_t result;
90 asm volatile("sqadd %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
91 return register_order(result);
92 }
93
94 native_inline native_target("neon") int16x8_t sqadd(int16x8_t a, int16x8_t b) noexcept {
95 auto left = register_order(a);
96 auto right = register_order(b);
97 int16x8_t result;
98 asm volatile("sqadd %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
99 return register_order(result);
100 }
101
102 native_inline native_target("neon") int32x2_t sqadd(int32x2_t a, int32x2_t b) noexcept {
103 auto left = register_order(a);
104 auto right = register_order(b);
105 int32x2_t result;
106 asm volatile("sqadd %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
107 return register_order(result);
108 }
109
110 native_inline native_target("neon") int32x4_t sqadd(int32x4_t a, int32x4_t b) noexcept {
111 auto left = register_order(a);
112 auto right = register_order(b);
113 int32x4_t result;
114 asm volatile("sqadd %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
115 return register_order(result);
116 }
117
118 native_inline native_target("neon") int64x1_t sqadd(int64x1_t a, int64x1_t b) noexcept {
119 auto left = register_order(a);
120 auto right = register_order(b);
121 int64x1_t result;
122 asm volatile("sqadd %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
123 return register_order(result);
124 }
125
126 native_inline native_target("neon") int64x2_t sqadd(int64x2_t a, int64x2_t b) noexcept {
127 auto left = register_order(a);
128 auto right = register_order(b);
129 int64x2_t result;
130 asm volatile("sqadd %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
131 return register_order(result);
132 }
133
134 native_inline native_target("neon") uint8x8_t uqadd(uint8x8_t a, uint8x8_t b) noexcept {
135 auto left = register_order(a);
136 auto right = register_order(b);
137 uint8x8_t result;
138 asm volatile("uqadd %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
139 return register_order(result);
140 }
141
142 native_inline native_target("neon") uint8x16_t uqadd(uint8x16_t a, uint8x16_t b) noexcept {
143 auto left = register_order(a);
144 auto right = register_order(b);
145 uint8x16_t result;
146 asm volatile("uqadd %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
147 return register_order(result);
148 }
149
150 native_inline native_target("neon") uint16x4_t uqadd(uint16x4_t a, uint16x4_t b) noexcept {
151 auto left = register_order(a);
152 auto right = register_order(b);
153 uint16x4_t result;
154 asm volatile("uqadd %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
155 return register_order(result);
156 }
157
158 native_inline native_target("neon") uint16x8_t uqadd(uint16x8_t a, uint16x8_t b) noexcept {
159 auto left = register_order(a);
160 auto right = register_order(b);
161 uint16x8_t result;
162 asm volatile("uqadd %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
163 return register_order(result);
164 }
165
166 native_inline native_target("neon") uint32x2_t uqadd(uint32x2_t a, uint32x2_t b) noexcept {
167 auto left = register_order(a);
168 auto right = register_order(b);
169 uint32x2_t result;
170 asm volatile("uqadd %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
171 return register_order(result);
172 }
173
174 native_inline native_target("neon") uint32x4_t uqadd(uint32x4_t a, uint32x4_t b) noexcept {
175 auto left = register_order(a);
176 auto right = register_order(b);
177 uint32x4_t result;
178 asm volatile("uqadd %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
179 return register_order(result);
180 }
181
182 native_inline native_target("neon") uint64x1_t uqadd(uint64x1_t a, uint64x1_t b) noexcept {
183 auto left = register_order(a);
184 auto right = register_order(b);
185 uint64x1_t result;
186 asm volatile("uqadd %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
187 return register_order(result);
188 }
189
190 native_inline native_target("neon") uint64x2_t uqadd(uint64x2_t a, uint64x2_t b) noexcept {
191 auto left = register_order(a);
192 auto right = register_order(b);
193 uint64x2_t result;
194 asm volatile("uqadd %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
195 return register_order(result);
196 }
197
198 native_inline native_target("neon") int8x8_t sqsub(int8x8_t a, int8x8_t b) noexcept {
199 auto left = register_order(a);
200 auto right = register_order(b);
201 int8x8_t result;
202 asm volatile("sqsub %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
203 return register_order(result);
204 }
205
206 native_inline native_target("neon") int8x16_t sqsub(int8x16_t a, int8x16_t b) noexcept {
207 auto left = register_order(a);
208 auto right = register_order(b);
209 int8x16_t result;
210 asm volatile("sqsub %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
211 return register_order(result);
212 }
213
214 native_inline native_target("neon") int16x4_t sqsub(int16x4_t a, int16x4_t b) noexcept {
215 auto left = register_order(a);
216 auto right = register_order(b);
217 int16x4_t result;
218 asm volatile("sqsub %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
219 return register_order(result);
220 }
221
222 native_inline native_target("neon") int16x8_t sqsub(int16x8_t a, int16x8_t b) noexcept {
223 auto left = register_order(a);
224 auto right = register_order(b);
225 int16x8_t result;
226 asm volatile("sqsub %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
227 return register_order(result);
228 }
229
230 native_inline native_target("neon") int32x2_t sqsub(int32x2_t a, int32x2_t b) noexcept {
231 auto left = register_order(a);
232 auto right = register_order(b);
233 int32x2_t result;
234 asm volatile("sqsub %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
235 return register_order(result);
236 }
237
238 native_inline native_target("neon") int32x4_t sqsub(int32x4_t a, int32x4_t b) noexcept {
239 auto left = register_order(a);
240 auto right = register_order(b);
241 int32x4_t result;
242 asm volatile("sqsub %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
243 return register_order(result);
244 }
245
246 native_inline native_target("neon") int64x1_t sqsub(int64x1_t a, int64x1_t b) noexcept {
247 auto left = register_order(a);
248 auto right = register_order(b);
249 int64x1_t result;
250 asm volatile("sqsub %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
251 return register_order(result);
252 }
253
254 native_inline native_target("neon") int64x2_t sqsub(int64x2_t a, int64x2_t b) noexcept {
255 auto left = register_order(a);
256 auto right = register_order(b);
257 int64x2_t result;
258 asm volatile("sqsub %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
259 return register_order(result);
260 }
261
262 native_inline native_target("neon") uint8x8_t uqsub(uint8x8_t a, uint8x8_t b) noexcept {
263 auto left = register_order(a);
264 auto right = register_order(b);
265 uint8x8_t result;
266 asm volatile("uqsub %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
267 return register_order(result);
268 }
269
270 native_inline native_target("neon") uint8x16_t uqsub(uint8x16_t a, uint8x16_t b) noexcept {
271 auto left = register_order(a);
272 auto right = register_order(b);
273 uint8x16_t result;
274 asm volatile("uqsub %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
275 return register_order(result);
276 }
277
278 native_inline native_target("neon") uint16x4_t uqsub(uint16x4_t a, uint16x4_t b) noexcept {
279 auto left = register_order(a);
280 auto right = register_order(b);
281 uint16x4_t result;
282 asm volatile("uqsub %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
283 return register_order(result);
284 }
285
286 native_inline native_target("neon") uint16x8_t uqsub(uint16x8_t a, uint16x8_t b) noexcept {
287 auto left = register_order(a);
288 auto right = register_order(b);
289 uint16x8_t result;
290 asm volatile("uqsub %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
291 return register_order(result);
292 }
293
294 native_inline native_target("neon") uint32x2_t uqsub(uint32x2_t a, uint32x2_t b) noexcept {
295 auto left = register_order(a);
296 auto right = register_order(b);
297 uint32x2_t result;
298 asm volatile("uqsub %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
299 return register_order(result);
300 }
301
302 native_inline native_target("neon") uint32x4_t uqsub(uint32x4_t a, uint32x4_t b) noexcept {
303 auto left = register_order(a);
304 auto right = register_order(b);
305 uint32x4_t result;
306 asm volatile("uqsub %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
307 return register_order(result);
308 }
309
310 native_inline native_target("neon") uint64x1_t uqsub(uint64x1_t a, uint64x1_t b) noexcept {
311 auto left = register_order(a);
312 auto right = register_order(b);
313 uint64x1_t result;
314 asm volatile("uqsub %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
315 return register_order(result);
316 }
317
318 native_inline native_target("neon") uint64x2_t uqsub(uint64x2_t a, uint64x2_t b) noexcept {
319 auto left = register_order(a);
320 auto right = register_order(b);
321 uint64x2_t result;
322 asm volatile("uqsub %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
323 return register_order(result);
324 }
325
326 native_inline native_target("neon") int16x4_t sqdmulh(int16x4_t a, int16x4_t b) noexcept {
327 auto left = register_order(a);
328 auto right = register_order(b);
329 int16x4_t result;
330 asm volatile("sqdmulh %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
331 return register_order(result);
332 }
333
334 native_inline native_target("neon") int16x8_t sqdmulh(int16x8_t a, int16x8_t b) noexcept {
335 auto left = register_order(a);
336 auto right = register_order(b);
337 int16x8_t result;
338 asm volatile("sqdmulh %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
339 return register_order(result);
340 }
341
342 native_inline native_target("neon") int32x2_t sqdmulh(int32x2_t a, int32x2_t b) noexcept {
343 auto left = register_order(a);
344 auto right = register_order(b);
345 int32x2_t result;
346 asm volatile("sqdmulh %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
347 return register_order(result);
348 }
349
350 native_inline native_target("neon") int32x4_t sqdmulh(int32x4_t a, int32x4_t b) noexcept {
351 auto left = register_order(a);
352 auto right = register_order(b);
353 int32x4_t result;
354 asm volatile("sqdmulh %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
355 return register_order(result);
356 }
357
358 native_inline native_target("neon") int16x4_t sqrdmulh(int16x4_t a, int16x4_t b) noexcept {
359 auto left = register_order(a);
360 auto right = register_order(b);
361 int16x4_t result;
362 asm volatile("sqrdmulh %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
363 return register_order(result);
364 }
365
366 native_inline native_target("neon") int16x8_t sqrdmulh(int16x8_t a, int16x8_t b) noexcept {
367 auto left = register_order(a);
368 auto right = register_order(b);
369 int16x8_t result;
370 asm volatile("sqrdmulh %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
371 return register_order(result);
372 }
373
374 native_inline native_target("neon") int32x2_t sqrdmulh(int32x2_t a, int32x2_t b) noexcept {
375 auto left = register_order(a);
376 auto right = register_order(b);
377 int32x2_t result;
378 asm volatile("sqrdmulh %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
379 return register_order(result);
380 }
381
382 native_inline native_target("neon") int32x4_t sqrdmulh(int32x4_t a, int32x4_t b) noexcept {
383 auto left = register_order(a);
384 auto right = register_order(b);
385 int32x4_t result;
386 asm volatile("sqrdmulh %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
387 return register_order(result);
388 }
389
390 native_inline native_target("neon") int8x8_t sshl(int8x8_t a, int8x8_t b) noexcept {
391 auto left = register_order(a);
392 auto right = register_order(b);
393 int8x8_t result;
394 asm volatile("sshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
395 return register_order(result);
396 }
397
398 native_inline native_target("neon") int8x16_t sshl(int8x16_t a, int8x16_t b) noexcept {
399 auto left = register_order(a);
400 auto right = register_order(b);
401 int8x16_t result;
402 asm volatile("sshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
403 return register_order(result);
404 }
405
406 native_inline native_target("neon") int16x4_t sshl(int16x4_t a, int16x4_t b) noexcept {
407 auto left = register_order(a);
408 auto right = register_order(b);
409 int16x4_t result;
410 asm volatile("sshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
411 return register_order(result);
412 }
413
414 native_inline native_target("neon") int16x8_t sshl(int16x8_t a, int16x8_t b) noexcept {
415 auto left = register_order(a);
416 auto right = register_order(b);
417 int16x8_t result;
418 asm volatile("sshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
419 return register_order(result);
420 }
421
422 native_inline native_target("neon") int32x2_t sshl(int32x2_t a, int32x2_t b) noexcept {
423 auto left = register_order(a);
424 auto right = register_order(b);
425 int32x2_t result;
426 asm volatile("sshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
427 return register_order(result);
428 }
429
430 native_inline native_target("neon") int32x4_t sshl(int32x4_t a, int32x4_t b) noexcept {
431 auto left = register_order(a);
432 auto right = register_order(b);
433 int32x4_t result;
434 asm volatile("sshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
435 return register_order(result);
436 }
437
438 native_inline native_target("neon") int64x1_t sshl(int64x1_t a, int64x1_t b) noexcept {
439 auto left = register_order(a);
440 auto right = register_order(b);
441 int64x1_t result;
442 asm volatile("sshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
443 return register_order(result);
444 }
445
446 native_inline native_target("neon") int64x2_t sshl(int64x2_t a, int64x2_t b) noexcept {
447 auto left = register_order(a);
448 auto right = register_order(b);
449 int64x2_t result;
450 asm volatile("sshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
451 return register_order(result);
452 }
453
454 native_inline native_target("neon") int8x8_t srshl(int8x8_t a, int8x8_t b) noexcept {
455 auto left = register_order(a);
456 auto right = register_order(b);
457 int8x8_t result;
458 asm volatile("srshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
459 return register_order(result);
460 }
461
462 native_inline native_target("neon") int8x16_t srshl(int8x16_t a, int8x16_t b) noexcept {
463 auto left = register_order(a);
464 auto right = register_order(b);
465 int8x16_t result;
466 asm volatile("srshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
467 return register_order(result);
468 }
469
470 native_inline native_target("neon") int16x4_t srshl(int16x4_t a, int16x4_t b) noexcept {
471 auto left = register_order(a);
472 auto right = register_order(b);
473 int16x4_t result;
474 asm volatile("srshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
475 return register_order(result);
476 }
477
478 native_inline native_target("neon") int16x8_t srshl(int16x8_t a, int16x8_t b) noexcept {
479 auto left = register_order(a);
480 auto right = register_order(b);
481 int16x8_t result;
482 asm volatile("srshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
483 return register_order(result);
484 }
485
486 native_inline native_target("neon") int32x2_t srshl(int32x2_t a, int32x2_t b) noexcept {
487 auto left = register_order(a);
488 auto right = register_order(b);
489 int32x2_t result;
490 asm volatile("srshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
491 return register_order(result);
492 }
493
494 native_inline native_target("neon") int32x4_t srshl(int32x4_t a, int32x4_t b) noexcept {
495 auto left = register_order(a);
496 auto right = register_order(b);
497 int32x4_t result;
498 asm volatile("srshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
499 return register_order(result);
500 }
501
502 native_inline native_target("neon") int64x1_t srshl(int64x1_t a, int64x1_t b) noexcept {
503 auto left = register_order(a);
504 auto right = register_order(b);
505 int64x1_t result;
506 asm volatile("srshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
507 return register_order(result);
508 }
509
510 native_inline native_target("neon") int64x2_t srshl(int64x2_t a, int64x2_t b) noexcept {
511 auto left = register_order(a);
512 auto right = register_order(b);
513 int64x2_t result;
514 asm volatile("srshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
515 return register_order(result);
516 }
517
518 native_inline native_target("neon") int8x8_t sqshl(int8x8_t a, int8x8_t b) noexcept {
519 auto left = register_order(a);
520 auto right = register_order(b);
521 int8x8_t result;
522 asm volatile("sqshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
523 return register_order(result);
524 }
525
526 native_inline native_target("neon") int8x16_t sqshl(int8x16_t a, int8x16_t b) noexcept {
527 auto left = register_order(a);
528 auto right = register_order(b);
529 int8x16_t result;
530 asm volatile("sqshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
531 return register_order(result);
532 }
533
534 native_inline native_target("neon") int16x4_t sqshl(int16x4_t a, int16x4_t b) noexcept {
535 auto left = register_order(a);
536 auto right = register_order(b);
537 int16x4_t result;
538 asm volatile("sqshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
539 return register_order(result);
540 }
541
542 native_inline native_target("neon") int16x8_t sqshl(int16x8_t a, int16x8_t b) noexcept {
543 auto left = register_order(a);
544 auto right = register_order(b);
545 int16x8_t result;
546 asm volatile("sqshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
547 return register_order(result);
548 }
549
550 native_inline native_target("neon") int32x2_t sqshl(int32x2_t a, int32x2_t b) noexcept {
551 auto left = register_order(a);
552 auto right = register_order(b);
553 int32x2_t result;
554 asm volatile("sqshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
555 return register_order(result);
556 }
557
558 native_inline native_target("neon") int32x4_t sqshl(int32x4_t a, int32x4_t b) noexcept {
559 auto left = register_order(a);
560 auto right = register_order(b);
561 int32x4_t result;
562 asm volatile("sqshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
563 return register_order(result);
564 }
565
566 native_inline native_target("neon") int64x1_t sqshl(int64x1_t a, int64x1_t b) noexcept {
567 auto left = register_order(a);
568 auto right = register_order(b);
569 int64x1_t result;
570 asm volatile("sqshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
571 return register_order(result);
572 }
573
574 native_inline native_target("neon") int64x2_t sqshl(int64x2_t a, int64x2_t b) noexcept {
575 auto left = register_order(a);
576 auto right = register_order(b);
577 int64x2_t result;
578 asm volatile("sqshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
579 return register_order(result);
580 }
581
582 native_inline native_target("neon") int8x8_t sqrshl(int8x8_t a, int8x8_t b) noexcept {
583 auto left = register_order(a);
584 auto right = register_order(b);
585 int8x8_t result;
586 asm volatile("sqrshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
587 return register_order(result);
588 }
589
590 native_inline native_target("neon") int8x16_t sqrshl(int8x16_t a, int8x16_t b) noexcept {
591 auto left = register_order(a);
592 auto right = register_order(b);
593 int8x16_t result;
594 asm volatile("sqrshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
595 return register_order(result);
596 }
597
598 native_inline native_target("neon") int16x4_t sqrshl(int16x4_t a, int16x4_t b) noexcept {
599 auto left = register_order(a);
600 auto right = register_order(b);
601 int16x4_t result;
602 asm volatile("sqrshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
603 return register_order(result);
604 }
605
606 native_inline native_target("neon") int16x8_t sqrshl(int16x8_t a, int16x8_t b) noexcept {
607 auto left = register_order(a);
608 auto right = register_order(b);
609 int16x8_t result;
610 asm volatile("sqrshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
611 return register_order(result);
612 }
613
614 native_inline native_target("neon") int32x2_t sqrshl(int32x2_t a, int32x2_t b) noexcept {
615 auto left = register_order(a);
616 auto right = register_order(b);
617 int32x2_t result;
618 asm volatile("sqrshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
619 return register_order(result);
620 }
621
622 native_inline native_target("neon") int32x4_t sqrshl(int32x4_t a, int32x4_t b) noexcept {
623 auto left = register_order(a);
624 auto right = register_order(b);
625 int32x4_t result;
626 asm volatile("sqrshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
627 return register_order(result);
628 }
629
630 native_inline native_target("neon") int64x1_t sqrshl(int64x1_t a, int64x1_t b) noexcept {
631 auto left = register_order(a);
632 auto right = register_order(b);
633 int64x1_t result;
634 asm volatile("sqrshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
635 return register_order(result);
636 }
637
638 native_inline native_target("neon") int64x2_t sqrshl(int64x2_t a, int64x2_t b) noexcept {
639 auto left = register_order(a);
640 auto right = register_order(b);
641 int64x2_t result;
642 asm volatile("sqrshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
643 return register_order(result);
644 }
645
646 native_inline native_target("neon") uint8x8_t ushl(uint8x8_t a, int8x8_t b) noexcept {
647 auto left = register_order(a);
648 auto right = register_order(b);
649 uint8x8_t result;
650 asm volatile("ushl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
651 return register_order(result);
652 }
653
654 native_inline native_target("neon") uint8x16_t ushl(uint8x16_t a, int8x16_t b) noexcept {
655 auto left = register_order(a);
656 auto right = register_order(b);
657 uint8x16_t result;
658 asm volatile("ushl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
659 return register_order(result);
660 }
661
662 native_inline native_target("neon") uint16x4_t ushl(uint16x4_t a, int16x4_t b) noexcept {
663 auto left = register_order(a);
664 auto right = register_order(b);
665 uint16x4_t result;
666 asm volatile("ushl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
667 return register_order(result);
668 }
669
670 native_inline native_target("neon") uint16x8_t ushl(uint16x8_t a, int16x8_t b) noexcept {
671 auto left = register_order(a);
672 auto right = register_order(b);
673 uint16x8_t result;
674 asm volatile("ushl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
675 return register_order(result);
676 }
677
678 native_inline native_target("neon") uint32x2_t ushl(uint32x2_t a, int32x2_t b) noexcept {
679 auto left = register_order(a);
680 auto right = register_order(b);
681 uint32x2_t result;
682 asm volatile("ushl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
683 return register_order(result);
684 }
685
686 native_inline native_target("neon") uint32x4_t ushl(uint32x4_t a, int32x4_t b) noexcept {
687 auto left = register_order(a);
688 auto right = register_order(b);
689 uint32x4_t result;
690 asm volatile("ushl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
691 return register_order(result);
692 }
693
694 native_inline native_target("neon") uint64x1_t ushl(uint64x1_t a, int64x1_t b) noexcept {
695 auto left = register_order(a);
696 auto right = register_order(b);
697 uint64x1_t result;
698 asm volatile("ushl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
699 return register_order(result);
700 }
701
702 native_inline native_target("neon") uint64x2_t ushl(uint64x2_t a, int64x2_t b) noexcept {
703 auto left = register_order(a);
704 auto right = register_order(b);
705 uint64x2_t result;
706 asm volatile("ushl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
707 return register_order(result);
708 }
709
710 native_inline native_target("neon") uint8x8_t urshl(uint8x8_t a, int8x8_t b) noexcept {
711 auto left = register_order(a);
712 auto right = register_order(b);
713 uint8x8_t result;
714 asm volatile("urshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
715 return register_order(result);
716 }
717
718 native_inline native_target("neon") uint8x16_t urshl(uint8x16_t a, int8x16_t b) noexcept {
719 auto left = register_order(a);
720 auto right = register_order(b);
721 uint8x16_t result;
722 asm volatile("urshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
723 return register_order(result);
724 }
725
726 native_inline native_target("neon") uint16x4_t urshl(uint16x4_t a, int16x4_t b) noexcept {
727 auto left = register_order(a);
728 auto right = register_order(b);
729 uint16x4_t result;
730 asm volatile("urshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
731 return register_order(result);
732 }
733
734 native_inline native_target("neon") uint16x8_t urshl(uint16x8_t a, int16x8_t b) noexcept {
735 auto left = register_order(a);
736 auto right = register_order(b);
737 uint16x8_t result;
738 asm volatile("urshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
739 return register_order(result);
740 }
741
742 native_inline native_target("neon") uint32x2_t urshl(uint32x2_t a, int32x2_t b) noexcept {
743 auto left = register_order(a);
744 auto right = register_order(b);
745 uint32x2_t result;
746 asm volatile("urshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
747 return register_order(result);
748 }
749
750 native_inline native_target("neon") uint32x4_t urshl(uint32x4_t a, int32x4_t b) noexcept {
751 auto left = register_order(a);
752 auto right = register_order(b);
753 uint32x4_t result;
754 asm volatile("urshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
755 return register_order(result);
756 }
757
758 native_inline native_target("neon") uint64x1_t urshl(uint64x1_t a, int64x1_t b) noexcept {
759 auto left = register_order(a);
760 auto right = register_order(b);
761 uint64x1_t result;
762 asm volatile("urshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
763 return register_order(result);
764 }
765
766 native_inline native_target("neon") uint64x2_t urshl(uint64x2_t a, int64x2_t b) noexcept {
767 auto left = register_order(a);
768 auto right = register_order(b);
769 uint64x2_t result;
770 asm volatile("urshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
771 return register_order(result);
772 }
773
774 native_inline native_target("neon") uint8x8_t uqshl(uint8x8_t a, int8x8_t b) noexcept {
775 auto left = register_order(a);
776 auto right = register_order(b);
777 uint8x8_t result;
778 asm volatile("uqshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
779 return register_order(result);
780 }
781
782 native_inline native_target("neon") uint8x16_t uqshl(uint8x16_t a, int8x16_t b) noexcept {
783 auto left = register_order(a);
784 auto right = register_order(b);
785 uint8x16_t result;
786 asm volatile("uqshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
787 return register_order(result);
788 }
789
790 native_inline native_target("neon") uint16x4_t uqshl(uint16x4_t a, int16x4_t b) noexcept {
791 auto left = register_order(a);
792 auto right = register_order(b);
793 uint16x4_t result;
794 asm volatile("uqshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
795 return register_order(result);
796 }
797
798 native_inline native_target("neon") uint16x8_t uqshl(uint16x8_t a, int16x8_t b) noexcept {
799 auto left = register_order(a);
800 auto right = register_order(b);
801 uint16x8_t result;
802 asm volatile("uqshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
803 return register_order(result);
804 }
805
806 native_inline native_target("neon") uint32x2_t uqshl(uint32x2_t a, int32x2_t b) noexcept {
807 auto left = register_order(a);
808 auto right = register_order(b);
809 uint32x2_t result;
810 asm volatile("uqshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
811 return register_order(result);
812 }
813
814 native_inline native_target("neon") uint32x4_t uqshl(uint32x4_t a, int32x4_t b) noexcept {
815 auto left = register_order(a);
816 auto right = register_order(b);
817 uint32x4_t result;
818 asm volatile("uqshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
819 return register_order(result);
820 }
821
822 native_inline native_target("neon") uint64x1_t uqshl(uint64x1_t a, int64x1_t b) noexcept {
823 auto left = register_order(a);
824 auto right = register_order(b);
825 uint64x1_t result;
826 asm volatile("uqshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
827 return register_order(result);
828 }
829
830 native_inline native_target("neon") uint64x2_t uqshl(uint64x2_t a, int64x2_t b) noexcept {
831 auto left = register_order(a);
832 auto right = register_order(b);
833 uint64x2_t result;
834 asm volatile("uqshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
835 return register_order(result);
836 }
837
838 native_inline native_target("neon") uint8x8_t uqrshl(uint8x8_t a, int8x8_t b) noexcept {
839 auto left = register_order(a);
840 auto right = register_order(b);
841 uint8x8_t result;
842 asm volatile("uqrshl %0.8b, %1.8b, %2.8b" : "=w"(result) : "w"(left), "w"(right));
843 return register_order(result);
844 }
845
846 native_inline native_target("neon") uint8x16_t uqrshl(uint8x16_t a, int8x16_t b) noexcept {
847 auto left = register_order(a);
848 auto right = register_order(b);
849 uint8x16_t result;
850 asm volatile("uqrshl %0.16b, %1.16b, %2.16b" : "=w"(result) : "w"(left), "w"(right));
851 return register_order(result);
852 }
853
854 native_inline native_target("neon") uint16x4_t uqrshl(uint16x4_t a, int16x4_t b) noexcept {
855 auto left = register_order(a);
856 auto right = register_order(b);
857 uint16x4_t result;
858 asm volatile("uqrshl %0.4h, %1.4h, %2.4h" : "=w"(result) : "w"(left), "w"(right));
859 return register_order(result);
860 }
861
862 native_inline native_target("neon") uint16x8_t uqrshl(uint16x8_t a, int16x8_t b) noexcept {
863 auto left = register_order(a);
864 auto right = register_order(b);
865 uint16x8_t result;
866 asm volatile("uqrshl %0.8h, %1.8h, %2.8h" : "=w"(result) : "w"(left), "w"(right));
867 return register_order(result);
868 }
869
870 native_inline native_target("neon") uint32x2_t uqrshl(uint32x2_t a, int32x2_t b) noexcept {
871 auto left = register_order(a);
872 auto right = register_order(b);
873 uint32x2_t result;
874 asm volatile("uqrshl %0.2s, %1.2s, %2.2s" : "=w"(result) : "w"(left), "w"(right));
875 return register_order(result);
876 }
877
878 native_inline native_target("neon") uint32x4_t uqrshl(uint32x4_t a, int32x4_t b) noexcept {
879 auto left = register_order(a);
880 auto right = register_order(b);
881 uint32x4_t result;
882 asm volatile("uqrshl %0.4s, %1.4s, %2.4s" : "=w"(result) : "w"(left), "w"(right));
883 return register_order(result);
884 }
885
886 native_inline native_target("neon") uint64x1_t uqrshl(uint64x1_t a, int64x1_t b) noexcept {
887 auto left = register_order(a);
888 auto right = register_order(b);
889 uint64x1_t result;
890 asm volatile("uqrshl %d0, %d1, %d2" : "=w"(result) : "w"(left), "w"(right));
891 return register_order(result);
892 }
893
894 native_inline native_target("neon") uint64x2_t uqrshl(uint64x2_t a, int64x2_t b) noexcept {
895 auto left = register_order(a);
896 auto right = register_order(b);
897 uint64x2_t result;
898 asm volatile("uqrshl %0.2d, %1.2d, %2.2d" : "=w"(result) : "w"(left), "w"(right));
899 return register_order(result);
900 }
901
902 native_inline native_target("neon") int8x8_t sqxtn(int16x8_t a) noexcept {
903 auto source = register_order(a);
904 int8x8_t result;
905 asm volatile("sqxtn %0.8b, %1.8h" : "=w"(result) : "w"(source));
906 return register_order(result);
907 }
908
909 native_inline native_target("neon") int8x16_t sqxtn_high(int8x8_t low, int16x8_t a) noexcept {
910 auto result = low_register(low);
911 auto source = register_order(a);
912 asm volatile("sqxtn2 %0.16b, %1.8h" : "+w"(result) : "w"(source));
913 return register_order(result);
914 }
915
916 native_inline native_target("neon") int16x4_t sqxtn(int32x4_t a) noexcept {
917 auto source = register_order(a);
918 int16x4_t result;
919 asm volatile("sqxtn %0.4h, %1.4s" : "=w"(result) : "w"(source));
920 return register_order(result);
921 }
922
923 native_inline native_target("neon") int16x8_t sqxtn_high(int16x4_t low, int32x4_t a) noexcept {
924 auto result = low_register(low);
925 auto source = register_order(a);
926 asm volatile("sqxtn2 %0.8h, %1.4s" : "+w"(result) : "w"(source));
927 return register_order(result);
928 }
929
930 native_inline native_target("neon") int32x2_t sqxtn(int64x2_t a) noexcept {
931 auto source = register_order(a);
932 int32x2_t result;
933 asm volatile("sqxtn %0.2s, %1.2d" : "=w"(result) : "w"(source));
934 return register_order(result);
935 }
936
937 native_inline native_target("neon") int32x4_t sqxtn_high(int32x2_t low, int64x2_t a) noexcept {
938 auto result = low_register(low);
939 auto source = register_order(a);
940 asm volatile("sqxtn2 %0.4s, %1.2d" : "+w"(result) : "w"(source));
941 return register_order(result);
942 }
943
944 native_inline native_target("neon") uint8x8_t uqxtn(uint16x8_t a) noexcept {
945 auto source = register_order(a);
946 uint8x8_t result;
947 asm volatile("uqxtn %0.8b, %1.8h" : "=w"(result) : "w"(source));
948 return register_order(result);
949 }
950
951 native_inline native_target("neon") uint8x16_t uqxtn_high(uint8x8_t low, uint16x8_t a) noexcept {
952 auto result = low_register(low);
953 auto source = register_order(a);
954 asm volatile("uqxtn2 %0.16b, %1.8h" : "+w"(result) : "w"(source));
955 return register_order(result);
956 }
957
958 native_inline native_target("neon") uint16x4_t uqxtn(uint32x4_t a) noexcept {
959 auto source = register_order(a);
960 uint16x4_t result;
961 asm volatile("uqxtn %0.4h, %1.4s" : "=w"(result) : "w"(source));
962 return register_order(result);
963 }
964
965 native_inline native_target("neon") uint16x8_t uqxtn_high(uint16x4_t low, uint32x4_t a) noexcept {
966 auto result = low_register(low);
967 auto source = register_order(a);
968 asm volatile("uqxtn2 %0.8h, %1.4s" : "+w"(result) : "w"(source));
969 return register_order(result);
970 }
971
972 native_inline native_target("neon") uint32x2_t uqxtn(uint64x2_t a) noexcept {
973 auto source = register_order(a);
974 uint32x2_t result;
975 asm volatile("uqxtn %0.2s, %1.2d" : "=w"(result) : "w"(source));
976 return register_order(result);
977 }
978
979 native_inline native_target("neon") uint32x4_t uqxtn_high(uint32x2_t low, uint64x2_t a) noexcept {
980 auto result = low_register(low);
981 auto source = register_order(a);
982 asm volatile("uqxtn2 %0.4s, %1.2d" : "+w"(result) : "w"(source));
983 return register_order(result);
984 }
985
986 native_inline native_target("neon") uint8x8_t sqxtun(int16x8_t a) noexcept {
987 auto source = register_order(a);
988 uint8x8_t result;
989 asm volatile("sqxtun %0.8b, %1.8h" : "=w"(result) : "w"(source));
990 return register_order(result);
991 }
992
993 native_inline native_target("neon") uint8x16_t sqxtun_high(uint8x8_t low, int16x8_t a) noexcept {
994 auto result = low_register(low);
995 auto source = register_order(a);
996 asm volatile("sqxtun2 %0.16b, %1.8h" : "+w"(result) : "w"(source));
997 return register_order(result);
998 }
999
1000 native_inline native_target("neon") uint16x4_t sqxtun(int32x4_t a) noexcept {
1001 auto source = register_order(a);
1002 uint16x4_t result;
1003 asm volatile("sqxtun %0.4h, %1.4s" : "=w"(result) : "w"(source));
1004 return register_order(result);
1005 }
1006
1007 native_inline native_target("neon") uint16x8_t sqxtun_high(uint16x4_t low, int32x4_t a) noexcept {
1008 auto result = low_register(low);
1009 auto source = register_order(a);
1010 asm volatile("sqxtun2 %0.8h, %1.4s" : "+w"(result) : "w"(source));
1011 return register_order(result);
1012 }
1013
1014 native_inline native_target("neon") uint32x2_t sqxtun(int64x2_t a) noexcept {
1015 auto source = register_order(a);
1016 uint32x2_t result;
1017 asm volatile("sqxtun %0.2s, %1.2d" : "=w"(result) : "w"(source));
1018 return register_order(result);
1019 }
1020
1021 native_inline native_target("neon") uint32x4_t sqxtun_high(uint32x2_t low, int64x2_t a) noexcept {
1022 auto result = low_register(low);
1023 auto source = register_order(a);
1024 asm volatile("sqxtun2 %0.4s, %1.2d" : "+w"(result) : "w"(source));
1025 return register_order(result);
1026 }
1027} // namespace native::detail::arm_neon
1028#endif
Compiler attributes for host code, with shader-safe shared modifiers.
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
Definition attributes.h:476