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/module.hpp"
8#include <type_traits>
9
10#ifdef HI_HAS_SSE
11#include <xmmintrin.h>
12#endif
13#ifdef HI_HAS_SSE2
14#include <emmintrin.h>
15#endif
16#ifdef HI_HAS_SSE3
17#include <pmmintrin.h>
18#endif
19#ifdef HI_HAS_SSSE3
20#include <tmmintrin.h>
21#endif
22#ifdef HI_HAS_SSE4_1
23#include <smmintrin.h>
24#endif
25#ifdef HI_HAS_SSE4_2
26#include <nmmintrin.h>
27#endif
28#ifdef HI_HAS_AVX
29#include <immintrin.h>
30#endif
31#ifdef HI_HAS_AVX512F
32#include <immintrin.h>
33#endif
34
35namespace hi { inline namespace v1 {
36
37#ifdef HI_HAS_SSE
38enum class native_rounding_mode : int {
39 nearest = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC,
40 negative_infinite = _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC,
41 positive_infinite = _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC,
42 truncate = _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC,
43
46 current = _MM_FROUND_CUR_DIRECTION
47};
48#endif
49
50namespace detail {
51
66template<fixed_string SourceElements, size_t NumElements>
67[[nodiscard]] constexpr size_t native_swizzle_to_packed_indices() noexcept
68{
69 constexpr auto max_elements = sizeof(size_t) == 8 ? 16 : 8;
70 static_assert(NumElements > 1 and NumElements <= max_elements and std::has_single_bit(NumElements));
71 static_assert(SourceElements.size() <= NumElements);
72
73 constexpr auto shift = std::bit_width(NumElements - 1);
74
75 auto r = 0_uz;
76
77 auto i = NumElements;
78
79 // Unspecified elements will retain their original position.
80 for (; i != SourceElements.size(); --i) {
81 r <<= shift;
82 r |= i - 1;
83 }
84
85 for (; i != 0; --i) {
86 hilet c = SourceElements[i - 1];
87
88 r <<= shift;
89 if (c >= '0' and c <= '9') {
90 // Numeric elements will retain their original position.
91 r |= i - 1;
92
93 } else if (c >= 'a' and c <= 'p') {
94 r |= char_cast<size_t>(c - 'a');
95
96 } else if (c >= 'x' and c <= 'z') {
97 r |= char_cast<size_t>(c - 'x');
98
99 } else if (c == 'w') {
100 r |= 3;
101
102 } else {
104 }
105 }
106
107 return r;
108}
109
121template<fixed_string SourceElements, size_t NumElements, char Value>
122[[nodiscard]] constexpr size_t native_swizzle_to_mask() noexcept
123{
124 static_assert(NumElements > 1 and NumElements <= sizeof(size_t) * CHAR_BIT and std::has_single_bit(NumElements));
125 static_assert(SourceElements.size() <= NumElements);
126
127 auto r = 0_uz;
128
129 auto i = NumElements;
130
131 // Unspecified elements will be treated as '0'.
132 for (; i != SourceElements.size(); --i) {
133 r <<= 1;
134 r |= wide_cast<size_t>(Value == '0');
135 }
136
137 for (; i != 0; --i) {
138 hilet c = SourceElements[i - 1];
139
140 r <<= 1;
141 r |= wide_cast<size_t>(c == Value);
142 }
143
144 return r;
145}
146
147} // namespace detail
148
158template<typename T, size_t N>
160
161}} // namespace hi::v1
162
163template<typename T, size_t N>
165 [[nodiscard]] constexpr bool operator()(::hi::native_simd<T, N> const& lhs, ::hi::native_simd<T, N> const& rhs) noexcept
166 {
167 return equal(lhs, rhs);
168 }
169};
170
171namespace testing::internal {
172
173// Add equality operator to Google-test internal namespace so that ASSERT_EQ() work.
174template<typename T, size_t N>
175inline bool operator==(::hi::native_simd<T, N> lhs, ::hi::native_simd<T, N> rhs) noexcept
176{
177 return std::equal_to<::hi::native_simd<T, N>>{}(lhs, rhs);
178}
179
180// Add equality operator to Google-test internal namespace so that ASSERT_NE() work.
181template<typename T, size_t N>
183{
184 return not std::equal_to<::hi::native_simd<T, N>>{}(lhs, rhs);
185}
186
187} // namespace testing::internal
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
@ current
Continue from the current position.
@ truncate
After the file has been opened, truncate it.
DOXYGEN BUG.
Definition algorithm.hpp:13
@ shift
The shift key is being held.
geometry/margins.hpp
Definition cache.hpp:11
A native-SIMD type.
Definition native_simd_utility.hpp:159
T equal(T... args)
T operator!=(T... args)