25 #ifndef _GLIBCXX_EXPERIMENTAL_SIMD_MATH_H_
26 #define _GLIBCXX_EXPERIMENTAL_SIMD_MATH_H_
28 #if __cplusplus >= 201703L
33 _GLIBCXX_SIMD_BEGIN_NAMESPACE
34 template <
typename _Tp,
typename _V>
35 using _Samesize = fixed_size_simd<_Tp, _V::size()>;
38 template <
typename _DoubleR,
typename _Tp,
typename _Abi>
39 struct _Math_return_type;
41 template <
typename _DoubleR,
typename _Tp,
typename _Abi>
42 using _Math_return_type_t =
43 typename _Math_return_type<_DoubleR, _Tp, _Abi>::type;
45 template <
typename _Tp,
typename _Abi>
46 struct _Math_return_type<double, _Tp, _Abi>
47 {
using type = simd<_Tp, _Abi>; };
49 template <
typename _Tp,
typename _Abi>
50 struct _Math_return_type<bool, _Tp, _Abi>
51 {
using type = simd_mask<_Tp, _Abi>; };
53 template <
typename _DoubleR,
typename _Tp,
typename _Abi>
54 struct _Math_return_type
55 {
using type = fixed_size_simd<_DoubleR, simd_size_v<_Tp, _Abi>>; };
59 #define _GLIBCXX_SIMD_MATH_CALL_(__name) \
60 template <typename _Tp, typename _Abi, typename..., \
61 typename _R = _Math_return_type_t< \
62 decltype(std::__name(declval<double>())), _Tp, _Abi>> \
63 enable_if_t<is_floating_point_v<_Tp>, _R> \
64 __name(simd<_Tp, _Abi> __x) \
65 { return {__private_init, _Abi::_SimdImpl::_S_##__name(__data(__x))}; }
69 template <
typename _Up,
typename _Tp,
typename _Abi>
70 struct _Extra_argument_type;
72 template <
typename _Tp,
typename _Abi>
73 struct _Extra_argument_type<_Tp*, _Tp, _Abi>
75 using type = simd<_Tp, _Abi>*;
76 static constexpr
double*
declval();
77 static constexpr
bool __needs_temporary_scalar =
true;
79 _GLIBCXX_SIMD_INTRINSIC
static constexpr
auto _S_data(type __x)
80 {
return &__data(*__x); }
83 template <
typename _Up,
typename _Tp,
typename _Abi>
84 struct _Extra_argument_type<_Up*, _Tp, _Abi>
86 static_assert(is_integral_v<_Up>);
87 using type = fixed_size_simd<_Up, simd_size_v<_Tp, _Abi>>*;
88 static constexpr _Up*
declval();
89 static constexpr
bool __needs_temporary_scalar =
true;
91 _GLIBCXX_SIMD_INTRINSIC
static constexpr
auto _S_data(type __x)
92 {
return &__data(*__x); }
95 template <
typename _Tp,
typename _Abi>
96 struct _Extra_argument_type<_Tp, _Tp, _Abi>
98 using type = simd<_Tp, _Abi>;
99 static constexpr
double declval();
100 static constexpr
bool __needs_temporary_scalar =
false;
102 _GLIBCXX_SIMD_INTRINSIC
static constexpr decltype(
auto)
103 _S_data(const type& __x)
104 {
return __data(__x); }
107 template <
typename _Up,
typename _Tp,
typename _Abi>
108 struct _Extra_argument_type
110 static_assert(is_integral_v<_Up>);
111 using type = fixed_size_simd<_Up, simd_size_v<_Tp, _Abi>>;
112 static constexpr _Up
declval();
113 static constexpr
bool __needs_temporary_scalar =
false;
115 _GLIBCXX_SIMD_INTRINSIC
static constexpr decltype(
auto)
116 _S_data(const type& __x)
117 {
return __data(__x); }
122 #define _GLIBCXX_SIMD_MATH_CALL2_(__name, __arg2) \
124 typename _Tp, typename _Abi, typename..., \
125 typename _Arg2 = _Extra_argument_type<__arg2, _Tp, _Abi>, \
126 typename _R = _Math_return_type_t< \
127 decltype(std::__name(declval<double>(), _Arg2::declval())), _Tp, _Abi>> \
128 enable_if_t<is_floating_point_v<_Tp>, _R> \
129 __name(const simd<_Tp, _Abi>& __x, const typename _Arg2::type& __y) \
131 return {__private_init, \
132 _Abi::_SimdImpl::_S_##__name(__data(__x), _Arg2::_S_data(__y))}; \
134 template <typename _Up, typename _Tp, typename _Abi> \
135 _GLIBCXX_SIMD_INTRINSIC _Math_return_type_t< \
136 decltype(std::__name( \
138 declval<enable_if_t< \
140 is_same<__arg2, _Tp>, \
141 negation<is_same<__remove_cvref_t<_Up>, simd<_Tp, _Abi>>>, \
142 is_convertible<_Up, simd<_Tp, _Abi>>, is_floating_point<_Tp>>, \
145 __name(_Up&& __xx, const simd<_Tp, _Abi>& __yy) \
146 { return __name(simd<_Tp, _Abi>(static_cast<_Up&&>(__xx)), __yy); }
150 #define _GLIBCXX_SIMD_MATH_CALL3_(__name, __arg2, __arg3) \
151 template <typename _Tp, typename _Abi, typename..., \
152 typename _Arg2 = _Extra_argument_type<__arg2, _Tp, _Abi>, \
153 typename _Arg3 = _Extra_argument_type<__arg3, _Tp, _Abi>, \
154 typename _R = _Math_return_type_t< \
155 decltype(std::__name(declval<double>(), _Arg2::declval(), \
156 _Arg3::declval())), \
158 enable_if_t<is_floating_point_v<_Tp>, _R> \
159 __name(const simd<_Tp, _Abi>& __x, const typename _Arg2::type& __y, \
160 const typename _Arg3::type& __z) \
162 return {__private_init, \
163 _Abi::_SimdImpl::_S_##__name(__data(__x), _Arg2::_S_data(__y), \
164 _Arg3::_S_data(__z))}; \
167 typename _T0, typename _T1, typename _T2, typename..., \
168 typename _U0 = __remove_cvref_t<_T0>, \
169 typename _U1 = __remove_cvref_t<_T1>, \
170 typename _U2 = __remove_cvref_t<_T2>, \
171 typename _Simd = conditional_t<is_simd_v<_U1>, _U1, _U2>, \
172 typename = enable_if_t<conjunction_v< \
173 is_simd<_Simd>, is_convertible<_T0&&, _Simd>, \
174 is_convertible<_T1&&, _Simd>, is_convertible<_T2&&, _Simd>, \
175 negation<conjunction< \
176 is_simd<_U0>, is_floating_point<__value_type_or_identity_t<_U0>>>>>>> \
177 _GLIBCXX_SIMD_INTRINSIC decltype(__name(declval<const _Simd&>(), \
178 declval<const _Simd&>(), \
179 declval<const _Simd&>())) \
180 __name(_T0&& __xx, _T1&& __yy, _T2&& __zz) \
182 return __name(_Simd(static_cast<_T0&&>(__xx)), \
183 _Simd(static_cast<_T1&&>(__yy)), \
184 _Simd(static_cast<_T2&&>(__zz))); \
189 template <
typename _Abi>
190 _GLIBCXX_SIMD_ALWAYS_INLINE
static simd<float, _Abi>
191 __cosSeries(
const simd<float, _Abi>& __x)
193 const simd<float, _Abi> __x2 = __x * __x;
194 simd<float, _Abi> __y;
196 __y = __y * __x2 - 0x1.6c1p-10f;
197 __y = __y * __x2 + 0x1.555556p-5f;
198 return __y * (__x2 * __x2) - .5f * __x2 + 1.f;
201 template <
typename _Abi>
202 _GLIBCXX_SIMD_ALWAYS_INLINE
static simd<double, _Abi>
203 __cosSeries(
const simd<double, _Abi>& __x)
205 const simd<double, _Abi> __x2 = __x * __x;
206 simd<double, _Abi> __y;
207 __y = 0x1.AC00000000000p-45;
208 __y = __y * __x2 - 0x1.9394000000000p-37;
209 __y = __y * __x2 + 0x1.1EED8C0000000p-29;
210 __y = __y * __x2 - 0x1.27E4FB7400000p-22;
211 __y = __y * __x2 + 0x1.A01A01A018000p-16;
212 __y = __y * __x2 - 0x1.6C16C16C16C00p-10;
213 __y = __y * __x2 + 0x1.5555555555554p-5;
214 return (__y * __x2 - .5f) * __x2 + 1.f;
219 template <
typename _Abi>
220 _GLIBCXX_SIMD_ALWAYS_INLINE
static simd<float, _Abi>
221 __sinSeries(
const simd<float, _Abi>& __x)
223 const simd<float, _Abi> __x2 = __x * __x;
224 simd<float, _Abi> __y;
225 __y = -0x1.9CC000p-13f;
226 __y = __y * __x2 + 0x1.111100p-7f;
227 __y = __y * __x2 - 0x1.555556p-3f;
228 return __y * (__x2 * __x) + __x;
231 template <
typename _Abi>
232 _GLIBCXX_SIMD_ALWAYS_INLINE
static simd<double, _Abi>
233 __sinSeries(
const simd<double, _Abi>& __x)
237 const simd<double, _Abi> __x2 = __x * __x;
238 simd<double, _Abi> __y;
239 __y = -0x1.ACF0000000000p-41;
240 __y = __y * __x2 + 0x1.6124400000000p-33;
241 __y = __y * __x2 - 0x1.AE64567000000p-26;
242 __y = __y * __x2 + 0x1.71DE3A5540000p-19;
243 __y = __y * __x2 - 0x1.A01A01A01A000p-13;
244 __y = __y * __x2 + 0x1.1111111111110p-7;
245 __y = __y * __x2 - 0x1.5555555555555p-3;
246 return __y * (__x2 * __x) + __x;
251 template <
int _Bits,
typename _Tp,
typename _Abi>
252 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi>
253 __zero_low_bits(simd<_Tp, _Abi> __x)
255 const simd<_Tp, _Abi> __bitmask
256 = __bit_cast<_Tp>(~
make_unsigned_t<__int_for_sizeof_t<_Tp>>() << _Bits);
257 return {__private_init,
258 _Abi::_SimdImpl::_S_bit_and(__data(__x), __data(__bitmask))};
282 template <
typename _Tp,
typename _Abi>
285 simd<_Tp, _Abi> _M_x;
286 rebind_simd_t<int, simd<_Tp, _Abi>> _M_quadrant;
289 namespace __math_float {
290 inline constexpr
float __pi_over_4 = 0x1.921FB6p-1f;
291 inline constexpr
float __2_over_pi = 0x1.45F306p-1f;
292 inline constexpr
float __pi_2_5bits0
294 inline constexpr
float __pi_2_5bits0_rem
297 namespace __math_double {
298 inline constexpr
double __pi_over_4 = 0x1.921fb54442d18p-1;
299 inline constexpr
double __2_over_pi = 0x1.45F306DC9C883p-1;
300 inline constexpr
double __pi_2 = 0x1.921fb54442d18p0;
303 template <
typename _Abi>
304 _GLIBCXX_SIMD_ALWAYS_INLINE _Folded<float, _Abi>
305 __fold_input(
const simd<float, _Abi>& __x)
307 using _V = simd<float, _Abi>;
308 using _IV = rebind_simd_t<int, _V>;
309 using namespace __math_float;
310 _Folded<float, _Abi> __r;
314 constexpr
float __1_over_pi = 0x1.45F306p-2f;
315 const auto __y = (__r._M_x * __1_over_pi + 0x1.8p23f) - 0x1.8p23f;
318 constexpr
float __pi0 = 0x1.920000p1f;
319 constexpr
float __pi1 = 0x1.fb4000p-11f;
320 constexpr
float __pi2 = 0x1.444000p-23f;
321 constexpr
float __pi3 = 0x1.68c234p-38f;
322 __r._M_x - __y*__pi0 - __y*__pi1 - __y*__pi2 - __y*__pi3
324 if (_GLIBCXX_SIMD_IS_UNLIKELY(all_of(__r._M_x < __pi_over_4)))
326 else if (_GLIBCXX_SIMD_IS_LIKELY(all_of(__r._M_x < 6 * __pi_over_4)))
328 const _V __y = nearbyint(__r._M_x * __2_over_pi);
329 __r._M_quadrant = static_simd_cast<_IV>(__y) & 3;
330 __r._M_x -= __y * __pi_2_5bits0;
331 __r._M_x -= __y * __pi_2_5bits0_rem;
335 using __math_double::__2_over_pi;
336 using __math_double::__pi_2;
337 using _VD = rebind_simd_t<double, _V>;
338 _VD __xd = static_simd_cast<_VD>(__r._M_x);
339 _VD __y = nearbyint(__xd * __2_over_pi);
340 __r._M_quadrant = static_simd_cast<_IV>(__y) & 3;
341 __r._M_x = static_simd_cast<_V>(__xd - __y * __pi_2);
347 template <
typename _Abi>
348 _GLIBCXX_SIMD_ALWAYS_INLINE _Folded<double, _Abi>
349 __fold_input(
const simd<double, _Abi>& __x)
351 using _V = simd<double, _Abi>;
352 using _IV = rebind_simd_t<int, _V>;
353 using namespace __math_double;
355 _Folded<double, _Abi> __r;
357 if (_GLIBCXX_SIMD_IS_UNLIKELY(all_of(__r._M_x < __pi_over_4)))
362 const _V __y = nearbyint(__r._M_x / (2 * __pi_over_4));
363 __r._M_quadrant = static_simd_cast<_IV>(__y) & 3;
365 if (_GLIBCXX_SIMD_IS_LIKELY(all_of(__r._M_x < 1025 * __pi_over_4)))
368 __r._M_x -= __y * 0x1.921FB54443000p0;
369 __r._M_x -= __y * -0x1.73DCB3B39A000p-43;
370 __r._M_x -= __y * 0x1.45C06E0E68948p-86;
372 else if (_GLIBCXX_SIMD_IS_LIKELY(all_of(__y <= 0x1.0p30)))
375 __r._M_x -= __y * 0x1.921FB40000000p0;
376 __r._M_x -= __y * 0x1.4442D00000000p-24;
377 __r._M_x -= __y * 0x1.8469898CC5170p-48;
382 const _V __y_hi = __zero_low_bits<26>(__y);
383 const _V __y_lo = __y - __y_hi;
384 const auto __pi_2_1 = 0x1.921FB50000000p0;
385 const auto __pi_2_2 = 0x1.110B460000000p-26;
386 const auto __pi_2_3 = 0x1.1A62630000000p-54;
387 const auto __pi_2_4 = 0x1.8A2E03707344Ap-81;
388 __r._M_x = __r._M_x - __y_hi * __pi_2_1
389 - max(__y_hi * __pi_2_2, __y_lo * __pi_2_1)
390 - min(__y_hi * __pi_2_2, __y_lo * __pi_2_1)
391 - max(__y_hi * __pi_2_3, __y_lo * __pi_2_2)
392 - min(__y_hi * __pi_2_3, __y_lo * __pi_2_2)
393 - max(__y * __pi_2_4, __y_lo * __pi_2_3)
394 - min(__y * __pi_2_4, __y_lo * __pi_2_3);
401 template <
typename _Tp,
typename _Abi>
402 rebind_simd_t<int, simd<_Tp, _Abi>>
403 __extract_exponent_as_int(
const simd<_Tp, _Abi>& __v)
405 using _Vp = simd<_Tp, _Abi>;
406 using _Up = make_unsigned_t<__int_for_sizeof_t<_Tp>>;
407 using namespace std::experimental::__float_bitwise_operators;
408 using namespace std::experimental::__proposed;
409 const _Vp __exponent_mask
411 return static_simd_cast<rebind_simd_t<int, _Vp>>(
412 simd_bit_cast<rebind_simd_t<_Up, _Vp>>(__v & __exponent_mask)
413 >> (__digits_v<_Tp> - 1));
418 template <
typename ImplFun,
typename FallbackFun,
typename... _Args>
419 _GLIBCXX_SIMD_INTRINSIC
auto
420 __impl_or_fallback_dispatch(
int, ImplFun&& __impl_fun, FallbackFun&&,
422 -> decltype(__impl_fun(
static_cast<_Args&&
>(__args)...))
423 {
return __impl_fun(
static_cast<_Args&&
>(__args)...); }
425 template <
typename ImplFun,
typename FallbackFun,
typename... _Args>
427 __impl_or_fallback_dispatch(
float, ImplFun&&, FallbackFun&& __fallback_fun,
429 -> decltype(__fallback_fun(
static_cast<_Args&&
>(__args)...))
430 {
return __fallback_fun(
static_cast<_Args&&
>(__args)...); }
432 template <
typename... _Args>
433 _GLIBCXX_SIMD_INTRINSIC
auto
434 __impl_or_fallback(_Args&&... __args)
436 return __impl_or_fallback_dispatch(
int(),
static_cast<_Args&&
>(__args)...);
441 _GLIBCXX_SIMD_MATH_CALL_(
acos)
442 _GLIBCXX_SIMD_MATH_CALL_(
asin)
443 _GLIBCXX_SIMD_MATH_CALL_(
atan)
444 _GLIBCXX_SIMD_MATH_CALL2_(atan2, _Tp)
461 template <
typename _Tp,
typename _Abi>
462 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
463 cos(
const simd<_Tp, _Abi>& __x)
465 using _V = simd<_Tp, _Abi>;
466 if constexpr (__is_scalar_abi<_Abi>() || __is_fixed_size_abi_v<_Abi>)
467 return {__private_init, _Abi::_SimdImpl::_S_cos(__data(__x))};
470 if constexpr (is_same_v<_Tp, float>)
471 if (_GLIBCXX_SIMD_IS_UNLIKELY(any_of(
abs(__x) >= 393382)))
472 return static_simd_cast<_V>(
473 cos(static_simd_cast<rebind_simd_t<double, _V>>(__x)));
475 const auto __f = __fold_input(__x);
481 using namespace std::experimental::__float_bitwise_operators;
483 = _V(-0.f) & static_simd_cast<_V>((1 + __f._M_quadrant) << 30);
485 const auto __need_cos = (__f._M_quadrant & 1) == 0;
486 if (_GLIBCXX_SIMD_IS_UNLIKELY(all_of(__need_cos)))
487 return __sign_flip ^ __cosSeries(__f._M_x);
488 else if (_GLIBCXX_SIMD_IS_UNLIKELY(none_of(__need_cos)))
489 return __sign_flip ^ __sinSeries(__f._M_x);
492 _V __r = __sinSeries(__f._M_x);
493 where(__need_cos.__cvt(), __r) = __cosSeries(__f._M_x);
494 return __r ^ __sign_flip;
499 template <
typename _Tp>
500 _GLIBCXX_SIMD_ALWAYS_INLINE
501 enable_if_t<is_floating_point<_Tp>::value, simd<_Tp, simd_abi::scalar>>
502 cos(simd<_Tp, simd_abi::scalar> __x)
507 template <
typename _Tp,
typename _Abi>
508 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
509 sin(
const simd<_Tp, _Abi>& __x)
511 using _V = simd<_Tp, _Abi>;
512 if constexpr (__is_scalar_abi<_Abi>() || __is_fixed_size_abi_v<_Abi>)
513 return {__private_init, _Abi::_SimdImpl::_S_sin(__data(__x))};
516 if constexpr (is_same_v<_Tp, float>)
517 if (_GLIBCXX_SIMD_IS_UNLIKELY(any_of(
abs(__x) >= 527449)))
518 return static_simd_cast<_V>(
519 sin(static_simd_cast<rebind_simd_t<double, _V>>(__x)));
521 const auto __f = __fold_input(__x);
527 using namespace std::experimental::__float_bitwise_operators;
528 const auto __sign_flip
529 = (__x ^ static_simd_cast<_V>(1 - __f._M_quadrant)) & _V(_Tp(-0.));
531 const auto __need_sin = (__f._M_quadrant & 1) == 0;
532 if (_GLIBCXX_SIMD_IS_UNLIKELY(all_of(__need_sin)))
533 return __sign_flip ^ __sinSeries(__f._M_x);
534 else if (_GLIBCXX_SIMD_IS_UNLIKELY(none_of(__need_sin)))
535 return __sign_flip ^ __cosSeries(__f._M_x);
538 _V __r = __cosSeries(__f._M_x);
539 where(__need_sin.__cvt(), __r) = __sinSeries(__f._M_x);
540 return __sign_flip ^ __r;
545 template <
typename _Tp>
546 _GLIBCXX_SIMD_ALWAYS_INLINE
547 enable_if_t<is_floating_point<_Tp>::value, simd<_Tp, simd_abi::scalar>>
548 sin(simd<_Tp, simd_abi::scalar> __x)
552 _GLIBCXX_SIMD_MATH_CALL_(
tan)
553 _GLIBCXX_SIMD_MATH_CALL_(
acosh)
554 _GLIBCXX_SIMD_MATH_CALL_(
asinh)
555 _GLIBCXX_SIMD_MATH_CALL_(
atanh)
556 _GLIBCXX_SIMD_MATH_CALL_(
cosh)
557 _GLIBCXX_SIMD_MATH_CALL_(
sinh)
558 _GLIBCXX_SIMD_MATH_CALL_(
tanh)
561 _GLIBCXX_SIMD_MATH_CALL_(
exp)
562 _GLIBCXX_SIMD_MATH_CALL_(exp2)
563 _GLIBCXX_SIMD_MATH_CALL_(expm1)
567 #if _GLIBCXX_SIMD_X86INTRIN
568 template <
typename _Tp,
size_t _Np>
569 _SimdWrapper<_Tp, _Np>
570 __getexp(_SimdWrapper<_Tp, _Np> __x)
572 if constexpr (__have_avx512vl && __is_sse_ps<_Tp, _Np>())
573 return __auto_bitcast(_mm_getexp_ps(__to_intrin(__x)));
574 else if constexpr (__have_avx512f && __is_sse_ps<_Tp, _Np>())
575 return __auto_bitcast(_mm512_getexp_ps(__auto_bitcast(__to_intrin(__x))));
576 else if constexpr (__have_avx512vl && __is_sse_pd<_Tp, _Np>())
577 return _mm_getexp_pd(__x);
578 else if constexpr (__have_avx512f && __is_sse_pd<_Tp, _Np>())
579 return __lo128(_mm512_getexp_pd(__auto_bitcast(__x)));
580 else if constexpr (__have_avx512vl && __is_avx_ps<_Tp, _Np>())
581 return _mm256_getexp_ps(__x);
582 else if constexpr (__have_avx512f && __is_avx_ps<_Tp, _Np>())
583 return __lo256(_mm512_getexp_ps(__auto_bitcast(__x)));
584 else if constexpr (__have_avx512vl && __is_avx_pd<_Tp, _Np>())
585 return _mm256_getexp_pd(__x);
586 else if constexpr (__have_avx512f && __is_avx_pd<_Tp, _Np>())
587 return __lo256(_mm512_getexp_pd(__auto_bitcast(__x)));
588 else if constexpr (__is_avx512_ps<_Tp, _Np>())
589 return _mm512_getexp_ps(__x);
590 else if constexpr (__is_avx512_pd<_Tp, _Np>())
591 return _mm512_getexp_pd(__x);
593 __assert_unreachable<_Tp>();
596 template <typename _Tp,
size_t _Np>
597 _SimdWrapper<_Tp, _Np>
598 __getmant_avx512(_SimdWrapper<_Tp, _Np> __x)
600 if constexpr (__have_avx512vl && __is_sse_ps<_Tp, _Np>())
601 return __auto_bitcast(_mm_getmant_ps(__to_intrin(__x), _MM_MANT_NORM_p5_1,
603 else if constexpr (__have_avx512f && __is_sse_ps<_Tp, _Np>())
604 return __auto_bitcast(_mm512_getmant_ps(__auto_bitcast(__to_intrin(__x)),
607 else if constexpr (__have_avx512vl && __is_sse_pd<_Tp, _Np>())
608 return _mm_getmant_pd(__x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
609 else if constexpr (__have_avx512f && __is_sse_pd<_Tp, _Np>())
610 return __lo128(_mm512_getmant_pd(__auto_bitcast(__x), _MM_MANT_NORM_p5_1,
612 else if constexpr (__have_avx512vl && __is_avx_ps<_Tp, _Np>())
613 return _mm256_getmant_ps(__x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
614 else if constexpr (__have_avx512f && __is_avx_ps<_Tp, _Np>())
615 return __lo256(_mm512_getmant_ps(__auto_bitcast(__x), _MM_MANT_NORM_p5_1,
617 else if constexpr (__have_avx512vl && __is_avx_pd<_Tp, _Np>())
618 return _mm256_getmant_pd(__x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
619 else if constexpr (__have_avx512f && __is_avx_pd<_Tp, _Np>())
620 return __lo256(_mm512_getmant_pd(__auto_bitcast(__x), _MM_MANT_NORM_p5_1,
622 else if constexpr (__is_avx512_ps<_Tp, _Np>())
623 return _mm512_getmant_ps(__x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
624 else if constexpr (__is_avx512_pd<_Tp, _Np>())
625 return _mm512_getmant_pd(__x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
627 __assert_unreachable<_Tp>();
637 template <
typename _Tp,
typename _Abi>
638 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
639 frexp(
const simd<_Tp, _Abi>& __x, _Samesize<
int, simd<_Tp, _Abi>>* __exp)
641 if constexpr (simd_size_v<_Tp, _Abi> == 1)
644 const auto __r = std::frexp(__x[0], &__tmp);
648 else if constexpr (__is_fixed_size_abi_v<_Abi>)
649 return {__private_init, _Abi::_SimdImpl::_S_frexp(__data(__x), __data(*__exp))};
650 #if _GLIBCXX_SIMD_X86INTRIN
651 else if constexpr (__have_avx512f)
653 constexpr
size_t _Np = simd_size_v<_Tp, _Abi>;
654 constexpr
size_t _NI = _Np < 4 ? 4 : _Np;
655 const auto __v = __data(__x);
656 const auto __isnonzero
657 = _Abi::_SimdImpl::_S_isnonzerovalue_mask(__v._M_data);
658 const _SimdWrapper<int, _NI> __exp_plus1
659 = 1 + __convert<_SimdWrapper<int, _NI>>(__getexp(__v))._M_data;
660 const _SimdWrapper<int, _Np> __e = __wrapper_bitcast<int, _Np>(
661 _Abi::_CommonImpl::_S_blend(_SimdWrapper<bool, _NI>(__isnonzero),
662 _SimdWrapper<int, _NI>(), __exp_plus1));
663 simd_abi::deduce_t<int, _Np>::_CommonImpl::_S_store(__e, __exp);
664 return {__private_init,
665 _Abi::_CommonImpl::_S_blend(_SimdWrapper<bool, _Np>(
667 __v, __getmant_avx512(__v))};
673 static_assert(
sizeof(_Tp) == 4 ||
sizeof(_Tp) == 8);
674 using _V = simd<_Tp, _Abi>;
675 using _IV = rebind_simd_t<int, _V>;
676 using namespace std::experimental::__proposed;
677 using namespace std::experimental::__float_bitwise_operators;
679 constexpr
int __exp_adjust =
sizeof(_Tp) == 4 ? 0x7e : 0x3fe;
680 constexpr
int __exp_offset =
sizeof(_Tp) == 4 ? 0x70 : 0x200;
681 constexpr _Tp __subnorm_scale =
sizeof(_Tp) == 4 ? 0x1p112 : 0x1p512;
682 _GLIBCXX_SIMD_USE_CONSTEXPR_API _V __exponent_mask
684 _GLIBCXX_SIMD_USE_CONSTEXPR_API _V __p5_1_exponent
685 = -(2 - __epsilon_v<_Tp>) / 2;
687 _V __mant = __p5_1_exponent & (__exponent_mask | __x);
688 const _IV __exponent_bits = __extract_exponent_as_int(__x);
689 if (_GLIBCXX_SIMD_IS_LIKELY(all_of(isnormal(__x))))
692 = simd_cast<_Samesize<int, _V>>(__exponent_bits - __exp_adjust);
696 #if __FINITE_MATH_ONLY__
699 const auto __iszero_inf_nan = __x == 0;
701 using _Ip = __int_for_sizeof_t<_Tp>;
702 const auto __as_int = simd_bit_cast<rebind_simd_t<_Ip, _V>>(
abs(__x));
703 const auto __inf = simd_bit_cast<rebind_simd_t<_Ip, _V>>(_V(__infinity_v<_Tp>));
704 const auto __iszero_inf_nan = static_simd_cast<typename _V::mask_type>(
705 __as_int == 0 || __as_int >= __inf);
708 const _V __scaled_subnormal = __x * __subnorm_scale;
709 const _V __mant_subnormal
710 = __p5_1_exponent & (__exponent_mask | __scaled_subnormal);
711 where(!isnormal(__x), __mant) = __mant_subnormal;
712 where(__iszero_inf_nan, __mant) = __x;
713 _IV __e = __extract_exponent_as_int(__scaled_subnormal);
715 typename conditional_t<
sizeof(
typename _V::value_type) ==
sizeof(
int),
717 const _MaskType __value_isnormal = isnormal(__x).__cvt();
718 where(__value_isnormal.__cvt(), __e) = __exponent_bits;
719 static_assert(
sizeof(_IV) ==
sizeof(__value_isnormal));
721 = (simd_bit_cast<_IV>(__value_isnormal) & _IV(__exp_adjust))
722 | (simd_bit_cast<_IV>(static_simd_cast<_MaskType>(__exponent_bits == 0)
723 & static_simd_cast<_MaskType>(__x != 0))
724 & _IV(__exp_adjust + __exp_offset));
725 *__exp = simd_cast<_Samesize<int, _V>>(__e - __offset);
731 _GLIBCXX_SIMD_MATH_CALL2_(ldexp,
int)
732 _GLIBCXX_SIMD_MATH_CALL_(ilogb)
735 _GLIBCXX_SIMD_MATH_CALL_(
log)
736 _GLIBCXX_SIMD_MATH_CALL_(
log10)
737 _GLIBCXX_SIMD_MATH_CALL_(log1p)
738 _GLIBCXX_SIMD_MATH_CALL_(log2)
742 template <
typename _Tp,
typename _Abi>
743 enable_if_t<is_floating_point<_Tp>::value, simd<_Tp, _Abi>>
744 logb(
const simd<_Tp, _Abi>& __x)
746 constexpr
size_t _Np = simd_size_v<_Tp, _Abi>;
747 if constexpr (_Np == 1)
748 return
std::logb(__x[0]);
749 else if constexpr (__is_fixed_size_abi_v<_Abi>)
750 return {__private_init, _Abi::_SimdImpl::_S_logb(__data(__x))};
751 #if _GLIBCXX_SIMD_X86INTRIN
752 else if constexpr (__have_avx512vl && __is_sse_ps<_Tp, _Np>())
753 return {__private_init,
754 __auto_bitcast(_mm_getexp_ps(__to_intrin(__as_vector(__x))))};
755 else if constexpr (__have_avx512vl && __is_sse_pd<_Tp, _Np>())
756 return {__private_init, _mm_getexp_pd(__data(__x))};
757 else if constexpr (__have_avx512vl && __is_avx_ps<_Tp, _Np>())
758 return {__private_init, _mm256_getexp_ps(__data(__x))};
759 else if constexpr (__have_avx512vl && __is_avx_pd<_Tp, _Np>())
760 return {__private_init, _mm256_getexp_pd(__data(__x))};
761 else if constexpr (__have_avx512f && __is_avx_ps<_Tp, _Np>())
762 return {__private_init,
763 __lo256(_mm512_getexp_ps(__auto_bitcast(__data(__x))))};
764 else if constexpr (__have_avx512f && __is_avx_pd<_Tp, _Np>())
765 return {__private_init,
766 __lo256(_mm512_getexp_pd(__auto_bitcast(__data(__x))))};
767 else if constexpr (__is_avx512_ps<_Tp, _Np>())
768 return {__private_init, _mm512_getexp_ps(__data(__x))};
769 else if constexpr (__is_avx512_pd<_Tp, _Np>())
770 return {__private_init, _mm512_getexp_pd(__data(__x))};
774 using _V = simd<_Tp, _Abi>;
775 using namespace std::experimental::__proposed;
776 auto __is_normal = isnormal(__x);
780 const _V abs_x =
abs(__x);
784 auto&& __exponent = [](
const _V& __v) {
785 using namespace std::experimental::__proposed;
786 using _IV = rebind_simd_t<
787 conditional_t<
sizeof(_Tp) ==
sizeof(_LLong), _LLong,
int>, _V>;
788 return (simd_bit_cast<_IV>(__v) >> (__digits_v<_Tp> - 1))
789 - (__max_exponent_v<_Tp> - 1);
791 _V __r = static_simd_cast<_V>(__exponent(abs_x));
792 if (_GLIBCXX_SIMD_IS_LIKELY(all_of(__is_normal)))
796 const auto __is_zero = __x == 0;
797 const auto __is_nan = isnan(__x);
798 const auto __is_inf = isinf(__x);
799 where(__is_zero, __r) = -__infinity_v<_Tp>;
800 where(__is_nan, __r) = __x;
801 where(__is_inf, __r) = __infinity_v<_Tp>;
802 __is_normal |= __is_zero || __is_nan || __is_inf;
803 if (all_of(__is_normal))
809 const _V __scaled = abs_x * _Tp(0x1p112);
810 _V __scaled_exp = static_simd_cast<_V>(__exponent(__scaled) - 112);
811 where(__is_normal, __scaled_exp) = __r;
817 template <
typename _Tp,
typename _Abi>
818 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
819 modf(
const simd<_Tp, _Abi>& __x, simd<_Tp, _Abi>* __iptr)
821 if constexpr (simd_size_v<_Tp, _Abi> == 1)
824 _Tp __r = std::modf(__x[0], &__tmp);
830 const auto __integral = trunc(__x);
831 *__iptr = __integral;
832 auto __r = __x - __integral;
833 #if !__FINITE_MATH_ONLY__
834 where(isinf(__x), __r) = _Tp();
836 return copysign(__r, __x);
840 _GLIBCXX_SIMD_MATH_CALL2_(scalbn,
int)
841 _GLIBCXX_SIMD_MATH_CALL2_(scalbln,
long)
843 _GLIBCXX_SIMD_MATH_CALL_(cbrt)
845 _GLIBCXX_SIMD_MATH_CALL_(
abs)
846 _GLIBCXX_SIMD_MATH_CALL_(
fabs)
850 template <
typename _Tp,
typename _Abi>
851 enable_if_t<!is_floating_point_v<_Tp> && is_signed_v<_Tp>, simd<_Tp, _Abi>>
852 abs(
const simd<_Tp, _Abi>& __x)
853 {
return {__private_init, _Abi::_SimdImpl::_S_abs(__data(__x))}; }
855 #define _GLIBCXX_SIMD_CVTING2(_NAME) \
856 template <typename _Tp, typename _Abi> \
857 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
858 const simd<_Tp, _Abi>& __x, const __type_identity_t<simd<_Tp, _Abi>>& __y) \
860 return _NAME(__x, __y); \
863 template <typename _Tp, typename _Abi> \
864 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
865 const __type_identity_t<simd<_Tp, _Abi>>& __x, const simd<_Tp, _Abi>& __y) \
867 return _NAME(__x, __y); \
870 #define _GLIBCXX_SIMD_CVTING3(_NAME) \
871 template <typename _Tp, typename _Abi> \
872 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
873 const __type_identity_t<simd<_Tp, _Abi>>& __x, const simd<_Tp, _Abi>& __y, \
874 const simd<_Tp, _Abi>& __z) \
876 return _NAME(__x, __y, __z); \
879 template <typename _Tp, typename _Abi> \
880 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
881 const simd<_Tp, _Abi>& __x, const __type_identity_t<simd<_Tp, _Abi>>& __y, \
882 const simd<_Tp, _Abi>& __z) \
884 return _NAME(__x, __y, __z); \
887 template <typename _Tp, typename _Abi> \
888 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
889 const simd<_Tp, _Abi>& __x, const simd<_Tp, _Abi>& __y, \
890 const __type_identity_t<simd<_Tp, _Abi>>& __z) \
892 return _NAME(__x, __y, __z); \
895 template <typename _Tp, typename _Abi> \
896 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
897 const simd<_Tp, _Abi>& __x, const __type_identity_t<simd<_Tp, _Abi>>& __y, \
898 const __type_identity_t<simd<_Tp, _Abi>>& __z) \
900 return _NAME(__x, __y, __z); \
903 template <typename _Tp, typename _Abi> \
904 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
905 const __type_identity_t<simd<_Tp, _Abi>>& __x, const simd<_Tp, _Abi>& __y, \
906 const __type_identity_t<simd<_Tp, _Abi>>& __z) \
908 return _NAME(__x, __y, __z); \
911 template <typename _Tp, typename _Abi> \
912 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi> _NAME( \
913 const __type_identity_t<simd<_Tp, _Abi>>& __x, \
914 const __type_identity_t<simd<_Tp, _Abi>>& __y, const simd<_Tp, _Abi>& __z) \
916 return _NAME(__x, __y, __z); \
919 template <
typename _R,
typename _ToApply,
typename _Tp,
typename... _Tps>
920 _GLIBCXX_SIMD_INTRINSIC _R
921 __fixed_size_apply(_ToApply&& __apply,
const _Tp& __arg0,
922 const _Tps&... __args)
924 return {__private_init,
925 __data(__arg0)._M_apply_per_chunk(
926 [&](
auto __impl,
const auto&... __inner) {
927 using _V =
typename decltype(__impl)::simd_type;
928 return __data(__apply(_V(__private_init, __inner)...));
933 template <
typename _VV>
934 __remove_cvref_t<_VV>
935 __hypot(_VV __x, _VV __y)
937 using _V = __remove_cvref_t<_VV>;
938 using _Tp =
typename _V::value_type;
939 if constexpr (_V::size() == 1)
940 return
std::hypot(_Tp(__x[0]), _Tp(__y[0]));
941 else if constexpr (__is_fixed_size_abi_v<typename _V::abi_type>)
943 return __fixed_size_apply<_V>([](
auto __a,
944 auto __b) {
return hypot(__a, __b); },
954 using namespace __float_bitwise_operators;
955 using namespace __proposed;
956 _V __absx =
abs(__x);
957 _V __absy =
abs(__y);
958 _V __hi =
max(__absx, __absy);
959 _V __lo =
min(__absy, __absx);
962 _GLIBCXX_SIMD_USE_CONSTEXPR_API _V __inf(__infinity_v<_Tp>);
964 #ifndef __FAST_MATH__
965 if constexpr (__have_neon && !__have_neon_a32)
968 const _V __hi_exp = __hi & __inf;
969 _V __scale_back = __hi_exp;
972 where(__hi_exp > 1, __scale_back) = __hi_exp * _Tp(0.125);
974 const _V __scale = (__scale_back ^ __inf) * _Tp(.5);
975 const _V __h1 = __hi * __scale;
976 const _V __l1 = __lo * __scale;
977 _V __r = __scale_back *
sqrt(__h1 * __h1 + __l1 * __l1);
979 where(__hi == 0, __r) = 0;
990 if (_GLIBCXX_SIMD_IS_LIKELY(all_of(isnormal(__x))
991 && all_of(isnormal(__y))))
994 const _V __hi_exp = __hi & __inf;
1000 #ifdef __FAST_MATH__
1001 using _Ip = __int_for_sizeof_t<_Tp>;
1002 using _IV = rebind_simd_t<_Ip, _V>;
1003 const auto __as_int = simd_bit_cast<_IV>(__hi_exp);
1005 = simd_bit_cast<_V>(2 * simd_bit_cast<_Ip>(_Tp(1)) - __as_int);
1007 const _V __scale = (__hi_exp ^ __inf) * _Tp(.5);
1009 _GLIBCXX_SIMD_USE_CONSTEXPR_API _V __mant_mask
1010 = __norm_min_v<_Tp> - __denorm_min_v<_Tp>;
1011 const _V __h1 = (__hi & __mant_mask) | _V(1);
1012 const _V __l1 = __lo * __scale;
1013 return __hi_exp *
sqrt(__h1 * __h1 + __l1 * __l1);
1020 _V __scale = _V(1 / __norm_min_v<_Tp>);
1024 where(__hi >= __norm_min_v<_Tp>, __scale)
1025 = ((__hi & __inf) ^ __inf) * _Tp(.5);
1027 _V __hi_exp = __norm_min_v<_Tp>;
1028 where(__hi >= __norm_min_v<_Tp>, __hi_exp)
1030 _V __h1 = __hi * __scale;
1031 _V __l1 = __lo * __scale;
1035 _V __r = __hi_exp *
sqrt(__h1 * __h1 + __l1 * __l1);
1036 #ifdef __STDC_IEC_559__
1048 where(isunordered(__x, __y), __fixup) = __quiet_NaN_v<_Tp>;
1049 where(isinf(__absx) || isinf(__absy), __fixup) = __inf;
1050 where(!(__lo == 0 || isunordered(__x, __y)
1051 || (isinf(__absx) || isinf(__absy))),
1061 template <
typename _Tp,
typename _Abi>
1062 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi>
1063 hypot(
const simd<_Tp, _Abi>& __x,
const simd<_Tp, _Abi>& __y)
1065 return __hypot<conditional_t<__is_fixed_size_abi_v<_Abi>,
1066 const simd<_Tp, _Abi>&, simd<_Tp, _Abi>>>(__x,
1070 _GLIBCXX_SIMD_CVTING2(hypot)
1072 template <
typename _VV>
1073 __remove_cvref_t<_VV>
1074 __hypot(_VV __x, _VV __y, _VV __z)
1076 using _V = __remove_cvref_t<_VV>;
1077 using _Abi =
typename _V::abi_type;
1078 using _Tp =
typename _V::value_type;
1084 if constexpr (__is_fixed_size_abi_v<_Abi> && _V::size() > 1)
1086 return __fixed_size_apply<simd<_Tp, _Abi>>(
1087 [](
auto __a,
auto __b,
auto __c) {
return hypot(__a, __b, __c); },
1092 using namespace __float_bitwise_operators;
1093 using namespace __proposed;
1094 const _V __absx =
abs(__x);
1095 const _V __absy =
abs(__y);
1096 const _V __absz =
abs(__z);
1097 _V __hi =
max(
max(__absx, __absy), __absz);
1098 _V __l0 =
min(__absz,
max(__absx, __absy));
1099 _V __l1 =
min(__absy, __absx);
1100 if constexpr (__digits_v<_Tp> == 64 && __max_exponent_v<_Tp> == 0x4000
1101 && __min_exponent_v<_Tp> == -0x3FFD && _V::size() == 1)
1105 #ifdef __STDC_IEC_559__
1107 if (isinf(__absx[0]) || isinf(__absy[0]) || isinf(__absz[0]))
1108 return __infinity_v<_Tp>;
1109 else if (isunordered(__absx[0], __absy[0] + __absz[0]))
1110 return __quiet_NaN_v<_Tp>;
1111 else if (__l0[0] == 0 && __l1[0] == 0)
1115 const _ULLong __tmp = 0x8000'0000'0000'0000ull;
1116 __builtin_memcpy(&__data(__hi_exp), &__tmp, 8);
1117 const _V __scale = 1 / __hi_exp;
1121 return __hi_exp *
sqrt((__l0 * __l0 + __l1 * __l1) + __hi * __hi);
1126 _GLIBCXX_SIMD_USE_CONSTEXPR_API _V __inf(__infinity_v<_Tp>);
1128 #ifndef __FAST_MATH__
1129 if constexpr (_V::size() > 1 && __have_neon && !__have_neon_a32)
1132 const _V __hi_exp = __hi & __inf;
1133 _V __scale_back = __hi_exp;
1136 where(__hi_exp > 1, __scale_back) = __hi_exp * _Tp(0.125);
1139 const _V __scale = (__scale_back ^ __inf) * _Tp(.5);
1140 const _V __h1 = __hi * __scale;
1143 _V __lo = __l0 * __l0
1145 asm(
"" :
"+m"(__lo));
1146 _V __r = __scale_back *
sqrt(__h1 * __h1 + __lo);
1148 where(__hi == 0, __r) = 0;
1153 #ifdef __FAST_MATH__
1159 if (_GLIBCXX_SIMD_IS_LIKELY(all_of(isnormal(__x))
1160 && all_of(isnormal(__y))
1161 && all_of(isnormal(__z))))
1164 const _V __hi_exp = __hi & __inf;
1170 #ifdef __FAST_MATH__
1171 using _Ip = __int_for_sizeof_t<_Tp>;
1172 using _IV = rebind_simd_t<_Ip, _V>;
1173 const auto __as_int = simd_bit_cast<_IV>(__hi_exp);
1175 = simd_bit_cast<_V>(2 * simd_bit_cast<_Ip>(_Tp(1)) - __as_int);
1177 const _V __scale = (__hi_exp ^ __inf) * _Tp(.5);
1179 constexpr _Tp __mant_mask
1180 = __norm_min_v<_Tp> - __denorm_min_v<_Tp>;
1181 const _V __h1 = (__hi & _V(__mant_mask)) | _V(1);
1187 return __hi_exp *
sqrt(__lo + __h1 * __h1);
1194 _V __scale = _V(1 / __norm_min_v<_Tp>);
1198 where(__hi >= __norm_min_v<_Tp>, __scale)
1199 = ((__hi & __inf) ^ __inf) * _Tp(.5);
1201 _V __hi_exp = __norm_min_v<_Tp>;
1202 where(__hi >= __norm_min_v<_Tp>, __hi_exp)
1204 _V __h1 = __hi * __scale;
1207 _V __lo = __l0 * __l0
1209 _V __r = __hi_exp *
sqrt(__lo + __h1 * __h1);
1210 #ifdef __STDC_IEC_559__
1214 where(isunordered(__x, __y + __z), __fixup)
1215 = __quiet_NaN_v<_Tp>;
1216 where(isinf(__absx) || isinf(__absy) || isinf(__absz), __fixup)
1225 where(!(__lo == 0 || isunordered(__x, __y + __z)
1226 || isinf(__absx) || isinf(__absy) || isinf(__absz)),
1237 template <
typename _Tp,
typename _Abi>
1238 _GLIBCXX_SIMD_INTRINSIC simd<_Tp, _Abi>
1239 hypot(
const simd<_Tp, _Abi>& __x,
const simd<_Tp, _Abi>& __y,
1240 const simd<_Tp, _Abi>& __z)
1242 return __hypot<conditional_t<__is_fixed_size_abi_v<_Abi>,
1243 const simd<_Tp, _Abi>&, simd<_Tp, _Abi>>>(__x,
1248 _GLIBCXX_SIMD_CVTING3(hypot)
1250 _GLIBCXX_SIMD_MATH_CALL2_(
pow, _Tp)
1252 _GLIBCXX_SIMD_MATH_CALL_(
sqrt)
1253 _GLIBCXX_SIMD_MATH_CALL_(erf)
1254 _GLIBCXX_SIMD_MATH_CALL_(erfc)
1255 _GLIBCXX_SIMD_MATH_CALL_(lgamma)
1256 _GLIBCXX_SIMD_MATH_CALL_(tgamma)
1257 _GLIBCXX_SIMD_MATH_CALL_(ceil)
1258 _GLIBCXX_SIMD_MATH_CALL_(floor)
1259 _GLIBCXX_SIMD_MATH_CALL_(nearbyint)
1260 _GLIBCXX_SIMD_MATH_CALL_(rint)
1261 _GLIBCXX_SIMD_MATH_CALL_(lrint)
1262 _GLIBCXX_SIMD_MATH_CALL_(llrint)
1264 _GLIBCXX_SIMD_MATH_CALL_(round)
1265 _GLIBCXX_SIMD_MATH_CALL_(lround)
1266 _GLIBCXX_SIMD_MATH_CALL_(llround)
1268 _GLIBCXX_SIMD_MATH_CALL_(trunc)
1270 _GLIBCXX_SIMD_MATH_CALL2_(fmod, _Tp)
1271 _GLIBCXX_SIMD_MATH_CALL2_(remainder, _Tp)
1272 _GLIBCXX_SIMD_MATH_CALL3_(remquo, _Tp,
int*)
1274 template <
typename _Tp,
typename _Abi>
1275 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1276 copysign(
const simd<_Tp, _Abi>& __x,
const simd<_Tp, _Abi>& __y)
1278 if constexpr (simd_size_v<_Tp, _Abi> == 1)
1279 return
std::copysign(__x[0], __y[0]);
1280 else if constexpr (__is_fixed_size_abi_v<_Abi>)
1281 return {__private_init, _Abi::_SimdImpl::_S_copysign(__data(__x), __data(__y))};
1284 using _V = simd<_Tp, _Abi>;
1285 using namespace std::experimental::__float_bitwise_operators;
1286 _GLIBCXX_SIMD_USE_CONSTEXPR_API
auto __signmask = _V(1) ^ _V(-1);
1287 return (__x & ~__signmask) | (__y & __signmask);
1291 _GLIBCXX_SIMD_MATH_CALL2_(nextafter, _Tp)
1294 _GLIBCXX_SIMD_MATH_CALL2_(fdim, _Tp)
1295 _GLIBCXX_SIMD_MATH_CALL2_(fmax, _Tp)
1296 _GLIBCXX_SIMD_MATH_CALL2_(fmin, _Tp)
1298 _GLIBCXX_SIMD_MATH_CALL3_(fma, _Tp, _Tp)
1299 _GLIBCXX_SIMD_MATH_CALL_(fpclassify)
1300 _GLIBCXX_SIMD_MATH_CALL_(isfinite)
1304 template <
typename _Tp,
typename _Abi,
typename...,
1305 typename _R = _Math_return_type_t<bool, _Tp, _Abi>>
1306 enable_if_t<is_floating_point_v<_Tp>, _R>
1307 isinf(simd<_Tp, _Abi> __x)
1308 {
return {__private_init, _Abi::_SimdImpl::_S_isinf(__data(__x))}; }
1310 template <
typename _Tp,
typename _Abi,
typename...,
1311 typename _R = _Math_return_type_t<bool, _Tp, _Abi>>
1312 enable_if_t<is_floating_point_v<_Tp>, _R>
1313 isnan(simd<_Tp, _Abi> __x)
1314 {
return {__private_init, _Abi::_SimdImpl::_S_isnan(__data(__x))}; }
1316 _GLIBCXX_SIMD_MATH_CALL_(isnormal)
1318 template <
typename...,
typename _Tp,
typename _Abi>
1319 simd_mask<_Tp, _Abi>
1320 signbit(simd<_Tp, _Abi> __x)
1322 if constexpr (is_integral_v<_Tp>)
1324 if constexpr (is_unsigned_v<_Tp>)
1325 return simd_mask<_Tp, _Abi>{};
1330 return {__private_init, _Abi::_SimdImpl::_S_signbit(__data(__x))};
1333 _GLIBCXX_SIMD_MATH_CALL2_(isgreater, _Tp)
1334 _GLIBCXX_SIMD_MATH_CALL2_(isgreaterequal, _Tp)
1335 _GLIBCXX_SIMD_MATH_CALL2_(isless, _Tp)
1336 _GLIBCXX_SIMD_MATH_CALL2_(islessequal, _Tp)
1337 _GLIBCXX_SIMD_MATH_CALL2_(islessgreater, _Tp)
1338 _GLIBCXX_SIMD_MATH_CALL2_(isunordered, _Tp)
1366 template <
typename _Tp,
typename _Abi>
1367 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1368 assoc_laguerre(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1369 const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __m,
1370 const simd<_Tp, _Abi>& __x)
1372 return simd<_Tp, _Abi>([&](
auto __i) {
1377 template <
typename _Tp,
typename _Abi>
1378 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1379 assoc_legendre(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1380 const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __m,
1381 const simd<_Tp, _Abi>& __x)
1383 return simd<_Tp, _Abi>([&](
auto __i) {
1388 _GLIBCXX_SIMD_MATH_CALL2_(
beta, _Tp)
1396 _GLIBCXX_SIMD_MATH_CALL2_(
ellint_1, _Tp)
1397 _GLIBCXX_SIMD_MATH_CALL2_(
ellint_2, _Tp)
1398 _GLIBCXX_SIMD_MATH_CALL3_(
ellint_3, _Tp, _Tp)
1399 _GLIBCXX_SIMD_MATH_CALL_(
expint)
1401 template <
typename _Tp,
typename _Abi>
1402 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1403 hermite(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1404 const simd<_Tp, _Abi>& __x)
1406 return simd<_Tp, _Abi>(
1407 [&](
auto __i) {
return std::hermite(__n[__i], __x[__i]); });
1410 template <
typename _Tp,
typename _Abi>
1411 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1412 laguerre(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1413 const simd<_Tp, _Abi>& __x)
1415 return simd<_Tp, _Abi>(
1416 [&](
auto __i) {
return std::laguerre(__n[__i], __x[__i]); });
1419 template <
typename _Tp,
typename _Abi>
1420 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1421 legendre(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1422 const simd<_Tp, _Abi>& __x)
1424 return simd<_Tp, _Abi>(
1425 [&](
auto __i) {
return std::legendre(__n[__i], __x[__i]); });
1430 template <
typename _Tp,
typename _Abi>
1431 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1432 sph_bessel(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1433 const simd<_Tp, _Abi>& __x)
1435 return simd<_Tp, _Abi>(
1439 template <
typename _Tp,
typename _Abi>
1440 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1441 sph_legendre(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __l,
1442 const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __m,
1443 const simd<_Tp, _Abi>& theta)
1445 return simd<_Tp, _Abi>([&](
auto __i) {
1450 template <
typename _Tp,
typename _Abi>
1451 enable_if_t<is_floating_point_v<_Tp>, simd<_Tp, _Abi>>
1452 sph_neumann(
const fixed_size_simd<
unsigned, simd_size_v<_Tp, _Abi>>& __n,
1453 const simd<_Tp, _Abi>& __x)
1455 return simd<_Tp, _Abi>(
1460 #undef _GLIBCXX_SIMD_CVTING2
1461 #undef _GLIBCXX_SIMD_CVTING3
1462 #undef _GLIBCXX_SIMD_MATH_CALL_
1463 #undef _GLIBCXX_SIMD_MATH_CALL2_
1464 #undef _GLIBCXX_SIMD_MATH_CALL3_
1466 _GLIBCXX_SIMD_END_NAMESPACE
complex< _Tp > log10(const complex< _Tp > &)
Return complex base 10 logarithm of z.
complex< _Tp > sin(const complex< _Tp > &)
Return complex sine of z.
complex< _Tp > log(const complex< _Tp > &)
Return complex natural logarithm of z.
complex< _Tp > tan(const complex< _Tp > &)
Return complex tangent of z.
_Tp abs(const complex< _Tp > &)
Return magnitude of z.
complex< _Tp > exp(const complex< _Tp > &)
Return complex base e exponential of z.
complex< _Tp > cosh(const complex< _Tp > &)
Return complex hyperbolic cosine of z.
complex< _Tp > tanh(const complex< _Tp > &)
Return complex hyperbolic tangent of z.
complex< _Tp > pow(const complex< _Tp > &, int)
Return x to the y'th power.
complex< _Tp > sinh(const complex< _Tp > &)
Return complex hyperbolic sine of z.
complex< _Tp > cos(const complex< _Tp > &)
Return complex cosine of z.
complex< _Tp > sqrt(const complex< _Tp > &)
Return complex square root of z.
typename make_unsigned< _Tp >::type make_unsigned_t
Alias template for make_unsigned.
typename conditional< _Cond, _Iftrue, _Iffalse >::type conditional_t
Alias template for conditional.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
__gnu_cxx::__promote_2< _Tpnu, _Tp >::__type cyl_bessel_i(_Tpnu __nu, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type sph_neumann(unsigned int __n, _Tp __x)
__gnu_cxx::__promote_3< _Tp, _Tpn, _Tpp >::__type ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi)
Return the incomplete elliptic integral of the third kind .
__gnu_cxx::__promote< _Tp >::__type comp_ellint_2(_Tp __k)
__gnu_cxx::__promote< _Tp >::__type assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type sph_bessel(unsigned int __n, _Tp __x)
__gnu_cxx::__promote_2< _Tpnu, _Tp >::__type cyl_bessel_j(_Tpnu __nu, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta)
__gnu_cxx::__promote_2< _Tpnu, _Tp >::__type cyl_neumann(_Tpnu __nu, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type riemann_zeta(_Tp __s)
__gnu_cxx::__promote_2< _Tpa, _Tpb >::__type beta(_Tpa __a, _Tpb __b)
__gnu_cxx::__promote_2< _Tpnu, _Tp >::__type cyl_bessel_k(_Tpnu __nu, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type expint(_Tp __x)
__gnu_cxx::__promote< _Tp >::__type hermite(unsigned int __n, _Tp __x)
__gnu_cxx::__promote< _Tp >::__type comp_ellint_1(_Tp __k)
__gnu_cxx::__promote< _Tp >::__type laguerre(unsigned int __n, _Tp __x)
__gnu_cxx::__promote_2< _Tp, _Tpp >::__type ellint_2(_Tp __k, _Tpp __phi)
__gnu_cxx::__promote_2< _Tp, _Tpn >::__type comp_ellint_3(_Tp __k, _Tpn __nu)
__gnu_cxx::__promote_2< _Tp, _Tpp >::__type ellint_1(_Tp __k, _Tpp __phi)
__gnu_cxx::__promote< _Tp >::__type legendre(unsigned int __l, _Tp __x)
ISO C++ entities toplevel namespace is std.
_Tp fabs(const std::complex< _Tp > &)
fabs(__z) [8.1.8].
std::complex< _Tp > asinh(const std::complex< _Tp > &)
asinh(__z) [8.1.6].
std::complex< _Tp > atan(const std::complex< _Tp > &)
atan(__z) [8.1.4].
std::complex< _Tp > atanh(const std::complex< _Tp > &)
atanh(__z) [8.1.7].
std::complex< _Tp > acosh(const std::complex< _Tp > &)
acosh(__z) [8.1.5].
std::complex< _Tp > acos(const std::complex< _Tp > &)
acos(__z) [8.1.2].
std::complex< _Tp > asin(const std::complex< _Tp > &)
asin(__z) [8.1.3].