@@ -5014,21 +5014,26 @@ ctz(size_t v)
5014
5014
#endif /* SIZEOF_SIZE_T */
5015
5015
return pos ;
5016
5016
}
5017
+ #else
5018
+ #define HAVE_CTZ 0
5017
5019
#endif
5018
5020
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.
5022
5023
static size_t
5023
5024
load_unaligned (const unsigned char * p , size_t size )
5024
5025
{
5025
- assert (size <= SIZEOF_SIZE_T );
5026
5026
union {
5027
5027
size_t s ;
5028
5028
unsigned char b [SIZEOF_SIZE_T ];
5029
5029
} u ;
5030
5030
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.
5031
5034
switch (size ) {
5035
+ default :
5036
+ #if SIZEOF_SIZE_T == 8
5032
5037
case 8 :
5033
5038
u .b [7 ] = p [7 ];
5034
5039
_Py_FALLTHROUGH ;
@@ -5041,6 +5046,7 @@ load_unaligned(const unsigned char *p, size_t size)
5041
5046
case 5 :
5042
5047
u .b [4 ] = p [4 ];
5043
5048
_Py_FALLTHROUGH ;
5049
+ #endif
5044
5050
case 4 :
5045
5051
u .b [3 ] = p [3 ];
5046
5052
_Py_FALLTHROUGH ;
@@ -5055,8 +5061,6 @@ load_unaligned(const unsigned char *p, size_t size)
5055
5061
break ;
5056
5062
case 0 :
5057
5063
break ;
5058
- default :
5059
- Py_UNREACHABLE ();
5060
5064
}
5061
5065
return u .s ;
5062
5066
}
@@ -5077,20 +5081,20 @@ find_first_nonascii(const unsigned char *start, const unsigned char *end)
5077
5081
5078
5082
if (end - start >= SIZEOF_SIZE_T ) {
5079
5083
const unsigned char * p2 = _Py_ALIGN_UP (p , SIZEOF_SIZE_T );
5084
+ #if PY_LITTLE_ENDIAN && HAVE_CTZ
5080
5085
if (p < p2 ) {
5081
- #if HAVE_CTZ
5082
5086
#if defined(_M_AMD64 ) || defined(_M_IX86 ) || defined(__x86_64__ ) || defined(__i386__ )
5083
5087
// x86 and amd64 are little endian and can load unaligned memory.
5084
5088
size_t u = * (const size_t * )p & ASCII_CHAR_MASK ;
5085
5089
#else
5086
5090
size_t u = load_unaligned (p , p2 - p ) & ASCII_CHAR_MASK ;
5087
5091
#endif
5088
5092
if (u ) {
5089
- return p - start + (ctz (u ) - 7 ) / 8 ;
5093
+ return (ctz (u ) - 7 ) / 8 ;
5090
5094
}
5091
5095
p = p2 ;
5092
5096
}
5093
- #else
5097
+ #else /* PY_LITTLE_ENDIAN && HAVE_CTZ */
5094
5098
while (p < p2 ) {
5095
5099
if (* p & 0x80 ) {
5096
5100
return p - start ;
@@ -5113,7 +5117,7 @@ find_first_nonascii(const unsigned char *start, const unsigned char *end)
5113
5117
p += SIZEOF_SIZE_T ;
5114
5118
}
5115
5119
}
5116
- #if HAVE_CTZ
5120
+ #if PY_LITTLE_ENDIAN && HAVE_CTZ
5117
5121
// we can not use *(const size_t*)p to avoid buffer overrun.
5118
5122
size_t u = load_unaligned (p , end - p ) & ASCII_CHAR_MASK ;
5119
5123
if (u ) {
0 commit comments