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_AVX2_MODE
84  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
85 #elif BLAZE_SSE2_MODE
86  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
87 #else
88  *address = (~value).value;
89 #endif
90 }
91 //*************************************************************************************************
92 
93 
94 //*************************************************************************************************
106 template< typename T1 // Type of the integral value
107  , typename T2 > // Type of the SIMD data type
108 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
109  storea( complex<T1>* address, const SIMDci8<T2>& value ) noexcept
110 {
111  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
112  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
113 
114 #if BLAZE_AVX2_MODE
115  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
116 #elif BLAZE_SSE2_MODE
117  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
118 #else
119  *address = (~value).value;
120 #endif
121 }
122 //*************************************************************************************************
123 
124 
125 
126 
127 //=================================================================================================
128 //
129 // 16-BIT INTEGRAL SIMD TYPES
130 //
131 //=================================================================================================
132 
133 //*************************************************************************************************
145 template< typename T1 // Type of the integral value
146  , typename T2 > // Type of the SIMD data type
147 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
148  storea( T1* address, const SIMDi16<T2>& value ) noexcept
149 {
150  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
151 
152 #if BLAZE_AVX2_MODE
153  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
154 #elif BLAZE_SSE2_MODE
155  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
156 #else
157  *address = (~value).value;
158 #endif
159 }
160 //*************************************************************************************************
161 
162 
163 //*************************************************************************************************
175 template< typename T1 // Type of the integral value
176  , typename T2 > // Type of the SIMD data type
177 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
178  storea( complex<T1>* address, const SIMDci16<T2>& value ) noexcept
179 {
180  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
181  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
182 
183 #if BLAZE_AVX2_MODE
184  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
185 #elif BLAZE_SSE2_MODE
186  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
187 #else
188  *address = (~value).value;
189 #endif
190 }
191 //*************************************************************************************************
192 
193 
194 
195 
196 //=================================================================================================
197 //
198 // 32-BIT INTEGRAL SIMD TYPES
199 //
200 //=================================================================================================
201 
202 //*************************************************************************************************
214 template< typename T1 // Type of the integral value
215  , typename T2 > // Type of the SIMD data type
216 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
217  storea( T1* address, const SIMDi32<T2>& value ) noexcept
218 {
219  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
220 
221 #if BLAZE_MIC_MODE
222  _mm512_store_epi32( address, (~value).value );
223 #elif BLAZE_AVX2_MODE
224  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
225 #elif BLAZE_SSE2_MODE
226  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
227 #else
228  *address = (~value).value;
229 #endif
230 }
231 //*************************************************************************************************
232 
233 
234 //*************************************************************************************************
246 template< typename T1 // Type of the integral value
247  , typename T2 > // Type of the SIMD data type
248 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
249  storea( complex<T1>* address, const SIMDci32<T2>& value ) noexcept
250 {
251  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
252  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
253 
254 #if BLAZE_MIC_MODE
255  _mm512_store_epi32( address, (~value).value );
256 #elif BLAZE_AVX2_MODE
257  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
258 #elif BLAZE_SSE2_MODE
259  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
260 #else
261  *address = (~value).value;
262 #endif
263 }
264 //*************************************************************************************************
265 
266 
267 
268 
269 //=================================================================================================
270 //
271 // 64-BIT INTEGRAL SIMD TYPES
272 //
273 //=================================================================================================
274 
275 //*************************************************************************************************
287 template< typename T1 // Type of the integral value
288  , typename T2 > // Type of the SIMD data type
289 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
290  storea( T1* address, const SIMDi64<T2>& value ) noexcept
291 {
292  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
293 
294 #if BLAZE_MIC_MODE
295  _mm512_store_epi64( address, (~value).value );
296 #elif BLAZE_AVX2_MODE
297  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
298 #elif BLAZE_SSE2_MODE
299  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
300 #else
301  *address = (~value).value;
302 #endif
303 }
304 //*************************************************************************************************
305 
306 
307 //*************************************************************************************************
319 template< typename T1 // Type of the integral value
320  , typename T2 > // Type of the SIMD data type
321 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
322  storea( complex<T1>* address, const SIMDci64<T2>& value ) noexcept
323 {
324  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
325  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
326 
327 #if BLAZE_MIC_MODE
328  _mm512_store_epi64( address, (~value).value );
329 #elif BLAZE_AVX2_MODE
330  _mm256_store_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
331 #elif BLAZE_SSE2_MODE
332  _mm_store_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
333 #else
334  *address = (~value).value;
335 #endif
336 }
337 //*************************************************************************************************
338 
339 
340 
341 
342 //=================================================================================================
343 //
344 // 32-BIT FLOATING POINT SIMD TYPES
345 //
346 //=================================================================================================
347 
348 //*************************************************************************************************
360 template< typename T > // Type of the operand
361 BLAZE_ALWAYS_INLINE void storea( float* address, const SIMDf32<T>& value ) noexcept
362 {
363  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
364 
365 #if BLAZE_MIC_MODE
366  _mm512_store_ps( address, (~value).eval().value );
367 #elif BLAZE_AVX_MODE
368  _mm256_store_ps( address, (~value).eval().value );
369 #elif BLAZE_SSE_MODE
370  _mm_store_ps( address, (~value).eval().value );
371 #else
372  *address = (~value).eval().value;
373 #endif
374 }
375 //*************************************************************************************************
376 
377 
378 //*************************************************************************************************
390 BLAZE_ALWAYS_INLINE void storea( complex<float>* address, const SIMDcfloat& value ) noexcept
391 {
392  BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
393  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
394 
395 #if BLAZE_MIC_MODE
396  _mm512_store_ps( reinterpret_cast<float*>( address ), value.value );
397 #elif BLAZE_AVX_MODE
398  _mm256_store_ps( reinterpret_cast<float*>( address ), value.value );
399 #elif BLAZE_SSE_MODE
400  _mm_store_ps( reinterpret_cast<float*>( address ), value.value );
401 #else
402  *address = value.value;
403 #endif
404 }
405 //*************************************************************************************************
406 
407 
408 
409 
410 //=================================================================================================
411 //
412 // 64-BIT FLOATING POINT SIMD TYPES
413 //
414 //=================================================================================================
415 
416 //*************************************************************************************************
428 template< typename T > // Type of the operand
429 BLAZE_ALWAYS_INLINE void storea( double* address, const SIMDf64<T>& value ) noexcept
430 {
431  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
432 
433 #if BLAZE_MIC_MODE
434  _mm512_store_pd( address, (~value).eval().value );
435 #elif BLAZE_AVX_MODE
436  _mm256_store_pd( address, (~value).eval().value );
437 #elif BLAZE_SSE2_MODE
438  _mm_store_pd( address, (~value).eval().value );
439 #else
440  *address = (~value).eval().value;
441 #endif
442 }
443 //*************************************************************************************************
444 
445 
446 //*************************************************************************************************
458 BLAZE_ALWAYS_INLINE void storea( complex<double>* address, const SIMDcdouble& value ) noexcept
459 {
460  BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
461  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
462 
463 #if BLAZE_MIC_MODE
464  _mm512_store_pd( reinterpret_cast<double*>( address ), value.value );
465 #elif BLAZE_AVX_MODE
466  _mm256_store_pd( reinterpret_cast<double*>( address ), value.value );
467 #elif BLAZE_SSE2_MODE
468  _mm_store_pd( reinterpret_cast<double*>( address ), value.value );
469 #else
470  *address = value.value;
471 #endif
472 }
473 //*************************************************************************************************
474 
475 } // namespace blaze
476 
477 #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
Header file for the IsIntegral type trait.
Header file for the And class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Compile time assertion.
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.
const DMatEvalExpr< MT, SO > eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:705
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