4#include "native/isa_import.h"
5#include "native/arm/detail/integer_constant.h"
6#include "native/arm/rdm.h"
7#include "native/targets.h"
12#if NATIVE_HOST_NEON || defined(NATIVE_DOXYGEN)
28 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(Arch.has(arm_feature::rdm))
30 constexpr int16_t
sqrdmlah(int16_t accumulator, int16_t lhs, int16_t rhs) noexcept {
31 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
33 auto result = detail::sqrdmlah<Arch>(
42 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(!Arch.has(arm_feature::rdm))
44 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
48 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
51 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
53 auto result = detail::sqrdmlah_lane<Arch, Lane>(
56 __builtin_bit_cast(int16x4_t, rhs.to_native()));
62 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
64 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
68 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
70 constexpr int16_t
sqrdmlah_lane(int16_t accumulator, int16_t lhs,
simd<
std::int16_t, 8, Arch> rhs) noexcept {
71 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
73 auto result = detail::sqrdmlah_lane<Arch, Lane>(
76 __builtin_bit_cast(int16x8_t, rhs.to_native()));
82 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
84 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
88 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
91 simd<
std::int16_t, 4, Arch> accumulator,
92 simd<
std::int16_t, 4, Arch> lhs,
93 simd<
std::int16_t, 4, Arch> rhs) noexcept {
94 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
96 auto result = detail::sqrdmlah<Arch>(
97 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
98 __builtin_bit_cast(int16x4_t, lhs.to_native()),
99 __builtin_bit_cast(int16x4_t, rhs.to_native()));
105 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
110 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
114 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
117 simd<
std::int16_t, 4, Arch> accumulator,
118 simd<
std::int16_t, 4, Arch> lhs,
119 simd<
std::int16_t, 4, Arch> rhs) noexcept {
120 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
122 auto result = detail::sqrdmlah_lane<Arch, Lane>(
123 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
124 __builtin_bit_cast(int16x4_t, lhs.to_native()),
125 __builtin_bit_cast(int16x4_t, rhs.to_native()));
131 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
136 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
140 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
143 simd<
std::int16_t, 4, Arch> accumulator,
144 simd<
std::int16_t, 4, Arch> lhs,
145 simd<
std::int16_t, 8, Arch> rhs) noexcept {
146 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
148 auto result = detail::sqrdmlah_lane<Arch, Lane>(
149 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
150 __builtin_bit_cast(int16x4_t, lhs.to_native()),
151 __builtin_bit_cast(int16x8_t, rhs.to_native()));
157 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>);
sizeof(simd<std::int16_t, 8, Arch>); })
162 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
166 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
169 simd<
std::int16_t, 8, Arch> accumulator,
170 simd<
std::int16_t, 8, Arch> lhs,
171 simd<
std::int16_t, 8, Arch> rhs) noexcept {
172 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
174 auto result = detail::sqrdmlah<Arch>(
175 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
176 __builtin_bit_cast(int16x8_t, lhs.to_native()),
177 __builtin_bit_cast(int16x8_t, rhs.to_native()));
183 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
188 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
192 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
195 simd<
std::int16_t, 8, Arch> accumulator,
196 simd<
std::int16_t, 8, Arch> lhs,
197 simd<
std::int16_t, 4, Arch> rhs) noexcept {
198 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
200 auto result = detail::sqrdmlah_lane<Arch, Lane>(
201 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
202 __builtin_bit_cast(int16x8_t, lhs.to_native()),
203 __builtin_bit_cast(int16x4_t, rhs.to_native()));
209 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>);
sizeof(simd<std::int16_t, 4, Arch>); })
214 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
218 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
221 simd<
std::int16_t, 8, Arch> accumulator,
222 simd<
std::int16_t, 8, Arch> lhs,
223 simd<
std::int16_t, 8, Arch> rhs) noexcept {
224 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
226 auto result = detail::sqrdmlah_lane<Arch, Lane>(
227 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
228 __builtin_bit_cast(int16x8_t, lhs.to_native()),
229 __builtin_bit_cast(int16x8_t, rhs.to_native()));
235 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
240 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
244 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(Arch.has(arm_feature::rdm))
246 constexpr int32_t
sqrdmlah(int32_t accumulator, int32_t lhs, int32_t rhs) noexcept {
247 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
249 auto result = detail::sqrdmlah<Arch>(
258 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(!Arch.has(arm_feature::rdm))
260 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
264 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
267 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
269 auto result = detail::sqrdmlah_lane<Arch, Lane>(
272 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
278 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
280 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
284 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
287 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
289 auto result = detail::sqrdmlah_lane<Arch, Lane>(
292 __builtin_bit_cast(int32x4_t, rhs.to_native()));
298 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
300 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
304 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
307 simd<
std::int32_t, 2, Arch> accumulator,
308 simd<
std::int32_t, 2, Arch> lhs,
309 simd<
std::int32_t, 2, Arch> rhs) noexcept {
310 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
312 auto result = detail::sqrdmlah<Arch>(
313 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
314 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
315 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
321 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
326 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
330 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
333 simd<
std::int32_t, 2, Arch> accumulator,
334 simd<
std::int32_t, 2, Arch> lhs,
335 simd<
std::int32_t, 2, Arch> rhs) noexcept {
336 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
338 auto result = detail::sqrdmlah_lane<Arch, Lane>(
339 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
340 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
341 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
347 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
352 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
356 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
359 simd<
std::int32_t, 2, Arch> accumulator,
360 simd<
std::int32_t, 2, Arch> lhs,
361 simd<
std::int32_t, 4, Arch> rhs) noexcept {
362 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
364 auto result = detail::sqrdmlah_lane<Arch, Lane>(
365 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
366 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
367 __builtin_bit_cast(int32x4_t, rhs.to_native()));
373 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>);
sizeof(simd<std::int32_t, 4, Arch>); })
378 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
382 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
385 simd<
std::int32_t, 4, Arch> accumulator,
386 simd<
std::int32_t, 4, Arch> lhs,
387 simd<
std::int32_t, 4, Arch> rhs) noexcept {
388 if consteval {
return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs); }
390 auto result = detail::sqrdmlah<Arch>(
391 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
392 __builtin_bit_cast(int32x4_t, lhs.to_native()),
393 __builtin_bit_cast(int32x4_t, rhs.to_native()));
399 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
404 return detail::arm_constant::rdm<
false, -1>(accumulator, lhs, rhs);
408 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
411 simd<
std::int32_t, 4, Arch> accumulator,
412 simd<
std::int32_t, 4, Arch> lhs,
413 simd<
std::int32_t, 2, Arch> rhs) noexcept {
414 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
416 auto result = detail::sqrdmlah_lane<Arch, Lane>(
417 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
418 __builtin_bit_cast(int32x4_t, lhs.to_native()),
419 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
425 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>);
sizeof(simd<std::int32_t, 2, Arch>); })
430 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
434 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
437 simd<
std::int32_t, 4, Arch> accumulator,
438 simd<
std::int32_t, 4, Arch> lhs,
439 simd<
std::int32_t, 4, Arch> rhs) noexcept {
440 if consteval {
return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs); }
442 auto result = detail::sqrdmlah_lane<Arch, Lane>(
443 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
444 __builtin_bit_cast(int32x4_t, lhs.to_native()),
445 __builtin_bit_cast(int32x4_t, rhs.to_native()));
451 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
456 return detail::arm_constant::rdm<false, Lane>(accumulator, lhs, rhs);
460 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(Arch.has(arm_feature::rdm))
462 constexpr int16_t
sqrdmlsh(int16_t accumulator, int16_t lhs, int16_t rhs) noexcept {
463 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
465 auto result = detail::sqrdmlsh<Arch>(
474 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(!Arch.has(arm_feature::rdm))
476 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
480 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
483 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
485 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
488 __builtin_bit_cast(int16x4_t, rhs.to_native()));
494 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
496 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
500 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
503 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
505 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
508 __builtin_bit_cast(int16x8_t, rhs.to_native()));
514 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
516 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
520 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
523 simd<
std::int16_t, 4, Arch> accumulator,
524 simd<
std::int16_t, 4, Arch> lhs,
525 simd<
std::int16_t, 4, Arch> rhs) noexcept {
526 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
528 auto result = detail::sqrdmlsh<Arch>(
529 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
530 __builtin_bit_cast(int16x4_t, lhs.to_native()),
531 __builtin_bit_cast(int16x4_t, rhs.to_native()));
537 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
542 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
546 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
549 simd<
std::int16_t, 4, Arch> accumulator,
550 simd<
std::int16_t, 4, Arch> lhs,
551 simd<
std::int16_t, 4, Arch> rhs) noexcept {
552 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
554 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
555 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
556 __builtin_bit_cast(int16x4_t, lhs.to_native()),
557 __builtin_bit_cast(int16x4_t, rhs.to_native()));
563 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>); })
568 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
572 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
575 simd<
std::int16_t, 4, Arch> accumulator,
576 simd<
std::int16_t, 4, Arch> lhs,
577 simd<
std::int16_t, 8, Arch> rhs) noexcept {
578 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
580 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
581 __builtin_bit_cast(int16x4_t, accumulator.to_native()),
582 __builtin_bit_cast(int16x4_t, lhs.to_native()),
583 __builtin_bit_cast(int16x8_t, rhs.to_native()));
589 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 4, Arch>);
sizeof(simd<std::int16_t, 8, Arch>); })
594 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
598 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
601 simd<
std::int16_t, 8, Arch> accumulator,
602 simd<
std::int16_t, 8, Arch> lhs,
603 simd<
std::int16_t, 8, Arch> rhs) noexcept {
604 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
606 auto result = detail::sqrdmlsh<Arch>(
607 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
608 __builtin_bit_cast(int16x8_t, lhs.to_native()),
609 __builtin_bit_cast(int16x8_t, rhs.to_native()));
615 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
620 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
624 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
627 simd<
std::int16_t, 8, Arch> accumulator,
628 simd<
std::int16_t, 8, Arch> lhs,
629 simd<
std::int16_t, 4, Arch> rhs) noexcept {
630 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
632 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
633 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
634 __builtin_bit_cast(int16x8_t, lhs.to_native()),
635 __builtin_bit_cast(int16x4_t, rhs.to_native()));
641 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>);
sizeof(simd<std::int16_t, 4, Arch>); })
646 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
650 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8)
653 simd<
std::int16_t, 8, Arch> accumulator,
654 simd<
std::int16_t, 8, Arch> lhs,
655 simd<
std::int16_t, 8, Arch> rhs) noexcept {
656 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
658 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
659 __builtin_bit_cast(int16x8_t, accumulator.to_native()),
660 __builtin_bit_cast(int16x8_t, lhs.to_native()),
661 __builtin_bit_cast(int16x8_t, rhs.to_native()));
667 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 8 &&
requires {
sizeof(simd<std::int16_t, 8, Arch>); })
672 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
676 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(Arch.has(arm_feature::rdm))
678 constexpr int32_t
sqrdmlsh(int32_t accumulator, int32_t lhs, int32_t rhs) noexcept {
679 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
681 auto result = detail::sqrdmlsh<Arch>(
690 template<isa<arm> Arch=NATIVE_BA
SELINE>
requires(!Arch.has(arm_feature::rdm))
692 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
696 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
699 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
701 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
704 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
710 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
712 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
716 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
719 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
721 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
724 __builtin_bit_cast(int32x4_t, rhs.to_native()));
730 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
732 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
736 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
739 simd<
std::int32_t, 2, Arch> accumulator,
740 simd<
std::int32_t, 2, Arch> lhs,
741 simd<
std::int32_t, 2, Arch> rhs) noexcept {
742 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
744 auto result = detail::sqrdmlsh<Arch>(
745 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
746 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
747 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
753 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
758 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
762 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
765 simd<
std::int32_t, 2, Arch> accumulator,
766 simd<
std::int32_t, 2, Arch> lhs,
767 simd<
std::int32_t, 2, Arch> rhs) noexcept {
768 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
770 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
771 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
772 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
773 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
779 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>); })
784 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
788 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
791 simd<
std::int32_t, 2, Arch> accumulator,
792 simd<
std::int32_t, 2, Arch> lhs,
793 simd<
std::int32_t, 4, Arch> rhs) noexcept {
794 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
796 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
797 vget_low_s32(__builtin_bit_cast(int32x4_t, accumulator.to_native())),
798 vget_low_s32(__builtin_bit_cast(int32x4_t, lhs.to_native())),
799 __builtin_bit_cast(int32x4_t, rhs.to_native()));
805 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 2, Arch>);
sizeof(simd<std::int32_t, 4, Arch>); })
810 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
814 template<isa<arm> Arch>
requires(Arch.has(arm_feature::rdm))
817 simd<
std::int32_t, 4, Arch> accumulator,
818 simd<
std::int32_t, 4, Arch> lhs,
819 simd<
std::int32_t, 4, Arch> rhs) noexcept {
820 if consteval {
return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs); }
822 auto result = detail::sqrdmlsh<Arch>(
823 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
824 __builtin_bit_cast(int32x4_t, lhs.to_native()),
825 __builtin_bit_cast(int32x4_t, rhs.to_native()));
831 template<isa<arm> Arch>
requires(!Arch.has(arm_feature::rdm) &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
836 return detail::arm_constant::rdm<
true, -1>(accumulator, lhs, rhs);
840 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2)
843 simd<
std::int32_t, 4, Arch> accumulator,
844 simd<
std::int32_t, 4, Arch> lhs,
845 simd<
std::int32_t, 2, Arch> rhs) noexcept {
846 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
848 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
849 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
850 __builtin_bit_cast(int32x4_t, lhs.to_native()),
851 vget_low_s32(__builtin_bit_cast(int32x4_t, rhs.to_native())));
857 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 2 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>);
sizeof(simd<std::int32_t, 2, Arch>); })
862 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
866 template<isa<arm> Arch,
int Lane>
requires(Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4)
869 simd<
std::int32_t, 4, Arch> accumulator,
870 simd<
std::int32_t, 4, Arch> lhs,
871 simd<
std::int32_t, 4, Arch> rhs) noexcept {
872 if consteval {
return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs); }
874 auto result = detail::sqrdmlsh_lane<Arch, Lane>(
875 __builtin_bit_cast(int32x4_t, accumulator.to_native()),
876 __builtin_bit_cast(int32x4_t, lhs.to_native()),
877 __builtin_bit_cast(int32x4_t, rhs.to_native()));
883 template<isa<arm> Arch,
int Lane>
requires(!Arch.has(arm_feature::rdm) && Lane >= 0 && Lane < 4 &&
requires {
sizeof(simd<std::int32_t, 4, Arch>); })
888 return detail::arm_constant::rdm<true, Lane>(accumulator, lhs, rhs);
892 template<isa<arm> Arch=NATIVE_BA
SELINE,
class A,
class B,
class C>
893 void sqrdmlah(A, B, C) =
delete;
894 template<isa<arm> Arch,
int Lane,
class A,
class B,
class C>
895 void sqrdmlah_lane(A, B, C) =
delete;
896 template<isa<arm> Arch=NATIVE_BA
SELINE,
class A,
class B,
class C>
897 void sqrdmlsh(A, B, C) =
delete;
898 template<isa<arm> Arch,
int Lane,
class A,
class B,
class C>
899 void sqrdmlsh_lane(A, B, C) =
delete;
constexpr int16_t sqrdmlah(int16_t accumulator, int16_t lhs, int16_t rhs) noexcept
SQRDMLAH: signed 16-bit rounding saturating add.
constexpr int16_t sqrdmlah_lane(int16_t accumulator, int16_t lhs, simd< std::int16_t, 4, Arch > rhs) noexcept
SQRDMLAH by element: broadcast rhs[Lane] before rounding and saturation.
constexpr int16_t sqrdmlsh_lane(int16_t accumulator, int16_t lhs, simd< std::int16_t, 4, Arch > rhs) noexcept
SQRDMLSH by element: broadcast rhs[Lane] before rounding and saturation.
constexpr int16_t sqrdmlsh(int16_t accumulator, int16_t lhs, int16_t rhs) noexcept
SQRDMLSH: signed 16-bit rounding saturating subtract.
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
constexpr int target
First matching requirement, with every later choice checked for shadowing.
Standard-library adaptations documented here for SIMD value types.
Omitted architecture arguments use the native.simd provider's baseline.