HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
native_simd_utility.hpp
1// Copyright Take Vos 2022, 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../utility/utility.hpp"
8#include "../macros.hpp"
9#include <type_traits>
10
11#ifdef HI_HAS_SSE
12#include <xmmintrin.h>
13#endif
14#ifdef HI_HAS_SSE2
15#include <emmintrin.h>
16#endif
17#ifdef HI_HAS_SSE3
18#include <pmmintrin.h>
19#endif
20#ifdef HI_HAS_SSSE3
21#include <tmmintrin.h>
22#endif
23#ifdef HI_HAS_SSE4_1
24#include <smmintrin.h>
25#endif
26#ifdef HI_HAS_SSE4_2
27#include <nmmintrin.h>
28#endif
29#ifdef HI_HAS_AVX
30#include <immintrin.h>
31#endif
32#ifdef HI_HAS_AVX512F
33#include <immintrin.h>
34#endif
35
36
37
38namespace hi { inline namespace v1 {
39
40#ifdef HI_HAS_SSE
41enum class native_rounding_mode : int {
46
50};
51#endif
52
53namespace detail {
54
69template<fixed_string SourceElements, size_t NumElements>
70[[nodiscard]] constexpr size_t native_swizzle_to_packed_indices() noexcept
71{
72 constexpr auto max_elements = sizeof(size_t) == 8 ? 16 : 8;
73 static_assert(NumElements > 1 and NumElements <= max_elements and std::has_single_bit(NumElements));
74 static_assert(SourceElements.size() <= NumElements);
75
76 constexpr auto shift = std::bit_width(NumElements - 1);
77
78 auto r = 0_uz;
79
80 auto i = NumElements;
81
82 // Unspecified elements will retain their original position.
83 for (; i != SourceElements.size(); --i) {
84 r <<= shift;
85 r |= i - 1;
86 }
87
88 for (; i != 0; --i) {
89 hilet c = SourceElements[i - 1];
90
91 r <<= shift;
92 if (c >= '0' and c <= '9') {
93 // Numeric elements will retain their original position.
94 r |= i - 1;
95
96 } else if (c >= 'a' and c <= 'p') {
97 r |= char_cast<size_t>(c - 'a');
98
99 } else if (c >= 'x' and c <= 'z') {
100 r |= char_cast<size_t>(c - 'x');
101
102 } else if (c == 'w') {
103 r |= 3;
104
105 } else {
106 hi_no_default();
107 }
108 }
109
110 return r;
111}
112
124template<fixed_string SourceElements, size_t NumElements, char Value>
125[[nodiscard]] constexpr size_t native_swizzle_to_mask() noexcept
126{
127 static_assert(NumElements > 1 and NumElements <= sizeof(size_t) * CHAR_BIT and std::has_single_bit(NumElements));
128 static_assert(SourceElements.size() <= NumElements);
129
130 auto r = 0_uz;
131
132 auto i = NumElements;
133
134 // Unspecified elements will be treated as '0'.
135 for (; i != SourceElements.size(); --i) {
136 r <<= 1;
137 r |= wide_cast<size_t>(Value == '0');
138 }
139
140 for (; i != 0; --i) {
141 hilet c = SourceElements[i - 1];
142
143 r <<= 1;
144 r |= wide_cast<size_t>(c == Value);
145 }
146
147 return r;
148}
149
150} // namespace detail
151
161template<typename T, size_t N>
163
164}} // namespace hi::v1
165
166template<typename T, size_t N>
168 [[nodiscard]] constexpr bool operator()(::hi::native_simd<T, N> const& lhs, ::hi::native_simd<T, N> const& rhs) noexcept
169 {
170 return equal(lhs, rhs);
171 }
172};
173
174namespace testing::internal {
175
176// Add equality operator to Google-test internal namespace so that ASSERT_EQ() work.
177template<typename T, size_t N>
178inline bool operator==(::hi::native_simd<T, N> lhs, ::hi::native_simd<T, N> rhs) noexcept
179{
180 return std::equal_to<::hi::native_simd<T, N>>{}(lhs, rhs);
181}
182
183// Add equality operator to Google-test internal namespace so that ASSERT_NE() work.
184template<typename T, size_t N>
186{
187 return not std::equal_to<::hi::native_simd<T, N>>{}(lhs, rhs);
188}
189
190} // namespace testing::internal
@ current
Continue from the current position.
@ truncate
After the file has been opened, truncate it.
DOXYGEN BUG.
Definition algorithm.hpp:16
@ shift
The shift key is being held.
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
A native-SIMD type.
Definition native_simd_utility.hpp:162
T equal(T... args)
T operator!=(T... args)