Skip to content

Commit

Permalink
use better define to identify msvc
Browse files Browse the repository at this point in the history
also propagate cross platform function fixes to test suite

Signed-off-by: Kimball Thurston <[email protected]>
  • Loading branch information
kdt3rd committed Dec 31, 2024
1 parent a6d0c52 commit 30dc084
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/lib/OpenEXRCore/internal_dwa_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#endif

#ifndef USE_CLZ
# ifdef _WIN32
# ifdef _MSC_VER
static int __inline __builtin_clz(uint32_t v)
{
#ifdef __BMI1__
Expand Down
70 changes: 49 additions & 21 deletions src/test/OpenEXRCoreTest/compressionTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#if defined(_WIN32)
#include <windows.h>
#include <intrin.h>
#endif

#if defined(OPENEXR_ENABLE_API_VISIBILITY)
Expand Down Expand Up @@ -509,40 +510,67 @@ testDWATable (const std::string&)
# if __has_builtin(__builtin_popcount)
# define USE_POPCOUNT 1
# endif
# if __has_builtin(__builtin_clz)
# define USE_CLZ 1
# endif
#endif
#ifndef USE_POPCOUNT
# define USE_POPCOUNT 0
#endif

#ifndef USE_CLZ
# ifdef _WIN32
static int __inline __builtin_clz(uint32_t v)
{
#ifdef __BMI1__
return __lzcnt(v);
#else
unsigned long r;
_BitScanReverse(&r, v);
return 31 - r;
#endif
}
# define USE_CLZ 1
# else
# define USE_CLZ 0
# endif
#endif

#if USE_POPCOUNT
static inline int
countSetBits (uint16_t src)
{
return __builtin_popcount (src);
}
#else
static inline uint8_t
countSetBits8 (uint8_t src)
// courtesy hacker's delight
static inline int countSetBits(uint32_t x)
{
static const int8_t numBitsSet[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
return numBitsSet[src];
uint64_t y;
y = x * 0x0002000400080010ULL;
y = y & 0x1111111111111111ULL;
y = y * 0x1111111111111111ULL;
y = y >> 60;
return y;
}
#endif

static inline uint8_t
countSetBits (uint16_t src)
#if USE_CLZ
static inline int
countLeadingZeros(uint16_t src)
{
return __builtin_clz (src);
}
#else
// courtesy hacker's delight
static int inline countLeadingZeros( uint32_t x )
{
return countSetBits8 (src & 0xff) + countSetBits8 (src >> 8);
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - countSetBits(x);
}
#endif

Expand Down Expand Up @@ -597,7 +625,7 @@ countSetBits (uint16_t src)
static uint16_t handleQuantizeDenormTol (
uint16_t abssrc, uint16_t tolSig, float errTol, float srcFloat, int doprint)
{
const uint16_t tsigshift = (32 - __builtin_clz (tolSig));
const uint16_t tsigshift = (32 - countLeadingZeros (tolSig));
const uint16_t npow2 = (1 << tsigshift);
const uint16_t lowermask = npow2 - 1;
const uint16_t mask = ~lowermask;
Expand Down Expand Up @@ -642,7 +670,7 @@ static uint16_t handleQuantizeGeneric (
// classic would do clz(significand - 1) but here we are trying to
// construct a mask, so want to ensure for an power of 2, we
// actually get the next (i.e. 2 returns 4)
const uint16_t tsigshift = (32 - __builtin_clz (tolSig));
const uint16_t tsigshift = (32 - countLeadingZeros (tolSig));
const uint16_t npow2 = (1 << tsigshift);
const uint16_t lowermask = npow2 - 1;
const uint16_t mask = ~lowermask;
Expand Down Expand Up @@ -1083,7 +1111,7 @@ static uint16_t handleQuantizeDefault (
// classic would do clz(significand - 1) but here we are trying to
// construct a mask, so want to ensure for an power of 2, we
// actually get the next (i.e. 2 returns 4)
const uint16_t tsigshift = (32 - __builtin_clz (tolSig));
const uint16_t tsigshift = (32 - countLeadingZeros (tolSig));
const uint16_t npow2 = (1 << tsigshift);
const uint16_t lowermask = npow2 - 1;
const uint16_t mask = ~lowermask;
Expand Down

0 comments on commit 30dc084

Please sign in to comment.