mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
bpo-29882: Add _Py_popcount32() function (GH-20518)
* Rename pycore_byteswap.h to pycore_bitutils.h. * Move popcount_digit() to pycore_bitutils.h as _Py_popcount32(). * _Py_popcount32() uses GCC and clang builtin function if available. * Add unit tests to _Py_popcount32().
This commit is contained in:
parent
301f0d4ff9
commit
c6b292cdee
11 changed files with 108 additions and 39 deletions
|
@ -12,7 +12,7 @@
|
|||
#define PY_SSIZE_T_CLEAN
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
#include "pycore_bitutils.h" // _Py_bswap32()
|
||||
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
||||
#include "pycore_hashtable.h" // _Py_hashtable_new()
|
||||
#include "pycore_gc.h" // PyGC_Head
|
||||
|
@ -63,6 +63,45 @@ test_bswap(PyObject *self, PyObject *Py_UNUSED(args))
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
check_popcount(uint32_t x, int expected)
|
||||
{
|
||||
// Use volatile to prevent the compiler to optimize out the whole test
|
||||
volatile uint32_t u = x;
|
||||
int bits = _Py_popcount32(u);
|
||||
if (bits != expected) {
|
||||
PyErr_Format(PyExc_AssertionError,
|
||||
"_Py_popcount32(%lu) returns %i, expected %i",
|
||||
(unsigned long)x, bits, expected);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
test_popcount(PyObject *self, PyObject *Py_UNUSED(args))
|
||||
{
|
||||
#define CHECK(X, RESULT) \
|
||||
do { \
|
||||
if (check_popcount(X, RESULT) < 0) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
CHECK(0, 0);
|
||||
CHECK(1, 1);
|
||||
CHECK(0x08080808, 4);
|
||||
CHECK(0x10101010, 4);
|
||||
CHECK(0x10204080, 4);
|
||||
CHECK(0xDEADCAFE, 22);
|
||||
CHECK(0xFFFFFFFF, 32);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
|
||||
#define TO_PTR(ch) ((void*)(uintptr_t)ch)
|
||||
#define FROM_PTR(ptr) ((uintptr_t)ptr)
|
||||
#define VALUE(key) (1 + ((int)(key) - 'a'))
|
||||
|
@ -157,6 +196,7 @@ static PyMethodDef TestMethods[] = {
|
|||
{"get_configs", get_configs, METH_NOARGS},
|
||||
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
||||
{"test_bswap", test_bswap, METH_NOARGS},
|
||||
{"test_popcount", test_popcount, METH_NOARGS},
|
||||
{"test_hashtable", test_hashtable, METH_NOARGS},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue