20hi_warning_ignore_msvc(26818);
22namespace hi {
inline namespace v1 {
24template<s
size_t A, s
size_t B, s
size_t C, s
size_t D>
25[[nodiscard]]
constexpr static int _mm_swizzle_ps_permute_mask() noexcept
27 static_assert(A >= -3 and A < 4);
28 static_assert(B >= -3 and B < 4);
29 static_assert(C >= -3 and C < 4);
30 static_assert(D >= -3 and D < 4);
116template<s
size_t A, s
size_t B, s
size_t C, s
size_t D>
117[[nodiscard]]
constexpr static int _mm_swizzle_ps_not_one_mask() noexcept
119 static_assert(A >= -3 && A < 4);
120 static_assert(B >= -3 && B < 4);
121 static_assert(C >= -3 && C < 4);
122 static_assert(D >= -3 && D < 4);
125 r |= (A == -2) ? 0 : 0b0001;
126 r |= (B == -2) ? 0 : 0b0010;
127 r |= (C == -2) ? 0 : 0b0100;
128 r |= (D == -2) ? 0 : 0b1000;
132template<s
size_t A, s
size_t B, s
size_t C, s
size_t D>
133[[nodiscard]]
constexpr static int _mm_swizzle_ps_number_mask() noexcept
135 static_assert(A >= -3 && A < 4);
136 static_assert(B >= -3 && B < 4);
137 static_assert(C >= -3 && C < 4);
138 static_assert(D >= -3 && D < 4);
141 r |= A < 0 ? 0b0001 : 0;
142 r |= B < 0 ? 0b0010 : 0;
143 r |= C < 0 ? 0b0100 : 0;
144 r |= D < 0 ? 0b1000 : 0;
148template<s
size_t A, s
size_t B, s
size_t C, s
size_t D>
149[[nodiscard]] __m128 _mm_swizzle_ps(__m128
const& value)
noexcept
151 static_assert(A >= -3 && A < 4);
152 static_assert(B >= -3 && B < 4);
153 static_assert(C >= -3 && C < 4);
154 static_assert(D >= -3 && D < 4);
156 constexpr int permute_mask = _mm_swizzle_ps_permute_mask<A, B, C, D>();
157 constexpr int not_one_mask = _mm_swizzle_ps_not_one_mask<A, B, C, D>();
158 constexpr int number_mask = _mm_swizzle_ps_number_mask<A, B, C, D>();
160 hilet swizzled = [&] {
162 if constexpr (permute_mask != 0b11'10'01'00) {
163 return _mm_permute_ps(value, permute_mask);
169 hilet numbers = [&] {
170 if constexpr (not_one_mask == 0b0000) {
171 return _mm_set_ps1(1.0f);
172 }
else if constexpr (not_one_mask == 0b1111) {
173 return _mm_setzero_ps();
174 }
else if constexpr (not_one_mask == 0b1110) {
175 return _mm_set_ss(1.0f);
177 hilet _1111 = _mm_set_ps1(1.0f);
178 return _mm_insert_ps(_1111, _1111, not_one_mask);
182 if constexpr (number_mask == 0b0000) {
184 }
else if constexpr (number_mask == 0b1111) {
186 }
else if constexpr (((not_one_mask | ~number_mask) & 0b1111) == 0b1111) {
187 return _mm_insert_ps(swizzled, swizzled, number_mask);
189 return _mm_blend_ps(swizzled, numbers, number_mask);
193template<s
size_t A, s
size_t B, s
size_t C, s
size_t D>
194[[nodiscard]] __m128i _mm_swizzle_epi32(__m128i
const& value)
noexcept
196 static_assert(A >= -3 && A < 4);
197 static_assert(B >= -3 && B < 4);
198 static_assert(C >= -3 && C < 4);
199 static_assert(D >= -3 && D < 4);
201 constexpr int permute_mask = _mm_swizzle_ps_permute_mask<A, B, C, D>();
202 constexpr int not_one_mask = _mm_swizzle_ps_not_one_mask<A, B, C, D>();
203 constexpr int number_mask = _mm_swizzle_ps_number_mask<A, B, C, D>();
205 hilet swizzled = [&] {
207 if constexpr (permute_mask != 0b11'10'01'00) {
208 return _mm_castps_si128(_mm_permute_ps(_mm_castsi128_ps(value), permute_mask));
214 hilet numbers = [&] {
215 if constexpr (not_one_mask == 0b0000) {
216 return _mm_set1_epi32(1);
217 }
else if constexpr (not_one_mask == 0b1111) {
218 return _mm_setzero_si128();
220 hilet _1111 = _mm_castsi128_ps(_mm_set1_epi32(1));
221 return _mm_castps_si128(_mm_insert_ps(_1111, _1111, not_one_mask));
225 if constexpr (number_mask == 0b0000) {
227 }
else if constexpr (number_mask == 0b1111) {
229 }
else if constexpr (((not_one_mask | ~number_mask) & 0b1111) == 0b1111) {
230 return _mm_castps_si128(_mm_insert_ps(_mm_castsi128_ps(swizzled), _mm_castsi128_ps(swizzled), number_mask));
232 return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(swizzled), _mm_castsi128_ps(numbers), number_mask));
237[[nodiscard]] __m128d _mm_swizzle_pd(__m128d
const& value)
noexcept
239 constexpr auto A1 = A >= 0 ? A * 2 : A;
240 constexpr auto A2 = A >= 0 ? A1 + 1 : A1;
241 constexpr auto B1 = B >= 0 ? B * 2 : B;
242 constexpr auto B2 = B >= 0 ? B1 + 1 : B1;
244 return _mm_castps_pd(_mm_swizzle_ps<A1, A2, B1, B2>(_mm_castpd_ps(value)));
248[[nodiscard]] __m128i _mm_swizzle_epi64(__m128i
const& value)
noexcept
250 return _mm_castpd_si128(_mm_swizzle_pd<A, B>(_mm_castsi128_pd(value)));
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
std::ptrdiff_t ssize_t
Signed size/index into an array.
Definition utility.hpp:173