diff --git a/FEXCore/include/FEXCore/Utils/MathUtils.h b/FEXCore/include/FEXCore/Utils/MathUtils.h index 76740ea5d..d86aa7fa6 100644 --- a/FEXCore/include/FEXCore/Utils/MathUtils.h +++ b/FEXCore/include/FEXCore/Utils/MathUtils.h @@ -25,4 +25,12 @@ requires(std::is_unsigned_v) return std::countr_zero(Value); } +// Divide a number by a power-of-2 by avoiding integer division. +// Can be a faster implementation than regular integer divide. +// Divisor requires to be power-of-2, is enforced in ilog2 helper. +template +requires(std::is_unsigned_v && std::is_unsigned_v) +[[nodiscard]] constexpr T DividePow2(T Dividend, TT Divisor) { + return Dividend >> ilog2(Divisor); +} } // namespace FEXCore diff --git a/FEXCore/unittests/APITests/ILog2.cpp b/FEXCore/unittests/APITests/ILog2.cpp index e4fca68de..5555fd71e 100644 --- a/FEXCore/unittests/APITests/ILog2.cpp +++ b/FEXCore/unittests/APITests/ILog2.cpp @@ -5,3 +5,9 @@ TEST_CASE("ILog2") { auto i = GENERATE(range(0, 64)); REQUIRE(FEXCore::ilog2(1ull << i) == i); } + +TEST_CASE("DividePow2") { + auto j = GENERATE(range(0, 64)); + auto i = GENERATE(range(0, 64)); + REQUIRE(FEXCore::DividePow2(1ull << j, 1ull << i) == ((1ull << j) / (1ull << i))); +}