115 lines · 2.9 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#ifndef _LINUX_UNALIGNED_GENERIC_H#define _LINUX_UNALIGNED_GENERIC_H #include <linux/types.h> /* * Cause a link-time error if we try an unaligned access other than * 1,2,4 or 8 bytes long */extern void __bad_unaligned_access_size(void); #define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({			\	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),	\	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),	\	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),	\	__bad_unaligned_access_size()))));					\	})) #define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({			\	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),	\	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),	\	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),	\	__bad_unaligned_access_size()))));					\	})) #define __put_unaligned_le(val, ptr) ({					\	void *__gu_p = (ptr);						\	switch (sizeof(*(ptr))) {					\	case 1:								\		*(u8 *)__gu_p = (__force u8)(val);			\		break;							\	case 2:								\		put_unaligned_le16((__force u16)(val), __gu_p);		\		break;							\	case 4:								\		put_unaligned_le32((__force u32)(val), __gu_p);		\		break;							\	case 8:								\		put_unaligned_le64((__force u64)(val), __gu_p);		\		break;							\	default:							\		__bad_unaligned_access_size();				\		break;							\	}								\	(void)0; }) #define __put_unaligned_be(val, ptr) ({					\	void *__gu_p = (ptr);						\	switch (sizeof(*(ptr))) {					\	case 1:								\		*(u8 *)__gu_p = (__force u8)(val);			\		break;							\	case 2:								\		put_unaligned_be16((__force u16)(val), __gu_p);		\		break;							\	case 4:								\		put_unaligned_be32((__force u32)(val), __gu_p);		\		break;							\	case 8:								\		put_unaligned_be64((__force u64)(val), __gu_p);		\		break;							\	default:							\		__bad_unaligned_access_size();				\		break;							\	}								\	(void)0; }) static inline u32 __get_unaligned_be24(const u8 *p){	return p[0] << 16 | p[1] << 8 | p[2];} static inline u32 get_unaligned_be24(const void *p){	return __get_unaligned_be24(p);} static inline u32 __get_unaligned_le24(const u8 *p){	return p[0] | p[1] << 8 | p[2] << 16;} static inline u32 get_unaligned_le24(const void *p){	return __get_unaligned_le24(p);} static inline void __put_unaligned_be24(const u32 val, u8 *p){	*p++ = val >> 16;	*p++ = val >> 8;	*p++ = val;} static inline void put_unaligned_be24(const u32 val, void *p){	__put_unaligned_be24(val, p);} static inline void __put_unaligned_le24(const u32 val, u8 *p){	*p++ = val;	*p++ = val >> 8;	*p++ = val >> 16;} static inline void put_unaligned_le24(const u32 val, void *p){	__put_unaligned_le24(val, p);} #endif /* _LINUX_UNALIGNED_GENERIC_H */