From 858cb114af3be21b7ba094efd5df65d3869a8ab1 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Sat, 16 Dec 2017 21:44:56 -0800 Subject: [PATCH] unaligned: let gcc generate optimal code on some architectures such as MIPS there are special unaligned load/store sequences, instead of having to do bitwise accesses https://www.linux-mips.org/wiki/Alignment --- src/basic/unaligned.h | 60 +++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/src/basic/unaligned.h b/src/basic/unaligned.h index 201b3d227..73302b423 100644 --- a/src/basic/unaligned.h +++ b/src/basic/unaligned.h @@ -26,89 +26,77 @@ /* BE */ static inline uint16_t unaligned_read_be16(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - return (((uint16_t) u[0]) << 8) | - ((uint16_t) u[1]); + return be16toh(u->x); } static inline uint32_t unaligned_read_be32(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - return (((uint32_t) unaligned_read_be16(u)) << 16) | - ((uint32_t) unaligned_read_be16(u + 2)); + return be32toh(u->x); } static inline uint64_t unaligned_read_be64(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - return (((uint64_t) unaligned_read_be32(u)) << 32) | - ((uint64_t) unaligned_read_be32(u + 4)); + return be64toh(u->x); } static inline void unaligned_write_be16(void *_u, uint16_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - u[0] = (uint8_t) (a >> 8); - u[1] = (uint8_t) a; + u->x = be16toh(a); } static inline void unaligned_write_be32(void *_u, uint32_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - unaligned_write_be16(u, (uint16_t) (a >> 16)); - unaligned_write_be16(u + 2, (uint16_t) a); + u->x = be32toh(a); } static inline void unaligned_write_be64(void *_u, uint64_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - unaligned_write_be32(u, (uint32_t) (a >> 32)); - unaligned_write_be32(u + 4, (uint32_t) a); + u->x = be64toh(a); } /* LE */ static inline uint16_t unaligned_read_le16(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - return (((uint16_t) u[1]) << 8) | - ((uint16_t) u[0]); + return le16toh(u->x); } static inline uint32_t unaligned_read_le32(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | - ((uint32_t) unaligned_read_le16(u)); + return le32toh(u->x); } static inline uint64_t unaligned_read_le64(const void *_u) { - const uint8_t *u = _u; + const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | - ((uint64_t) unaligned_read_le32(u)); + return le64toh(u->x); } static inline void unaligned_write_le16(void *_u, uint16_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u; - u[0] = (uint8_t) a; - u[1] = (uint8_t) (a >> 8); + u->x = le16toh(a); } static inline void unaligned_write_le32(void *_u, uint32_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u; - unaligned_write_le16(u, (uint16_t) a); - unaligned_write_le16(u + 2, (uint16_t) (a >> 16)); + u->x = le32toh(a); } static inline void unaligned_write_le64(void *_u, uint64_t a) { - uint8_t *u = _u; + struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u; - unaligned_write_le32(u, (uint32_t) a); - unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); + u->x = le64toh(a); } #if __BYTE_ORDER == __BIG_ENDIAN -- 2.30.2