@@ -216,6 +216,80 @@ test_bit_length(PyObject *self, PyObject *Py_UNUSED(args))
216216}
217217
218218
219+ static int
220+ check_rotateright_uintptr (uintptr_t ptr , unsigned int bits , uintptr_t expected )
221+ {
222+ #if SIZEOF_UINTPTR_T == 8
223+ # define FMT "0x%llx"
224+ #else
225+ # define FMT "0x%lx"
226+ #endif
227+
228+ // Use volatile to prevent the compiler to optimize out the whole test
229+ volatile uintptr_t x = ptr ;
230+ uintptr_t y = _Py_rotateright_uintptr (x , bits );
231+ if (y != expected ) {
232+ PyErr_Format (PyExc_AssertionError ,
233+ "_Py_rotateright_uintptr(" FMT ", %u) returns " FMT ", expected " FMT ,
234+ x , bits , y , expected );
235+ return -1 ;
236+ }
237+ return 0 ;
238+
239+ #undef FMT
240+ }
241+
242+
243+ static PyObject *
244+ test_rotateright_uintptr (PyObject * self , PyObject * Py_UNUSED (args ))
245+ {
246+ #define CHECK (X , BITS , EXPECTED ) \
247+ do { \
248+ if (check_rotateright_uintptr(X, BITS, EXPECTED) < 0) { \
249+ return NULL; \
250+ } \
251+ } while (0)
252+
253+ // Test _Py_rotateright_uintptr()
254+ #if SIZEOF_UINTPTR_T == 8
255+ CHECK (UINT64_C (0x1234567890ABCDEF ), 4 , UINT64_C (0xF1234567890ABCDE ));
256+ CHECK (UINT64_C (0x1234567890ABCDEF ), 8 , UINT64_C (0xEF1234567890ABCD ));
257+ CHECK (UINT64_C (0x1234567890ABCDEF ), 12 , UINT64_C (0xDEF1234567890ABC ));
258+ CHECK (UINT64_C (0x1234567890ABCDEF ), 16 , UINT64_C (0xCDEF1234567890AB ));
259+ CHECK (UINT64_C (0x1234567890ABCDEF ), 20 , UINT64_C (0xBCDEF1234567890A ));
260+ CHECK (UINT64_C (0x1234567890ABCDEF ), 24 , UINT64_C (0xABCDEF1234567890 ));
261+ CHECK (UINT64_C (0x1234567890ABCDEF ), 28 , UINT64_C (0x0ABCDEF123456789 ));
262+ CHECK (UINT64_C (0x1234567890ABCDEF ), 32 , UINT64_C (0x90ABCDEF12345678 ));
263+ CHECK (UINT64_C (0x1234567890ABCDEF ), 36 , UINT64_C (0x890ABCDEF1234567 ));
264+ CHECK (UINT64_C (0x1234567890ABCDEF ), 40 , UINT64_C (0x7890ABCDEF123456 ));
265+ CHECK (UINT64_C (0x1234567890ABCDEF ), 44 , UINT64_C (0x67890ABCDEF12345 ));
266+ CHECK (UINT64_C (0x1234567890ABCDEF ), 48 , UINT64_C (0x567890ABCDEF1234 ));
267+ CHECK (UINT64_C (0x1234567890ABCDEF ), 52 , UINT64_C (0x4567890ABCDEF123 ));
268+ CHECK (UINT64_C (0x1234567890ABCDEF ), 56 , UINT64_C (0x34567890ABCDEF12 ));
269+ CHECK (UINT64_C (0x1234567890ABCDEF ), 60 , UINT64_C (0x234567890ABCDEF1 ));
270+
271+ CHECK (UINT64_C (0xFEE4ABEDD1CECA5E ), 4 , UINT64_C (0xEFEE4ABEDD1CECA5 ));
272+ CHECK (UINT64_C (0xFEE4ABEDD1CECA5E ), 32 , UINT64_C (0xD1CECA5EFEE4ABED ));
273+ #elif SIZEOF_UINTPTR_T == 4
274+ CHECK (UINT32_C (0x12345678 ), 4 , UINT32_C (0x81234567 ));
275+ CHECK (UINT32_C (0x12345678 ), 8 , UINT32_C (0x78123456 ));
276+ CHECK (UINT32_C (0x12345678 ), 12 , UINT32_C (0x67812345 ));
277+ CHECK (UINT32_C (0x12345678 ), 16 , UINT32_C (0x56781234 ));
278+ CHECK (UINT32_C (0x12345678 ), 20 , UINT32_C (0x45678123 ));
279+ CHECK (UINT32_C (0x12345678 ), 24 , UINT32_C (0x34567812 ));
280+ CHECK (UINT32_C (0x12345678 ), 28 , UINT32_C (0x23456781 ));
281+
282+ CHECK (UINT32_C (0xDEADCAFE ), 4 , UINT32_C (0xEDEADCAF ));
283+ CHECK (UINT32_C (0xDEADCAFE ), 16 , UINT32_C (0xCAFEDEAD ));
284+ #else
285+ # error "unsupported uintptr_t size"
286+ #endif
287+ Py_RETURN_NONE ;
288+
289+ #undef CHECK
290+ }
291+
292+
219293#define TO_PTR (ch ) ((void*)(uintptr_t)ch)
220294#define FROM_PTR (ptr ) ((uintptr_t)ptr)
221295#define VALUE (key ) (1 + ((int)(key) - 'a'))
@@ -1614,6 +1688,7 @@ static PyMethodDef module_functions[] = {
16141688 {"test_bswap" , test_bswap , METH_NOARGS },
16151689 {"test_popcount" , test_popcount , METH_NOARGS },
16161690 {"test_bit_length" , test_bit_length , METH_NOARGS },
1691+ {"test_rotateright_uintptr" , test_rotateright_uintptr , METH_NOARGS },
16171692 {"test_hashtable" , test_hashtable , METH_NOARGS },
16181693 {"get_config" , test_get_config , METH_NOARGS },
16191694 {"set_config" , test_set_config , METH_O },
0 commit comments