Multiplication.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_INTRINSICS_MULTIPLICATION_H_
36 #define _BLAZE_MATH_INTRINSICS_MULTIPLICATION_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
44 #include <blaze/system/Inline.h>
46 
47 
48 namespace blaze {
49 
50 //=================================================================================================
51 //
52 // INTRINSIC MULTIPLICATION OPERATORS
53 //
54 //=================================================================================================
55 
56 //*************************************************************************************************
65 #if BLAZE_AVX2_MODE
66 BLAZE_ALWAYS_INLINE simd_int16_t operator*( const simd_int16_t& a, const simd_int16_t& b )
67 {
68  return _mm256_mullo_epi16( a.value, b.value );
69 }
70 #elif BLAZE_SSE2_MODE
71 BLAZE_ALWAYS_INLINE simd_int16_t operator*( const simd_int16_t& a, const simd_int16_t& b )
72 {
73  return _mm_mullo_epi16( a.value, b.value );
74 }
75 #endif
76 //*************************************************************************************************
77 
78 
79 //*************************************************************************************************
88 #if BLAZE_MIC_MODE
89 BLAZE_ALWAYS_INLINE simd_int32_t operator*( const simd_int32_t& a, const simd_int32_t& b )
90 {
91  return _mm512_mullo_epi32( a.value, b.value );
92 }
93 #elif BLAZE_AVX2_MODE
94 BLAZE_ALWAYS_INLINE simd_int32_t operator*( const simd_int32_t& a, const simd_int32_t& b )
95 {
96  return _mm256_mullo_epi32( a.value, b.value );
97 }
98 #elif BLAZE_SSE4_MODE
99 BLAZE_ALWAYS_INLINE simd_int32_t operator*( const simd_int32_t& a, const simd_int32_t& b )
100 {
101  return _mm_mullo_epi32( a.value, b.value );
102 }
103 #endif
104 //*************************************************************************************************
105 
106 
107 //*************************************************************************************************
116 #if BLAZE_MIC_MODE
117 BLAZE_ALWAYS_INLINE simd_int64_t operator*( const simd_int64_t& a, const simd_int64_t& b )
118 {
119  return _mm512_mullo_epi64( a.value, b.value );
120 }
121 #endif
122 //*************************************************************************************************
123 
124 
125 //*************************************************************************************************
134 #if BLAZE_MIC_MODE
135 BLAZE_ALWAYS_INLINE simd_float_t operator*( const simd_float_t& a, const simd_float_t& b )
136 {
137  return _mm512_mul_ps( a.value, b.value );
138 }
139 #elif BLAZE_AVX_MODE
140 BLAZE_ALWAYS_INLINE simd_float_t operator*( const simd_float_t& a, const simd_float_t& b )
141 {
142  return _mm256_mul_ps( a.value, b.value );
143 }
144 #elif BLAZE_SSE_MODE
145 BLAZE_ALWAYS_INLINE simd_float_t operator*( const simd_float_t& a, const simd_float_t& b )
146 {
147  return _mm_mul_ps( a.value, b.value );
148 }
149 #endif
150 //*************************************************************************************************
151 
152 
153 //*************************************************************************************************
162 #if BLAZE_MIC_MODE
163 BLAZE_ALWAYS_INLINE simd_double_t operator*( const simd_double_t& a, const simd_double_t& b )
164 {
165  return _mm512_mul_pd( a.value, b.value );
166 }
167 #elif BLAZE_AVX_MODE
168 BLAZE_ALWAYS_INLINE simd_double_t operator*( const simd_double_t& a, const simd_double_t& b )
169 {
170  return _mm256_mul_pd( a.value, b.value );
171 }
172 #elif BLAZE_SSE2_MODE
173 BLAZE_ALWAYS_INLINE simd_double_t operator*( const simd_double_t& a, const simd_double_t& b )
174 {
175  return _mm_mul_pd( a.value, b.value );
176 }
177 #endif
178 //*************************************************************************************************
179 
180 
181 //*************************************************************************************************
190 #if BLAZE_AVX2_MODE
191 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_cint16_t& a, const simd_int16_t& b )
192 {
193  return _mm256_mullo_epi16( a.value, b.value );
194 }
195 #elif BLAZE_SSE2_MODE
196 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_cint16_t& a, const simd_int16_t& b )
197 {
198  return _mm_mullo_epi16( a.value, b.value );
199 }
200 #endif
201 //*************************************************************************************************
202 
203 
204 //*************************************************************************************************
213 #if BLAZE_AVX2_MODE
214 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_int16_t& a, const simd_cint16_t& b )
215 {
216  return _mm256_mullo_epi16( a.value, b.value );
217 }
218 #elif BLAZE_SSE2_MODE
219 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_int16_t& a, const simd_cint16_t& b )
220 {
221  return _mm_mullo_epi16( a.value, b.value );
222 }
223 #endif
224 //*************************************************************************************************
225 
226 
227 //*************************************************************************************************
236 #if BLAZE_AVX2_MODE
237 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_cint16_t& a, const simd_cint16_t& b )
238 {
239  __m256i x, y, z;
240  const __m256i neg( _mm256_set_epi16( 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1 ) );
241 
242  x = _mm256_shufflelo_epi16( a.value, 0xA0 );
243  x = _mm256_shufflehi_epi16( x, 0xA0 );
244  z = _mm256_mullo_epi16( x, b.value );
245  x = _mm256_shufflelo_epi16( a.value, 0xF5 );
246  x = _mm256_shufflehi_epi16( x, 0xF5 );
247  y = _mm256_shufflelo_epi16( b.value, 0xB1 );
248  y = _mm256_shufflehi_epi16( y, 0xB1 );
249  y = _mm256_mullo_epi16( x, y );
250  y = _mm256_mullo_epi16( y, neg );
251  return _mm256_add_epi16( z, y );
252 }
253 #elif BLAZE_SSE2_MODE
254 BLAZE_ALWAYS_INLINE simd_cint16_t operator*( const simd_cint16_t& a, const simd_cint16_t& b )
255 {
256  __m128i x, y, z;
257  const __m128i neg( _mm_set_epi16( 1, -1, 1, -1, 1, -1, 1, -1 ) );
258 
259  x = _mm_shufflelo_epi16( a.value, 0xA0 );
260  x = _mm_shufflehi_epi16( x, 0xA0 );
261  z = _mm_mullo_epi16( x, b.value );
262  x = _mm_shufflelo_epi16( a.value, 0xF5 );
263  x = _mm_shufflehi_epi16( x, 0xF5 );
264  y = _mm_shufflelo_epi16( b.value, 0xB1 );
265  y = _mm_shufflehi_epi16( y, 0xB1 );
266  y = _mm_mullo_epi16( x, y );
267  y = _mm_mullo_epi16( y, neg );
268  return _mm_add_epi16( z, y );
269 }
270 #endif
271 //*************************************************************************************************
272 
273 
274 //*************************************************************************************************
283 #if BLAZE_MIC_MODE
284 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_int32_t& b )
285 {
286  return _mm512_mullo_epi32( a.value, b.value );
287 }
288 #elif BLAZE_AVX2_MODE
289 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_int32_t& b )
290 {
291  return _mm256_mullo_epi32( a.value, b.value );
292 }
293 #elif BLAZE_SSE4_MODE
294 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_int32_t& b )
295 {
296  return _mm_mullo_epi32( a.value, b.value );
297 }
298 #endif
299 //*************************************************************************************************
300 
301 
302 //*************************************************************************************************
311 #if BLAZE_MIC_MODE
312 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_int32_t& a, const simd_cint32_t& b )
313 {
314  return _mm512_mullo_epi32( a.value, b.value );
315 }
316 #elif BLAZE_AVX2_MODE
317 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_int32_t& a, const simd_cint32_t& b )
318 {
319  return _mm256_mullo_epi32( a.value, b.value );
320 }
321 #elif BLAZE_SSE4_MODE
322 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_int32_t& a, const simd_cint32_t& b )
323 {
324  return _mm_mullo_epi32( a.value, b.value );
325 }
326 #endif
327 //*************************************************************************************************
328 
329 
330 //*************************************************************************************************
339 #if BLAZE_MIC_MODE
340 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_cint32_t& b )
341 {
342  __m512i x, y, z;
343  const __m512i neg( _mm256_set_epi32( 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1 ) );
344 
345  x = _mm512_shuffle_epi32( a.value, 0xA0 );
346  z = _mm512_mullo_epi32( x, b.value );
347  x = _mm512_shuffle_epi32( a.value, 0xF5 );
348  y = _mm512_shuffle_epi32( b.value, 0xB1 );
349  y = _mm512_mullo_epi32( x, y );
350  y = _mm512_mullo_epi32( y, neg );
351  return _mm512_add_epi32( z, y );
352 }
353 #elif BLAZE_AVX2_MODE
354 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_cint32_t& b )
355 {
356  __m256i x, y, z;
357  const __m256i neg( _mm256_set_epi32( 1, -1, 1, -1, 1, -1, 1, -1 ) );
358 
359  x = _mm256_shuffle_epi32( a.value, 0xA0 );
360  z = _mm256_mullo_epi32( x, b.value );
361  x = _mm256_shuffle_epi32( a.value, 0xF5 );
362  y = _mm256_shuffle_epi32( b.value, 0xB1 );
363  y = _mm256_mullo_epi32( x, y );
364  y = _mm256_mullo_epi32( y, neg );
365  return _mm256_add_epi32( z, y );
366 }
367 #elif BLAZE_SSE4_MODE
368 BLAZE_ALWAYS_INLINE simd_cint32_t operator*( const simd_cint32_t& a, const simd_cint32_t& b )
369 {
370  __m128i x, y, z;
371  const __m128i neg( _mm_set_epi32( 1, -1, 1, -1 ) );
372 
373  x = _mm_shuffle_epi32( a.value, 0xA0 );
374  z = _mm_mullo_epi32( x, b.value );
375  x = _mm_shuffle_epi32( a.value, 0xF5 );
376  y = _mm_shuffle_epi32( b.value, 0xB1 );
377  y = _mm_mullo_epi32( x, y );
378  y = _mm_mullo_epi32( y, neg );
379  return _mm_add_epi32( z, y );
380 }
381 #endif
382 //*************************************************************************************************
383 
384 
385 //*************************************************************************************************
394 #if BLAZE_MIC_MODE
395 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_cfloat_t& a, const simd_float_t& b )
396 {
397  return _mm512_mul_ps( a.value, b.value );
398 }
399 #elif BLAZE_AVX_MODE
400 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_cfloat_t& a, const simd_float_t& b )
401 {
402  return _mm256_mul_ps( a.value, b.value );
403 }
404 #elif BLAZE_SSE_MODE
405 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_cfloat_t& a, const simd_float_t& b )
406 {
407  return _mm_mul_ps( a.value, b.value );
408 }
409 #endif
410 //*************************************************************************************************
411 
412 
413 //*************************************************************************************************
422 #if BLAZE_MIC_MODE
423 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_float_t& a, const simd_cfloat_t& b )
424 {
425  return _mm512_mul_ps( a.value, b.value );
426 }
427 #elif BLAZE_AVX_MODE
428 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_float_t& a, const simd_cfloat_t& b )
429 {
430  return _mm256_mul_ps( a.value, b.value );
431 }
432 #elif BLAZE_SSE_MODE
433 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_float_t& a, const simd_cfloat_t& b )
434 {
435  return _mm_mul_ps( a.value, b.value );
436 }
437 #endif
438 //*************************************************************************************************
439 
440 
441 //*************************************************************************************************
450 #if BLAZE_AVX_MODE
451 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_cfloat_t& a, const simd_cfloat_t& b )
452 {
453  __m256 x, y, z;
454 
455  x = _mm256_shuffle_ps( a.value, a.value, 0xA0 );
456  z = _mm256_mul_ps( x, b.value );
457  x = _mm256_shuffle_ps( a.value, a.value, 0xF5 );
458  y = _mm256_shuffle_ps( b.value, b.value, 0xB1 );
459  y = _mm256_mul_ps( x, y );
460  return _mm256_addsub_ps( z, y );
461 }
462 #elif BLAZE_SSE3_MODE
463 BLAZE_ALWAYS_INLINE simd_cfloat_t operator*( const simd_cfloat_t& a, const simd_cfloat_t& b )
464 {
465  __m128 x, y, z;
466 
467  x = _mm_shuffle_ps( a.value, a.value, 0xA0 );
468  z = _mm_mul_ps( x, b.value );
469  x = _mm_shuffle_ps( a.value, a.value, 0xF5 );
470  y = _mm_shuffle_ps( b.value, b.value, 0xB1 );
471  y = _mm_mul_ps( x, y );
472  return _mm_addsub_ps( z, y );
473 }
474 #endif
475 //*************************************************************************************************
476 
477 
478 //*************************************************************************************************
487 #if BLAZE_MIC_MODE
488 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_cdouble_t& a, const simd_double_t& b )
489 {
490  return _mm512_mul_pd( a.value, b.value );
491 }
492 #elif BLAZE_AVX_MODE
493 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_cdouble_t& a, const simd_double_t& b )
494 {
495  return _mm256_mul_pd( a.value, b.value );
496 }
497 #elif BLAZE_SSE2_MODE
498 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_cdouble_t& a, const simd_double_t& b )
499 {
500  return _mm_mul_pd( a.value, b.value );
501 }
502 #endif
503 //*************************************************************************************************
504 
505 
506 //*************************************************************************************************
515 #if BLAZE_MIC_MODE
516 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_double_t& a, const simd_cdouble_t& b )
517 {
518  return _mm512_mul_pd( a.value, b.value );
519 }
520 #elif BLAZE_AVX_MODE
521 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_double_t& a, const simd_cdouble_t& b )
522 {
523  return _mm256_mul_pd( a.value, b.value );
524 }
525 #elif BLAZE_SSE2_MODE
526 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_double_t& a, const simd_cdouble_t& b )
527 {
528  return _mm_mul_pd( a.value, b.value );
529 }
530 #endif
531 //*************************************************************************************************
532 
533 
534 //*************************************************************************************************
543 #if BLAZE_AVX_MODE
544 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_cdouble_t& a, const simd_cdouble_t& b )
545 {
546  __m256d x, y, z;
547 
548  x = _mm256_shuffle_pd( a.value, a.value, 0 );
549  z = _mm256_mul_pd( x, b.value );
550  x = _mm256_shuffle_pd( a.value, a.value, 15 );
551  y = _mm256_shuffle_pd( b.value, b.value, 5 );
552  y = _mm256_mul_pd( x, y );
553  return _mm256_addsub_pd( z, y );
554 }
555 #elif BLAZE_SSE3_MODE
556 BLAZE_ALWAYS_INLINE simd_cdouble_t operator*( const simd_cdouble_t& a, const simd_cdouble_t& b )
557 {
558  __m128d x, y, z;
559 
560  x = _mm_shuffle_pd( a.value, a.value, 0 );
561  z = _mm_mul_pd( x, b.value );
562  x = _mm_shuffle_pd( a.value, a.value, 3 );
563  y = _mm_shuffle_pd( b.value, b.value, 1 );
564  y = _mm_mul_pd( x, y );
565  return _mm_addsub_pd( z, y );
566 }
567 #endif
568 //*************************************************************************************************
569 
570 } // namespace blaze
571 
572 #endif
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7820
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
Header file for the basic intrinsic types.
System settings for the SSE mode.
System settings for the inline keywords.