1072a4ba8SAndrew Turner /* 2072a4ba8SAndrew Turner * Function wrappers for ulp. 3072a4ba8SAndrew Turner * 4*f3087befSAndrew Turner * Copyright (c) 2022-2024, Arm Limited. 5072a4ba8SAndrew Turner * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6072a4ba8SAndrew Turner */ 7072a4ba8SAndrew Turner 85a02ffc3SAndrew Turner /* clang-format off */ 95a02ffc3SAndrew Turner 10*f3087befSAndrew Turner #if __aarch64__ && __linux__ 11*f3087befSAndrew Turner #include <arm_neon.h> 12*f3087befSAndrew Turner #endif 13*f3087befSAndrew Turner 14*f3087befSAndrew Turner #include <stdbool.h> 15*f3087befSAndrew Turner 16072a4ba8SAndrew Turner /* Wrappers for sincos. */ 17072a4ba8SAndrew Turner static float sincosf_sinf(float x) {(void)cosf(x); return sinf(x);} 18072a4ba8SAndrew Turner static float sincosf_cosf(float x) {(void)sinf(x); return cosf(x);} 19072a4ba8SAndrew Turner static double sincos_sin(double x) {(void)cos(x); return sin(x);} 20072a4ba8SAndrew Turner static double sincos_cos(double x) {(void)sin(x); return cos(x);} 21072a4ba8SAndrew Turner #if USE_MPFR 22072a4ba8SAndrew Turner static int sincos_mpfr_sin(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_cos(y,x,r); return mpfr_sin(y,x,r); } 23072a4ba8SAndrew Turner static int sincos_mpfr_cos(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_sin(y,x,r); return mpfr_cos(y,x,r); } 24*f3087befSAndrew Turner static int modf_mpfr_frac(mpfr_t f, const mpfr_t x, mpfr_rnd_t r) { MPFR_DECL_INIT(i, 80); return mpfr_modf(i,f,x,r); } 25*f3087befSAndrew Turner static int modf_mpfr_int(mpfr_t i, const mpfr_t x, mpfr_rnd_t r) { MPFR_DECL_INIT(f, 80); return mpfr_modf(i,f,x,r); } 26*f3087befSAndrew Turner # if MPFR_VERSION < MPFR_VERSION_NUM(4, 2, 0) 27*f3087befSAndrew Turner static int mpfr_tanpi (mpfr_t ret, const mpfr_t arg, mpfr_rnd_t rnd) { 28*f3087befSAndrew Turner MPFR_DECL_INIT (frd, 1080); 29*f3087befSAndrew Turner mpfr_const_pi (frd, GMP_RNDN); 30*f3087befSAndrew Turner mpfr_mul (frd, frd, arg, GMP_RNDN); 31*f3087befSAndrew Turner return mpfr_tan (ret, frd, GMP_RNDN); 32*f3087befSAndrew Turner } 33*f3087befSAndrew Turner static int mpfr_sinpi (mpfr_t ret, const mpfr_t arg, mpfr_rnd_t rnd) { 34*f3087befSAndrew Turner MPFR_DECL_INIT (frd, 1080); 35*f3087befSAndrew Turner mpfr_const_pi (frd, GMP_RNDN); 36*f3087befSAndrew Turner mpfr_mul (frd, frd, arg, GMP_RNDN); 37*f3087befSAndrew Turner return mpfr_sin (ret, frd, GMP_RNDN); 38*f3087befSAndrew Turner } 39*f3087befSAndrew Turner 40*f3087befSAndrew Turner static int mpfr_cospi (mpfr_t ret, const mpfr_t arg, mpfr_rnd_t rnd) { 41*f3087befSAndrew Turner MPFR_DECL_INIT (frd, 1080); 42*f3087befSAndrew Turner mpfr_const_pi (frd, GMP_RNDN); 43*f3087befSAndrew Turner mpfr_mul (frd, frd, arg, GMP_RNDN); 44*f3087befSAndrew Turner return mpfr_cos (ret, frd, GMP_RNDN); 45*f3087befSAndrew Turner } 46*f3087befSAndrew Turner # endif 47*f3087befSAndrew Turner # if WANT_EXPERIMENTAL_MATH 48*f3087befSAndrew Turner static int wrap_mpfr_powi(mpfr_t ret, const mpfr_t x, const mpfr_t y, mpfr_rnd_t rnd) { 49*f3087befSAndrew Turner mpfr_t y2; 50*f3087befSAndrew Turner mpfr_init(y2); 51*f3087befSAndrew Turner mpfr_trunc(y2, y); 52*f3087befSAndrew Turner return mpfr_pow(ret, x, y2, rnd); 53*f3087befSAndrew Turner } 54*f3087befSAndrew Turner # endif 55072a4ba8SAndrew Turner #endif 56072a4ba8SAndrew Turner 57*f3087befSAndrew Turner float modff_frac(float x) { float i; return modff(x, &i); } 58*f3087befSAndrew Turner float modff_int(float x) { float i; modff(x, &i); return i; } 59*f3087befSAndrew Turner double modf_frac(double x) { double i; return modf(x, &i); } 60*f3087befSAndrew Turner double modf_int(double x) { double i; modf(x, &i); return i; } 61*f3087befSAndrew Turner long double modfl_frac(long double x) { long double i; return modfl(x, &i); } 62*f3087befSAndrew Turner long double modfl_int(long double x) { long double i; modfl(x, &i); return i; } 63*f3087befSAndrew Turner 64072a4ba8SAndrew Turner /* Wrappers for vector functions. */ 65*f3087befSAndrew Turner #if __aarch64__ && __linux__ 665a02ffc3SAndrew Turner static float Z_expf_1u(float x) { return _ZGVnN4v_expf_1u(argf(x))[0]; } 675a02ffc3SAndrew Turner static float Z_exp2f_1u(float x) { return _ZGVnN4v_exp2f_1u(argf(x))[0]; } 68072a4ba8SAndrew Turner #endif 695a02ffc3SAndrew Turner 705a02ffc3SAndrew Turner /* clang-format on */ 71*f3087befSAndrew Turner 72*f3087befSAndrew Turner /* No wrappers for scalar routines, but TEST_SIG will emit them. */ 73*f3087befSAndrew Turner #define ZSNF1_WRAP(func) 74*f3087befSAndrew Turner #define ZSNF2_WRAP(func) 75*f3087befSAndrew Turner #define ZSND1_WRAP(func) 76*f3087befSAndrew Turner #define ZSND2_WRAP(func) 77*f3087befSAndrew Turner 78*f3087befSAndrew Turner #define ZVNF1_WRAP(func) \ 79*f3087befSAndrew Turner static float Z_##func##f (float x) \ 80*f3087befSAndrew Turner { \ 81*f3087befSAndrew Turner return _ZGVnN4v_##func##f (argf (x))[0]; \ 82*f3087befSAndrew Turner } 83*f3087befSAndrew Turner #define ZVNF2_WRAP(func) \ 84*f3087befSAndrew Turner static float Z_##func##f (float x, float y) \ 85*f3087befSAndrew Turner { \ 86*f3087befSAndrew Turner return _ZGVnN4vv_##func##f (argf (x), argf (y))[0]; \ 87*f3087befSAndrew Turner } 88*f3087befSAndrew Turner #define ZVND1_WRAP(func) \ 89*f3087befSAndrew Turner static double Z_##func (double x) { return _ZGVnN2v_##func (argd (x))[0]; } 90*f3087befSAndrew Turner #define ZVND2_WRAP(func) \ 91*f3087befSAndrew Turner static double Z_##func (double x, double y) \ 92*f3087befSAndrew Turner { \ 93*f3087befSAndrew Turner return _ZGVnN2vv_##func (argd (x), argd (y))[0]; \ 94*f3087befSAndrew Turner } 95*f3087befSAndrew Turner 96*f3087befSAndrew Turner #if WANT_TRIGPI_TESTS 97*f3087befSAndrew Turner float 98*f3087befSAndrew Turner arm_math_sincospif_sin (float x) 99*f3087befSAndrew Turner { 100*f3087befSAndrew Turner float s, c; 101*f3087befSAndrew Turner arm_math_sincospif (x, &s, &c); 102*f3087befSAndrew Turner return s; 103*f3087befSAndrew Turner } 104*f3087befSAndrew Turner float 105*f3087befSAndrew Turner arm_math_sincospif_cos (float x) 106*f3087befSAndrew Turner { 107*f3087befSAndrew Turner float s, c; 108*f3087befSAndrew Turner arm_math_sincospif (x, &s, &c); 109*f3087befSAndrew Turner return c; 110*f3087befSAndrew Turner } 111*f3087befSAndrew Turner double 112*f3087befSAndrew Turner arm_math_sincospi_sin (double x) 113*f3087befSAndrew Turner { 114*f3087befSAndrew Turner double s, c; 115*f3087befSAndrew Turner arm_math_sincospi (x, &s, &c); 116*f3087befSAndrew Turner return s; 117*f3087befSAndrew Turner } 118*f3087befSAndrew Turner double 119*f3087befSAndrew Turner arm_math_sincospi_cos (double x) 120*f3087befSAndrew Turner { 121*f3087befSAndrew Turner double s, c; 122*f3087befSAndrew Turner arm_math_sincospi (x, &s, &c); 123*f3087befSAndrew Turner return c; 124*f3087befSAndrew Turner } 125*f3087befSAndrew Turner #endif 126*f3087befSAndrew Turner 127*f3087befSAndrew Turner #if __aarch64__ && __linux__ 128*f3087befSAndrew Turner 129*f3087befSAndrew Turner # if WANT_TRIGPI_TESTS 130*f3087befSAndrew Turner ZVNF1_WRAP (cospi) 131*f3087befSAndrew Turner ZVND1_WRAP (cospi) 132*f3087befSAndrew Turner ZVNF1_WRAP (sinpi) 133*f3087befSAndrew Turner ZVND1_WRAP (sinpi) 134*f3087befSAndrew Turner ZVNF1_WRAP (tanpi) 135*f3087befSAndrew Turner ZVND1_WRAP (tanpi) 136*f3087befSAndrew Turner 137*f3087befSAndrew Turner double 138*f3087befSAndrew Turner v_sincospi_sin (double x) 139*f3087befSAndrew Turner { 140*f3087befSAndrew Turner double s[2], c[2]; 141*f3087befSAndrew Turner _ZGVnN2vl8l8_sincospi (vdupq_n_f64 (x), s, c); 142*f3087befSAndrew Turner return s[0]; 143*f3087befSAndrew Turner } 144*f3087befSAndrew Turner double 145*f3087befSAndrew Turner v_sincospi_cos (double x) 146*f3087befSAndrew Turner { 147*f3087befSAndrew Turner double s[2], c[2]; 148*f3087befSAndrew Turner _ZGVnN2vl8l8_sincospi (vdupq_n_f64 (x), s, c); 149*f3087befSAndrew Turner return c[0]; 150*f3087befSAndrew Turner } 151*f3087befSAndrew Turner float 152*f3087befSAndrew Turner v_sincospif_sin (float x) 153*f3087befSAndrew Turner { 154*f3087befSAndrew Turner float s[4], c[4]; 155*f3087befSAndrew Turner _ZGVnN4vl4l4_sincospif (vdupq_n_f32 (x), s, c); 156*f3087befSAndrew Turner return s[0]; 157*f3087befSAndrew Turner } 158*f3087befSAndrew Turner float 159*f3087befSAndrew Turner v_sincospif_cos (float x) 160*f3087befSAndrew Turner { 161*f3087befSAndrew Turner float s[4], c[4]; 162*f3087befSAndrew Turner _ZGVnN4vl4l4_sincospif (vdupq_n_f32 (x), s, c); 163*f3087befSAndrew Turner return c[0]; 164*f3087befSAndrew Turner } 165*f3087befSAndrew Turner # endif // WANT_TRIGPI_TESTS 166*f3087befSAndrew Turner 167*f3087befSAndrew Turner float 168*f3087befSAndrew Turner v_sincosf_sin (float x) 169*f3087befSAndrew Turner { 170*f3087befSAndrew Turner float s[4], c[4]; 171*f3087befSAndrew Turner _ZGVnN4vl4l4_sincosf (vdupq_n_f32 (x), s, c); 172*f3087befSAndrew Turner return s[0]; 173*f3087befSAndrew Turner } 174*f3087befSAndrew Turner float 175*f3087befSAndrew Turner v_sincosf_cos (float x) 176*f3087befSAndrew Turner { 177*f3087befSAndrew Turner float s[4], c[4]; 178*f3087befSAndrew Turner _ZGVnN4vl4l4_sincosf (vdupq_n_f32 (x), s, c); 179*f3087befSAndrew Turner return c[0]; 180*f3087befSAndrew Turner } 181*f3087befSAndrew Turner float 182*f3087befSAndrew Turner v_cexpif_sin (float x) 183*f3087befSAndrew Turner { 184*f3087befSAndrew Turner return _ZGVnN4v_cexpif (vdupq_n_f32 (x)).val[0][0]; 185*f3087befSAndrew Turner } 186*f3087befSAndrew Turner float 187*f3087befSAndrew Turner v_cexpif_cos (float x) 188*f3087befSAndrew Turner { 189*f3087befSAndrew Turner return _ZGVnN4v_cexpif (vdupq_n_f32 (x)).val[1][0]; 190*f3087befSAndrew Turner } 191*f3087befSAndrew Turner float 192*f3087befSAndrew Turner v_modff_frac (float x) 193*f3087befSAndrew Turner { 194*f3087befSAndrew Turner float y[4]; 195*f3087befSAndrew Turner return _ZGVnN4vl4_modff (vdupq_n_f32 (x), y)[0]; 196*f3087befSAndrew Turner } 197*f3087befSAndrew Turner float 198*f3087befSAndrew Turner v_modff_int (float x) 199*f3087befSAndrew Turner { 200*f3087befSAndrew Turner float y[4]; 201*f3087befSAndrew Turner _ZGVnN4vl4_modff (vdupq_n_f32 (x), y); 202*f3087befSAndrew Turner return y[0]; 203*f3087befSAndrew Turner } 204*f3087befSAndrew Turner double 205*f3087befSAndrew Turner v_sincos_sin (double x) 206*f3087befSAndrew Turner { 207*f3087befSAndrew Turner double s[2], c[2]; 208*f3087befSAndrew Turner _ZGVnN2vl8l8_sincos (vdupq_n_f64 (x), s, c); 209*f3087befSAndrew Turner return s[0]; 210*f3087befSAndrew Turner } 211*f3087befSAndrew Turner double 212*f3087befSAndrew Turner v_sincos_cos (double x) 213*f3087befSAndrew Turner { 214*f3087befSAndrew Turner double s[2], c[2]; 215*f3087befSAndrew Turner _ZGVnN2vl8l8_sincos (vdupq_n_f64 (x), s, c); 216*f3087befSAndrew Turner return c[0]; 217*f3087befSAndrew Turner } 218*f3087befSAndrew Turner double 219*f3087befSAndrew Turner v_cexpi_sin (double x) 220*f3087befSAndrew Turner { 221*f3087befSAndrew Turner return _ZGVnN2v_cexpi (vdupq_n_f64 (x)).val[0][0]; 222*f3087befSAndrew Turner } 223*f3087befSAndrew Turner double 224*f3087befSAndrew Turner v_cexpi_cos (double x) 225*f3087befSAndrew Turner { 226*f3087befSAndrew Turner return _ZGVnN2v_cexpi (vdupq_n_f64 (x)).val[1][0]; 227*f3087befSAndrew Turner } 228*f3087befSAndrew Turner double 229*f3087befSAndrew Turner v_modf_frac (double x) 230*f3087befSAndrew Turner { 231*f3087befSAndrew Turner double y[2]; 232*f3087befSAndrew Turner return _ZGVnN2vl8_modf (vdupq_n_f64 (x), y)[0]; 233*f3087befSAndrew Turner } 234*f3087befSAndrew Turner double 235*f3087befSAndrew Turner v_modf_int (double x) 236*f3087befSAndrew Turner { 237*f3087befSAndrew Turner double y[2]; 238*f3087befSAndrew Turner _ZGVnN2vl8_modf (vdupq_n_f64 (x), y); 239*f3087befSAndrew Turner return y[0]; 240*f3087befSAndrew Turner } 241*f3087befSAndrew Turner #endif // __aarch64__ && __linux__ 242*f3087befSAndrew Turner 243*f3087befSAndrew Turner #if WANT_SVE_TESTS 244*f3087befSAndrew Turner # define ZSVNF1_WRAP(func) \ 245*f3087befSAndrew Turner static float Z_sv_##func##f (svbool_t pg, float x) \ 246*f3087befSAndrew Turner { \ 247*f3087befSAndrew Turner return svretf (_ZGVsMxv_##func##f (svargf (x), pg), pg); \ 248*f3087befSAndrew Turner } 249*f3087befSAndrew Turner # define ZSVNF2_WRAP(func) \ 250*f3087befSAndrew Turner static float Z_sv_##func##f (svbool_t pg, float x, float y) \ 251*f3087befSAndrew Turner { \ 252*f3087befSAndrew Turner return svretf (_ZGVsMxvv_##func##f (svargf (x), svargf (y), pg), pg); \ 253*f3087befSAndrew Turner } 254*f3087befSAndrew Turner # define ZSVND1_WRAP(func) \ 255*f3087befSAndrew Turner static double Z_sv_##func (svbool_t pg, double x) \ 256*f3087befSAndrew Turner { \ 257*f3087befSAndrew Turner return svretd (_ZGVsMxv_##func (svargd (x), pg), pg); \ 258*f3087befSAndrew Turner } 259*f3087befSAndrew Turner # define ZSVND2_WRAP(func) \ 260*f3087befSAndrew Turner static double Z_sv_##func (svbool_t pg, double x, double y) \ 261*f3087befSAndrew Turner { \ 262*f3087befSAndrew Turner return svretd (_ZGVsMxvv_##func (svargd (x), svargd (y), pg), pg); \ 263*f3087befSAndrew Turner } 264*f3087befSAndrew Turner 265*f3087befSAndrew Turner # if WANT_TRIGPI_TESTS 266*f3087befSAndrew Turner ZSVNF1_WRAP (cospi) 267*f3087befSAndrew Turner ZSVND1_WRAP (cospi) 268*f3087befSAndrew Turner ZSVNF1_WRAP (sinpi) 269*f3087befSAndrew Turner ZSVND1_WRAP (sinpi) 270*f3087befSAndrew Turner ZSVNF1_WRAP (tanpi) 271*f3087befSAndrew Turner ZSVND1_WRAP (tanpi) 272*f3087befSAndrew Turner double 273*f3087befSAndrew Turner sv_sincospi_sin (svbool_t pg, double x) 274*f3087befSAndrew Turner { 275*f3087befSAndrew Turner double s[svcntd ()], c[svcntd ()]; 276*f3087befSAndrew Turner _ZGVsMxvl8l8_sincospi (svdup_f64 (x), s, c, pg); 277*f3087befSAndrew Turner return svretd (svld1 (pg, s), pg); 278*f3087befSAndrew Turner } 279*f3087befSAndrew Turner double 280*f3087befSAndrew Turner sv_sincospi_cos (svbool_t pg, double x) 281*f3087befSAndrew Turner { 282*f3087befSAndrew Turner double s[svcntd ()], c[svcntd ()]; 283*f3087befSAndrew Turner _ZGVsMxvl8l8_sincospi (svdup_f64 (x), s, c, pg); 284*f3087befSAndrew Turner return svretd (svld1 (pg, c), pg); 285*f3087befSAndrew Turner } 286*f3087befSAndrew Turner float 287*f3087befSAndrew Turner sv_sincospif_sin (svbool_t pg, float x) 288*f3087befSAndrew Turner { 289*f3087befSAndrew Turner float s[svcntw ()], c[svcntw ()]; 290*f3087befSAndrew Turner _ZGVsMxvl4l4_sincospif (svdup_f32 (x), s, c, pg); 291*f3087befSAndrew Turner return svretf (svld1 (pg, s), pg); 292*f3087befSAndrew Turner } 293*f3087befSAndrew Turner float 294*f3087befSAndrew Turner sv_sincospif_cos (svbool_t pg, float x) 295*f3087befSAndrew Turner { 296*f3087befSAndrew Turner float s[svcntw ()], c[svcntw ()]; 297*f3087befSAndrew Turner _ZGVsMxvl4l4_sincospif (svdup_f32 (x), s, c, pg); 298*f3087befSAndrew Turner return svretf (svld1 (pg, c), pg); 299*f3087befSAndrew Turner } 300*f3087befSAndrew Turner # endif // WANT_TRIGPI_TESTS 301*f3087befSAndrew Turner 302*f3087befSAndrew Turner float 303*f3087befSAndrew Turner sv_sincosf_sin (svbool_t pg, float x) 304*f3087befSAndrew Turner { 305*f3087befSAndrew Turner float s[svcntw ()], c[svcntw ()]; 306*f3087befSAndrew Turner _ZGVsMxvl4l4_sincosf (svdup_f32 (x), s, c, pg); 307*f3087befSAndrew Turner return svretf (svld1 (pg, s), pg); 308*f3087befSAndrew Turner } 309*f3087befSAndrew Turner float 310*f3087befSAndrew Turner sv_sincosf_cos (svbool_t pg, float x) 311*f3087befSAndrew Turner { 312*f3087befSAndrew Turner float s[svcntw ()], c[svcntw ()]; 313*f3087befSAndrew Turner _ZGVsMxvl4l4_sincosf (svdup_f32 (x), s, c, pg); 314*f3087befSAndrew Turner return svretf (svld1 (pg, c), pg); 315*f3087befSAndrew Turner } 316*f3087befSAndrew Turner float 317*f3087befSAndrew Turner sv_cexpif_sin (svbool_t pg, float x) 318*f3087befSAndrew Turner { 319*f3087befSAndrew Turner return svretf (svget2 (_ZGVsMxv_cexpif (svdup_f32 (x), pg), 0), pg); 320*f3087befSAndrew Turner } 321*f3087befSAndrew Turner float 322*f3087befSAndrew Turner sv_cexpif_cos (svbool_t pg, float x) 323*f3087befSAndrew Turner { 324*f3087befSAndrew Turner return svretf (svget2 (_ZGVsMxv_cexpif (svdup_f32 (x), pg), 1), pg); 325*f3087befSAndrew Turner } 326*f3087befSAndrew Turner float 327*f3087befSAndrew Turner sv_modff_frac (svbool_t pg, float x) 328*f3087befSAndrew Turner { 329*f3087befSAndrew Turner float i[svcntw ()]; 330*f3087befSAndrew Turner return svretf (_ZGVsMxvl4_modff (svdup_f32 (x), i, pg), pg); 331*f3087befSAndrew Turner } 332*f3087befSAndrew Turner float 333*f3087befSAndrew Turner sv_modff_int (svbool_t pg, float x) 334*f3087befSAndrew Turner { 335*f3087befSAndrew Turner float i[svcntw ()]; 336*f3087befSAndrew Turner _ZGVsMxvl4_modff (svdup_f32 (x), i, pg); 337*f3087befSAndrew Turner return svretf (svld1 (pg, i), pg); 338*f3087befSAndrew Turner } 339*f3087befSAndrew Turner double 340*f3087befSAndrew Turner sv_sincos_sin (svbool_t pg, double x) 341*f3087befSAndrew Turner { 342*f3087befSAndrew Turner double s[svcntd ()], c[svcntd ()]; 343*f3087befSAndrew Turner _ZGVsMxvl8l8_sincos (svdup_f64 (x), s, c, pg); 344*f3087befSAndrew Turner return svretd (svld1 (pg, s), pg); 345*f3087befSAndrew Turner } 346*f3087befSAndrew Turner double 347*f3087befSAndrew Turner sv_sincos_cos (svbool_t pg, double x) 348*f3087befSAndrew Turner { 349*f3087befSAndrew Turner double s[svcntd ()], c[svcntd ()]; 350*f3087befSAndrew Turner _ZGVsMxvl8l8_sincos (svdup_f64 (x), s, c, pg); 351*f3087befSAndrew Turner return svretd (svld1 (pg, c), pg); 352*f3087befSAndrew Turner } 353*f3087befSAndrew Turner double 354*f3087befSAndrew Turner sv_cexpi_sin (svbool_t pg, double x) 355*f3087befSAndrew Turner { 356*f3087befSAndrew Turner return svretd (svget2 (_ZGVsMxv_cexpi (svdup_f64 (x), pg), 0), pg); 357*f3087befSAndrew Turner } 358*f3087befSAndrew Turner double 359*f3087befSAndrew Turner sv_cexpi_cos (svbool_t pg, double x) 360*f3087befSAndrew Turner { 361*f3087befSAndrew Turner return svretd (svget2 (_ZGVsMxv_cexpi (svdup_f64 (x), pg), 1), pg); 362*f3087befSAndrew Turner } 363*f3087befSAndrew Turner double 364*f3087befSAndrew Turner sv_modf_frac (svbool_t pg, double x) 365*f3087befSAndrew Turner { 366*f3087befSAndrew Turner double i[svcntd ()]; 367*f3087befSAndrew Turner return svretd (_ZGVsMxvl8_modf (svdup_f64 (x), i, pg), pg); 368*f3087befSAndrew Turner } 369*f3087befSAndrew Turner double 370*f3087befSAndrew Turner sv_modf_int (svbool_t pg, double x) 371*f3087befSAndrew Turner { 372*f3087befSAndrew Turner double i[svcntd ()]; 373*f3087befSAndrew Turner _ZGVsMxvl8_modf (svdup_f64 (x), i, pg); 374*f3087befSAndrew Turner return svretd (svld1 (pg, i), pg); 375*f3087befSAndrew Turner } 376*f3087befSAndrew Turner 377*f3087befSAndrew Turner # if WANT_EXPERIMENTAL_MATH 378*f3087befSAndrew Turner 379*f3087befSAndrew Turner /* Our implementations of powi/powk are too imprecise to verify 380*f3087befSAndrew Turner against any established pow implementation. Instead we have the 381*f3087befSAndrew Turner following simple implementation, against which it is enough to 382*f3087befSAndrew Turner maintain bitwise reproducibility. Note the test framework expects 383*f3087befSAndrew Turner the reference impl to be of higher precision than the function 384*f3087befSAndrew Turner under test. For instance this means that the reference for 385*f3087befSAndrew Turner double-precision powi will be passed a long double, so to check 386*f3087befSAndrew Turner bitwise reproducibility we have to cast it back down to 387*f3087befSAndrew Turner double. This is fine since a round-trip to higher precision and 388*f3087befSAndrew Turner back down is correctly rounded. */ 389*f3087befSAndrew Turner # define DECL_POW_INT_REF(NAME, DBL_T, FLT_T, INT_T) \ 390*f3087befSAndrew Turner static DBL_T __attribute__ ((unused)) NAME (DBL_T in_val, DBL_T y) \ 391*f3087befSAndrew Turner { \ 392*f3087befSAndrew Turner INT_T n = (INT_T) round (y); \ 393*f3087befSAndrew Turner FLT_T acc = 1.0; \ 394*f3087befSAndrew Turner bool want_recip = n < 0; \ 395*f3087befSAndrew Turner n = n < 0 ? -n : n; \ 396*f3087befSAndrew Turner \ 397*f3087befSAndrew Turner for (FLT_T c = in_val; n; c *= c, n >>= 1) \ 398*f3087befSAndrew Turner { \ 399*f3087befSAndrew Turner if (n & 0x1) \ 400*f3087befSAndrew Turner { \ 401*f3087befSAndrew Turner acc *= c; \ 402*f3087befSAndrew Turner } \ 403*f3087befSAndrew Turner } \ 404*f3087befSAndrew Turner if (want_recip) \ 405*f3087befSAndrew Turner { \ 406*f3087befSAndrew Turner acc = 1.0 / acc; \ 407*f3087befSAndrew Turner } \ 408*f3087befSAndrew Turner return acc; \ 409*f3087befSAndrew Turner } 410*f3087befSAndrew Turner 411*f3087befSAndrew Turner DECL_POW_INT_REF (ref_powif, double, float, int) 412*f3087befSAndrew Turner DECL_POW_INT_REF (ref_powi, long double, double, int) 413*f3087befSAndrew Turner static float 414*f3087befSAndrew Turner Z_sv_powi (svbool_t pg, float x, float y) 415*f3087befSAndrew Turner { 416*f3087befSAndrew Turner return svretf (_ZGVsMxvv_powi (svargf (x), svdup_s32 ((int) round (y)), pg), 417*f3087befSAndrew Turner pg); 418*f3087befSAndrew Turner } 419*f3087befSAndrew Turner static double 420*f3087befSAndrew Turner Z_sv_powk (svbool_t pg, double x, double y) 421*f3087befSAndrew Turner { 422*f3087befSAndrew Turner return svretd (_ZGVsMxvv_powk (svargd (x), svdup_s64 ((long) round (y)), pg), 423*f3087befSAndrew Turner pg); 424*f3087befSAndrew Turner } 425*f3087befSAndrew Turner 426*f3087befSAndrew Turner # endif // WANT_EXPERIMENTAL_MATH 427*f3087befSAndrew Turner #endif // WANT_SVE_TESTS 428*f3087befSAndrew Turner 429*f3087befSAndrew Turner #include "test/ulp_wrappers_gen.h" 430