|
12 | 12 | #define PY_SSIZE_T_CLEAN
|
13 | 13 |
|
14 | 14 | #include "Python.h"
|
15 |
| -#include "pycore_byteswap.h" // _Py_bswap32() |
| 15 | +#include "pycore_bitutils.h" // _Py_bswap32() |
16 | 16 | #include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
17 | 17 | #include "pycore_hashtable.h" // _Py_hashtable_new()
|
18 | 18 | #include "pycore_gc.h" // PyGC_Head
|
@@ -63,6 +63,45 @@ test_bswap(PyObject *self, PyObject *Py_UNUSED(args))
|
63 | 63 | }
|
64 | 64 |
|
65 | 65 |
|
| 66 | +static int |
| 67 | +check_popcount(uint32_t x, int expected) |
| 68 | +{ |
| 69 | + // Use volatile to prevent the compiler to optimize out the whole test |
| 70 | + volatile uint32_t u = x; |
| 71 | + int bits = _Py_popcount32(u); |
| 72 | + if (bits != expected) { |
| 73 | + PyErr_Format(PyExc_AssertionError, |
| 74 | + "_Py_popcount32(%lu) returns %i, expected %i", |
| 75 | + (unsigned long)x, bits, expected); |
| 76 | + return -1; |
| 77 | + } |
| 78 | + return 0; |
| 79 | +} |
| 80 | + |
| 81 | + |
| 82 | +static PyObject* |
| 83 | +test_popcount(PyObject *self, PyObject *Py_UNUSED(args)) |
| 84 | +{ |
| 85 | +#define CHECK(X, RESULT) \ |
| 86 | + do { \ |
| 87 | + if (check_popcount(X, RESULT) < 0) { \ |
| 88 | + return NULL; \ |
| 89 | + } \ |
| 90 | + } while (0) |
| 91 | + |
| 92 | + CHECK(0, 0); |
| 93 | + CHECK(1, 1); |
| 94 | + CHECK(0x08080808, 4); |
| 95 | + CHECK(0x10101010, 4); |
| 96 | + CHECK(0x10204080, 4); |
| 97 | + CHECK(0xDEADCAFE, 22); |
| 98 | + CHECK(0xFFFFFFFF, 32); |
| 99 | + Py_RETURN_NONE; |
| 100 | + |
| 101 | +#undef CHECK |
| 102 | +} |
| 103 | + |
| 104 | + |
66 | 105 | #define TO_PTR(ch) ((void*)(uintptr_t)ch)
|
67 | 106 | #define FROM_PTR(ptr) ((uintptr_t)ptr)
|
68 | 107 | #define VALUE(key) (1 + ((int)(key) - 'a'))
|
@@ -157,6 +196,7 @@ static PyMethodDef TestMethods[] = {
|
157 | 196 | {"get_configs", get_configs, METH_NOARGS},
|
158 | 197 | {"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
159 | 198 | {"test_bswap", test_bswap, METH_NOARGS},
|
| 199 | + {"test_popcount", test_popcount, METH_NOARGS}, |
160 | 200 | {"test_hashtable", test_hashtable, METH_NOARGS},
|
161 | 201 | {NULL, NULL} /* sentinel */
|
162 | 202 | };
|
|
0 commit comments