xref: /freebsd-src/contrib/arm-optimized-routines/math/test/ulp_wrappers.h (revision f3087bef11543b42e0d69b708f367097a4118d24)
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