Blaze 3.9
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
43#include <blaze/math/simd/Add.h>
46#include <blaze/math/simd/Sub.h>
47#include <blaze/system/Inline.h>
49
50
51namespace blaze {
52
53//=================================================================================================
54//
55// 32-BIT FLOATING POINT SIMD TYPES
56//
57//=================================================================================================
58
59//*************************************************************************************************
66template< 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 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//*************************************************************************************************
130template< 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 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
200template< 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
225template< 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
228BLAZE_ALWAYS_INLINE const SIMDf32FmaddExpr<T2,T3,T1>
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
251template< 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
255BLAZE_ALWAYS_INLINE const SIMDf32FmaddExpr< T1, T2, SIMDf32MultExpr<T3,T4> >
256 operator+( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32MultExpr<T3,T4>& b )
257{
258 return SIMDf32FmaddExpr< T1, T2, SIMDf32MultExpr<T3,T4> >( a.a_, a.b_, b );
259}
260#endif
262//*************************************************************************************************
263
264
265//*************************************************************************************************
279#if BLAZE_FMA_MODE
280template< 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
284BLAZE_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
291//*************************************************************************************************
292
293
294//*************************************************************************************************
308#if BLAZE_FMA_MODE
309template< 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
313BLAZE_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
320//*************************************************************************************************
321
322
323//*************************************************************************************************
337#if BLAZE_FMA_MODE
338template< 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
343BLAZE_ALWAYS_INLINE const SIMDf32FmaddExpr< T4, T5, SIMDf32FmaddExpr<T1,T2,T3> >
344 operator+( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32MultExpr<T4,T5>& b )
345{
346 return SIMDf32FmaddExpr< T4, T5, SIMDf32FmaddExpr<T1,T2,T3> >( b.a_, b.b_, a );
347}
348#endif
350//*************************************************************************************************
351
352
353//*************************************************************************************************
367#if BLAZE_FMA_MODE
368template< 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
373BLAZE_ALWAYS_INLINE const SIMDf32FmaddExpr< T1, T2, SIMDf32FmaddExpr<T3,T4,T5> >
374 operator+( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32FmaddExpr<T3,T4,T5>& b )
375{
376 return SIMDf32FmaddExpr< T1, T2, SIMDf32FmaddExpr<T3,T4,T5> >( a.a_, a.b_, b );
377}
378#endif
380//*************************************************************************************************
381
382
383//*************************************************************************************************
396#if BLAZE_FMA_MODE
397template< 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
403BLAZE_ALWAYS_INLINE decltype(auto)
404 operator+( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32FmaddExpr<T4,T5,T6>& b )
405{
406 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
407}
408#endif
410//*************************************************************************************************
411
412
413//*************************************************************************************************
426#if BLAZE_FMA_MODE
427template< 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
433BLAZE_ALWAYS_INLINE decltype(auto)
434 operator+( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32FmsubExpr<T4,T5,T6>& b )
435{
436 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
437}
438#endif
440//*************************************************************************************************
441
442
443//*************************************************************************************************
456#if BLAZE_FMA_MODE
457template< 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
463BLAZE_ALWAYS_INLINE decltype(auto)
464 operator+( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32FmaddExpr<T4,T5,T6>& b )
465{
466 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
467}
468#endif
470//*************************************************************************************************
471
472
473//*************************************************************************************************
486#if BLAZE_FMA_MODE
487template< 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
493BLAZE_ALWAYS_INLINE decltype(auto)
494 operator+( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32FmsubExpr<T4,T5,T6>& b )
495{
496 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) - ( b.c_ + a.c_ ) );
497}
498#endif
500//*************************************************************************************************
501
502
503//*************************************************************************************************
515#if BLAZE_FMA_MODE
516template< 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
519BLAZE_ALWAYS_INLINE const SIMDf32FmsubExpr<T1,T2,T3>
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
542template< 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
546BLAZE_ALWAYS_INLINE const SIMDf32FmsubExpr< T1, T2, SIMDf32MultExpr<T3,T4> >
547 operator-( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32MultExpr<T3,T4>& b )
548{
549 return SIMDf32FmsubExpr< T1, T2, SIMDf32MultExpr<T3,T4> >( a.a_, a.b_, b );
550}
551#endif
553//*************************************************************************************************
554
555
556//*************************************************************************************************
570#if BLAZE_FMA_MODE
571template< 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
575BLAZE_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
582//*************************************************************************************************
583
584
585//*************************************************************************************************
599#if BLAZE_FMA_MODE
600template< 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
605BLAZE_ALWAYS_INLINE decltype(auto)
606 operator-( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32MultExpr<T4,T5>& b )
607{
608 return ( a.a_ * a.b_ ) - ( b.a_ * b.b_ + a.c_ );
609}
610#endif
612//*************************************************************************************************
613
614
615//*************************************************************************************************
629#if BLAZE_FMA_MODE
630template< 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
635BLAZE_ALWAYS_INLINE const SIMDf32FmsubExpr< T1, T2, SIMDf32FmsubExpr<T3,T4,T5> >
636 operator-( const SIMDf32MultExpr<T1,T2>& a, const SIMDf32FmsubExpr<T3,T4,T5>& b )
637{
638 return SIMDf32FmsubExpr< T1, T2, SIMDf32FmsubExpr<T3,T4,T5> >( a.a_, a.b_, b );
639}
640#endif
642//*************************************************************************************************
643
644
645//*************************************************************************************************
658#if BLAZE_FMA_MODE
659template< 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
665BLAZE_ALWAYS_INLINE decltype(auto)
666 operator-( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32FmaddExpr<T4,T5,T6>& b )
667{
668 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
669}
670#endif
672//*************************************************************************************************
673
674
675//*************************************************************************************************
688#if BLAZE_FMA_MODE
689template< 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
695BLAZE_ALWAYS_INLINE decltype(auto)
696 operator-( const SIMDf32FmaddExpr<T1,T2,T3>& a, const SIMDf32FmsubExpr<T4,T5,T6>& b )
697{
698 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) - ( a.c_ + b.c_ ) );
699}
700#endif
702//*************************************************************************************************
703
704
705//*************************************************************************************************
718#if BLAZE_FMA_MODE
719template< 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
725BLAZE_ALWAYS_INLINE decltype(auto)
726 operator-( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32FmaddExpr<T4,T5,T6>& b )
727{
728 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
729}
730#endif
732//*************************************************************************************************
733
734
735//*************************************************************************************************
748#if BLAZE_FMA_MODE
749template< 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
755BLAZE_ALWAYS_INLINE decltype(auto)
756 operator-( const SIMDf32FmsubExpr<T1,T2,T3>& a, const SIMDf32FmsubExpr<T4,T5,T6>& b )
757{
758 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
759}
760#endif
762//*************************************************************************************************
763
764
765
766
767//=================================================================================================
768//
769// 64-BIT FLOATING POINT SIMD TYPES
770//
771//=================================================================================================
772
773//*************************************************************************************************
780template< 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 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//*************************************************************************************************
844template< 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 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
914template< 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
939template< 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
942BLAZE_ALWAYS_INLINE const SIMDf64FmaddExpr<T2,T3,T1>
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
965template< 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
969BLAZE_ALWAYS_INLINE const SIMDf64FmaddExpr< T1, T2, SIMDf64MultExpr<T3,T4> >
970 operator+( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64MultExpr<T3,T4>& b )
971{
972 return SIMDf64FmaddExpr< T1, T2, SIMDf64MultExpr<T3,T4> >( a.a_, a.b_, b );
973}
974#endif
976//*************************************************************************************************
977
978
979//*************************************************************************************************
993#if BLAZE_FMA_MODE
994template< 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
998BLAZE_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
1005//*************************************************************************************************
1006
1007
1008//*************************************************************************************************
1022#if BLAZE_FMA_MODE
1023template< 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
1027BLAZE_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
1034//*************************************************************************************************
1035
1036
1037//*************************************************************************************************
1051#if BLAZE_FMA_MODE
1052template< 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
1057BLAZE_ALWAYS_INLINE const SIMDf64FmaddExpr< T4, T5, SIMDf64FmaddExpr<T1,T2,T3> >
1058 operator+( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64MultExpr<T4,T5>& b )
1059{
1060 return SIMDf64FmaddExpr< T4, T5, SIMDf64FmaddExpr<T1,T2,T3> >( b.a_, b.b_, a );
1061}
1062#endif
1064//*************************************************************************************************
1065
1066
1067//*************************************************************************************************
1081#if BLAZE_FMA_MODE
1082template< 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
1087BLAZE_ALWAYS_INLINE const SIMDf64FmaddExpr< T1, T2, SIMDf64FmaddExpr<T3,T4,T5> >
1088 operator+( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64FmaddExpr<T3,T4,T5>& b )
1089{
1090 return SIMDf64FmaddExpr< T1, T2, SIMDf64FmaddExpr<T3,T4,T5> >( a.a_, a.b_, b );
1091}
1092#endif
1094//*************************************************************************************************
1095
1096
1097//*************************************************************************************************
1110#if BLAZE_FMA_MODE
1111template< 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
1117BLAZE_ALWAYS_INLINE decltype(auto)
1118 operator+( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64FmaddExpr<T4,T5,T6>& b )
1119{
1120 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
1121}
1122#endif
1124//*************************************************************************************************
1125
1126
1127//*************************************************************************************************
1140#if BLAZE_FMA_MODE
1141template< 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
1147BLAZE_ALWAYS_INLINE decltype(auto)
1148 operator+( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64FmsubExpr<T4,T5,T6>& b )
1149{
1150 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
1151}
1152#endif
1154//*************************************************************************************************
1155
1156
1157//*************************************************************************************************
1170#if BLAZE_FMA_MODE
1171template< 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
1177BLAZE_ALWAYS_INLINE decltype(auto)
1178 operator+( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64FmaddExpr<T4,T5,T6>& b )
1179{
1180 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
1181}
1182#endif
1184//*************************************************************************************************
1185
1186
1187//*************************************************************************************************
1200#if BLAZE_FMA_MODE
1201template< 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
1207BLAZE_ALWAYS_INLINE decltype(auto)
1208 operator+( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64FmsubExpr<T4,T5,T6>& b )
1209{
1210 return ( a.a_ * a.b_ ) + ( ( b.a_ * b.b_ ) - ( b.c_ + a.c_ ) );
1211}
1212#endif
1214//*************************************************************************************************
1215
1216
1217//*************************************************************************************************
1229#if BLAZE_FMA_MODE
1230template< 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
1233BLAZE_ALWAYS_INLINE const SIMDf64FmsubExpr<T1,T2,T3>
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
1256template< 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
1260BLAZE_ALWAYS_INLINE const SIMDf64FmsubExpr< T1, T2, SIMDf64MultExpr<T3,T4> >
1261 operator-( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64MultExpr<T3,T4>& b )
1262{
1263 return SIMDf64FmsubExpr< T1, T2, SIMDf64MultExpr<T3,T4> >( a.a_, a.b_, b );
1264}
1265#endif
1267//*************************************************************************************************
1268
1269
1270//*************************************************************************************************
1284#if BLAZE_FMA_MODE
1285template< 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
1289BLAZE_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
1296//*************************************************************************************************
1297
1298
1299//*************************************************************************************************
1313#if BLAZE_FMA_MODE
1314template< 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
1319BLAZE_ALWAYS_INLINE decltype(auto)
1320 operator-( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64MultExpr<T4,T5>& b )
1321{
1322 return ( a.a_ * a.b_ ) - ( b.a_ * b.b_ + a.c_ );
1323}
1324#endif
1326//*************************************************************************************************
1327
1328
1329//*************************************************************************************************
1343#if BLAZE_FMA_MODE
1344template< 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
1349BLAZE_ALWAYS_INLINE const SIMDf64FmsubExpr< T1, T2, SIMDf64FmsubExpr<T3,T4,T5> >
1350 operator-( const SIMDf64MultExpr<T1,T2>& a, const SIMDf64FmsubExpr<T3,T4,T5>& b )
1351{
1352 return SIMDf64FmsubExpr< T1, T2, SIMDf64FmsubExpr<T3,T4,T5> >( a.a_, a.b_, b );
1353}
1354#endif
1356//*************************************************************************************************
1357
1358
1359//*************************************************************************************************
1372#if BLAZE_FMA_MODE
1373template< 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
1379BLAZE_ALWAYS_INLINE decltype(auto)
1380 operator-( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64FmaddExpr<T4,T5,T6>& b )
1381{
1382 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( b.c_ - a.c_ ) );
1383}
1384#endif
1386//*************************************************************************************************
1387
1388
1389//*************************************************************************************************
1402#if BLAZE_FMA_MODE
1403template< 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
1409BLAZE_ALWAYS_INLINE decltype(auto)
1410 operator-( const SIMDf64FmaddExpr<T1,T2,T3>& a, const SIMDf64FmsubExpr<T4,T5,T6>& b )
1411{
1412 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) - ( a.c_ + b.c_ ) );
1413}
1414#endif
1416//*************************************************************************************************
1417
1418
1419//*************************************************************************************************
1432#if BLAZE_FMA_MODE
1433template< 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
1439BLAZE_ALWAYS_INLINE decltype(auto)
1440 operator-( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64FmaddExpr<T4,T5,T6>& b )
1441{
1442 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ + b.c_ ) );
1443}
1444#endif
1446//*************************************************************************************************
1447
1448
1449//*************************************************************************************************
1462#if BLAZE_FMA_MODE
1463template< 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
1469BLAZE_ALWAYS_INLINE decltype(auto)
1470 operator-( const SIMDf64FmsubExpr<T1,T2,T3>& a, const SIMDf64FmsubExpr<T4,T5,T6>& b )
1471{
1472 return ( a.a_ * a.b_ ) - ( ( b.a_ * b.b_ ) + ( a.c_ - b.c_ ) );
1473}
1474#endif
1476//*************************************************************************************************
1477
1478} // namespace blaze
1479
1480#endif
Header file for the basic SIMD types.
constexpr 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:751
constexpr 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:719
SIMD type for 64-bit double precision floating point data values.
SIMD type for 32-bit single precision floating point data values.
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for the SIMD addition functionality.
Header file for the SIMD multiplication functionality.
Header file for the SIMD subtraction functionality.
Expression object for 32-bit floating point fused multiply-add operations.
Definition: FMA.h:71
SIMDf32< This > BaseType
Base type of this SIMDf32FMaddExpr instance.
Definition: FMA.h:74
BLAZE_ALWAYS_INLINE const SIMDfloat eval() const noexcept=delete
Evaluation of the expression object.
BLAZE_ALWAYS_INLINE SIMDf32FmaddExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf32FmaddExpr class.
Definition: FMA.h:84
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:115
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:116
const T3 c_
The right-hand side operand for the addition.
Definition: FMA.h:117
Expression object for 32-bit floating point fused multiply-subtract operations.
Definition: FMA.h:135
BLAZE_ALWAYS_INLINE const SIMDfloat eval() const noexcept=delete
Evaluation of the expression object.
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:179
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:180
SIMDf32< This > BaseType
Base type of this SIMDf32FMsubExpr instance.
Definition: FMA.h:138
BLAZE_ALWAYS_INLINE SIMDf32FmsubExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf32FmsubExpr class.
Definition: FMA.h:148
const T3 c_
The right-hand side operand for the subtraction.
Definition: FMA.h:181
Expression object for 32-bit floating point multiplication operations.
Definition: Mult.h:756
const T1 a_
The left-hand side operand for the multiplication.
Definition: Mult.h:798
const T2 b_
The right-hand side operand for the multiplication.
Definition: Mult.h:799
Addition operator for fusing a 32-bit floating point multiplication and addition.
Definition: FMA.h:785
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:830
const T3 c_
The right-hand side operand for the addition.
Definition: FMA.h:831
const T1 a_
The left-hand side operand for the multiplication.
Definition: FMA.h:829
SIMDf64< This > BaseType
Base type of this SIMDf64FMaddExpr instance.
Definition: FMA.h:788
BLAZE_ALWAYS_INLINE SIMDf64FmaddExpr(const T1 &a, const T2 &b, const T3 &c)
Constructor for the SIMDf64FmaddExpr class.
Definition: FMA.h:798
BLAZE_ALWAYS_INLINE const SIMDdouble eval() const noexcept=delete
Evaluation of the expression object.
Expression object for 64-bit floating point fused multiply-subtract operations.
Definition: FMA.h:849
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:893
SIMDf64< This > BaseType
Base type of this SIMDf64FMsubExpr instance.
Definition: FMA.h:852
BLAZE_ALWAYS_INLINE const SIMDdouble eval() const noexcept=delete
Evaluation of the expression object.
const T2 b_
The right-hand side operand for the multiplication.
Definition: FMA.h:894
const T3 c_
The right-hand side operand for the subtraction.
Definition: FMA.h:895
Expression object for 64-bit floating point multiplication operations.
Definition: Mult.h:951
const T1 a_
The left-hand side operand for the multiplication.
Definition: Mult.h:993
const T2 b_
The right-hand side operand for the multiplication.
Definition: Mult.h:994
System settings for the inline keywords.
System settings for the SSE mode.