diff mbox series

[8/8] asm-generic: simplify unaligned.h

Message ID 20230522122238.4191762-9-jens.wiklander@linaro.org (mailing list archive)
State New, archived
Headers show
Series Cleanup unaligned access macros | expand

Commit Message

Jens Wiklander May 22, 2023, 12:22 p.m. UTC
The get_unaligned()/put_unaligned() implementations are more
complex than necessary.

Move everything into one file and use a more compact implementation based
on packed struct access and byte swapping macros.

This patch is based on the Linux kernel commit 803f4e1eab7a
("asm-generic: simplify asm/unaligned.h") by Arnd Bergmann.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
---
 include/asm-generic/unaligned.h | 89 +++++++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
index 3d33a5a063e8..9e5d93ec3041 100644
--- a/include/asm-generic/unaligned.h
+++ b/include/asm-generic/unaligned.h
@@ -1,24 +1,81 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _GENERIC_UNALIGNED_H
 #define _GENERIC_UNALIGNED_H
 
 #include <asm/byteorder.h>
 
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-/*
- * Select endianness
- */
-#if defined(__LITTLE_ENDIAN)
-#define get_unaligned	__get_unaligned_le
-#define put_unaligned	__put_unaligned_le
-#elif defined(__BIG_ENDIAN)
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-#else
-#error invalid endian
-#endif
+#define __get_unaligned_t(type, ptr) ({						\
+	const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);	\
+	__pptr->x;								\
+})
+
+#define __put_unaligned_t(type, val, ptr) do {					\
+	struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);		\
+	__pptr->x = (val);							\
+} while (0)
+
+#define get_unaligned(ptr)	__get_unaligned_t(typeof(*(ptr)), (ptr))
+#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+	return le16_to_cpu(__get_unaligned_t(__le16, p));
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+	return le32_to_cpu(__get_unaligned_t(__le32, p));
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+	return le64_to_cpu(__get_unaligned_t(__le64, p));
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+	__put_unaligned_t(__le16, cpu_to_le16(val), p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+	__put_unaligned_t(__le32, cpu_to_le32(val), p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+	__put_unaligned_t(__le64, cpu_to_le64(val), p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+	return be16_to_cpu(__get_unaligned_t(__be16, p));
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+	return be32_to_cpu(__get_unaligned_t(__be32, p));
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+	return be64_to_cpu(__get_unaligned_t(__be64, p));
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+	__put_unaligned_t(__be16, cpu_to_be16(val), p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+	__put_unaligned_t(__be32, cpu_to_be32(val), p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+	__put_unaligned_t(__be64, cpu_to_be64(val), p);
+}
 
 /* Allow unaligned memory access */
 void allow_unaligned(void);