diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2020-12-09 15:48:09 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2020-12-09 16:06:52 +0000 |
commit | b8a651df4782d790130c73e8c5fe70154ff7e11b (patch) | |
tree | 7ff91dbf5b5bba5a901d158a72038a979a2db799 /gtk/gtkpopcountprivate.h | |
parent | c5dd34344f0c660ceffffb3bf9da43c263db16e1 (diff) | |
download | gtk+-b8a651df4782d790130c73e8c5fe70154ff7e11b.tar.gz |
Share the popcount() fallback for MSVC
We use __builtin_popcount() in a couple of places, so it makes sense to
have it in one header.
Diffstat (limited to 'gtk/gtkpopcountprivate.h')
-rw-r--r-- | gtk/gtkpopcountprivate.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/gtk/gtkpopcountprivate.h b/gtk/gtkpopcountprivate.h new file mode 100644 index 0000000000..8a99dd2b26 --- /dev/null +++ b/gtk/gtkpopcountprivate.h @@ -0,0 +1,42 @@ +/* gtkpopcountprivate.h: Private implementation of popcount + * + * Copyright 2020 GNOME Foundation + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#if defined(_MSC_VER) +#include <intrin.h> + +static inline guint +gtk_popcount (guint32 value) +{ + return __popcnt (value); +} +#elif defined(__GNUC__) || defined(__clang__) +# define gtk_popcount(v) __builtin_popcount(v) +#else +static inline guint +gtk_popcount (guint32 value) +{ + /* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */ + return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) + + ((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) + + (((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f); +} +#endif |