Merge pull request #7675 from shawnl/unaligned

Issue #7654 (unaligned loads on sparc64)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2018-01-20 10:00:14 +11:00
committed by GitHub
3 changed files with 30 additions and 40 deletions
+24 -36
View File
@@ -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