GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/details/inner_fma.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 4 4 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /*
2 POLYFLOAT - Extended precision floating points
3 Copyright : POLYFLOAT Contributors & Maintainers
4 SPDX-License-Identifier: BSL-1.0
5 */
6 //======================================================================================================================
7 #pragma once
8 #include <polyfloat/module/core/three_fma.hpp>
9
10 namespace plf::_
11 {
12 template<typename Z1, typename Z2, typename Z3>
13 4 constexpr auto inner_fma(Z1 const& x, Z2 const& y, Z3 const& z) noexcept
14 {
15 using r_t = as_polyfloat_t<Z1, Z2, Z3>;
16 if constexpr (dimension_v<r_t> == 1) return eve::fma[pedantic](x, y, z);
17 else if constexpr ((dimension_v<Z1> > 2) || (dimension_v<Z2> > 2) || (dimension_v<Z3> > 2))
18 {
19 using r_t = as_polyfloat_t<Z1, Z2, Z3>;
20 12 auto cvt = [](auto a) { return plf::convert(a, eve::as<eve::element_type_t<r_t>>()); };
21 12 auto [r, e0, e1] = three_fma(cvt(x), cvt(y), cvt(z));
22 4 return r;
23 }
24 else if constexpr ((dimension_v<Z1> == 2) && (dimension_v<Z2> == 2) && (dimension_v<Z3> == 2))
25 {
26 // auto fmap = eve::fma[pedantic];
27 auto [xhi, xlo] = x;
28 auto [yhi, ylo] = y;
29 auto [zhi, zlo] = z;
30 auto [chi, c1] = eve::two_prod(xhi, yhi);
31 auto t0 = xlo * ylo;
32 auto t1 = eve::fma(xhi, ylo, t0);
33 auto c2 = eve::fma(xlo, yhi, t1);
34 auto c3 = c1 + c2;
35 auto [dhi, dlo] = eve::two_add[eve::raw](chi, c3);
36
37 auto [shi, slo] = eve::two_add(zhi, dhi);
38 auto [thi, tlo] = eve::two_add(zlo, dlo);
39 auto c = slo + thi;
40 auto [vhi, vlo] = eve::two_add[eve::raw](shi, c);
41 auto w = tlo + vlo;
42 auto [hi, lo] = eve::two_add[eve::raw](vhi, w);
43 return r_t(hi, lo);
44 }
45 else if constexpr ((dimension_v<Z1> == 1) && (dimension_v<Z2> == 1))
46 {
47 auto [zhi, zlo] = z;
48 auto [chi, c1] = eve::two_prod(x, y);
49 auto [shi, slo] = eve::two_add(zhi, chi);
50 auto [thi, tlo] = eve::two_add(zlo, c1);
51 auto c = slo + thi;
52 auto [vhi, vlo] = eve::two_add[eve::raw](shi, c);
53 auto w = tlo + vlo;
54 auto [hi, lo] = eve::two_add[eve::raw](vhi, w);
55 return r_t(hi, lo);
56 }
57 // else
58 // {
59 // using r_t = as_polyfloat_t<Z1, Z2, Z3>;
60 // auto cvt = [](auto a){return plf::convert(a, eve::as<eve::element_type_t<r_t>>());};
61 // return fma(cvt(x), cvt(y), cvt(z));
62 // }
63 }
64 }
65