1 | //===-- Common header for PolyEval implementations --------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_POLYEVAL_H |
10 | #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_POLYEVAL_H |
11 | |
12 | #include "multiply_add.h" |
13 | #include "src/__support/CPP/type_traits.h" |
14 | #include "src/__support/common.h" |
15 | |
16 | // Evaluate polynomial using Horner's Scheme: |
17 | // With polyeval(x, a_0, a_1, ..., a_n) = a_n * x^n + ... + a_1 * x + a_0, we |
18 | // evaluated it as: a_0 + x * (a_1 + x * ( ... (a_(n-1) + x * a_n) ... ) ) ). |
19 | // We will use FMA instructions if available. |
20 | // Example: to evaluate x^3 + 2*x^2 + 3*x + 4, call |
21 | // polyeval( x, 4.0, 3.0, 2.0, 1.0 ) |
22 | |
23 | namespace LIBC_NAMESPACE { |
24 | namespace fputil { |
25 | |
26 | template <typename T> |
27 | LIBC_INLINE cpp::enable_if_t<(sizeof(T) > sizeof(void *)), T> |
28 | polyeval(const T &, const T &a0) { |
29 | return a0; |
30 | } |
31 | |
32 | template <typename T> |
33 | LIBC_INLINE cpp::enable_if_t<(sizeof(T) <= sizeof(void *)), T> polyeval(T, |
34 | T a0) { |
35 | return a0; |
36 | } |
37 | |
38 | template <typename T, typename... Ts> |
39 | LIBC_INLINE cpp::enable_if_t<(sizeof(T) > sizeof(void *)), T> |
40 | polyeval(const T &x, const T &a0, const Ts &...a) { |
41 | return multiply_add(x, polyeval(x, a...), a0); |
42 | } |
43 | |
44 | template <typename T, typename... Ts> |
45 | LIBC_INLINE cpp::enable_if_t<(sizeof(T) <= sizeof(void *)), T> |
46 | polyeval(T x, T a0, Ts... a) { |
47 | return multiply_add(x, polyeval(x, a...), a0); |
48 | } |
49 | |
50 | } // namespace fputil |
51 | } // namespace LIBC_NAMESPACE |
52 | |
53 | #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_POLYEVAL_H |
54 | |