Skip to content

Commit ed16b18

Browse files
committed
rework U8TOxx_LE macros to force unsigned access
This introduces a _shifted_octet() utility macro to make things more clear, it also adds support for USE_UNALIGNED_PTR_DEREF for little-endian platforms that allow unaligned access. This must be manually defined and ONLY affects little endian builds currently, and is there primarily for -g builds on x86 (eg for perl developers themselves).
1 parent 783bd73 commit ed16b18

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

hv_macro.h

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
#define CAN64BITHASH
66
#endif
77

8+
#ifdef CAN64BITHASH
9+
#ifndef U64TYPE
10+
/* This probably isn't going to work, but failing with a compiler error due to
11+
lack of uint64_t is no worse than failing right now with an #error. */
12+
#define U64 uint64_t
13+
#endif
14+
#endif
15+
16+
817
/*-----------------------------------------------------------------------------
918
* Endianess and util macros
1019
*
@@ -21,26 +30,47 @@
2130
*/
2231

2332
#ifndef U8TO16_LE
33+
#define _shifted_octet(type,ptr,idx,shift) (((type)(((U8*)ptr)[idx]))<<shift)
2434
#if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678)
25-
#define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8)
26-
#define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24)
27-
#define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\
28-
(U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\
29-
(U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56)
35+
#ifdef USE_UNALIGNED_PTR_DEREF
36+
#define U8TO16_LE(ptr) (*((const U16*)(ptr)))
37+
#define U8TO32_LE(ptr) (*((const U32*)(ptr)))
38+
#define U8TO64_LE(ptr) (*((const U64*)(ptr)))
39+
#else
40+
#define U8TO16_LE(ptr) (_shifted_octet(U16,ptr,0, 0)|\
41+
_shifted_octet(U16,ptr,1, 8))
42+
43+
#define U8TO32_LE(ptr) (_shifted_octet(U32,ptr,0, 0)|\
44+
_shifted_octet(U32,ptr,1, 8)|\
45+
_shifted_octet(U32,ptr,2,16)|\
46+
_shifted_octet(U32,ptr,3,24))
47+
48+
#define U8TO64_LE(ptr) (_shifted_octet(U64,ptr,0, 0)|\
49+
_shifted_octet(U64,ptr,1, 8)|\
50+
_shifted_octet(U64,ptr,2,16)|\
51+
_shifted_octet(U64,ptr,3,24)|\
52+
_shifted_octet(U64,ptr,4,32)|\
53+
_shifted_octet(U64,ptr,5,40)|\
54+
_shifted_octet(U64,ptr,6,48)|\
55+
_shifted_octet(U64,ptr,7,56))
56+
#endif
3057
#elif (BYTEORDER == 0x4321 || BYTEORDER == 0x87654321)
31-
#define U8TO16_LE(ptr) ((U32)(ptr)[1]|(U32)(ptr)[0]<<8)
32-
#define U8TO32_LE(ptr) ((U32)(ptr)[3]|(U32)(ptr)[2]<<8|(U32)(ptr)[1]<<16|(U32)(ptr)[0]<<24)
33-
#define U8TO64_LE(ptr) ((U64)(ptr)[7]|(U64)(ptr)[6]<<8|(U64)(ptr)[5]<<16|(U64)(ptr)[4]<<24|\
34-
(U64)(ptr)[3]<<32|(U64)(ptr)[2]<<40|\
35-
(U64)(ptr)[1]<<48|(U64)(ptr)[0]<<56)
36-
#endif
37-
#endif
58+
#define U8TO16_LE(ptr) (_shifted_octet(U16,ptr,1, 0)|\
59+
_shifted_octet(U16,ptr,0, 8))
3860

39-
#ifdef CAN64BITHASH
40-
#ifndef U64TYPE
41-
/* This probably isn't going to work, but failing with a compiler error due to
42-
lack of uint64_t is no worse than failing right now with an #error. */
43-
#define U64 uint64_t
61+
#define U8TO32_LE(ptr) (_shifted_octet(U32,ptr,3, 0)|\
62+
_shifted_octet(U32,ptr,2, 8)|\
63+
_shifted_octet(U32,ptr,1,16)|\
64+
_shifted_octet(U32,ptr,0,24))
65+
66+
#define U8TO64_LE(ptr) (_shifted_octet(U64,ptr,7, 0)|\
67+
_shifted_octet(U64,ptr,6, 8)|\
68+
_shifted_octet(U64,ptr,5,16)|\
69+
_shifted_octet(U64,ptr,4,24)|\
70+
_shifted_octet(U64,ptr,3,32)|\
71+
_shifted_octet(U64,ptr,2,40)|\
72+
_shifted_octet(U64,ptr,1,48)|\
73+
_shifted_octet(U64,ptr,0,56))
4474
#endif
4575
#endif
4676

0 commit comments

Comments
 (0)