native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
bits_body.h
Go to the documentation of this file.
1
2namespace NATIVE_BACKEND_NAMESPACE::native {
3 namespace detail {
4 template<class V> struct fp32_bit_bridge;
5 template<std::size_t N, ::native::isa<> Arch>
6 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<N>
7 struct fp32_bit_bridge<::native::simd<float,N,Arch>> {
8 using value_type=::native::simd<float,N,Arch>;
9 using bits_type=typename value_type::bits_type;
10 static native_inline constexpr bits_type encode(value_type x) noexcept { return x.bits(); }
11 static native_inline constexpr value_type decode(bits_type x) noexcept { return value_type::from_bits(x); }
12 };
13 } // namespace detail
14 template <class V>
15 concept fp32_bits_register = requires { typename detail::fp32_bit_bridge<V>::bits_type; };
16
17} // namespace NATIVE_BACKEND_NAMESPACE::native
18
19namespace NATIVE_BACKEND_NAMESPACE::native {
20 namespace detail {
21 template <unsigned_register U> native_inline constexpr U flush_clear_bits(U bits, U clear) noexcept {
22 return bits & (clear ^ U(0xffffffffu));
23 }
24#if NATIVE_HAS_AVX2
25 native_inline constexpr uint32x8 flush_clear_bits(uint32x8 bits, uint32x8 clear) noexcept {
26 if consteval { return bits & (clear ^ uint32x8(0xffffffffu)); }
27 return uint32x8::from_native(_mm256_andnot_si256(clear.value, bits.value));
28 }
29#endif
30#if NATIVE_HAS_AVX512F && NATIVE_HAS_AVX512DQ
31 native_inline constexpr uint32x16 flush_clear_bits(uint32x16 bits, uint32x16 clear) noexcept {
32 if consteval { return bits & (clear ^ uint32x16(0xffffffffu)); }
33 return uint32x16::from_native(_mm512_andnot_si512(clear.value, bits.value));
34 }
35#endif
36#if NATIVE_HAS_ARM_NEON
37 native_inline constexpr uint32x4 flush_clear_bits(uint32x4 bits, uint32x4 clear) noexcept {
38 if consteval { return bits & (clear ^ uint32x4(0xffffffffu)); }
39 return uint32x4::from_native(vbicq_u8(bits.value, clear.value));
40 }
41#endif
42 } // namespace detail
43
51 template <fp32_bits_register V, std::size_t N>
52 native_inline constexpr std::array<V, N> flush_to_zero(std::array<V, N> const & x) noexcept {
53 if consteval {
54 std::array<V,N> result{};
55 for(std::size_t i=0;i<N;++i) result[i]=::native::detail::float_constant::map([](auto bits) {
56 return (bits&0x7f800000u)?bits:(bits&0x80000000u);
57 },x[i]);
58 return result;
59 }
60 if constexpr (N == 0) return {};
61 else {
62 auto const & [...value] = x;
63#if NATIVE_HAS_AVX512F && NATIVE_HAS_AVX512DQ
64 if constexpr (V::lanes == 16) {
65 // Include both signed zeros: DAZ may classify a denormal as zero.
66 auto const [...tiny] = std::array{_mm512_fpclass_ps_mask(value.value, 0x26)...};
67 auto const sign = _mm512_castsi512_ps(_mm512_set1_epi32(
68 std::bit_cast<std::int32_t>(0x80000000u)));
69 return {{V(_mm512_mask_and_ps(value.value, tiny, value.value, sign))...}};
70 } else
71#endif
72 {
73 using bridge = detail::fp32_bit_bridge<V>;
74 using U = typename bridge::bits_type;
75 auto [...bits] = std::array{bridge::encode(value)...};
76 auto const [...exponent] = std::array{(bits & U(0x7f800000u))...};
77 auto const [...zero] = std::array{mask_bits<uint32_t>(exponent == U(0))...};
78 auto const [...clear] = std::array{(zero & U(0x007fffffu))...};
79 ((bits = detail::flush_clear_bits(bits, clear)), ...);
80 return {{bridge::decode(bits)...}};
81 }
82 }
83 }
84
86 template <fp32_bits_register V> native_inline constexpr V flush_to_zero(V x) noexcept {
87 return flush_to_zero(std::array{x})[0];
88 }
89} // namespace NATIVE_BACKEND_NAMESPACE::native
90
91namespace native {
92 using ::NATIVE_BACKEND_NAMESPACE::native::flush_to_zero;
93}
94
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
constexpr auto mask_bits(simd< M, N, Arch > m) noexcept
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
constexpr std::array< V, N > flush_to_zero(std::array< V, N > const &x) noexcept
Replace binary32 subnormal lanes with signed zero. Both zero signs, normal values,...
Definition bits_body.h:52