FMA.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SIMD_FMA_H_
36 #define _BLAZE_MATH_SIMD_FMA_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
47 #include <blaze/system/Inline.h>
49 
50 
51 namespace blaze {
52 
53 //=================================================================================================
54 //
55 // 32-BIT FLOATING POINT SIMD TYPES
56 //
57 //=================================================================================================
58 
59 //*************************************************************************************************
66 template< typename T1 // Type of the left-hand side multiplication operand
67  , typename T2 // Type of the right-hand side multiplication operand
68  , typename T3 > // Type of the right-hand side addition operand
70  : public SIMDf32< SIMDf32FmaddExpr<T1,T2,T3> >
71 {
72  //**Type definitions****************************************************************************
74  using BaseType = SIMDf32<This>;
75  //**********************************************************************************************
76 
77  //**Constructor*********************************************************************************
84  explicit BLAZE_ALWAYS_INLINE SIMDf32FmaddExpr( const T1& a, const T2& b, const T3& c )
85  : a_( a ) // The left-hand side operand for the multiplication
86  , b_( b ) // The right-hand side operand for the multiplication
87  , c_( c ) // The right-hand side operand for the addition
88  {}
89  //**********************************************************************************************
90 
91  //**Evaluation function*************************************************************************
96  BLAZE_ALWAYS_INLINE const SIMDfloat eval() const noexcept
97 #if BLAZE_FMA_MODE && ( BLAZE_AVX512F_MODE || BLAZE_MIC_MODE )
98  {
99  return _mm512_fmadd_ps( a_.eval().value, b_.eval().value, c_.eval().value );
100  }
101 #elif BLAZE_FMA_MODE && BLAZE_AVX_MODE
102  {
103  return _mm256_fmadd_ps( a_.eval().value, b_.eval().value, c_.eval().value );
104  }
105 #elif BLAZE_FMA_MODE && BLAZE_SSE2_MODE
106  {
107  return _mm_fmadd_ps( a_.eval().value, b_.eval().value, c_.eval().value );
108  }
109 #else
110  = delete;
111 #endif
112  //**********************************************************************************************
113 
114  //**Member variables****************************************************************************
115  const T1 a_;
116  const T2 b_;
117  const T3 c_;
118  //**********************************************************************************************
119 };
120 //*************************************************************************************************
121 
122 
123 //*************************************************************************************************
130 template< typename T1 // Type of the left-hand side multiplication operand
131  , typename T2 // Type of the right-hand side multiplication operand
132  , typename T3 > // Type of the right-hand side subtraction operand
134  : public SIMDf32< SIMDf32FmsubExpr<T1,T2,T3> >
135 {
136  //**Type definitions****************************************************************************
138  using BaseType = SIMDf32<This>;
139  //**********************************************************************************************
140 
141  //**Constructor*********************************************************************************
148  explicit BLAZE_ALWAYS_INLINE SIMDf32FmsubExpr( const T1& a, const T2& b, const T3& c )
149  : a_( a ) // The left-hand side operand for the multiplication
150  , b_( b ) // The right-hand side operand for the multiplication
151  , c_( c ) // The right-hand side operand for the subtraction
152  {}
153  //**********************************************************************************************
154 
155  //**Evaluation function*************************************************************************
160  BLAZE_ALWAYS_INLINE const SIMDfloat eval() const noexcept
161 #if BLAZE_FMA_MODE && ( BLAZE_AVX512F_MODE || BLAZE_MIC_MODE )
162  {
163  return _mm512_fmsub_ps( a_.eval().value, b_.eval().value, c_.eval().value );
164  }
165 #elif BLAZE_FMA_MODE && BLAZE_AVX_MODE
166  {
167  return _mm256_fmsub_ps( a_.eval().value, b_.eval().value, c_.eval().value );
168  }
169 #elif BLAZE_FMA_MODE && BLAZE_SSE2_MODE
170  {
171  return _mm_fmsub_ps( a_.eval().value, b_.eval().value, c_.eval().value );
172  }
173 #else
174  = delete;
175 #endif
176  //**********************************************************************************************
177 
178  //**Member variables****************************************************************************
179  const T1 a_;
180  const T2 b_;
181  const T3 c_;
182  //**********************************************************************************************
183 };
184 //*************************************************************************************************
185 
186 
187 //*************************************************************************************************
199 #if BLAZE_FMA_MODE
200 template< typename T1 // Type of the first multiplication operand
201  , typename T2 // Type of the second multiplication operand
202  , typename T3 > // Type of the second addition operand
204  operator+( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32<T3>& b )
205 {
206  return SIMDf32FmaddExpr<T1,T2,T3>( a.a_, a.b_, ~b );
207 }
208 #endif
209 //*************************************************************************************************
210 
211 
212 //*************************************************************************************************
224 #if BLAZE_FMA_MODE
225 template< typename T1 // Type of the first addition operand
226  , typename T2 // Type of the first multiplication operand
227  , typename T3 > // Type of the second multiplication operand
229  operator+( const SIMDf32<T1>& a, const SIMDf32MultExpr<T2,T3>& b )
230 {
231  return SIMDf32FmaddExpr<T2,T3,T1>( b.a_, b.b_, ~a );
232 }
233 #endif
234 //*************************************************************************************************
235 
236 
237 //*************************************************************************************************
250 #if BLAZE_FMA_MODE
251 template< typename T1 // Type of the first operand of the left-hand side multiplication
252  , typename T2 // Type of the second operand of the left-hand side multiplication
253  , typename T3 // Type of the first operand of the right-hand side multiplication
254  , typename T4 > // Type of the second operand of the right-hand side multiplication
257 {
259 }
260 #endif
261 
262 //*************************************************************************************************
263 
264 
265 //*************************************************************************************************
279 #if BLAZE_FMA_MODE
280 template< typename T1 // Type of the first FMA multiplication operand
281  , typename T2 // Type of the second FMA multiplication operand
282  , typename T3 // Type of the FMA addition operand
283  , typename T4 > // Type of the second addition operand
284 BLAZE_ALWAYS_INLINE decltype(auto)
285  operator+( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32<T4>& b )
286 {
287  return ( a.a_ * a.b_ ) + ( a.c_ + (~b) );
288 }
289 #endif
290 
291 //*************************************************************************************************
292 
293 
294 //*************************************************************************************************
308 #if BLAZE_FMA_MODE
309 template< typename T1 // Type of the first addition operand
310  , typename T2 // Type of the first FMA multiplication operand
311  , typename T3 // Type of the second FMA multiplication operand
312  , typename T4 > // Type of the FMA addition operand
313 BLAZE_ALWAYS_INLINE decltype(auto)
314  operator+( const SIMDf32<T1>& a, const SIMDf32FmaddExpr<T2,T3,T4>& b )
315 {
316  return ( b.a_ * b.b_ ) + ( b.c_ + (~a) );
317 }
318 #endif
319 
320 //*************************************************************************************************
321 
322 
323 //*************************************************************************************************
337 #if BLAZE_FMA_MODE
338 template< typename T1 // Type of the first FMA multiplication operand
339  , typename T2 // Type of the second FMA multiplication operand
340  , typename T3 // Type of the FMA addition operand
341  , typename T4 // Type of the first multiplication operand
342  , typename T5 > // Type of the second multiplication operand
345 {
347 }
348 #endif
349 
350 //*************************************************************************************************
351 
352 
353 //*************************************************************************************************
367 #if BLAZE_FMA_MODE
368 template< typename T1 // Type of the first multiplication operand
369  , typename T2 // Type of the second multiplication operand
370  , typename T3 // Type of the first FMA multiplication operand
371  , typename T4 // Type of the second FMA multiplication operand
372  , typename T5 > // Type of the FMA addition operand
375 {
377 }
378 #endif
379 
380 //*************************************************************************************************
381 
382 
383 //*************************************************************************************************
396 #if BLAZE_FMA_MODE
397 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
398  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
399  , typename T3 // Type of the addition operand of the left-hand side FMA
400  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
401  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
402  , typename T6 > // Type of the addition operand of the right-hand side FMA
403 BLAZE_ALWAYS_INLINE decltype(auto)
405 {
406  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
407 }
408 #endif
409 
410 //*************************************************************************************************
411 
412 
413 //*************************************************************************************************
426 #if BLAZE_FMA_MODE
427 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
428  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
429  , typename T3 // Type of the addition operand of the left-hand side FMA
430  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
431  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
432  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
433 BLAZE_ALWAYS_INLINE decltype(auto)
435 {
436  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
437 }
438 #endif
439 
440 //*************************************************************************************************
441 
442 
443 //*************************************************************************************************
456 #if BLAZE_FMA_MODE
457 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
458  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
459  , typename T3 // Type of the subtraction operand of the left-hand side FMA
460  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
461  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
462  , typename T6 > // Type of the addition operand of the right-hand side FMA
463 BLAZE_ALWAYS_INLINE decltype(auto)
465 {
466  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
467 }
468 #endif
469 
470 //*************************************************************************************************
471 
472 
473 //*************************************************************************************************
486 #if BLAZE_FMA_MODE
487 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
488  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
489  , typename T3 // Type of the subtraction operand of the left-hand side FMA
490  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
491  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
492  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
493 BLAZE_ALWAYS_INLINE decltype(auto)
495 {
496  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) - ( b.c_ + a.c_ ) );
497 }
498 #endif
499 
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
515 #if BLAZE_FMA_MODE
516 template< typename T1 // Type of the first multiplication operand
517  , typename T2 // Type of the second multiplication operand
518  , typename T3 > // Type of the second subtraction operand
520  operator-( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32<T3>& b )
521 {
522  return SIMDf32FmsubExpr<T1,T2,T3>( a.a_, a.b_, ~b );
523 }
524 #endif
525 //*************************************************************************************************
526 
527 
528 //*************************************************************************************************
541 #if BLAZE_FMA_MODE
542 template< typename T1 // Type of the first operand of the left-hand side multiplication
543  , typename T2 // Type of the second operand of the left-hand side multiplication
544  , typename T3 // Type of the first operand of the right-hand side multiplication
545  , typename T4 > // Type of the second operand of the right-hand side multiplication
548 {
550 }
551 #endif
552 
553 //*************************************************************************************************
554 
555 
556 //*************************************************************************************************
570 #if BLAZE_FMA_MODE
571 template< typename T1 // Type of the first FMA multiplication operand
572  , typename T2 // Type of the second FMA multiplication operand
573  , typename T3 // Type of the FMA subtraction operand
574  , typename T4 > // Type of the second subtraction operand
575 BLAZE_ALWAYS_INLINE decltype(auto)
576  operator-( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32<T4>& b )
577 {
578  return ( a.a_ * a.b_ ) - ( a.c_ + (~b) );
579 }
580 #endif
581 
582 //*************************************************************************************************
583 
584 
585 //*************************************************************************************************
599 #if BLAZE_FMA_MODE
600 template< typename T1 // Type of the first FMA multiplication operand
601  , typename T2 // Type of the second FMA multiplication operand
602  , typename T3 // Type of the FMA subtraction operand
603  , typename T4 // Type of the first multiplication operand
604  , typename T5 > // Type of the second multiplication operand
605 BLAZE_ALWAYS_INLINE decltype(auto)
607 {
608  return ( a.a_ * a.b_ ) - ( b.a_ * b.b_ + a.c_ );
609 }
610 #endif
611 
612 //*************************************************************************************************
613 
614 
615 //*************************************************************************************************
629 #if BLAZE_FMA_MODE
630 template< typename T1 // Type of the first multiplication operand
631  , typename T2 // Type of the second multiplication operand
632  , typename T3 // Type of the first FMA multiplication operand
633  , typename T4 // Type of the second FMA multiplication operand
634  , typename T5 > // Type of the FMA subtraction operand
637 {
639 }
640 #endif
641 
642 //*************************************************************************************************
643 
644 
645 //*************************************************************************************************
658 #if BLAZE_FMA_MODE
659 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
660  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
661  , typename T3 // Type of the addition operand of the left-hand side FMA
662  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
663  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
664  , typename T6 > // Type of the addition operand of the right-hand side FMA
665 BLAZE_ALWAYS_INLINE decltype(auto)
667 {
668  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
669 }
670 #endif
671 
672 //*************************************************************************************************
673 
674 
675 //*************************************************************************************************
688 #if BLAZE_FMA_MODE
689 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
690  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
691  , typename T3 // Type of the addition operand of the left-hand side FMA
692  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
693  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
694  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
695 BLAZE_ALWAYS_INLINE decltype(auto)
697 {
698  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) - ( a.c_ + b.c_ ) );
699 }
700 #endif
701 
702 //*************************************************************************************************
703 
704 
705 //*************************************************************************************************
718 #if BLAZE_FMA_MODE
719 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
720  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
721  , typename T3 // Type of the subtraction operand of the left-hand side FMA
722  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
723  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
724  , typename T6 > // Type of the addition operand of the right-hand side FMA
725 BLAZE_ALWAYS_INLINE decltype(auto)
727 {
728  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
729 }
730 #endif
731 
732 //*************************************************************************************************
733 
734 
735 //*************************************************************************************************
748 #if BLAZE_FMA_MODE
749 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
750  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
751  , typename T3 // Type of the subtraction operand of the left-hand side FMA
752  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
753  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
754  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
755 BLAZE_ALWAYS_INLINE decltype(auto)
757 {
758  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
759 }
760 #endif
761 
762 //*************************************************************************************************
763 
764 
765 
766 
767 //=================================================================================================
768 //
769 // 64-BIT FLOATING POINT SIMD TYPES
770 //
771 //=================================================================================================
772 
773 //*************************************************************************************************
780 template< typename T1 // Type of the left-hand side multiplication operand
781  , typename T2 // Type of the right-hand side multiplication operand
782  , typename T3 > // Type of the right-hand side addition operand
784  : public SIMDf64< SIMDf64FmaddExpr<T1,T2,T3> >
785 {
786  //**Type definitions****************************************************************************
788  using BaseType = SIMDf64<This>;
789  //**********************************************************************************************
790 
791  //**Constructor*********************************************************************************
798  explicit BLAZE_ALWAYS_INLINE SIMDf64FmaddExpr( const T1& a, const T2& b, const T3& c )
799  : a_( a ) // The left-hand side operand for the multiplication
800  , b_( b ) // The right-hand side operand for the multiplication
801  , c_( c ) // The right-hand side operand for the addition
802  {}
803  //**********************************************************************************************
804 
805  //**Evaluation function*************************************************************************
810  BLAZE_ALWAYS_INLINE const SIMDdouble eval() const noexcept
811 #if BLAZE_FMA_MODE && ( BLAZE_AVX512F_MODE || BLAZE_MIC_MODE )
812  {
813  return _mm512_fmadd_pd( a_.eval().value, b_.eval().value, c_.eval().value );
814  }
815 #elif BLAZE_FMA_MODE && BLAZE_AVX_MODE
816  {
817  return _mm256_fmadd_pd( a_.eval().value, b_.eval().value, c_.eval().value );
818  }
819 #elif BLAZE_FMA_MODE && BLAZE_SSE2_MODE
820  {
821  return _mm_fmadd_pd( a_.eval().value, b_.eval().value, c_.eval().value );
822  }
823 #else
824  = delete;
825 #endif
826  //**********************************************************************************************
827 
828  //**Member variables****************************************************************************
829  const T1 a_;
830  const T2 b_;
831  const T3 c_;
832  //**********************************************************************************************
833 };
834 //*************************************************************************************************
835 
836 
837 //*************************************************************************************************
844 template< typename T1 // Type of the left-hand side multiplication operand
845  , typename T2 // Type of the right-hand side multiplication operand
846  , typename T3 > // Type of the right-hand side subtraction operand
848  : public SIMDf64< SIMDf64FmsubExpr<T1,T2,T3> >
849 {
850  //**Type definitions****************************************************************************
852  using BaseType = SIMDf64<This>;
853  //**********************************************************************************************
854 
855  //**Constructor*********************************************************************************
862  explicit BLAZE_ALWAYS_INLINE SIMDf64FmsubExpr( const T1& a, const T2& b, const T3& c )
863  : a_( a ) // The left-hand side operand for the multiplication
864  , b_( b ) // The right-hand side operand for the multiplication
865  , c_( c ) // The right-hand side operand for the subtraction
866  {}
867  //**********************************************************************************************
868 
869  //**Evaluation function*************************************************************************
874  BLAZE_ALWAYS_INLINE const SIMDdouble eval() const noexcept
875 #if BLAZE_FMA_MODE && ( BLAZE_AVX512F_MODE || BLAZE_MIC_MODE )
876  {
877  return _mm512_fmsub_pd( a_.eval().value, b_.eval().value, c_.eval().value );
878  }
879 #elif BLAZE_FMA_MODE && BLAZE_AVX_MODE
880  {
881  return _mm256_fmsub_pd( a_.eval().value, b_.eval().value, c_.eval().value );
882  }
883 #elif BLAZE_FMA_MODE && BLAZE_SSE2_MODE
884  {
885  return _mm_fmsub_pd( a_.eval().value, b_.eval().value, c_.eval().value );
886  }
887 #else
888  = delete;
889 #endif
890  //**********************************************************************************************
891 
892  //**Member variables****************************************************************************
893  const T1 a_;
894  const T2 b_;
895  const T3 c_;
896  //**********************************************************************************************
897 };
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
913 #if BLAZE_FMA_MODE
914 template< typename T1 // Type of the first multiplication operand
915  , typename T2 // Type of the second multiplication operand
916  , typename T3 > // Type of the second addition operand
918  operator+( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64<T3>& b )
919 {
920  return SIMDf64FmaddExpr<T1,T2,T3>( a.a_, a.b_, ~b );
921 }
922 #endif
923 //*************************************************************************************************
924 
925 
926 //*************************************************************************************************
938 #if BLAZE_FMA_MODE
939 template< typename T1 // Type of the first addition operand
940  , typename T2 // Type of the first multiplication operand
941  , typename T3 > // Type of the second multiplication operand
943  operator+( const SIMDf64<T1>& a, const SIMDf64MultExpr<T2,T3>& b )
944 {
945  return SIMDf64FmaddExpr<T2,T3,T1>( b.a_, b.b_, ~a );
946 }
947 #endif
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
964 #if BLAZE_FMA_MODE
965 template< typename T1 // Type of the first operand of the left-hand side multiplication
966  , typename T2 // Type of the second operand of the left-hand side multiplication
967  , typename T3 // Type of the first operand of the right-hand side multiplication
968  , typename T4 > // Type of the second operand of the right-hand side multiplication
971 {
973 }
974 #endif
975 
976 //*************************************************************************************************
977 
978 
979 //*************************************************************************************************
993 #if BLAZE_FMA_MODE
994 template< typename T1 // Type of the first FMA multiplication operand
995  , typename T2 // Type of the second FMA multiplication operand
996  , typename T3 // Type of the FMA addition operand
997  , typename T4 > // Type of the second addition operand
998 BLAZE_ALWAYS_INLINE decltype(auto)
999  operator+( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64<T4>& b )
1000 {
1001  return ( a.a_ * a.b_ ) + ( a.c_ + (~b) );
1002 }
1003 #endif
1004 
1005 //*************************************************************************************************
1006 
1007 
1008 //*************************************************************************************************
1022 #if BLAZE_FMA_MODE
1023 template< typename T1 // Type of the first addition operand
1024  , typename T2 // Type of the first FMA multiplication operand
1025  , typename T3 // Type of the second FMA multiplication operand
1026  , typename T4 > // Type of the FMA addition operand
1027 BLAZE_ALWAYS_INLINE decltype(auto)
1028  operator+( const SIMDf64<T1>& a, const SIMDf64FmaddExpr<T2,T3,T4>& b )
1029 {
1030  return ( b.a_ * b.b_ ) + ( b.c_ + (~a) );
1031 }
1032 #endif
1033 
1034 //*************************************************************************************************
1035 
1036 
1037 //*************************************************************************************************
1051 #if BLAZE_FMA_MODE
1052 template< typename T1 // Type of the first FMA multiplication operand
1053  , typename T2 // Type of the second FMA multiplication operand
1054  , typename T3 // Type of the FMA addition operand
1055  , typename T4 // Type of the first multiplication operand
1056  , typename T5 > // Type of the second multiplication operand
1059 {
1061 }
1062 #endif
1063 
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1081 #if BLAZE_FMA_MODE
1082 template< typename T1 // Type of the first multiplication operand
1083  , typename T2 // Type of the second multiplication operand
1084  , typename T3 // Type of the first FMA multiplication operand
1085  , typename T4 // Type of the second FMA multiplication operand
1086  , typename T5 > // Type of the FMA addition operand
1089 {
1091 }
1092 #endif
1093 
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1110 #if BLAZE_FMA_MODE
1111 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1112  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1113  , typename T3 // Type of the addition operand of the left-hand side FMA
1114  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1115  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1116  , typename T6 > // Type of the addition operand of the right-hand side FMA
1117 BLAZE_ALWAYS_INLINE decltype(auto)
1119 {
1120  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
1121 }
1122 #endif
1123 
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1140 #if BLAZE_FMA_MODE
1141 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1142  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1143  , typename T3 // Type of the addition operand of the left-hand side FMA
1144  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1145  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1146  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
1147 BLAZE_ALWAYS_INLINE decltype(auto)
1149 {
1150  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
1151 }
1152 #endif
1153 
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1170 #if BLAZE_FMA_MODE
1171 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1172  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1173  , typename T3 // Type of the subtraction operand of the left-hand side FMA
1174  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1175  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1176  , typename T6 > // Type of the addition operand of the right-hand side FMA
1177 BLAZE_ALWAYS_INLINE decltype(auto)
1179 {
1180  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
1181 }
1182 #endif
1183 
1184 //*************************************************************************************************
1185 
1186 
1187 //*************************************************************************************************
1200 #if BLAZE_FMA_MODE
1201 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1202  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1203  , typename T3 // Type of the subtraction operand of the left-hand side FMA
1204  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1205  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1206  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
1207 BLAZE_ALWAYS_INLINE decltype(auto)
1209 {
1210  return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) - ( b.c_ + a.c_ ) );
1211 }
1212 #endif
1213 
1214 //*************************************************************************************************
1215 
1216 
1217 //*************************************************************************************************
1229 #if BLAZE_FMA_MODE
1230 template< typename T1 // Type of the first multiplication operand
1231  , typename T2 // Type of the second multiplication operand
1232  , typename T3 > // Type of the second subtraction operand
1234  operator-( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64<T3>& b )
1235 {
1236  return SIMDf64FmsubExpr<T1,T2,T3>( a.a_, a.b_, ~b );
1237 }
1238 #endif
1239 //*************************************************************************************************
1240 
1241 
1242 //*************************************************************************************************
1255 #if BLAZE_FMA_MODE
1256 template< typename T1 // Type of the first operand of the left-hand side multiplication
1257  , typename T2 // Type of the second operand of the left-hand side multiplication
1258  , typename T3 // Type of the first operand of the right-hand side multiplication
1259  , typename T4 > // Type of the second operand of the right-hand side multiplication
1262 {
1264 }
1265 #endif
1266 
1267 //*************************************************************************************************
1268 
1269 
1270 //*************************************************************************************************
1284 #if BLAZE_FMA_MODE
1285 template< typename T1 // Type of the first FMA multiplication operand
1286  , typename T2 // Type of the second FMA multiplication operand
1287  , typename T3 // Type of the FMA subtraction operand
1288  , typename T4 > // Type of the second subtraction operand
1289 BLAZE_ALWAYS_INLINE decltype(auto)
1290  operator-( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64<T4>& b )
1291 {
1292  return ( a.a_ * a.b_ ) - ( a.c_ + (~b) );
1293 }
1294 #endif
1295 
1296 //*************************************************************************************************
1297 
1298 
1299 //*************************************************************************************************
1313 #if BLAZE_FMA_MODE
1314 template< typename T1 // Type of the first FMA multiplication operand
1315  , typename T2 // Type of the second FMA multiplication operand
1316  , typename T3 // Type of the FMA subtraction operand
1317  , typename T4 // Type of the first multiplication operand
1318  , typename T5 > // Type of the second multiplication operand
1319 BLAZE_ALWAYS_INLINE decltype(auto)
1321 {
1322  return ( a.a_ * a.b_ ) - ( b.a_ * b.b_ + a.c_ );
1323 }
1324 #endif
1325 
1326 //*************************************************************************************************
1327 
1328 
1329 //*************************************************************************************************
1343 #if BLAZE_FMA_MODE
1344 template< typename T1 // Type of the first multiplication operand
1345  , typename T2 // Type of the second multiplication operand
1346  , typename T3 // Type of the first FMA multiplication operand
1347  , typename T4 // Type of the second FMA multiplication operand
1348  , typename T5 > // Type of the FMA subtraction operand
1351 {
1353 }
1354 #endif
1355 
1356 //*************************************************************************************************
1357 
1358 
1359 //*************************************************************************************************
1372 #if BLAZE_FMA_MODE
1373 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1374  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1375  , typename T3 // Type of the addition operand of the left-hand side FMA
1376  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1377  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1378  , typename T6 > // Type of the addition operand of the right-hand side FMA
1379 BLAZE_ALWAYS_INLINE decltype(auto)
1381 {
1382  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
1383 }
1384 #endif
1385 
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1402 #if BLAZE_FMA_MODE
1403 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1404  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1405  , typename T3 // Type of the addition operand of the left-hand side FMA
1406  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1407  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1408  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
1409 BLAZE_ALWAYS_INLINE decltype(auto)
1411 {
1412  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) - ( a.c_ + b.c_ ) );
1413 }
1414 #endif
1415 
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1432 #if BLAZE_FMA_MODE
1433 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1434  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1435  , typename T3 // Type of the subtraction operand of the left-hand side FMA
1436  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1437  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1438  , typename T6 > // Type of the addition operand of the right-hand side FMA
1439 BLAZE_ALWAYS_INLINE decltype(auto)
1441 {
1442  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
1443 }
1444 #endif
1445 
1446 //*************************************************************************************************
1447 
1448 
1449 //*************************************************************************************************
1462 #if BLAZE_FMA_MODE
1463 template< typename T1 // Type of the first multiplication operand of the left-hand side FMA
1464  , typename T2 // Type of the second multiplication operand of the left-hand side FMA
1465  , typename T3 // Type of the subtraction operand of the left-hand side FMA
1466  , typename T4 // Type of the first multiplication operand of the right-hand side FMA
1467  , typename T5 // Type of the second multiplication operand of the right-hand side FMA
1468  , typename T6 > // Type of the subtraction operand of the right-hand side FMA
1469 BLAZE_ALWAYS_INLINE decltype(auto)
1471 {
1472  return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
1473 }
1474 #endif
1475 
1476 //*************************************************************************************************
1477 
1478 } // namespace blaze
1479 
1480 #endif
Addition operator for fusing a 32-bit floating point multiplication and addition. ...
Definition: FMA.h:783
Expression object for 64-bit floating point fused multiply-subtract operations.The SIMDf64FmsubExpr c...
Definition: FMA.h:847
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:829
Expression object for 64-bit floating point multiplication operations.The SIMDf64MultExpr class repre...
Definition: Multiplication.h:949
Expression object for 32-bit floating point fused multiply-subtract operations.The SIMDf32FmsubExpr c...
Definition: FMA.h:133
Header file for the SIMD subtraction functionality.
const T3 c_
The right-hand side operand for the addition.
Definition: FMA.h:831
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:701
Header file for the SIMD multiplication functionality.
BLAZE_ALWAYS_INLINE SIMDf64FmaddExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf64FmaddExpr class.
Definition: FMA.h:798
Expression object for 32-bit floating point fused multiply-add operations.The SIMDf32FmaddExpr class ...
Definition: FMA.h:69
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
SIMDf64< This > BaseType
Base type of this SIMDf64FMaddExpr instance.
Definition: FMA.h:788
SIMD type for 64-bit double precision floating point data values.
SIMDf32< This > BaseType
Base type of this SIMDf32FMaddExpr instance.
Definition: FMA.h:74
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
const T2 b_
The right-hand side operand for the multiplication.
Definition: Multiplication.h:994
BLAZE_ALWAYS_INLINE const SIMDfloat eval() const noexcept=delete
Evaluation of the expression object.
Header file for the basic SIMD types.
SIMDf32< This > BaseType
Base type of this SIMDf32FMsubExpr instance.
Definition: FMA.h:138
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:830
const T1 a_
The left-hand side operand for the multiplication.
Definition: Multiplication.h:798
SIMDf64< This > BaseType
Base type of this SIMDf64FMsubExpr instance.
Definition: FMA.h:852
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:893
BLAZE_ALWAYS_INLINE SIMDf32FmsubExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf32FmsubExpr class.
Definition: FMA.h:148
SIMD type for 32-bit single precision floating point data values.
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:115
BLAZE_ALWAYS_INLINE SIMDf64FmsubExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf64FmsubExpr class.
Definition: FMA.h:862
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:179
Header file for the SIMD addition functionality.
System settings for the SSE mode.
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:180
Expression object for 32-bit floating point multiplication operations.The SIMDf32MultExpr class repre...
Definition: Multiplication.h:754
const T2 b_
The right-hand side operand for the multiplication.
Definition: Multiplication.h:799
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:116
System settings for the inline keywords.
BLAZE_ALWAYS_INLINE SIMDf32FmaddExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf32FmaddExpr class.
Definition: FMA.h:84
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:894
const T1 a_
The left-hand side operand for the multiplication.
Definition: Multiplication.h:993
const T3 c_
The right-hand side operand for the subtraction.
Definition: FMA.h:181
const T3 c_
The right-hand side operand for the subtraction.
Definition: FMA.h:895
const T3 c_
The right-hand side operand for the addition.
Definition: FMA.h:117