18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _LINUX_UNALIGNED_GENERIC_H
38c2ecf20Sopenharmony_ci#define _LINUX_UNALIGNED_GENERIC_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/types.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/*
88c2ecf20Sopenharmony_ci * Cause a link-time error if we try an unaligned access other than
98c2ecf20Sopenharmony_ci * 1,2,4 or 8 bytes long
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ciextern void __bad_unaligned_access_size(void);
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({			\
148c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
158c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),	\
168c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),	\
178c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),	\
188c2ecf20Sopenharmony_ci	__bad_unaligned_access_size()))));					\
198c2ecf20Sopenharmony_ci	}))
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({			\
228c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
238c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),	\
248c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),	\
258c2ecf20Sopenharmony_ci	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),	\
268c2ecf20Sopenharmony_ci	__bad_unaligned_access_size()))));					\
278c2ecf20Sopenharmony_ci	}))
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define __put_unaligned_le(val, ptr) ({					\
308c2ecf20Sopenharmony_ci	void *__gu_p = (ptr);						\
318c2ecf20Sopenharmony_ci	switch (sizeof(*(ptr))) {					\
328c2ecf20Sopenharmony_ci	case 1:								\
338c2ecf20Sopenharmony_ci		*(u8 *)__gu_p = (__force u8)(val);			\
348c2ecf20Sopenharmony_ci		break;							\
358c2ecf20Sopenharmony_ci	case 2:								\
368c2ecf20Sopenharmony_ci		put_unaligned_le16((__force u16)(val), __gu_p);		\
378c2ecf20Sopenharmony_ci		break;							\
388c2ecf20Sopenharmony_ci	case 4:								\
398c2ecf20Sopenharmony_ci		put_unaligned_le32((__force u32)(val), __gu_p);		\
408c2ecf20Sopenharmony_ci		break;							\
418c2ecf20Sopenharmony_ci	case 8:								\
428c2ecf20Sopenharmony_ci		put_unaligned_le64((__force u64)(val), __gu_p);		\
438c2ecf20Sopenharmony_ci		break;							\
448c2ecf20Sopenharmony_ci	default:							\
458c2ecf20Sopenharmony_ci		__bad_unaligned_access_size();				\
468c2ecf20Sopenharmony_ci		break;							\
478c2ecf20Sopenharmony_ci	}								\
488c2ecf20Sopenharmony_ci	(void)0; })
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define __put_unaligned_be(val, ptr) ({					\
518c2ecf20Sopenharmony_ci	void *__gu_p = (ptr);						\
528c2ecf20Sopenharmony_ci	switch (sizeof(*(ptr))) {					\
538c2ecf20Sopenharmony_ci	case 1:								\
548c2ecf20Sopenharmony_ci		*(u8 *)__gu_p = (__force u8)(val);			\
558c2ecf20Sopenharmony_ci		break;							\
568c2ecf20Sopenharmony_ci	case 2:								\
578c2ecf20Sopenharmony_ci		put_unaligned_be16((__force u16)(val), __gu_p);		\
588c2ecf20Sopenharmony_ci		break;							\
598c2ecf20Sopenharmony_ci	case 4:								\
608c2ecf20Sopenharmony_ci		put_unaligned_be32((__force u32)(val), __gu_p);		\
618c2ecf20Sopenharmony_ci		break;							\
628c2ecf20Sopenharmony_ci	case 8:								\
638c2ecf20Sopenharmony_ci		put_unaligned_be64((__force u64)(val), __gu_p);		\
648c2ecf20Sopenharmony_ci		break;							\
658c2ecf20Sopenharmony_ci	default:							\
668c2ecf20Sopenharmony_ci		__bad_unaligned_access_size();				\
678c2ecf20Sopenharmony_ci		break;							\
688c2ecf20Sopenharmony_ci	}								\
698c2ecf20Sopenharmony_ci	(void)0; })
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic inline u32 __get_unaligned_be24(const u8 *p)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	return p[0] << 16 | p[1] << 8 | p[2];
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic inline u32 get_unaligned_be24(const void *p)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	return __get_unaligned_be24(p);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline u32 __get_unaligned_le24(const u8 *p)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	return p[0] | p[1] << 8 | p[2] << 16;
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic inline u32 get_unaligned_le24(const void *p)
878c2ecf20Sopenharmony_ci{
888c2ecf20Sopenharmony_ci	return __get_unaligned_le24(p);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic inline void __put_unaligned_be24(const u32 val, u8 *p)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	*p++ = val >> 16;
948c2ecf20Sopenharmony_ci	*p++ = val >> 8;
958c2ecf20Sopenharmony_ci	*p++ = val;
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_cistatic inline void put_unaligned_be24(const u32 val, void *p)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	__put_unaligned_be24(val, p);
1018c2ecf20Sopenharmony_ci}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic inline void __put_unaligned_le24(const u32 val, u8 *p)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	*p++ = val;
1068c2ecf20Sopenharmony_ci	*p++ = val >> 8;
1078c2ecf20Sopenharmony_ci	*p++ = val >> 16;
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic inline void put_unaligned_le24(const u32 val, void *p)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	__put_unaligned_le24(val, p);
1138c2ecf20Sopenharmony_ci}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci#endif /* _LINUX_UNALIGNED_GENERIC_H */
116