1 /* 2 * Double-precision vector sincos function. 3 * 4 * Copyright (c) 2023, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6 */ 7 8 /* Define _GNU_SOURCE in order to include sincos declaration. If building 9 pre-GLIBC 2.1, or on a non-GNU conforming system, this routine will need to 10 be linked against the scalar sincosf from math/. */ 11 #define _GNU_SOURCE 12 #include <math.h> 13 #undef _GNU_SOURCE 14 15 #include "sv_sincos_common.h" 16 #include "sv_math.h" 17 #include "pl_test.h" 18 19 static void NOINLINE 20 special_case (svfloat64_t x, svbool_t special, double *out_sin, 21 double *out_cos) 22 { 23 svbool_t p = svptrue_pat_b64 (SV_VL1); 24 for (int i = 0; i < svcntd (); i++) 25 { 26 if (svptest_any (special, p)) 27 sincos (svlastb (p, x), out_sin + i, out_cos + i); 28 p = svpnext_b64 (svptrue_b64 (), p); 29 } 30 } 31 32 /* Double-precision vector function allowing calculation of both sin and cos in 33 one function call, using shared argument reduction and separate polynomials. 34 Largest observed error is for sin, 3.22 ULP: 35 sv_sincos_sin (0x1.d70eef40f39b1p+12) got -0x1.ffe9537d5dbb7p-3 36 want -0x1.ffe9537d5dbb4p-3. */ 37 void 38 _ZGVsMxvl8l8_sincos (svfloat64_t x, double *out_sin, double *out_cos, 39 svbool_t pg) 40 { 41 const struct sv_sincos_data *d = ptr_barrier (&sv_sincos_data); 42 svbool_t special = check_ge_rangeval (pg, x, d); 43 44 svfloat64x2_t sc = sv_sincos_inline (pg, x, d); 45 46 svst1 (pg, out_sin, svget2 (sc, 0)); 47 svst1 (pg, out_cos, svget2 (sc, 1)); 48 49 if (unlikely (svptest_any (pg, special))) 50 special_case (x, special, out_sin, out_cos); 51 } 52 53 PL_TEST_ULP (_ZGVsMxv_sincos_sin, 2.73) 54 PL_TEST_ULP (_ZGVsMxv_sincos_cos, 2.73) 55 #define SV_SINCOS_INTERVAL(lo, hi, n) \ 56 PL_TEST_INTERVAL (_ZGVsMxv_sincos_sin, lo, hi, n) \ 57 PL_TEST_INTERVAL (_ZGVsMxv_sincos_cos, lo, hi, n) 58 SV_SINCOS_INTERVAL (0, 0x1p23, 500000) 59 SV_SINCOS_INTERVAL (-0, -0x1p23, 500000) 60 SV_SINCOS_INTERVAL (0x1p23, inf, 10000) 61 SV_SINCOS_INTERVAL (-0x1p23, -inf, 10000) 62