1 /* 2 * Single-precision polynomial evaluation function for scalar 3 * atan(x) and atan2(y,x). 4 * 5 * Copyright (c) 2021-2023, Arm Limited. 6 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 7 */ 8 9 #ifndef PL_MATH_ATANF_COMMON_H 10 #define PL_MATH_ATANF_COMMON_H 11 12 #include "math_config.h" 13 #include "poly_scalar_f32.h" 14 15 /* Polynomial used in fast atanf(x) and atan2f(y,x) implementations 16 The order 7 polynomial P approximates (atan(sqrt(x))-sqrt(x))/x^(3/2). */ 17 static inline float 18 eval_poly (float z, float az, float shift) 19 { 20 /* Use 2-level Estrin scheme for P(z^2) with deg(P)=7. However, 21 a standard implementation using z8 creates spurious underflow 22 in the very last fma (when z^8 is small enough). 23 Therefore, we split the last fma into a mul and and an fma. 24 Horner and single-level Estrin have higher errors that exceed 25 threshold. */ 26 float z2 = z * z; 27 float z4 = z2 * z2; 28 29 /* Then assemble polynomial. */ 30 float y = fmaf ( 31 z4, z4 * pairwise_poly_3_f32 (z2, z4, __atanf_poly_data.poly + 4), 32 pairwise_poly_3_f32 (z2, z4, __atanf_poly_data.poly)); 33 /* Finalize: 34 y = shift + z * P(z^2). */ 35 return fmaf (y, z2 * az, az) + shift; 36 } 37 38 #endif // PL_MATH_ATANF_COMMON_H 39