Skip to content

Commit

Permalink
div/sub left/right + cylindrical decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap authored Nov 11, 2024
1 parent b2d8b63 commit 1025587
Show file tree
Hide file tree
Showing 17 changed files with 179 additions and 91 deletions.
9 changes: 9 additions & 0 deletions include/eve/module/core/decorator/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ namespace eve
struct associated_mode {};
struct compensated_mode {};
struct condon_shortley_mode {};
struct cylindrical_mode {};
struct definitely_mode {};
struct kind_1_mode {};
struct kind_2_mode {};
struct left_mode {};
struct numeric_mode {};
struct p_kind_mode {};
struct promote_mode {};
struct q_kind_mode {};
struct right_mode {};
struct spherical_mode {};
struct successor_mode {};

Expand All @@ -53,15 +56,18 @@ namespace eve
[[maybe_unused]] inline constexpr auto associated = ::rbr::flag( associated_mode{} );
[[maybe_unused]] inline constexpr auto compensated = ::rbr::flag( compensated_mode{} );
[[maybe_unused]] inline constexpr auto condon_shortley = ::rbr::flag( condon_shortley_mode{} );
[[maybe_unused]] inline constexpr auto cylindrical = ::rbr::flag( cylindrical_mode{} );
[[maybe_unused]] inline constexpr auto downward = ::rbr::flag( downward_mode{} );
[[maybe_unused]] inline constexpr auto kind_1 = ::rbr::flag( kind_1_mode{} );
[[maybe_unused]] inline constexpr auto kind_2 = ::rbr::flag( kind_2_mode{} );
[[maybe_unused]] inline constexpr auto left = ::rbr::flag( left_mode{} );
[[maybe_unused]] inline constexpr auto numeric = ::rbr::flag( numeric_mode{} );
[[maybe_unused]] inline constexpr auto pedantic = ::rbr::flag( pedantic_mode{} );
[[maybe_unused]] inline constexpr auto p_kind = ::rbr::flag( p_kind_mode{} );
[[maybe_unused]] inline constexpr auto promote = ::rbr::flag( promote_mode{} );
[[maybe_unused]] inline constexpr auto q_kind = ::rbr::flag( q_kind_mode{} );
[[maybe_unused]] inline constexpr auto raw = ::rbr::flag( raw_mode{} );
[[maybe_unused]] inline constexpr auto right = ::rbr::flag( right_mode{} );
[[maybe_unused]] inline constexpr auto spherical = ::rbr::flag( spherical_mode{} );
[[maybe_unused]] inline constexpr auto successor = ::rbr::flag( successor_mode{} );
[[maybe_unused]] inline constexpr auto to_nearest = ::rbr::flag( to_nearest_mode{} );
Expand All @@ -76,8 +82,10 @@ namespace eve
struct associated_option : detail::exact_option<associated> {};
struct compensated_option : detail::exact_option<compensated> {};
struct condon_shortley_option : detail::exact_option<condon_shortley> {};
struct cylindrical_option : detail::exact_option<cylindrical> {};
struct kind_1_option : detail::exact_option<kind_1> {};
struct kind_2_option : detail::exact_option<kind_2> {};
struct left_option : detail::exact_option<left> {};
struct numeric_option : detail::exact_option<numeric> {};
struct p_kind_option : detail::exact_option<p_kind> {};
struct promote_option : detail::exact_option<promote> {};
Expand All @@ -87,6 +95,7 @@ namespace eve
struct downward_option : detail::exact_option<downward> {};
struct pedantic_option : detail::exact_option<pedantic> {};
struct raw_option : detail::exact_option<raw> {};
struct right_option : detail::exact_option<right> {};
struct to_nearest_option : detail::exact_option<to_nearest> {};
struct toward_zero_option : detail::exact_option<toward_zero> {};
struct upward_option : detail::exact_option<upward> {};
Expand Down
9 changes: 7 additions & 2 deletions include/eve/module/core/regular/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ namespace eve
{
template<typename Options>
struct div_t : tuple_callable<div_t, Options, saturated_option, upward_option, downward_option,
to_nearest_option, toward_zero_option, upper_option, lower_option, strict_option>
to_nearest_option, toward_zero_option, upper_option,
lower_option, strict_option, left_option,
right_option>
{
template<eve::value T0, value T1, value... Ts>
requires(eve::same_lanes_or_scalar<T0, T1, Ts...>)
Expand Down Expand Up @@ -69,7 +71,9 @@ namespace eve
//! constexpr auto div[upper][srict](/*any of the above overloads*/) noexcept; // 6
//!
//! // Semantic options
//! constexpr auto div[right](/*any of the above overloads*/) noexcept; // 1
//! constexpr auto div[saturated](integral_value auto x, integral_value auto y)) noexcept; // 7
//! constexpr auto div[left](/*any of the above overloads*/) noexcept; // 8
//! }
//! @endcode
//!
Expand Down Expand Up @@ -100,7 +104,8 @@ namespace eve
//! ensures generally faster computation, but strict inequality.
//! 7. computes the saturated division of `x` by `y`.
//! The result is always defined even if the denominator is 0.
//!
//! 8. `div[left](a, b)` is semantically equivalent to `div(b, a)`
///!
//! The relevant cases are just in fact the division by 0 for integral types
//! in which case the result is [`eve::valmin(as(x))`](@ref valmin) or
//! [`valmax(as(x))`](ref eve::valmax) according to the dividend sign, and
Expand Down
7 changes: 6 additions & 1 deletion include/eve/module/core/regular/impl/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ namespace eve::detail
template<callable_options O, typename T>
EVE_FORCEINLINE constexpr T div_(EVE_REQUIRES(cpu_), O const& o, T a, T b) noexcept
{
if constexpr(floating_value<T> && (O::contains(upper) || O::contains(lower) ))
if constexpr(O::contains(left))
{
return div[o.drop(left)](b, a);
}
else if constexpr(floating_value<T> && (O::contains(upper) || O::contains(lower) ))
{
if constexpr(O::contains(strict))
{
Expand Down Expand Up @@ -220,6 +224,7 @@ namespace eve::detail

template<typename T, std::same_as<T>... Ts, callable_options O>
EVE_FORCEINLINE constexpr T div_(EVE_REQUIRES(cpu_), O const & o, T r0, T r1, Ts... rs) noexcept
requires(!O::contains(left))
{
auto that = r1;
if (O::contains(upper)) that = mul[lower](r1, rs...);
Expand Down
6 changes: 5 additions & 1 deletion include/eve/module/core/regular/impl/simd/arm/neon/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ namespace eve::detail
EVE_FORCEINLINE wide<T, N> div_(EVE_REQUIRES(neon128_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires arm_abi<abi_t<T, N>>
{
if constexpr (O::contains_any(saturated, upper, lower, toward_zero,
if (O::contains(left))
{
return div[opts.drop(left)](b, a);
}
else if constexpr (O::contains_any(saturated, upper, lower, toward_zero,
upward, downward, to_nearest, widen))
{
return div.behavior(cpu_{}, opts, a, b);
Expand Down
41 changes: 26 additions & 15 deletions include/eve/module/core/regular/impl/simd/arm/neon/sub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,40 @@ namespace eve::detail
wide<T, N> v, wide<T, N> w) noexcept
requires (arm_abi<abi_t<T, N>> && O::contains(widen))
{
constexpr auto c = categorize<wide<T, N>>();
if (O::contains(left))
{
return sub[opts.drop(left)](w, v);
}
else
{
constexpr auto c = categorize<wide<T, N>>();

auto fix = [](auto r){
using u_t = upgrade_t<T>;
using uw_t = upgrade_t<wide<T, N>>;
if constexpr(N::value == expected_cardinal_v<u_t>) return uw_t{r};
else return simd_cast(wide<u_t>{r}, as<uw_t>{});
};
auto fix = [](auto r){
using u_t = upgrade_t<T>;
using uw_t = upgrade_t<wide<T, N>>;
if constexpr(N::value == expected_cardinal_v<u_t>) return uw_t{r};
else return simd_cast(wide<u_t>{r}, as<uw_t>{});
};

if constexpr( c == category::int32x2 ) return fix(vsubl_s32(v, w));
else if constexpr( c == category::uint32x2 ) return fix(vsubl_u32(v, w));
else if constexpr( c == category::int16x4 ) return fix(vsubl_s16(v, w));
else if constexpr( c == category::uint16x4 ) return fix(vsubl_u16(v, w));
else if constexpr( c == category::int8x8 ) return fix(vsubl_s8 (v, w));
else if constexpr( c == category::uint8x8 ) return fix(vsubl_u8 (v, w));
else return sub.behavior(cpu_{}, opts, v, w);
if constexpr( c == category::int32x2 ) return fix(vsubl_s32(v, w));
else if constexpr( c == category::uint32x2 ) return fix(vsubl_u32(v, w));
else if constexpr( c == category::int16x4 ) return fix(vsubl_s16(v, w));
else if constexpr( c == category::uint16x4 ) return fix(vsubl_u16(v, w));
else if constexpr( c == category::int8x8 ) return fix(vsubl_s8 (v, w));
else if constexpr( c == category::uint8x8 ) return fix(vsubl_u8 (v, w));
else return sub.behavior(cpu_{}, opts, v, w);
}
}

template<callable_options O, arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE wide<T, N> sub_(EVE_REQUIRES(neon128_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires (arm_abi<abi_t<T, N>> && !O::contains(widen))
{
if constexpr(O::contains_any(lower, upper))
if constexpr(O::contains(left))
{
return sub[opts.drop(left)](b, a);
}
else if constexpr(O::contains_any(lower, upper))
{
return sub.behavior(cpu_{}, opts, a, b);
}
Expand Down
12 changes: 10 additions & 2 deletions include/eve/module/core/regular/impl/simd/arm/sve/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ namespace eve::detail
EVE_FORCEINLINE wide<T,N> div_(EVE_REQUIRES(sve_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires sve_abi<abi_t<T, N>>
{
if constexpr (O::contains(saturated) || O::contains(upper) || O::contains(lower))
if (O::contains(left))
{
return div[opts.drop(left)](b, a);
}
else if constexpr (O::contains(saturated) || O::contains(upper) || O::contains(lower))
{
return div.behavior(cpu_{}, opts, a, b);
}
Expand All @@ -37,7 +41,11 @@ namespace eve::detail
EVE_FORCEINLINE wide<T,N> div_(EVE_REQUIRES(sve_), C const& cx, O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires sve_abi<abi_t<T, N>>
{
if constexpr (O::contains(saturated) || O::contains(upper) || O::contains(lower))
if (O::contains(left))
{
return div.behavior(cpu_{}, opts, a, b);
}
else if constexpr (O::contains(saturated) || O::contains(upper) || O::contains(lower))
{
return div.behavior(cpu_{}, opts, a, b);
}
Expand Down
8 changes: 6 additions & 2 deletions include/eve/module/core/regular/impl/simd/arm/sve/sub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace eve::detail
EVE_FORCEINLINE auto sub_(EVE_REQUIRES(sve_), C const& mask, O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires sve_abi<abi_t<T, N>>
{
if constexpr(O::contains(widen))
if constexpr(O::contains_any(widen, left))
{
return sub.behavior(cpu_{}, opts, a, b);
}
Expand Down Expand Up @@ -51,7 +51,11 @@ namespace eve::detail
EVE_FORCEINLINE auto sub_(EVE_REQUIRES(sve_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires sve_abi<abi_t<T, N>>
{
if constexpr(O::contains(widen))
if constexpr(O::contains(left))
{
return sub[opts.drop(left)](b, a);
}
else if constexpr(O::contains(widen))
{
return sub.behavior(cpu_{}, opts, a, b);
}
Expand Down
6 changes: 5 additions & 1 deletion include/eve/module/core/regular/impl/simd/ppc/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ namespace eve::detail
EVE_FORCEINLINE wide<T, N> div_(EVE_REQUIRES(vmx_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires ppc_abi<abi_t<T, N>>
{
if constexpr (O::contains(saturated)|| O::contains(upper) || O::contains(lower))
if (O::contains(left))
{
return div[opts.drop(left)](b, a);
}
else if constexpr (O::contains(saturated)|| O::contains(upper) || O::contains(lower))
{
return div.behavior(cpu_{}, opts, a, b);
}
Expand Down
6 changes: 5 additions & 1 deletion include/eve/module/core/regular/impl/simd/ppc/sub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ namespace eve::detail
EVE_FORCEINLINE auto sub_(EVE_REQUIRES(vmx_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires ppc_abi<abi_t<T, N>>
{
if constexpr( O::contains_any(lower, upper, widen) || (O::contains(saturated) && std::integral<T>))
if constexpr(O::contains(left))
{
return sub[opts.drop(left)](b, a);
}
else if constexpr( O::contains_any(lower, upper, widen) || (O::contains(saturated) && std::integral<T>))
return sub.behavior(cpu_{}, opts, a, b);
else
return wide<T, N>(vec_sub(a.storage(), b.storage()));
Expand Down
12 changes: 10 additions & 2 deletions include/eve/module/core/regular/impl/simd/x86/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ namespace eve::detail
EVE_FORCEINLINE wide<T, N> div_(EVE_REQUIRES(sse2_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires x86_abi<abi_t<T, N>>
{
if constexpr(O::contains(saturated) ||
if constexpr(O::contains(left))
{
return div[opts.drop(left)](b, a);
}
else if constexpr(O::contains(saturated) ||
O::contains(toward_zero) || O::contains(upward) ||
O::contains(downward) || O::contains(to_nearest))
{
Expand Down Expand Up @@ -86,7 +90,11 @@ namespace eve::detail
{
constexpr auto c = categorize<wide<T, N>>();
auto src = alternative(cx, v, as<wide<T, N>> {});
if constexpr (floating_value<T> && !O::contains(strict) && (O::contains(lower) || O::contains(upper)))
if constexpr(O::contains(left))
{
return div.behavior(cpu_{}, o, v, w);
}
else if constexpr (floating_value<T> && !O::contains(strict) && (O::contains(lower) || O::contains(upper)))
{
if constexpr(current_api >= avx512)
{
Expand Down
Loading

0 comments on commit 1025587

Please sign in to comment.