at v5.10 3.0 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LINUX_UNALIGNED_GENERIC_H 3#define _LINUX_UNALIGNED_GENERIC_H 4 5#include <linux/types.h> 6 7/* 8 * Cause a link-time error if we try an unaligned access other than 9 * 1,2,4 or 8 bytes long 10 */ 11extern void __bad_unaligned_access_size(void); 12 13#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \ 14 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ 15 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \ 16 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \ 17 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \ 18 __bad_unaligned_access_size())))); \ 19 })) 20 21#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \ 22 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ 23 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \ 24 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \ 25 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \ 26 __bad_unaligned_access_size())))); \ 27 })) 28 29#define __put_unaligned_le(val, ptr) ({ \ 30 void *__gu_p = (ptr); \ 31 switch (sizeof(*(ptr))) { \ 32 case 1: \ 33 *(u8 *)__gu_p = (__force u8)(val); \ 34 break; \ 35 case 2: \ 36 put_unaligned_le16((__force u16)(val), __gu_p); \ 37 break; \ 38 case 4: \ 39 put_unaligned_le32((__force u32)(val), __gu_p); \ 40 break; \ 41 case 8: \ 42 put_unaligned_le64((__force u64)(val), __gu_p); \ 43 break; \ 44 default: \ 45 __bad_unaligned_access_size(); \ 46 break; \ 47 } \ 48 (void)0; }) 49 50#define __put_unaligned_be(val, ptr) ({ \ 51 void *__gu_p = (ptr); \ 52 switch (sizeof(*(ptr))) { \ 53 case 1: \ 54 *(u8 *)__gu_p = (__force u8)(val); \ 55 break; \ 56 case 2: \ 57 put_unaligned_be16((__force u16)(val), __gu_p); \ 58 break; \ 59 case 4: \ 60 put_unaligned_be32((__force u32)(val), __gu_p); \ 61 break; \ 62 case 8: \ 63 put_unaligned_be64((__force u64)(val), __gu_p); \ 64 break; \ 65 default: \ 66 __bad_unaligned_access_size(); \ 67 break; \ 68 } \ 69 (void)0; }) 70 71static inline u32 __get_unaligned_be24(const u8 *p) 72{ 73 return p[0] << 16 | p[1] << 8 | p[2]; 74} 75 76static inline u32 get_unaligned_be24(const void *p) 77{ 78 return __get_unaligned_be24(p); 79} 80 81static inline u32 __get_unaligned_le24(const u8 *p) 82{ 83 return p[0] | p[1] << 8 | p[2] << 16; 84} 85 86static inline u32 get_unaligned_le24(const void *p) 87{ 88 return __get_unaligned_le24(p); 89} 90 91static inline void __put_unaligned_be24(const u32 val, u8 *p) 92{ 93 *p++ = val >> 16; 94 *p++ = val >> 8; 95 *p++ = val; 96} 97 98static inline void put_unaligned_be24(const u32 val, void *p) 99{ 100 __put_unaligned_be24(val, p); 101} 102 103static inline void __put_unaligned_le24(const u32 val, u8 *p) 104{ 105 *p++ = val; 106 *p++ = val >> 8; 107 *p++ = val >> 16; 108} 109 110static inline void put_unaligned_le24(const u32 val, void *p) 111{ 112 __put_unaligned_le24(val, p); 113} 114 115#endif /* _LINUX_UNALIGNED_GENERIC_H */