summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sal/rtl/math.cxx29
-rw-r--r--tools/source/generic/fract.cxx24
-rw-r--r--tools/source/misc/fix16.cxx31
3 files changed, 12 insertions, 72 deletions
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index fe45b90a8297..5b6c780b5001 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -24,6 +24,7 @@
#include <rtl/math.hxx>
#include <algorithm>
+#include <bit>
#include <cassert>
#include <cfenv>
#include <cmath>
@@ -118,18 +119,6 @@ bool isRepresentableInteger(double fAbsValue)
return nInt == fAbsValue;
}
-// Returns 1-based index of least significant bit in a number, or zero if number is zero
-int findFirstSetBit(unsigned n)
-{
-#if defined _WIN32
- unsigned long pos;
- unsigned char bNonZero = _BitScanForward(&pos, n);
- return (bNonZero == 0) ? 0 : pos + 1;
-#else
- return __builtin_ffs(n);
-#endif
-}
-
/** Returns number of binary bits for fractional part of the number
Expects a proper non-negative double value, not +-INF, not NAN
*/
@@ -138,19 +127,13 @@ int getBitsInFracPart(double fAbsValue)
assert(std::isfinite(fAbsValue) && fAbsValue >= 0.0);
if (fAbsValue == 0.0)
return 0;
- auto pValParts = reinterpret_cast<const sal_math_Double*>(&fAbsValue);
- int nExponent = pValParts->inf_parts.exponent - 1023;
+ auto& rValParts = reinterpret_cast<const sal_math_Double*>(&fAbsValue)->parts;
+ int nExponent = rValParts.exponent - 1023;
if (nExponent >= 52)
return 0; // All bits in fraction are in integer part of the number
- int nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_lo);
- if (nLeastSignificant == 0)
- {
- nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_hi);
- if (nLeastSignificant == 0)
- nLeastSignificant = 53; // the implied leading 1 is the least significant
- else
- nLeastSignificant += 32;
- }
+ int nLeastSignificant = rValParts.fraction
+ ? std::countr_zero(rValParts.fraction) + 1
+ : 53; // the implied leading 1 is the least significant
int nFracSignificant = 53 - nLeastSignificant;
int nBitsInFracPart = nFracSignificant - nExponent;
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index abe8ee41b206..7dfddf50a880 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -25,18 +25,16 @@
#include <osl/diagnose.h>
#include <algorithm>
+#include <bit>
#include <cmath>
#include <numeric>
#include <boost/rational.hpp>
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
static boost::rational<sal_Int32> rational_FromDouble(double dVal);
static void rational_ReduceInaccurate(boost::rational<sal_Int32>& rRational, unsigned nSignificantBits);
-static int impl_NumberOfBits( sal_uInt32 nNum );
+// Find the number of bits required to represent this number
+static int impl_NumberOfBits(sal_uInt32 nNum) { return 32 - std::countl_zero(nNum); }
static boost::rational<sal_Int32> toRational(sal_Int32 n, sal_Int32 d)
{
@@ -406,22 +404,6 @@ static boost::rational<sal_Int32> rational_FromDouble(double dVal)
return boost::rational<sal_Int32>( sal_Int32(dVal), nDen );
}
-/**
- * Find the number of bits required to represent this number, using the CLZ intrinsic
- */
-static int impl_NumberOfBits( sal_uInt32 nNum )
-{
- if (nNum == 0)
- return 0;
-#ifdef _MSC_VER
- unsigned long r = 0;
- _BitScanReverse(&r, nNum);
- return r + 1;
-#else
- return 32 - __builtin_clz(nNum);
-#endif
-}
-
/** Inaccurate cancellation for a fraction.
Clip both nominator and denominator to said number of bits. If
diff --git a/tools/source/misc/fix16.cxx b/tools/source/misc/fix16.cxx
index 978f77291dce..58c40704d931 100644
--- a/tools/source/misc/fix16.cxx
+++ b/tools/source/misc/fix16.cxx
@@ -24,6 +24,8 @@
#include <tools/fix16.hxx>
+#include <bit>
+
const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */
const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows */
@@ -74,33 +76,6 @@ fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
return result;
}
-/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3.
- * Performs 32-bit divisions repeatedly to reduce the remainder. For this to
- * be efficient, the processor has to have 32-bit hardware division.
- */
-#ifdef __GNUC__
-// Count leading zeros, using processor-specific instruction if available.
-#define clz(x) (__builtin_clzl(x) - (8 * sizeof(long) - 32))
-#else
-static uint8_t clz(uint32_t x)
-{
- uint8_t result = 0;
- if (x == 0)
- return 32;
- while (!(x & 0xF0000000))
- {
- result += 4;
- x <<= 4;
- }
- while (!(x & 0x80000000))
- {
- result += 1;
- x <<= 1;
- }
- return result;
-}
-#endif
-
fix16_t fix16_div(fix16_t a, fix16_t b)
{
// This uses a hardware 32/32 bit division multiple times, until we have
@@ -135,7 +110,7 @@ fix16_t fix16_div(fix16_t a, fix16_t b)
while (remainder && bit_pos >= 0)
{
// Shift remainder as much as we can without overflowing
- int shift = clz(remainder);
+ int shift = std::countl_zero(remainder);
if (shift > bit_pos)
shift = bit_pos;
remainder <<= shift;