1072a4ba8SAndrew Turner /*
2072a4ba8SAndrew Turner  * Wrapper functions for SVE ACLE.
3072a4ba8SAndrew Turner  *
4072a4ba8SAndrew Turner  * Copyright (c) 2019-2023, Arm Limited.
5072a4ba8SAndrew Turner  * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6072a4ba8SAndrew Turner  */
7072a4ba8SAndrew Turner 
8072a4ba8SAndrew Turner #ifndef SV_MATH_H
9072a4ba8SAndrew Turner #define SV_MATH_H
10072a4ba8SAndrew Turner 
11072a4ba8SAndrew Turner #ifndef WANT_VMATH
12072a4ba8SAndrew Turner /* Enable the build of vector math code.  */
13072a4ba8SAndrew Turner # define WANT_VMATH 1
14072a4ba8SAndrew Turner #endif
15072a4ba8SAndrew Turner 
16*5a02ffc3SAndrew Turner #if WANT_VMATH
17072a4ba8SAndrew Turner 
18072a4ba8SAndrew Turner # include <arm_sve.h>
19072a4ba8SAndrew Turner # include <stdbool.h>
20072a4ba8SAndrew Turner 
21072a4ba8SAndrew Turner # include "math_config.h"
22072a4ba8SAndrew Turner 
23072a4ba8SAndrew Turner /* Double precision.  */
24*5a02ffc3SAndrew Turner static inline svint64_t
sv_s64(int64_t x)25*5a02ffc3SAndrew Turner sv_s64 (int64_t x)
26072a4ba8SAndrew Turner {
27*5a02ffc3SAndrew Turner   return svdup_s64 (x);
28072a4ba8SAndrew Turner }
29072a4ba8SAndrew Turner 
30*5a02ffc3SAndrew Turner static inline svuint64_t
sv_u64(uint64_t x)31*5a02ffc3SAndrew Turner sv_u64 (uint64_t x)
32072a4ba8SAndrew Turner {
33*5a02ffc3SAndrew Turner   return svdup_u64 (x);
34072a4ba8SAndrew Turner }
35072a4ba8SAndrew Turner 
36*5a02ffc3SAndrew Turner static inline svfloat64_t
sv_f64(double x)37*5a02ffc3SAndrew Turner sv_f64 (double x)
38072a4ba8SAndrew Turner {
39*5a02ffc3SAndrew Turner   return svdup_f64 (x);
40072a4ba8SAndrew Turner }
41072a4ba8SAndrew Turner 
42*5a02ffc3SAndrew Turner static inline svfloat64_t
sv_call_f64(double (* f)(double),svfloat64_t x,svfloat64_t y,svbool_t cmp)43*5a02ffc3SAndrew Turner sv_call_f64 (double (*f) (double), svfloat64_t x, svfloat64_t y, svbool_t cmp)
44072a4ba8SAndrew Turner {
45072a4ba8SAndrew Turner   svbool_t p = svpfirst (cmp, svpfalse ());
46072a4ba8SAndrew Turner   while (svptest_any (cmp, p))
47072a4ba8SAndrew Turner     {
48*5a02ffc3SAndrew Turner       double elem = svclastb (p, 0, x);
49072a4ba8SAndrew Turner       elem = (*f) (elem);
50*5a02ffc3SAndrew Turner       svfloat64_t y2 = sv_f64 (elem);
51*5a02ffc3SAndrew Turner       y = svsel (p, y2, y);
52072a4ba8SAndrew Turner       p = svpnext_b64 (cmp, p);
53072a4ba8SAndrew Turner     }
54072a4ba8SAndrew Turner   return y;
55072a4ba8SAndrew Turner }
56072a4ba8SAndrew Turner 
57*5a02ffc3SAndrew Turner static inline svfloat64_t
sv_call2_f64(double (* f)(double,double),svfloat64_t x1,svfloat64_t x2,svfloat64_t y,svbool_t cmp)58*5a02ffc3SAndrew Turner sv_call2_f64 (double (*f) (double, double), svfloat64_t x1, svfloat64_t x2,
59*5a02ffc3SAndrew Turner 	      svfloat64_t y, svbool_t cmp)
60072a4ba8SAndrew Turner {
61072a4ba8SAndrew Turner   svbool_t p = svpfirst (cmp, svpfalse ());
62072a4ba8SAndrew Turner   while (svptest_any (cmp, p))
63072a4ba8SAndrew Turner     {
64*5a02ffc3SAndrew Turner       double elem1 = svclastb (p, 0, x1);
65*5a02ffc3SAndrew Turner       double elem2 = svclastb (p, 0, x2);
66*5a02ffc3SAndrew Turner       double ret = (*f) (elem1, elem2);
67*5a02ffc3SAndrew Turner       svfloat64_t y2 = sv_f64 (ret);
68*5a02ffc3SAndrew Turner       y = svsel (p, y2, y);
69072a4ba8SAndrew Turner       p = svpnext_b64 (cmp, p);
70072a4ba8SAndrew Turner     }
71072a4ba8SAndrew Turner   return y;
72072a4ba8SAndrew Turner }
73072a4ba8SAndrew Turner 
74*5a02ffc3SAndrew Turner static inline svuint64_t
sv_mod_n_u64_x(svbool_t pg,svuint64_t x,uint64_t y)75*5a02ffc3SAndrew Turner sv_mod_n_u64_x (svbool_t pg, svuint64_t x, uint64_t y)
76072a4ba8SAndrew Turner {
77*5a02ffc3SAndrew Turner   svuint64_t q = svdiv_x (pg, x, y);
78*5a02ffc3SAndrew Turner   return svmls_x (pg, x, q, y);
79072a4ba8SAndrew Turner }
80072a4ba8SAndrew Turner 
81072a4ba8SAndrew Turner /* Single precision.  */
82*5a02ffc3SAndrew Turner static inline svint32_t
sv_s32(int32_t x)83*5a02ffc3SAndrew Turner sv_s32 (int32_t x)
84072a4ba8SAndrew Turner {
85*5a02ffc3SAndrew Turner   return svdup_s32 (x);
86072a4ba8SAndrew Turner }
87072a4ba8SAndrew Turner 
88*5a02ffc3SAndrew Turner static inline svuint32_t
sv_u32(uint32_t x)89*5a02ffc3SAndrew Turner sv_u32 (uint32_t x)
90072a4ba8SAndrew Turner {
91*5a02ffc3SAndrew Turner   return svdup_u32 (x);
92072a4ba8SAndrew Turner }
93072a4ba8SAndrew Turner 
94*5a02ffc3SAndrew Turner static inline svfloat32_t
sv_f32(float x)95*5a02ffc3SAndrew Turner sv_f32 (float x)
96072a4ba8SAndrew Turner {
97*5a02ffc3SAndrew Turner   return svdup_f32 (x);
98072a4ba8SAndrew Turner }
99072a4ba8SAndrew Turner 
100*5a02ffc3SAndrew Turner static inline svfloat32_t
sv_call_f32(float (* f)(float),svfloat32_t x,svfloat32_t y,svbool_t cmp)101*5a02ffc3SAndrew Turner sv_call_f32 (float (*f) (float), svfloat32_t x, svfloat32_t y, svbool_t cmp)
102072a4ba8SAndrew Turner {
103072a4ba8SAndrew Turner   svbool_t p = svpfirst (cmp, svpfalse ());
104072a4ba8SAndrew Turner   while (svptest_any (cmp, p))
105072a4ba8SAndrew Turner     {
106*5a02ffc3SAndrew Turner       float elem = svclastb (p, 0, x);
107072a4ba8SAndrew Turner       elem = (*f) (elem);
108*5a02ffc3SAndrew Turner       svfloat32_t y2 = sv_f32 (elem);
109*5a02ffc3SAndrew Turner       y = svsel (p, y2, y);
110072a4ba8SAndrew Turner       p = svpnext_b32 (cmp, p);
111072a4ba8SAndrew Turner     }
112072a4ba8SAndrew Turner   return y;
113072a4ba8SAndrew Turner }
114072a4ba8SAndrew Turner 
115*5a02ffc3SAndrew Turner static inline svfloat32_t
sv_call2_f32(float (* f)(float,float),svfloat32_t x1,svfloat32_t x2,svfloat32_t y,svbool_t cmp)116*5a02ffc3SAndrew Turner sv_call2_f32 (float (*f) (float, float), svfloat32_t x1, svfloat32_t x2,
117*5a02ffc3SAndrew Turner 	      svfloat32_t y, svbool_t cmp)
118072a4ba8SAndrew Turner {
119072a4ba8SAndrew Turner   svbool_t p = svpfirst (cmp, svpfalse ());
120072a4ba8SAndrew Turner   while (svptest_any (cmp, p))
121072a4ba8SAndrew Turner     {
122*5a02ffc3SAndrew Turner       float elem1 = svclastb (p, 0, x1);
123*5a02ffc3SAndrew Turner       float elem2 = svclastb (p, 0, x2);
124*5a02ffc3SAndrew Turner       float ret = (*f) (elem1, elem2);
125*5a02ffc3SAndrew Turner       svfloat32_t y2 = sv_f32 (ret);
126*5a02ffc3SAndrew Turner       y = svsel (p, y2, y);
127072a4ba8SAndrew Turner       p = svpnext_b32 (cmp, p);
128072a4ba8SAndrew Turner     }
129072a4ba8SAndrew Turner   return y;
130072a4ba8SAndrew Turner }
131*5a02ffc3SAndrew Turner #endif
132072a4ba8SAndrew Turner 
133072a4ba8SAndrew Turner #endif
134