@@ -36,7 +36,11 @@ inline uint64_t SafeLoadUpTo8Bytes(const uint8_t* bytes, int num_bytes) {
3636 } else {
3737 uint64_t word = 0 ;
3838 for (int i = 0 ; i < num_bytes; ++i) {
39+ #if ARROW_LITTLE_ENDIAN
3940 word |= static_cast <uint64_t >(bytes[i]) << (8 * i);
41+ #else
42+ word |= static_cast <uint64_t >(bytes[i]) << (8 * (num_bytes - 1 - i));
43+ #endif
4044 }
4145 return word;
4246 }
@@ -47,16 +51,13 @@ inline void SafeStoreUpTo8Bytes(uint8_t* bytes, int num_bytes, uint64_t value) {
4751 if (num_bytes == 8 ) {
4852 util::SafeStore (reinterpret_cast <uint64_t *>(bytes), value);
4953 } else {
50- #if ARROW_LITTLE_ENDIAN
5154 for (int i = 0 ; i < num_bytes; ++i) {
55+ #if ARROW_LITTLE_ENDIAN
5256 bytes[i] = static_cast <uint8_t >(value >> (8 * i));
53- }
5457#else
55- // Big-endian: most significant byte first
56- for (int i = 0 ; i < num_bytes; ++i) {
5758 bytes[i] = static_cast <uint8_t >(value >> (8 * (num_bytes - 1 - i)));
58- }
5959#endif
60+ }
6061 }
6162}
6263
@@ -102,6 +103,9 @@ void bits_to_indexes_internal(int64_t hardware_flags, const int num_bits,
102103 *num_indexes = 0 ;
103104 for (int i = 0 ; i < num_bits / unroll; ++i) {
104105 uint64_t word = util::SafeLoad (&reinterpret_cast <const uint64_t *>(bits)[i]);
106+ #if !ARROW_LITTLE_ENDIAN
107+ word = ::arrow::bit_util::ByteSwap (word);
108+ #endif
105109 if (bit_to_search == 0 ) {
106110 word = ~word;
107111 }
@@ -117,21 +121,9 @@ void bits_to_indexes_internal(int64_t hardware_flags, const int num_bits,
117121 // Optionally process the last partial word with masking out bits outside range
118122 if (tail) {
119123 const uint8_t * bits_tail = bits + (num_bits - tail) / 8 ;
120- #if ARROW_LITTLE_ENDIAN
121124 uint64_t word = SafeLoadUpTo8Bytes (bits_tail, (tail + 7 ) / 8 );
122- #else
123- int tail_bytes = (tail + 7 ) / 8 ;
124- uint64_t word;
125- if (tail_bytes == 8 ) {
126- word = util::SafeLoad (reinterpret_cast <const uint64_t *>(bits_tail));
127- } else {
128- // For bit manipulation, always load into least significant bits
129- // to ensure compatibility with CountTrailingZeros on Big-endian systems
130- word = 0 ;
131- for (int i = 0 ; i < tail_bytes; ++i) {
132- word |= static_cast <uint64_t >(bits_tail[i]) << (8 * i);
133- }
134- }
125+ #if !ARROW_LITTLE_ENDIAN
126+ word = ::arrow::bit_util::ByteSwap (word);
135127#endif
136128 if (bit_to_search == 0 ) {
137129 word = ~word;
@@ -305,6 +297,9 @@ void bytes_to_bits(int64_t hardware_flags, const int num_bits, const uint8_t* by
305297 constexpr int unroll = 8 ;
306298 for (int i = num_processed / unroll; i < num_bits / unroll; ++i) {
307299 uint64_t bytes_next = util::SafeLoad (&reinterpret_cast <const uint64_t *>(bytes)[i]);
300+ #if !ARROW_LITTLE_ENDIAN
301+ bytes_next = ::arrow::bit_util::ByteSwap (bytes_next);
302+ #endif
308303 bytes_next &= 0x0101010101010101ULL ;
309304 bytes_next |= (bytes_next >> 7 ); // Pairs of adjacent output bits in individual bytes
310305 bytes_next |= (bytes_next >> 14 ); // 4 adjacent output bits in individual bytes
@@ -313,16 +308,9 @@ void bytes_to_bits(int64_t hardware_flags, const int num_bits, const uint8_t* by
313308 }
314309 int tail = num_bits % unroll;
315310 if (tail) {
316- uint64_t bytes_next;
317- #if ARROW_LITTLE_ENDIAN
318- bytes_next = SafeLoadUpTo8Bytes (bytes + num_bits - tail, tail);
319- #else
320- // On Big-endian systems, for bytes_to_bits, load all tail bytes in little-endian
321- // order to ensure compatibility with subsequent bit operations
322- bytes_next = 0 ;
323- for (int i = 0 ; i < tail; ++i) {
324- bytes_next |= static_cast <uint64_t >((bytes + num_bits - tail)[i]) << (8 * i);
325- }
311+ uint64_t bytes_next = SafeLoadUpTo8Bytes (bytes + num_bits - tail, tail);
312+ #if !ARROW_LITTLE_ENDIAN
313+ bytes_next = ::arrow::bit_util::ByteSwap (bytes_next);
326314#endif
327315 bytes_next &= 0x0101010101010101ULL ;
328316 bytes_next |= (bytes_next >> 7 ); // Pairs of adjacent output bits in individual bytes
0 commit comments