Storea.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SIMD_STOREA_H_
36 #define _BLAZE_MATH_SIMD_STOREA_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
44 #include <blaze/system/Inline.h>
47 #include <blaze/util/Assert.h>
48 #include <blaze/util/Complex.h>
49 #include <blaze/util/EnableIf.h>
50 #include <blaze/util/mpl/And.h>
54 
55 
56 namespace blaze {
57 
58 //=================================================================================================
59 //
60 // 8-BIT INTEGRAL SIMD TYPES
61 //
62 //=================================================================================================
63 
64 //*************************************************************************************************
76 template< typename T1 // Type of the integral value
77  , typename T2 > // Type of the SIMD data type
78 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
79  storea( T1* address, const SIMDi8<T2>& value ) noexcept
80 {
81  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
82 
83 #if BLAZE_AVX512BW_MODE
84  _mm512_store_si512( address, (~value).value );
85 #elif BLAZE_AVX2_MODE
86  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
87 #elif BLAZE_SSE2_MODE
88  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
89 #else
90  *address = (~value).value;
91 #endif
92 }
93 //*************************************************************************************************
94 
95 
96 //*************************************************************************************************
108 template< typename T1 // Type of the integral value
109  , typename T2 > // Type of the SIMD data type
110 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
111  storea( complex<T1>* address, const SIMDci8<T2>& value ) noexcept
112 {
113  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
114  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
115 
116 #if BLAZE_AVX512BW_MODE
117  _mm512_store_si512( address, (~value).value );
118 #elif BLAZE_AVX2_MODE
119  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
120 #elif BLAZE_SSE2_MODE
121  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
122 #else
123  *address = (~value).value;
124 #endif
125 }
126 //*************************************************************************************************
127 
128 
129 
130 
131 //=================================================================================================
132 //
133 // 16-BIT INTEGRAL SIMD TYPES
134 //
135 //=================================================================================================
136 
137 //*************************************************************************************************
149 template< typename T1 // Type of the integral value
150  , typename T2 > // Type of the SIMD data type
151 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
152  storea( T1* address, const SIMDi16<T2>& value ) noexcept
153 {
154  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
155 
156 #if BLAZE_AVX512BW_MODE
157  _mm512_store_si512( address, (~value).value );
158 #elif BLAZE_AVX2_MODE
159  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
160 #elif BLAZE_SSE2_MODE
161  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
162 #else
163  *address = (~value).value;
164 #endif
165 }
166 //*************************************************************************************************
167 
168 
169 //*************************************************************************************************
181 template< typename T1 // Type of the integral value
182  , typename T2 > // Type of the SIMD data type
183 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
184  storea( complex<T1>* address, const SIMDci16<T2>& value ) noexcept
185 {
186  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
187  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
188 
189 #if BLAZE_AVX512BW_MODE
190  _mm512_store_si512( address, (~value).value );
191 #elif BLAZE_AVX2_MODE
192  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
193 #elif BLAZE_SSE2_MODE
194  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
195 #else
196  *address = (~value).value;
197 #endif
198 }
199 //*************************************************************************************************
200 
201 
202 
203 
204 //=================================================================================================
205 //
206 // 32-BIT INTEGRAL SIMD TYPES
207 //
208 //=================================================================================================
209 
210 //*************************************************************************************************
222 template< typename T1 // Type of the integral value
223  , typename T2 > // Type of the SIMD data type
224 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
225  storea( T1* address, const SIMDi32<T2>& value ) noexcept
226 {
227  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
228 
229 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
230  _mm512_store_epi32( address, (~value).value );
231 #elif BLAZE_AVX2_MODE
232  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
233 #elif BLAZE_SSE2_MODE
234  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
235 #else
236  *address = (~value).value;
237 #endif
238 }
239 //*************************************************************************************************
240 
241 
242 //*************************************************************************************************
254 template< typename T1 // Type of the integral value
255  , typename T2 > // Type of the SIMD data type
256 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
257  storea( complex<T1>* address, const SIMDci32<T2>& value ) noexcept
258 {
259  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
260  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
261 
262 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
263  _mm512_store_epi32( address, (~value).value );
264 #elif BLAZE_AVX2_MODE
265  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
266 #elif BLAZE_SSE2_MODE
267  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
268 #else
269  *address = (~value).value;
270 #endif
271 }
272 //*************************************************************************************************
273 
274 
275 
276 
277 //=================================================================================================
278 //
279 // 64-BIT INTEGRAL SIMD TYPES
280 //
281 //=================================================================================================
282 
283 //*************************************************************************************************
295 template< typename T1 // Type of the integral value
296  , typename T2 > // Type of the SIMD data type
297 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
298  storea( T1* address, const SIMDi64<T2>& value ) noexcept
299 {
300  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
301 
302 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
303  _mm512_store_epi64( address, (~value).value );
304 #elif BLAZE_AVX2_MODE
305  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
306 #elif BLAZE_SSE2_MODE
307  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
308 #else
309  *address = (~value).value;
310 #endif
311 }
312 //*************************************************************************************************
313 
314 
315 //*************************************************************************************************
327 template< typename T1 // Type of the integral value
328  , typename T2 > // Type of the SIMD data type
329 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
330  storea( complex<T1>* address, const SIMDci64<T2>& value ) noexcept
331 {
332  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
333  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
334 
335 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
336  _mm512_store_epi64( address, (~value).value );
337 #elif BLAZE_AVX2_MODE
338  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
339 #elif BLAZE_SSE2_MODE
340  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
341 #else
342  *address = (~value).value;
343 #endif
344 }
345 //*************************************************************************************************
346 
347 
348 
349 
350 //=================================================================================================
351 //
352 // 32-BIT FLOATING POINT SIMD TYPES
353 //
354 //=================================================================================================
355 
356 //*************************************************************************************************
368 template< typename T > // Type of the operand
369 BLAZE_ALWAYS_INLINE void storea( float* address, const SIMDf32<T>& value ) noexcept
370 {
371  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
372 
373 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
374  _mm512_store_ps( address, (~value).eval().value );
375 #elif BLAZE_AVX_MODE
376  _mm256_store_ps( address, (~value).eval().value );
377 #elif BLAZE_SSE_MODE
378  _mm_store_ps( address, (~value).eval().value );
379 #else
380  *address = (~value).eval().value;
381 #endif
382 }
383 //*************************************************************************************************
384 
385 
386 //*************************************************************************************************
398 BLAZE_ALWAYS_INLINE void storea( complex<float>* address, const SIMDcfloat& value ) noexcept
399 {
400  BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
401  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
402 
403 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
404  _mm512_store_ps( reinterpret_cast<float*>( address ), value.value );
405 #elif BLAZE_AVX_MODE
406  _mm256_store_ps( reinterpret_cast<float*>( address ), value.value );
407 #elif BLAZE_SSE_MODE
408  _mm_store_ps( reinterpret_cast<float*>( address ), value.value );
409 #else
410  *address = value.value;
411 #endif
412 }
413 //*************************************************************************************************
414 
415 
416 
417 
418 //=================================================================================================
419 //
420 // 64-BIT FLOATING POINT SIMD TYPES
421 //
422 //=================================================================================================
423 
424 //*************************************************************************************************
436 template< typename T > // Type of the operand
437 BLAZE_ALWAYS_INLINE void storea( double* address, const SIMDf64<T>& value ) noexcept
438 {
439  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
440 
441 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
442  _mm512_store_pd( address, (~value).eval().value );
443 #elif BLAZE_AVX_MODE
444  _mm256_store_pd( address, (~value).eval().value );
445 #elif BLAZE_SSE2_MODE
446  _mm_store_pd( address, (~value).eval().value );
447 #else
448  *address = (~value).eval().value;
449 #endif
450 }
451 //*************************************************************************************************
452 
453 
454 //*************************************************************************************************
466 BLAZE_ALWAYS_INLINE void storea( complex<double>* address, const SIMDcdouble& value ) noexcept
467 {
468  BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
469  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
470 
471 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
472  _mm512_store_pd( reinterpret_cast<double*>( address ), value.value );
473 #elif BLAZE_AVX_MODE
474  _mm256_store_pd( reinterpret_cast<double*>( address ), value.value );
475 #elif BLAZE_SSE2_MODE
476  _mm_store_pd( reinterpret_cast<double*>( address ), value.value );
477 #else
478  *address = value.value;
479 #endif
480 }
481 //*************************************************************************************************
482 
483 } // namespace blaze
484 
485 #endif
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
Compile time size check.This class offers the possibility to test the size of a type at compile time...
Definition: HasSize.h:75
Header file for the IsIntegral type trait.
Header file for the And class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Compile time assertion.
decltype(auto) eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:794
Header file for the EnableIf class template.
Header file for the basic SIMD types.
Header file for run time assertion macros.
Header file for the HasSize type trait.
SIMD type for 32-bit single precision complex values.
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Header file for the alignment check function.
SIMD type for 64-bit double precision complex values.
System settings for the SSE mode.
Header file for the complex data type.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101