2#include "native/simd.h"
3#include "native/wide_math.h"
4#define NATIVE_BACKEND_BODY "native/simd/math/exp_body.h"
5#include "native/simd/for_each_backend.h"
6#undef NATIVE_BACKEND_BODY
8#if NATIVE_HOST_WASM && (!defined(NATIVE_PROFILE) || NATIVE_PROFILE != 0)
9#pragma clang attribute push(__attribute__((target("simd128"))), apply_to=function)
12 template<
bool Flush = false,
unsigned Degree = 6, isa<> A>
requires(Degree >= 1 && Degree <= 7 && A.has(wasm_feature::simd128))
14 return ::math::exp<Flush, Degree>(x);
17 template<
bool Flush = false,
unsigned Degree = 6, std::
size_t N, isa<> A>
requires(Degree >= 1 && Degree <= 7 && A.has(wasm_feature::simd128))
19 return ::math::exp<Flush, Degree>(x);
21 template<
bool Flush,
unsigned Degree = 6, isa<> A>
requires(Degree >= 1 && Degree <= 7 && A.has(wasm_feature::simd128))
23 return ::math::exp<Flush, Degree>(x);
25 template<
bool Flush,
unsigned Degree = 6, std::
size_t N, isa<> A>
requires(Degree >= 1 && Degree <= 7 && A.has(wasm_feature::simd128))
27 std::bool_constant<Flush>, std::integral_constant<unsigned, Degree> = {})
noexcept {
28 return ::math::exp<Flush, Degree>(x);
31 template<
bool Flush = false, isa<> A>
requires(A.has(wasm_feature::simd128))
33 return ::math::exp2<Flush>(x);
36 template<
bool Flush = false, std::
size_t N, isa<> A>
requires(A.has(wasm_feature::simd128))
38 return ::math::exp2<Flush>(x);
40 template<
bool Flush, isa<> A>
requires(A.has(wasm_feature::simd128))
42 return ::math::exp2<Flush>(x);
44 template<
bool Flush, std::
size_t N, isa<> A>
requires(A.has(wasm_feature::simd128))
46 std::bool_constant<Flush>)
noexcept {
47 return ::math::exp2<Flush>(x);
49#define NATIVE_WASM_MATH(name) \
50 template<isa<> A> requires(A.has(wasm_feature::simd128)) \
51 native_nodiscard native_inline constexpr auto name(simd<float,4,A> x) noexcept { \
52 return ::math::name(x); \
54 template<std::size_t N, isa<> A> requires(A.has(wasm_feature::simd128)) \
55 native_nodiscard native_inline constexpr auto name(std::array<simd<float,4,A>,N> const & x) noexcept { \
56 return ::math::name(x); \
63 NATIVE_WASM_MATH(
expm1)
66 NATIVE_WASM_MATH(
log2)
67 NATIVE_WASM_MATH(
log1p)
68 NATIVE_WASM_MATH(
tanh)
69#undef NATIVE_WASM_MATH
71 template<isa<> A>
requires(A.has(wasm_feature::simd128))
73 return ::math::atan2(y,x);
76 template<std::
size_t N, isa<> A>
requires(A.has(wasm_feature::simd128))
78 std::array<
simd<float,4,A>,N>
const & x)
noexcept { return ::math::atan2(y,x); }
80#pragma clang attribute pop
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
constexpr simd< float, L, Arch > atan2(simd< float, L, Arch > y, simd< float, L, Arch > x) noexcept
constexpr simd< float, L, Arch > exp2(simd< float, L, Arch > input) noexcept
constexpr simd< float, L, Arch > exp(simd< float, L, Arch > input) noexcept
Evaluate the binary32 range-reduced exponential approximation. Degree selects a polynomial from one t...
constexpr auto sincos(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &x) { detail::wide_generic_detail::adl_sincos(x);}) return noexcept(detail::wide_generic_detail::adl_sincos(std::declval< std::array< R, N > const & >())) &&std::is_nothrow_move_constructible_v< std::array< R, N > >;else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||(noexcept(detail::wide_generic_detail::adl_sincos(std::declval< R const & >())) &&noexcept(std::declval< R & >()=std::declval< decltype(detail::wide_generic_detail::adl_sincos(std::declval< R const & >())) & >().first) &&noexcept(std::declval< R & >()=std::declval< decltype(detail::wide_generic_detail::adl_sincos(std::declval< R const & >())) & >().second)));}())
constexpr wide< R, N > cos(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_cos(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_cos(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_cos(std::declval< R const & >())));}())
constexpr wide< R, N > tanh(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_tanh(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_tanh(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_tanh(std::declval< R const & >())));}())
constexpr wide< R, N > sin(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_sin(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_sin(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_sin(std::declval< R const & >())));}())
constexpr wide< R, N > log(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log(std::declval< R const & >())));}())
constexpr wide< R, N > log2(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log2(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log2(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log2(std::declval< R const & >())));}())
constexpr wide< R, N > damping_gain(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_damping_gain(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_damping_gain(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_damping_gain(std::declval< R const & >())));}())
constexpr wide< R, N > expm1(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_expm1(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_expm1(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_expm1(std::declval< R const & >())));}())
constexpr wide< R, N > log1p(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log1p(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log1p(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log1p(std::declval< R const & >())));}())
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Omitted architecture arguments use the native.simd provider's baseline.