1 | /* gtkpopcountprivate.h: Private implementation of popcount |
2 | * |
3 | * Copyright 2020 GNOME Foundation |
4 | * |
5 | * SPDX-License-Identifier: LGPL-2.1-or-later |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
19 | */ |
20 | |
21 | #pragma once |
22 | |
23 | #if (defined(_MSC_VER) && !_M_ARM && !_M_ARM64) && (__AVX__ || __SSE4_2__ || __POPCNT__) |
24 | #include <intrin.h> |
25 | |
26 | static inline guint |
27 | gtk_popcount (guint32 value) |
28 | { |
29 | return __popcnt (value); |
30 | } |
31 | #elif defined(__GNUC__) || defined(__clang__) |
32 | #define gtk_popcount(v) __builtin_popcount (v) |
33 | #else |
34 | static inline guint |
35 | gtk_popcount (guint32 value) |
36 | { |
37 | /* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */ |
38 | return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) + |
39 | ((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) + |
40 | (((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f); |
41 | } |
42 | #endif |
43 | |