|
4 | 4 | #include "pycore_strhex.h" // _Py_strhex_with_sep() |
5 | 5 | #include "pycore_unicodeobject.h" // _PyUnicode_CheckConsistency() |
6 | 6 |
|
| 7 | +/* Scalar hexlify: convert len bytes to 2*len hex characters. |
| 8 | + Uses table lookup via Py_hexdigits for the conversion. */ |
| 9 | +static inline void |
| 10 | +_Py_hexlify_scalar(const unsigned char *src, Py_UCS1 *dst, Py_ssize_t len) |
| 11 | +{ |
| 12 | + for (Py_ssize_t i = 0; i < len; i++) { |
| 13 | + unsigned char c = src[i]; |
| 14 | + *dst++ = Py_hexdigits[c >> 4]; |
| 15 | + *dst++ = Py_hexdigits[c & 0x0f]; |
| 16 | + } |
| 17 | +} |
| 18 | + |
7 | 19 | /* Portable SIMD optimization for hexlify using GCC/Clang vector extensions. |
8 | 20 | Uses __builtin_shufflevector for portable interleave that compiles to |
9 | 21 | native SIMD instructions (SSE2 punpcklbw/punpckhbw on x86-64, |
@@ -87,13 +99,7 @@ _Py_hexlify_simd(const unsigned char *src, Py_UCS1 *dst, Py_ssize_t len) |
87 | 99 | } |
88 | 100 |
|
89 | 101 | /* Scalar fallback for remaining 0-15 bytes */ |
90 | | - for (; i < len; i++, dst += 2) { |
91 | | - unsigned int c = src[i]; |
92 | | - unsigned int h = c >> 4; |
93 | | - unsigned int l = c & 0x0f; |
94 | | - dst[0] = (Py_UCS1)(h + '0' + (h > 9) * ('a' - '0' - 10)); |
95 | | - dst[1] = (Py_UCS1)(l + '0' + (l > 9) * ('a' - '0' - 10)); |
96 | | - } |
| 102 | + _Py_hexlify_scalar(src + i, dst, len - i); |
97 | 103 | } |
98 | 104 |
|
99 | 105 | #endif /* PY_HEXLIFY_CAN_COMPILE_SIMD */ |
@@ -184,11 +190,7 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, |
184 | 190 | else |
185 | 191 | #endif |
186 | 192 | { |
187 | | - for (i = j = 0; i < arglen; ++i) { |
188 | | - c = argbuf[i]; |
189 | | - retbuf[j++] = Py_hexdigits[c >> 4]; |
190 | | - retbuf[j++] = Py_hexdigits[c & 0x0f]; |
191 | | - } |
| 193 | + _Py_hexlify_scalar((const unsigned char *)argbuf, retbuf, arglen); |
192 | 194 | } |
193 | 195 | } |
194 | 196 | else { |
|
0 commit comments