diff options
Diffstat (limited to 'math/v_sinf.c')
-rw-r--r-- | math/v_sinf.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/math/v_sinf.c b/math/v_sinf.c index e66bfce..ce35dac 100644 --- a/math/v_sinf.c +++ b/math/v_sinf.c @@ -1,8 +1,8 @@ /* * Single-precision vector sin function. * - * Copyright (c) 2019, Arm Limited. - * SPDX-License-Identifier: MIT + * Copyright (c) 2019-2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include "mathlib.h" @@ -24,6 +24,7 @@ static const float Poly[] = { #define A7 v_f32 (Poly[1]) #define A9 v_f32 (Poly[0]) #define RangeVal v_f32 (0x1p20f) +#define TinyBound v_f32 (0x1p-61f) #define InvPi v_f32 (0x1.45f306p-2f) #define Shift v_f32 (0x1.8p+23f) #define AbsMask v_u32 (0x7fffffff) @@ -41,11 +42,23 @@ v_f32_t V_NAME(sinf) (v_f32_t x) { v_f32_t n, r, r2, y; - v_u32_t sign, odd, cmp; + v_u32_t sign, odd, cmp, ir; - r = v_as_f32_u32 (v_as_u32_f32 (x) & AbsMask); + ir = v_as_u32_f32 (x) & AbsMask; + r = v_as_f32_u32 (ir); sign = v_as_u32_f32 (x) & ~AbsMask; - cmp = v_cond_u32 (v_as_u32_f32 (r) >= v_as_u32_f32 (RangeVal)); + +#if WANT_SIMD_EXCEPT + cmp = v_cond_u32 ((ir - v_as_u32_f32 (TinyBound) + >= v_as_u32_f32 (RangeVal) - v_as_u32_f32 (TinyBound))); + if (unlikely (v_any_u32 (cmp))) + /* If fenv exceptions are to be triggered correctly, set any special lanes + to 1 (which is neutral w.r.t. fenv). These lanes will be fixed by + specialcase later. */ + r = v_sel_f32 (cmp, v_f32 (1), r); +#else + cmp = v_cond_u32 (ir >= v_as_u32_f32 (RangeVal)); +#endif /* n = rint(|x|/pi) */ n = v_fma_f32 (InvPi, r, Shift); |