Also use MSVC intrinsics for bit scanning (up to 2x as fast on 64-bit systems)

This commit is contained in:
rdb 2014-10-31 17:05:10 +00:00
parent 10a72e595b
commit 2c4fbf08be
2 changed files with 28 additions and 6 deletions

View File

@ -145,7 +145,10 @@ flood_bits_up(PN_uint64 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_lowest_on_bit(PN_uint16 x) {
#ifdef __GNUC__
#if defined(_MSC_VER)
unsigned long result;
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return __builtin_ffs((unsigned int) x) - 1;
#else
if (x == 0) {
@ -164,7 +167,10 @@ get_lowest_on_bit(PN_uint16 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_lowest_on_bit(PN_uint32 x) {
#ifdef __GNUC__
#if defined(_MSC_VER)
unsigned long result;
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return __builtin_ffs((unsigned int) x) - 1;
#else
if (x == 0) {
@ -183,7 +189,10 @@ get_lowest_on_bit(PN_uint32 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_lowest_on_bit(PN_uint64 x) {
#ifdef __GNUC__
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long result;
return (_BitScanForward64(&result, (unsigned __int64) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return __builtin_ffsll((unsigned long long) x) - 1;
#else
if (x == 0) {
@ -202,7 +211,10 @@ get_lowest_on_bit(PN_uint64 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_highest_on_bit(PN_uint16 x) {
#ifdef __GNUC__
#if defined(_MSC_VER)
unsigned long result;
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
#else
PN_uint16 w = flood_bits_down(x);
@ -217,7 +229,10 @@ get_highest_on_bit(PN_uint16 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_highest_on_bit(PN_uint32 x) {
#ifdef __GNUC__
#if defined(_MSC_VER)
unsigned long result;
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
#else
PN_uint32 w = flood_bits_down(x);
@ -232,7 +247,10 @@ get_highest_on_bit(PN_uint32 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_highest_on_bit(PN_uint64 x) {
#ifdef __GNUC__
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long result;
return (_BitScanReverse64(&result, (unsigned __int64) x) == 0) ? -1 : result;
#elif defined(__GNUC__)
return (x == 0) ? -1 : 63 - __builtin_clzll((unsigned long long) x);
#else
PN_uint64 w = flood_bits_down(x);

View File

@ -18,6 +18,10 @@
#include "pandabase.h"
#include "numeric_types.h"
#ifdef _MSC_VER
#include <intrin.h>
#endif
////////////////////////////////////////////////////////////////////
// This file defines a few low-level bit-operation routines, optimized
// all to heck.