Skip to content

Commit

Permalink
New style for more bit operations
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap authored Apr 30, 2024
1 parent a6326f8 commit a2e2cf5
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 101 deletions.
33 changes: 29 additions & 4 deletions include/eve/module/core/regular/bit_not.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,25 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/forward.hpp>
#include <eve/module/core/regular/bit_cast.hpp>

namespace eve
{

template<typename Options>
struct bit_not_t : elementwise_callable<bit_not_t, Options, saturated_option>
{
template<eve::value T>
constexpr EVE_FORCEINLINE T operator()(T v) const noexcept
{ return EVE_DISPATCH_CALL(v); }

EVE_CALLABLE_OBJECT(bit_not_t, bit_not_);
};

//================================================================================================
//! @addtogroup core_bitops
//! @{
Expand Down Expand Up @@ -55,7 +70,17 @@ namespace eve
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bit_not_, bit_not);
inline constexpr auto bit_not = functor<bit_not_t>;

namespace detail
{
template<ordered_value T, callable_options O>
constexpr T bit_not_(EVE_REQUIRES(cpu_), O const&, T const& v) noexcept
{
if constexpr( floating_scalar_value<T> )
return bit_cast(~bit_cast(v, as<as_integer_t<T>> {}), as(v));
else
return T(~v);
}
}
}

#include <eve/module/core/regular/impl/bit_not.hpp>
41 changes: 37 additions & 4 deletions include/eve/module/core/regular/bit_swap_pairs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,30 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>

#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/forward.hpp>
#include <eve/assert.hpp>
#include <eve/module/core/regular/bit_cast.hpp>
#include <eve/module/core/regular/bit_xor.hpp>
#include <eve/module/core/regular/bit_shl.hpp>
#include <eve/module/core/constant/one.hpp>

namespace eve
{

template<typename Options>
struct bit_swap_pairs_t : strict_elementwise_callable<bit_swap_pairs_t, Options>
{
template<eve::value T, integral_value I0, integral_value I1>
constexpr EVE_FORCEINLINE T operator()(T v, I0 i0, I1 i1) const noexcept
{ return EVE_DISPATCH_CALL(v, i0, i1); }

EVE_CALLABLE_OBJECT(bit_swap_pairs_t, bit_swap_pairs_);
};

//================================================================================================
//! @addtogroup core_bitops
//! @{
Expand Down Expand Up @@ -58,7 +78,20 @@ namespace eve
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bit_swap_pairs_, bit_swap_pairs);
}
inline constexpr auto bit_swap_pairs = functor<bit_swap_pairs_t>;

namespace detail
{

#include <eve/module/core/regular/impl/bit_swap_pairs.hpp>
template<ordered_value T, integral_value I0, integral_value I1, callable_options O>
constexpr T bit_swap_pairs_(EVE_REQUIRES(cpu_), O const&, T a, I0 i0, I1 i1) noexcept
{
[[maybe_unused]] constexpr std::ptrdiff_t S8 = sizeof(element_type_t<T>)*8;
EVE_ASSERT(eve::all(i0 < S8 && i1 < S8), "some indexes are out or range");
auto x = bit_and(bit_xor(bit_shr(a, i0), bit_shr(a, i1)), one(as(a)));
a ^= bit_shl(x, i1);
a ^= bit_shl(x, i0);
return a;
}
}
}
30 changes: 26 additions & 4 deletions include/eve/module/core/regular/bit_width.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/forward.hpp>
#include <eve/module/core/regular/countl_zero.hpp>

namespace eve
{
template<typename Options>
struct bit_width_t : elementwise_callable<bit_width_t, Options, saturated_option>
{
template<eve::value T>
constexpr EVE_FORCEINLINE T operator()(T v) const noexcept
{ return EVE_DISPATCH_CALL(v); }

EVE_CALLABLE_OBJECT(bit_width_t, bit_width_);
};

//================================================================================================
//! @addtogroup core_bitops
//! @{
Expand Down Expand Up @@ -48,7 +62,15 @@ namespace eve
//! @godbolt{doc/core/bit_width.cpp}
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bit_width_, bit_width);
}
inline constexpr auto bit_width = functor<bit_width_t>;

#include <eve/module/core/regular/impl/bit_width.hpp>
namespace detail
{
template<unsigned_value T, callable_options O>
constexpr T bit_width_(EVE_REQUIRES(cpu_), O const&, T const& v) noexcept
{
using elt_t = element_type_t<T>;
return sizeof(elt_t) * 8 - countl_zero(v);
}
}
}
31 changes: 27 additions & 4 deletions include/eve/module/core/regular/bitofsign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/forward.hpp>
#include <eve/module/core/constant/signmask.hpp>
#include <eve/module/core/regular/bit_and.hpp>

namespace eve
{

template<typename Options>
struct bitofsign_t : elementwise_callable<bitofsign_t, Options, saturated_option>
{
template<eve::value T>
constexpr EVE_FORCEINLINE T operator()(T v) const noexcept
{ return EVE_DISPATCH_CALL(v); }

EVE_CALLABLE_OBJECT(bitofsign_t, bitofsign_);
};

//================================================================================================
//! @addtogroup core_internal
//! @{
Expand Down Expand Up @@ -58,7 +74,14 @@ namespace eve
//! @godbolt{doc/core/bitofsign.cpp}
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bitofsign_, bitofsign);
}
inline constexpr auto bitofsign = functor<bitofsign_t>;

#include <eve/module/core/regular/impl/bitofsign.hpp>
namespace detail
{
template<ordered_value T, callable_options O>
constexpr T bitofsign_(EVE_REQUIRES(cpu_), O const&, T const& a) noexcept
{
return bit_and(a, signmask(eve::as(a)));
}
}
}
32 changes: 28 additions & 4 deletions include/eve/module/core/regular/byte_swap_adjacent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/module/core/regular/bit_swap_adjacent.hpp>

namespace eve
{

template<typename Options>
struct byte_swap_adjacent_t : strict_elementwise_callable<byte_swap_adjacent_t, Options>
{
template<eve::value T, integral_value I>
constexpr EVE_FORCEINLINE T operator()(T v, I i) const
{ return EVE_DISPATCH_CALL(v, i); }

EVE_CALLABLE_OBJECT(byte_swap_adjacent_t, byte_swap_adjacent_);
};

//================================================================================================
//! @addtogroup core_bitops
//! @{
Expand Down Expand Up @@ -64,7 +78,17 @@ namespace eve
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(byte_swap_adjacent_, byte_swap_adjacent);
}
inline constexpr auto byte_swap_adjacent = functor<byte_swap_adjacent_t>;

#include <eve/module/core/regular/impl/byte_swap_adjacent.hpp>
namespace detail
{
template<typename T, integral_value N, callable_options O>
EVE_FORCEINLINE constexpr T
byte_swap_adjacent_(EVE_REQUIRES(cpu_), O const&, T const& x, N const & n) noexcept
{
using v_t = element_type_t<T>;
if constexpr(sizeof(v_t) == 0) return x;
else return bit_swap_adjacent(x, n*8);
}
}
}
35 changes: 0 additions & 35 deletions include/eve/module/core/regular/impl/bit_not.hpp

This file was deleted.

39 changes: 0 additions & 39 deletions include/eve/module/core/regular/impl/bit_swap_pairs.hpp

This file was deleted.

31 changes: 27 additions & 4 deletions include/eve/module/core/regular/reldist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>
#include <eve/module/core/regular/abs.hpp>
#include <eve/module/core/regular/dist.hpp>
#include <eve/module/core/regular/max.hpp>
#include <eve/module/core/constant/one.hpp>

namespace eve
{
template<typename Options>
struct reldist_t : elementwise_callable<reldist_t, Options, saturated_option, pedantic_option>
{
template<value T, value U>
EVE_FORCEINLINE constexpr common_value_t<T, U> operator()(T a, U b) const noexcept
{ return EVE_DISPATCH_CALL(a, b); }

EVE_CALLABLE_OBJECT(reldist_t, reldist_);
};

//================================================================================================
//! @addtogroup core_arithmetic
//! @{
Expand Down Expand Up @@ -47,7 +63,14 @@ namespace eve
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(reldist_, reldist);
}
inline constexpr auto reldist = functor<reldist_t>;

#include <eve/module/core/regular/impl/reldist.hpp>
namespace detail
{
template<value T, callable_options O>
constexpr T reldist_(EVE_REQUIRES(cpu_), O const&, T a, T b)
{
return dist(a, b)/max(abs(a), abs(b), one(as(a)));
}
}
}
3 changes: 1 addition & 2 deletions test/unit/module/core/bit_not.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ TTS_CASE_TPL("Check return types of bit_not", eve::test::simd::all_types)
// conditional
TTS_EXPR_IS(eve::bit_not[logical<T>()](T()), T);
TTS_EXPR_IS(eve::bit_not[logical<v_t>()](T()), T);
TTS_EXPR_IS(eve::bit_not[logical<T>()](v_t()), T);
};

//==================================================================================================
Expand Down Expand Up @@ -65,7 +64,7 @@ TTS_CASE_WITH("Check behavior of eve::masked(eve::bit_not)(eve::wide)",
eve::test::simd::ieee_reals,
tts::generate(tts::randoms(eve::valmin, eve::valmax),
tts::logicals(0, 3)))
<typename T, typename M>(T const& a0,
<typename T, typename M>(T const& a0,
M const& mask)
{
TTS_IEEE_EQUAL(eve::bit_not[mask](a0),
Expand Down
1 change: 0 additions & 1 deletion test/unit/module/core/bitofsign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ TTS_CASE_TPL("Check return types of bitofsign", eve::test::simd::all_types)
TTS_EXPR_IS(eve::bitofsign(T()), T);
TTS_EXPR_IS(eve::bitofsign(v_t()), v_t);
TTS_EXPR_IS(eve::bitofsign[eve::logical<T>()](T()), T);
TTS_EXPR_IS(eve::bitofsign[eve::logical<T>()](v_t()), T);
TTS_EXPR_IS(eve::bitofsign[eve::logical<v_t>()](T()), T);
TTS_EXPR_IS(eve::bitofsign[eve::logical<v_t>()](v_t()), v_t);
TTS_EXPR_IS(eve::bitofsign[bool()](T()), T);
Expand Down

0 comments on commit a2e2cf5

Please sign in to comment.