summaryrefslogtreecommitdiff
path: root/hv_macro.h
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2019-09-04 21:48:56 -0700
committerTony Cook <tony@develop-help.com>2019-10-08 09:27:43 +1100
commite8864dba80952684bf3afe83438d4eee0c3939a9 (patch)
treeef39f361559ca7cabef294085a643c3742e6d4f5 /hv_macro.h
parentee9ac1cd8eb988fea70841eae211b11355711416 (diff)
downloadperl-e8864dba80952684bf3afe83438d4eee0c3939a9.tar.gz
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
Diffstat (limited to 'hv_macro.h')
-rw-r--r--hv_macro.h31
1 files changed, 12 insertions, 19 deletions
diff --git a/hv_macro.h b/hv_macro.h
index 77a4c84896..02c0baad08 100644
--- a/hv_macro.h
+++ b/hv_macro.h
@@ -6,7 +6,7 @@
#endif
/*-----------------------------------------------------------------------------
- * Endianess, misalignment capabilities and util macros
+ * Endianess and util macros
*
* The following 3 macros are defined in this section. The other macros defined
* are only needed to help derive these 3.
@@ -20,29 +20,22 @@
* ROTR64(x,r) Rotate x right by r bits
*/
-#ifndef U32_ALIGNMENT_REQUIRED
+#ifndef U8TO16_LE
#if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678)
- #define U8TO16_LE(ptr) (*((const U16*)(ptr)))
- #define U8TO32_LE(ptr) (*((const U32*)(ptr)))
- #define U8TO64_LE(ptr) (*((const U64*)(ptr)))
+ #define U8TO16_LE(ptr) ((U32)(ptr)[1]|(U32)(ptr)[0]<<8)
+ #define U8TO32_LE(ptr) ((U32)(ptr)[3]|(U32)(ptr)[2]<<8|(U32)(ptr)[1]<<16|(U32)(ptr)[0]<<24)
+ #define U8TO64_LE(ptr) ((U64)(ptr)[7]|(U64)(ptr)[6]<<8|(U64)(ptr)[5]<<16|(U64)(ptr)[4]<<24|\
+ (U64)(ptr)[3]<<32|(U64)(ptr)[4]<<40|\
+ (U64)(ptr)[1]<<48|(U64)(ptr)[0]<<56)
#elif (BYTEORDER == 0x4321 || BYTEORDER == 0x87654321)
- #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
- #define U8TO16_LE(ptr) (__builtin_bswap16(*((U16*)(ptr))))
- #define U8TO32_LE(ptr) (__builtin_bswap32(*((U32*)(ptr))))
- #define U8TO64_LE(ptr) (__builtin_bswap64(*((U64*)(ptr))))
- #endif
+ #define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8)
+ #define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24)
+ #define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\
+ (U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\
+ (U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56)
#endif
#endif
-#ifndef U8TO16_LE
- /* Without a known fast bswap32 we're just as well off doing this */
- #define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8)
- #define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24)
- #define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\
- (U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\
- (U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56)
-#endif
-
#ifdef CAN64BITHASH
#ifndef U64TYPE
/* This probably isn't going to work, but failing with a compiler error due to