Skip to content

Commit e8864db

Browse files
mattst88tonycoz
authored andcommitted
Clean up U8TO*_LE macro implementations
The code guarded by #ifndef U32_ALIGNMENT_REQUIRED attempts to optimize byte-swapping by doing unaligned loads, but accessing data through unaligned pointers is undefined behavior in C. Moreover, compilers are more than capable of recognizing these open-coded byte-swap patterns and emitting a bswap instruction, or an unaligned load instruction, or a combined load, etc. There's no need for multiple paths to attain the desired result. See https://rt.perl.org/Ticket/Display.html?id=133495
1 parent ee9ac1c commit e8864db

File tree

3 files changed

+12
-106
lines changed

3 files changed

+12
-106
lines changed

hv_macro.h

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#endif
77

88
/*-----------------------------------------------------------------------------
9-
* Endianess, misalignment capabilities and util macros
9+
* Endianess and util macros
1010
*
1111
* The following 3 macros are defined in this section. The other macros defined
1212
* are only needed to help derive these 3.
@@ -20,29 +20,22 @@
2020
* ROTR64(x,r) Rotate x right by r bits
2121
*/
2222

23-
#ifndef U32_ALIGNMENT_REQUIRED
23+
#ifndef U8TO16_LE
2424
#if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678)
25-
#define U8TO16_LE(ptr) (*((const U16*)(ptr)))
26-
#define U8TO32_LE(ptr) (*((const U32*)(ptr)))
27-
#define U8TO64_LE(ptr) (*((const U64*)(ptr)))
25+
#define U8TO16_LE(ptr) ((U32)(ptr)[1]|(U32)(ptr)[0]<<8)
26+
#define U8TO32_LE(ptr) ((U32)(ptr)[3]|(U32)(ptr)[2]<<8|(U32)(ptr)[1]<<16|(U32)(ptr)[0]<<24)
27+
#define U8TO64_LE(ptr) ((U64)(ptr)[7]|(U64)(ptr)[6]<<8|(U64)(ptr)[5]<<16|(U64)(ptr)[4]<<24|\
28+
(U64)(ptr)[3]<<32|(U64)(ptr)[4]<<40|\
29+
(U64)(ptr)[1]<<48|(U64)(ptr)[0]<<56)
2830
#elif (BYTEORDER == 0x4321 || BYTEORDER == 0x87654321)
29-
#if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
30-
#define U8TO16_LE(ptr) (__builtin_bswap16(*((U16*)(ptr))))
31-
#define U8TO32_LE(ptr) (__builtin_bswap32(*((U32*)(ptr))))
32-
#define U8TO64_LE(ptr) (__builtin_bswap64(*((U64*)(ptr))))
33-
#endif
31+
#define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8)
32+
#define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24)
33+
#define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\
34+
(U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\
35+
(U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56)
3436
#endif
3537
#endif
3638

37-
#ifndef U8TO16_LE
38-
/* Without a known fast bswap32 we're just as well off doing this */
39-
#define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8)
40-
#define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24)
41-
#define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\
42-
(U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\
43-
(U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56)
44-
#endif
45-
4639
#ifdef CAN64BITHASH
4740
#ifndef U64TYPE
4841
/* This probably isn't going to work, but failing with a compiler error due to

stadtx_hash.h

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -43,58 +43,6 @@
4343
#define STMT_END while(0)
4444
#endif
4545

46-
#ifndef STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
47-
/* STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN only matters if nothing has defined U8TO64_LE etc,
48-
* and when built with Perl these should be defined before this file is loaded.
49-
*/
50-
#ifdef U32_ALIGNMENT_REQUIRED
51-
#define STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 0
52-
#else
53-
#define STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 1
54-
#endif
55-
#endif
56-
57-
#ifndef U8TO64_LE
58-
#if STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
59-
#define U8TO64_LE(ptr) (*((const U64 *)(ptr)))
60-
#else
61-
#define U8TO64_LE(ptr) (\
62-
(U64)(ptr)[7] << 56 | \
63-
(U64)(ptr)[6] << 48 | \
64-
(U64)(ptr)[5] << 40 | \
65-
(U64)(ptr)[4] << 32 | \
66-
(U64)(ptr)[3] << 24 | \
67-
(U64)(ptr)[2] << 16 | \
68-
(U64)(ptr)[1] << 8 | \
69-
(U64)(ptr)[0] \
70-
)
71-
#endif
72-
#endif
73-
74-
#ifndef U8TO32_LE
75-
#if STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
76-
#define U8TO32_LE(ptr) (*((const U32 *)(ptr)))
77-
#else
78-
#define U8TO32_LE(ptr) (\
79-
(U32)(ptr)[3] << 24 | \
80-
(U32)(ptr)[2] << 16 | \
81-
(U32)(ptr)[1] << 8 | \
82-
(U32)(ptr)[0] \
83-
)
84-
#endif
85-
#endif
86-
87-
#ifndef U8TO16_LE
88-
#if STADTX_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
89-
#define U8TO16_LE(ptr) (*((const U16 *)(ptr)))
90-
#else
91-
#define U8TO16_LE(ptr) (\
92-
(U16)(ptr)[1] << 8 | \
93-
(U16)(ptr)[0] \
94-
)
95-
#endif
96-
#endif
97-
9846
/* Find best way to ROTL32/ROTL64 */
9947
#if defined(_MSC_VER)
10048
#include <stdlib.h> /* Microsoft put _rotl declaration in here */

zaphod32_hash.h

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -74,41 +74,6 @@
7474
#define STMT_END while(0)
7575
#endif
7676

77-
#ifndef ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
78-
/* ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN only matters if nothing has defined U8TO64_LE etc,
79-
* and when built with Perl these should be defined before this file is loaded.
80-
*/
81-
#ifdef U32_ALIGNMENT_REQUIRED
82-
#define ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 0
83-
#else
84-
#define ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 1
85-
#endif
86-
#endif
87-
88-
#ifndef U8TO32_LE
89-
#if ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
90-
#define U8TO32_LE(ptr) (*((const U32 *)(ptr)))
91-
#else
92-
#define U8TO32_LE(ptr) (\
93-
(U32)(ptr)[3] << 24 | \
94-
(U32)(ptr)[2] << 16 | \
95-
(U32)(ptr)[1] << 8 | \
96-
(U32)(ptr)[0] \
97-
)
98-
#endif
99-
#endif
100-
101-
#ifndef U8TO16_LE
102-
#if ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN
103-
#define U8TO16_LE(ptr) (*((const U16 *)(ptr)))
104-
#else
105-
#define U8TO16_LE(ptr) (\
106-
(U16)(ptr)[1] << 8 | \
107-
(U16)(ptr)[0] \
108-
)
109-
#endif
110-
#endif
111-
11277
/* This is two marsaglia xor-shift permutes, with a prime-multiple
11378
* sandwiched inside. The end result of doing this twice with different
11479
* primes is a completely avalanched v. */

0 commit comments

Comments
 (0)