Improve _hb_popcount()
Support 128bit type.
This commit is contained in:
parent
7b5ce74047
commit
978ace6fbb
@ -76,7 +76,8 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
|
||||
AM_CONDITIONAL([ENABLE_GTK_DOC], false)
|
||||
])
|
||||
|
||||
# Functions and headers
|
||||
# Types, functions, and headers
|
||||
AC_CHECK_TYPES(unsigned __int128)
|
||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l setlinebuf)
|
||||
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h)
|
||||
|
||||
|
@ -99,7 +99,7 @@ struct ValueFormat : HBUINT16
|
||||
#endif
|
||||
|
||||
inline unsigned int get_len (void) const
|
||||
{ return _hb_popcount32 ((unsigned int) *this); }
|
||||
{ return _hb_popcount ((unsigned int) *this); }
|
||||
inline unsigned int get_size (void) const
|
||||
{ return get_len () * Value::static_size; }
|
||||
|
||||
|
@ -139,7 +139,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||
{
|
||||
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
|
||||
unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
|
||||
unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED);
|
||||
unsigned int global_bit_shift = _hb_popcount (HB_GLYPH_FLAG_DEFINED);
|
||||
|
||||
m.global_mask = global_bit_mask;
|
||||
|
||||
|
@ -323,31 +323,50 @@ typedef const struct _hb_void_t *hb_void_t;
|
||||
#define HB_VOID ((const _hb_void_t *) nullptr)
|
||||
|
||||
/* Return the number of 1 bits in mask. */
|
||||
template <typename T>
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
_hb_popcount32 (uint32_t mask)
|
||||
_hb_popcount (T mask)
|
||||
{
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
return __builtin_popcount (mask);
|
||||
#else
|
||||
/* "HACKMEM 169" */
|
||||
uint32_t y;
|
||||
y = (mask >> 1) &033333333333;
|
||||
y = mask - y - ((y >>1) & 033333333333);
|
||||
return (((y + (y >> 3)) & 030707070707) % 077);
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined(__OPTIMIZE__)
|
||||
if (sizeof (unsigned int) >= sizeof (mask))
|
||||
return __builtin_popcount (mask);
|
||||
|
||||
if (sizeof (unsigned long) >= sizeof (mask))
|
||||
return __builtin_popcountl (mask);
|
||||
|
||||
if (sizeof (unsigned long long) >= sizeof (mask))
|
||||
return __builtin_popcountll (mask);
|
||||
#endif
|
||||
|
||||
if (sizeof (T) <= 4)
|
||||
{
|
||||
/* "HACKMEM 169" */
|
||||
uint32_t y;
|
||||
y = (mask >> 1) &033333333333;
|
||||
y = mask - y - ((y >>1) & 033333333333);
|
||||
return (((y + (y >> 3)) & 030707070707) % 077);
|
||||
}
|
||||
|
||||
if (sizeof (T) == 8)
|
||||
{
|
||||
unsigned int shift = 32;
|
||||
return _hb_popcount<uint32_t> ((uint32_t) mask) + _hb_popcount ((uint32_t) (mask >> shift));
|
||||
}
|
||||
|
||||
if (sizeof (T) == 16)
|
||||
{
|
||||
unsigned int shift = 64;
|
||||
return _hb_popcount<uint64_t> ((uint64_t) mask) + _hb_popcount ((uint64_t) (mask >> shift));
|
||||
}
|
||||
|
||||
unsigned int count = 0;
|
||||
while (mask)
|
||||
{
|
||||
count += _hb_popcount<uint64_t> ((uint64_t) mask);
|
||||
unsigned int shift = 64;
|
||||
mask = (T) (mask >> shift);
|
||||
}
|
||||
}
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
_hb_popcount64 (uint64_t mask)
|
||||
{
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
if (sizeof (long) >= sizeof (mask))
|
||||
return __builtin_popcountl (mask);
|
||||
#endif
|
||||
return _hb_popcount32 (mask & 0xFFFFFFFF) + _hb_popcount32 (mask >> 32);
|
||||
}
|
||||
template <typename T> static inline unsigned int _hb_popcount (T mask);
|
||||
template <> inline unsigned int _hb_popcount<uint32_t> (uint32_t mask) { return _hb_popcount32 (mask); }
|
||||
template <> inline unsigned int _hb_popcount<uint64_t> (uint64_t mask) { return _hb_popcount64 (mask); }
|
||||
|
||||
/* Returns the number of bits needed to store number */
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
|
Loading…
Reference in New Issue
Block a user