Mjolnir Core
Core functionality of the Mjolnir API
direct_access.h
Go to the documentation of this file.
1 
7 
8 #pragma once
9 
12 
13 namespace mjolnir::x86
14 {
17 
18 
32 template <FloatVectorRegister T_RegisterType>
33 [[nodiscard]] inline auto get(T_RegisterType src, UST index) noexcept -> ElementType<T_RegisterType>;
34 
35 
49 template <UST t_index, FloatVectorRegister T_RegisterType>
50 [[nodiscard]] inline auto get(T_RegisterType src) noexcept -> ElementType<T_RegisterType>;
51 
52 
65 template <FloatVectorRegister T_RegisterType>
66 inline void set(T_RegisterType& dst, UST index, ElementType<T_RegisterType> value) noexcept;
67 
68 
81 template <UST t_index, FloatVectorRegister T_RegisterType>
82 inline void set(T_RegisterType& dst, ElementType<T_RegisterType> value) noexcept;
83 
84 
86 } // namespace mjolnir::x86
87 
88 
89 // === DEFINITIONS ====================================================================================================
90 
93 
94 #include <array>
95 #include <cassert>
96 
97 namespace mjolnir::x86
98 {
99 // --------------------------------------------------------------------------------------------------------------------
100 
101 template <FloatVectorRegister T_RegisterType>
102 [[nodiscard]] inline auto get(T_RegisterType src, UST index) noexcept -> ElementType<T_RegisterType>
103 {
104  assert(index < num_elements<T_RegisterType>); // NOLINT
105 
106  VectorDataArray<T_RegisterType> array = {{0}};
107 
108  mm_store(array.data(), src);
109  return array[index];
110 }
111 
112 
113 // --------------------------------------------------------------------------------------------------------------------
114 
115 template <UST t_index, FloatVectorRegister T_RegisterType>
116 [[nodiscard]] inline auto get(T_RegisterType src) noexcept -> ElementType<T_RegisterType>
117 {
118  static_assert(t_index < num_elements<T_RegisterType>, "Index out of bounds.");
119 
120  if constexpr (t_index == 0)
121  return mm_cvt_float(src);
122  else if constexpr (t_index < num_lane_elements<T_RegisterType>)
123  return mm_cvt_float(broadcast<t_index>(src));
124  else
125  return mm_cvt_float(broadcast_across_lanes<t_index>(src));
126 }
127 
128 
129 // --------------------------------------------------------------------------------------------------------------------
130 
131 template <FloatVectorRegister T_RegisterType>
132 inline void set(T_RegisterType& dst, UST index, ElementType<T_RegisterType> value) noexcept
133 {
134  assert(index < num_elements<T_RegisterType>); // NOLINT
135 
136  VectorDataArray<T_RegisterType> array = {{0}};
137 
138  mm_store(array.data(), dst);
139  array[index] = value;
140  dst = mm_load<T_RegisterType>(array.data());
141 }
142 
143 
144 // --------------------------------------------------------------------------------------------------------------------
145 
146 template <UST t_index, FloatVectorRegister T_RegisterType>
147 inline void set(T_RegisterType& dst, ElementType<T_RegisterType> value) noexcept
148 {
149  static_assert(t_index < num_elements<T_RegisterType>, "Index out of bounds.");
150 
151  auto tmp = mm_set1<T_RegisterType>(value);
152  dst = blend_at<t_index>(dst, tmp);
153 }
154 
155 } // namespace mjolnir::x86
Defines the fundamental data types.
std::size_t UST
Unsigned integer type that is returned by sizeof operations.
Definition: fundamental_types.h:29
auto get(T_RegisterType src) noexcept -> ElementType< T_RegisterType >
Get the value of a specific element from a vector register.
Definition: direct_access.h:116
auto mm_cvt_float(T_RegisterType src) -> ElementType< T_RegisterType >
Return the first element of src.
Definition: intrinsics.h:739
void set(T_RegisterType &dst, ElementType< T_RegisterType > value) noexcept
Set the value of a specific vector register element.
Definition: direct_access.h:147
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
void mm_store(ElementType< T_RegisterType > *ptr, T_RegisterType reg) noexcept
Store the content of a register to a memory address.
Definition: intrinsics.h:943
Contains generalized/template versions of the x86 intrinsics.
Contains functions to permute and blend the elements of vector registers.
A std::array of correct alignment, type and size to store all elements of a vector register type.
Definition: definitions.h:286
Contains x86 vectorization specific constants, concepts and definitions.