libdpf/include/dpf/uint256_t.hpp
Ryan Henry e4e666f459 Initial import of libdpf.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-24 14:08:32 -06:00

253 lines
6.9 KiB
C++

#ifndef LIBDPF_INCLUDE_DPF_UINT256_T_HPP__
#define LIBDPF_INCLUDE_DPF_UINT256_T_HPP__
#include "hedley/hedley.h"
#include <type_traits>
#include <limits>
#include "uint256_t/uint256_t.hpp"
#include "dpf/utils.hpp"
#include "dpf/leaf_arithmetic.hpp"
namespace dpf
{
namespace leaf_arithmetic
{
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
template <> struct add_t<uint128_t, simde__m128i> final
{
auto operator()(const simde__m128i & lhs, const simde__m128i & rhs) const
{
simde__m128i ret;
uint128_t lhs_, rhs_;
std::memcpy(&lhs_, &lhs, sizeof(uint128_t));
std::memcpy(&rhs_, &rhs, sizeof(uint128_t));
uint128_t sum = lhs_ + rhs_;
std::memcpy(&ret, &sum, sizeof(simde__m128i));
return ret;
}
};
template <> struct add_t<uint128_t, simde__m256i> final
{
auto operator()(const simde__m256i & lhs, const simde__m256i & rhs) const
{
simde__m256i ret;
uint128_t lhs_[2], rhs_[2];
std::memcpy(&lhs_, &lhs, sizeof(uint128_t) * 2);
std::memcpy(&rhs_, &rhs, sizeof(uint128_t) * 2);
uint128_t sum[2] = { lhs_[0] + rhs_[0], lhs_[1] + rhs_[1] };
std::memcpy(&ret, &sum, sizeof(simde__m256i));
return ret;
}
};
template <> struct add_t<uint256_t, simde__m256i> final
{
auto operator()(const simde__m256i & lhs, const simde__m256i & rhs) const
{
simde__m256i ret;
uint256_t lhs_, rhs_;
std::memcpy(&lhs_, &lhs, sizeof(uint256_t));
std::memcpy(&rhs_, &rhs, sizeof(uint256_t));
uint256_t sum = lhs_ + rhs_;
std::memcpy(&ret, &sum, sizeof(simde__m256i));
return ret;
}
};
template <> struct add_t<uint256_t, std::array<simde__m128i, 2>> final
{
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
HEDLEY_PURE
auto operator()(const std::array<simde__m128i, 2> & a, const std::array<simde__m128i, 2> & b) const noexcept
{
std::array<simde__m128i, 2> c;
uint256_t a_, b_;
std::memcpy(&a_, std::data(a), sizeof(uint256_t));
std::memcpy(&b_, std::data(b), sizeof(uint256_t));
uint256_t c_ = a_ + b_;
std::memcpy(std::data(c), &c_, sizeof(std::array<simde__m128i, 2>));
return c;
}
};
template <> struct subtract_t<uint128_t, simde__m128i> final
{
auto operator()(const simde__m128i & lhs, const simde__m128i & rhs) const
{
simde__m128i ret;
uint128_t lhs_, rhs_;
std::memcpy(&lhs_, &lhs, sizeof(uint128_t));
std::memcpy(&rhs_, &rhs, sizeof(uint128_t));
uint128_t sum = lhs_ - rhs_;
std::memcpy(&ret, &sum, sizeof(simde__m128i));
return ret;
}
};
template <> struct subtract_t<uint128_t, simde__m256i> final
{
auto operator()(const simde__m256i & lhs, const simde__m256i & rhs) const
{
simde__m256i ret;
uint128_t lhs_[2], rhs_[2];
std::memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2);
std::memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2);
uint128_t sum[2] = { lhs_[0] - rhs_[0], lhs_[1] - rhs_[1] };
std::memcpy(&ret, &sum, sizeof(simde__m256i));
return ret;
}
};
template <> struct subtract_t<uint256_t, simde__m256i> final
{
auto operator()(const simde__m256i & lhs, const simde__m256i & rhs) const
{
simde__m256i ret;
uint256_t lhs_, rhs_;
std::memcpy(&lhs_, &lhs, sizeof(uint256_t));
std::memcpy(&rhs_, &rhs, sizeof(uint256_t));
uint256_t sum = lhs_ - rhs_;
std::memcpy(&ret, &sum, sizeof(simde__m256i));
return ret;
}
};
template <> struct subtract_t<uint256_t, std::array<simde__m128i, 2>> final
{
auto operator()(const std::array<simde__m128i, 2> & a, const std::array<simde__m128i, 2> & b) const
{
std::array<simde__m128i, 2> c;
uint256_t a_, b_;
std::memcpy(&a_, std::data(a), sizeof(uint256_t));
std::memcpy(&b_, std::data(b), sizeof(uint256_t));
uint256_t c_ = a_ - b_;
std::memcpy(std::data(c), &c_, sizeof(std::array<simde__m128i, 2>));
return c;
}
};
template <> struct multiply_t<uint128_t, simde__m128i> final
{
auto operator()(const simde__m128i & a, uint128_t b) const
{
uint128_t a_;
simde__m128i c;
std::memcpy(&a_, &a, sizeof(uint128_t));
uint128_t c_ = a_ * b;
std::memcpy(&c, &c_, sizeof(simde__m128i));
return c;
}
};
template <> struct multiply_t<uint256_t, std::array<simde__m128i, 2>> final
{
auto operator()(const std::array<simde__m128i, 2> & a, uint256_t b) const
{
uint256_t a_;
std::memcpy(&a_, &a, sizeof(uint256_t));
uint256_t c_ = a_ * b;
std::array<simde__m128i, 2> c;
std::memcpy(&c, &c_, sizeof(std::array<simde__m128i, 2>));
return c;
}
};
template <> struct multiply_t<uint128_t, simde__m256i> final
{
auto operator()(const simde__m256i & a, uint128_t b) const
{
uint256_t a_;
simde__m256i c;
std::memcpy(&a_, &a, sizeof(uint256_t));
uint256_t c_{a_.upper() * b, a_.lower() * b};
std::memcpy(&c, &c_, sizeof(simde__m256i));
return c;
}
};
template <> struct multiply_t<uint256_t, simde__m256i> final
{
auto operator()(const simde__m256i & a, uint256_t b) const
{
uint256_t a_;
simde__m256i c;
std::memcpy(&a_, &a, sizeof(uint256_t));
uint256_t c_ = a_ * b;
std::memcpy(&c, &c_, sizeof(simde__m256i));
return c;
}
};
HEDLEY_PRAGMA(GCC diagnostic pop)
} // namespace leaf_arithmetic
namespace utils
{
template <>
struct msb_of<uint128_t>
{
constexpr static uint128_t value{1ul << 63, 0ul};
};
template <>
struct msb_of<uint256_t>
{
constexpr static uint256_t value{uint128_t{1ul << 63, 0ul}, uint128_t{0ul, 0ul}};
};
template <>
struct mod_pow_2<uint128_t>
{
std::size_t operator()(uint128_t val, std::size_t n) const noexcept
{
return mod_pow_2<uint64_t>{}(static_cast<uint64_t>(val.lower()), n);
}
};
template <>
struct mod_pow_2<uint256_t>
{
std::size_t operator()(uint256_t val, std::size_t n) const noexcept
{
return mod_pow_2<uint128_t>{}(val.lower(), n);
}
};
template <>
struct to_integral_type<uint128_t>
: to_integral_type_base<uint128_t>
{
using parent = to_integral_type_base<uint128_t>;
using typename parent::integral_type;
constexpr integral_type operator()(uint128_t val) const noexcept
{
return (simde_uint128(val.upper()) << 64) | simde_uint128(val.lower());
}
};
template <>
struct to_integral_type<uint256_t>
: to_integral_type_base<uint256_t>
{
using parent = to_integral_type_base<uint256_t>;
using typename parent::integral_type;
constexpr integral_type operator()(uint256_t val) const noexcept
{
return val;
}
};
} // namespace dpf::utils
} // namespace dpf
#endif // LIBDPF_INCLUDE_DPF_UINT256_T_HPP__