Mjolnir Core
Core functionality of the Mjolnir API
definitions.h
Go to the documentation of this file.
1 
7 
8 #pragma once
11 #include "mjolnir/core/x86/x86.h"
12 #include <type_traits>
13 
14 #include <array>
15 
16 // === DECLARATION ====================================================================================================
17 
18 namespace mjolnir::x86
19 {
22 
23 
29 template <typename T_Type>
30 concept VectorRegister = is_any_of<T_Type, __m128, __m128d, __m128i, __m256, __m256d, __m256i>();
31 
32 
38 template <typename T_Type>
39 concept FloatVectorRegister = is_any_of<T_Type, __m128, __m128d, __m256, __m256d>();
40 
41 
47 template <typename T_Type>
48 concept FloatSSERegister = is_any_of<T_Type, __m128, __m128d>();
49 
50 
56 template <typename T_Type>
57 concept FloatAVXRegister = is_any_of<T_Type, __m256, __m256d>();
58 
59 
65 template <typename T_Type>
66 concept SinglePrecisionVectorRegister = is_any_of<T_Type, __m128, __m256>();
67 
68 
74 template <typename T_Type>
75 concept DoublePrecisionVectorRegister = is_any_of<T_Type, __m128d, __m256d>();
76 
77 
83 template <typename T_Type>
84 concept IntegerVectorRegister = is_any_of<T_Type, __m128i, __m256i>();
85 
86 
92 template <typename T_Type>
93 inline constexpr bool is_m128 = std::is_same_v<T_Type, __m128>;
94 
95 
101 template <typename T_Type>
102 inline constexpr bool is_m128d = std::is_same_v<T_Type, __m128d>;
103 
104 
110 template <typename T_Type>
111 inline constexpr bool is_m128i = std::is_same_v<T_Type, __m128i>;
112 
113 
119 template <typename T_Type>
120 inline constexpr bool is_m256 = std::is_same_v<T_Type, __m256>;
121 
122 
128 template <typename T_Type>
129 inline constexpr bool is_m256d = std::is_same_v<T_Type, __m256d>;
130 
131 
137 template <typename T_Type>
138 inline constexpr bool is_m256i = std::is_same_v<T_Type, __m256i>;
139 
140 
146 template <typename T_Type>
147 inline constexpr bool is_vector_register = is_any_of<T_Type, __m128, __m128d, __m128i, __m256, __m256d, __m256i>();
148 
149 
155 template <typename T_Type>
156 inline constexpr bool is_sse_register = is_any_of<T_Type, __m128, __m128d, __m128i>();
157 
158 
164 template <typename T_Type>
165 inline constexpr bool is_avx_register = is_any_of<T_Type, __m256, __m256d, __m256i>();
166 
167 
173 template <typename T_Type>
174 inline constexpr bool is_float_register = is_any_of<T_Type, __m128, __m128d, __m256, __m256d>();
175 
176 
182 template <typename T_Type>
183 inline constexpr bool is_integer_register = is_any_of<T_Type, __m128i, __m256i>();
184 
185 
186 // ---internal declarations -------------------------------------------------------------------------------------------
187 
189 namespace internal
190 {
192 template <VectorRegister T_Type>
193 [[nodiscard]] consteval auto get_alignment_bytes() noexcept -> UST;
194 
196 template <VectorRegister T_Type>
197 [[nodiscard]] consteval auto get_num_lanes() noexcept -> UST;
198 
199 
200 } // namespace internal
202 
203 
204 // --- continued public declarations ----------------------------------------------------------------------------------
205 
211 template <FloatVectorRegister T_RegisterType>
212 using ElementType = typename std::conditional_t<is_any_of<T_RegisterType, __m128d, __m256d>(), F64, F32>;
213 
214 
220 template <FloatVectorRegister T_RegisterType>
221 inline constexpr bool is_single_precision = std::is_same_v<ElementType<T_RegisterType>, F32>;
222 
223 
229 template <FloatVectorRegister T_RegisterType>
230 inline constexpr bool is_double_precision = std::is_same_v<ElementType<T_RegisterType>, F64>;
231 
232 
238 template <VectorRegister T_RegisterType>
239 inline constexpr UST alignment_bytes = internal::get_alignment_bytes<T_RegisterType>();
240 
241 
247 template <VectorRegister T_RegisterType>
248 inline constexpr UST num_lanes = internal::get_num_lanes<T_RegisterType>();
249 
250 
256 template <FloatVectorRegister T_RegisterType>
257 inline constexpr UST num_elements = sizeof(T_RegisterType) / sizeof(ElementType<T_RegisterType>);
258 
259 
265 template <FloatVectorRegister T_RegisterType>
266 inline constexpr UST num_lane_elements = num_elements<T_RegisterType> / num_lanes<T_RegisterType>;
267 
268 
274 template <FloatVectorRegister T_RegisterType>
275 inline constexpr bool is_multi_lane = num_lanes<T_RegisterType> > 1;
276 
277 
283 template <FloatVectorRegister T_RegisterType>
284 struct alignas(alignment_bytes<T_RegisterType>) VectorDataArray
285  : public std::array<ElementType<T_RegisterType>, num_elements<T_RegisterType>>
286 {
287 };
288 
289 
291 } // namespace mjolnir::x86
292 
293 
294 // === DEFINITIONS ====================================================================================================
295 
297 namespace mjolnir::x86::internal
298 {
299 // --------------------------------------------------------------------------------------------------------------------
300 
301 template <VectorRegister T_Type>
302 [[nodiscard]] consteval auto get_alignment_bytes() noexcept -> UST
303 {
304  constexpr UST alignment_bytes_sse = 16;
305  constexpr UST alignment_bytes_avx = 32;
306 
307  if constexpr (is_sse_register<T_Type>)
308  return alignment_bytes_sse;
309  else
310  return alignment_bytes_avx;
311 }
312 
313 
314 // --------------------------------------------------------------------------------------------------------------------
315 
316 template <VectorRegister T_Type>
317 [[nodiscard]] consteval auto get_num_lanes() noexcept -> UST
318 {
319  constexpr UST num_lanes_sse = 1;
320  constexpr UST num_lanes_avx = 2;
321 
322  if constexpr (is_sse_register<T_Type>)
323  return num_lanes_sse;
324  else
325  return num_lanes_avx;
326 }
327 
328 
329 } // namespace mjolnir::x86::internal
Defines the fundamental data types.
float F32
32 bit floating point type
Definition: fundamental_types.h:31
std::size_t UST
Unsigned integer type that is returned by sizeof operations.
Definition: fundamental_types.h:29
double F64
64 bit floating point type
Definition: fundamental_types.h:32
consteval auto is_any_of() noexcept -> bool
Return true if the tested type is identical to any of a list of types.
Definition: type.h:77
constexpr bool is_single_precision
true if the element type has single precision and false otherwise.
Definition: definitions.h:221
constexpr bool is_m128d
Type dependent constant that is only true for __m128d and false for all other types.
Definition: definitions.h:102
concept IntegerVectorRegister
Concept for a x86 vector register that has integer elements.
Definition: definitions.h:84
concept SinglePrecisionVectorRegister
Concept for a x86 vector register that has single precision elements.
Definition: definitions.h:66
concept FloatAVXRegister
Concept for a x86 vector register that has floating-point elements.
Definition: definitions.h:57
concept VectorRegister
Concept for a x86 vector register.
Definition: definitions.h:30
constexpr bool is_integer_register
Type dependent constant that is only true for x86 vector registers that have integer types as element...
Definition: definitions.h:183
constexpr bool is_m128
Type dependent constant that is only true for __m128 and false for all other types.
Definition: definitions.h:93
typename std::conditional_t< is_any_of< T_RegisterType, __m128d, __m256d >(), F64, F32 > ElementType
The element type of an x86 vector register that is based on floating-point types.
Definition: definitions.h:212
constexpr UST alignment_bytes
Alignment requirement of an x86 vector register in bytes.
Definition: definitions.h:239
concept FloatSSERegister
Concept for a x86 SSE vector register that has floating-point elements.
Definition: definitions.h:48
constexpr bool is_vector_register
Type dependent constant that is only true for supported x86 vector registers.
Definition: definitions.h:147
constexpr UST num_lane_elements
Number of elements per register lane.
Definition: definitions.h:266
constexpr bool is_sse_register
Type dependent constant that is only true for SSE vector registers.
Definition: definitions.h:156
constexpr bool is_m128i
Type dependent constant that is only true for __m128i and false for all other types.
Definition: definitions.h:111
concept FloatVectorRegister
Concept for a x86 vector register that has floating-point elements.
Definition: definitions.h:39
constexpr bool is_double_precision
true if the element type has double precision and false otherwise.
Definition: definitions.h:230
concept DoublePrecisionVectorRegister
Concept for a x86 vector register that has double precision elements.
Definition: definitions.h:75
constexpr bool is_avx_register
Type dependent constant that is only true for AVX vector registers.
Definition: definitions.h:165
constexpr bool is_multi_lane
true if the register has multiple lanes and false otherwise.
Definition: definitions.h:275
constexpr bool is_m256d
Type dependent constant that is only true for __m256d and false for all other types.
Definition: definitions.h:129
constexpr bool is_float_register
Type dependent constant that is only true for x86 vector registers that have floating-point types as ...
Definition: definitions.h:174
constexpr bool is_m256i
Type dependent constant that is only true for __m256i and false for all other types.
Definition: definitions.h:138
constexpr UST num_elements
Number of register elements.
Definition: definitions.h:257
constexpr bool is_m256
Type dependent constant that is only true for __m256 and false for all other types.
Definition: definitions.h:120
constexpr UST num_lanes
Number of register lanes.
Definition: definitions.h:248
A std::array of correct alignment, type and size to store all elements of a vector register type.
Definition: definitions.h:286
Contains multiple utility functions for type related operations.
This header includes the correct x86 header depending on the operation system.