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