mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +00:00
More robust popcnt
This commit is contained in:
parent
a9afcf873c
commit
5feba3a716
1 changed files with 52 additions and 53 deletions
|
@ -26,39 +26,11 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#if defined(i386) || defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
|
||||
#define IS_INTEL
|
||||
#endif
|
||||
#if defined( _MSC_VER )
|
||||
|
||||
#ifdef IS_INTEL
|
||||
#if defined ( _MSC_VER )
|
||||
#include <intrin.h>
|
||||
|
||||
static void cpuid( int info[4], int infoType )
|
||||
{
|
||||
__cpuidex( info, infoType, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
|
||||
static void cpuid( int info[4], int infoType )
|
||||
{
|
||||
__cpuid_count( infoType, 0, info[0], info[1], info[2], info[3] );
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Lynx
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static constexpr int64_t CNT_MAX = std::numeric_limits<int64_t>::max() & ~15;
|
||||
|
||||
uint32_t popcnt_generic( uint32_t x )
|
||||
static uint32_t popcnt_generic( uint32_t x )
|
||||
{
|
||||
int v = 0;
|
||||
while ( x != 0 )
|
||||
|
@ -69,18 +41,60 @@ uint32_t popcnt_generic( uint32_t x )
|
|||
return v;
|
||||
}
|
||||
|
||||
#ifdef IS_INTEL
|
||||
uint32_t popcnt_intrinsic( uint32_t x )
|
||||
#if defined( _M_IX86 ) || defined( _M_X64 )
|
||||
|
||||
static uint32_t popcnt_intrinsic( uint32_t x )
|
||||
{
|
||||
#if defined ( _MSC_VER )
|
||||
return __popcnt( x );
|
||||
#else
|
||||
return __builtin_popcount( x );
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t( *popcnt )( uint32_t );
|
||||
|
||||
//detecting popcnt availability on msvc intel
|
||||
static void selectPOPCNT()
|
||||
{
|
||||
int info[4];
|
||||
__cpuid( info, 1 );
|
||||
if ( ( info[2] & ( (int)1 << 23 ) ) != 0 )
|
||||
{
|
||||
popcnt = &popcnt_intrinsic;
|
||||
}
|
||||
else
|
||||
{
|
||||
popcnt = &popcnt_generic;
|
||||
}
|
||||
}
|
||||
|
||||
#else //defined( _M_IX86 ) || defined( _M_X64 )
|
||||
|
||||
//MSVC non INTEL should use generic implementation
|
||||
inline void selectPOPCNT()
|
||||
{
|
||||
}
|
||||
|
||||
#define popcnt popcnt_generic
|
||||
|
||||
#endif
|
||||
|
||||
static uint32_t( *popcnt )( uint32_t x );
|
||||
#else //defined( _MSC_VER )
|
||||
|
||||
//non MVSC should use builtin implementation
|
||||
|
||||
inline void selectPOPCNT()
|
||||
{
|
||||
}
|
||||
|
||||
#define popcnt __builtin_popcount
|
||||
|
||||
#endif
|
||||
|
||||
namespace Lynx
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static constexpr int64_t CNT_MAX = std::numeric_limits<int64_t>::max() & ~15;
|
||||
|
||||
int32_t clamp( int32_t v, int32_t lo, int32_t hi )
|
||||
{
|
||||
|
@ -526,23 +540,8 @@ private:
|
|||
|
||||
Mikey::Mikey( uint32_t sampleRate ) : mMikey{ std::make_unique<MikeyPimpl>() }, mQueue{ std::make_unique<ActionQueue>() }, mTick{}, mNextTick{}, mSampleRate{ sampleRate }, mSamplesRemainder{}, mTicksPerSample{ 16000000 / mSampleRate, 16000000 % mSampleRate }
|
||||
{
|
||||
selectPOPCNT();
|
||||
enqueueSampling();
|
||||
|
||||
//detecting popcnt availability
|
||||
#ifdef IS_INTEL
|
||||
int info[4];
|
||||
cpuid( info, 1 );
|
||||
if ( ( info[2] & ( (int)1 << 23 ) ) != 0 )
|
||||
{
|
||||
popcnt = &popcnt_intrinsic;
|
||||
}
|
||||
else
|
||||
{
|
||||
popcnt = &popcnt_generic;
|
||||
}
|
||||
#else
|
||||
popcnt = &popcnt_generic;
|
||||
#endif
|
||||
}
|
||||
|
||||
Mikey::~Mikey()
|
||||
|
|
Loading…
Reference in a new issue