@@ -5014,21 +5014,26 @@ ctz(size_t v)
50145014#endif /* SIZEOF_SIZE_T */
50155015 return pos ;
50165016}
5017+ #else
5018+ #define HAVE_CTZ 0
50175019#endif
50185020
5019- #if HAVE_CTZ
5020- // load p[0]..p[size-1] as a little-endian size_t
5021- // without unaligned access nor read ahead.
5021+ #if HAVE_CTZ && PY_LITTLE_ENDIAN
5022+ // load p[0]..p[size-1] as a size_t without unaligned access nor read ahead.
50225023static size_t
50235024load_unaligned (const unsigned char * p , size_t size )
50245025{
5025- assert (size <= SIZEOF_SIZE_T );
50265026 union {
50275027 size_t s ;
50285028 unsigned char b [SIZEOF_SIZE_T ];
50295029 } u ;
50305030 u .s = 0 ;
5031+ // This switch statement assumes little endian because:
5032+ // * union is faster than bitwise or and shift.
5033+ // * big endian machine is rare and hard to maintain.
50315034 switch (size ) {
5035+ default :
5036+ #if SIZEOF_SIZE_T == 8
50325037 case 8 :
50335038 u .b [7 ] = p [7 ];
50345039 _Py_FALLTHROUGH ;
@@ -5041,6 +5046,7 @@ load_unaligned(const unsigned char *p, size_t size)
50415046 case 5 :
50425047 u .b [4 ] = p [4 ];
50435048 _Py_FALLTHROUGH ;
5049+ #endif
50445050 case 4 :
50455051 u .b [3 ] = p [3 ];
50465052 _Py_FALLTHROUGH ;
@@ -5055,8 +5061,6 @@ load_unaligned(const unsigned char *p, size_t size)
50555061 break ;
50565062 case 0 :
50575063 break ;
5058- default :
5059- Py_UNREACHABLE ();
50605064 }
50615065 return u .s ;
50625066}
@@ -5077,20 +5081,20 @@ find_first_nonascii(const unsigned char *start, const unsigned char *end)
50775081
50785082 if (end - start >= SIZEOF_SIZE_T ) {
50795083 const unsigned char * p2 = _Py_ALIGN_UP (p , SIZEOF_SIZE_T );
5084+ #if PY_LITTLE_ENDIAN && HAVE_CTZ
50805085 if (p < p2 ) {
5081- #if HAVE_CTZ
50825086#if defined(_M_AMD64 ) || defined(_M_IX86 ) || defined(__x86_64__ ) || defined(__i386__ )
50835087 // x86 and amd64 are little endian and can load unaligned memory.
50845088 size_t u = * (const size_t * )p & ASCII_CHAR_MASK ;
50855089#else
50865090 size_t u = load_unaligned (p , p2 - p ) & ASCII_CHAR_MASK ;
50875091#endif
50885092 if (u ) {
5089- return p - start + (ctz (u ) - 7 ) / 8 ;
5093+ return (ctz (u ) - 7 ) / 8 ;
50905094 }
50915095 p = p2 ;
50925096 }
5093- #else
5097+ #else /* PY_LITTLE_ENDIAN && HAVE_CTZ */
50945098 while (p < p2 ) {
50955099 if (* p & 0x80 ) {
50965100 return p - start ;
@@ -5113,7 +5117,7 @@ find_first_nonascii(const unsigned char *start, const unsigned char *end)
51135117 p += SIZEOF_SIZE_T ;
51145118 }
51155119 }
5116- #if HAVE_CTZ
5120+ #if PY_LITTLE_ENDIAN && HAVE_CTZ
51175121 // we can not use *(const size_t*)p to avoid buffer overrun.
51185122 size_t u = load_unaligned (p , end - p ) & ASCII_CHAR_MASK ;
51195123 if (u ) {
0 commit comments