unaligned.h (3402B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef __ASM_GENERIC_UNALIGNED_H 3#define __ASM_GENERIC_UNALIGNED_H 4 5/* 6 * This is the most generic implementation of unaligned accesses 7 * and should work almost anywhere. 8 */ 9#include <linux/unaligned/packed_struct.h> 10#include <asm/byteorder.h> 11 12#define __get_unaligned_t(type, ptr) ({ \ 13 const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 14 __pptr->x; \ 15}) 16 17#define __put_unaligned_t(type, val, ptr) do { \ 18 struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 19 __pptr->x = (val); \ 20} while (0) 21 22#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr)) 23#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr)) 24 25static inline u16 get_unaligned_le16(const void *p) 26{ 27 return le16_to_cpu(__get_unaligned_t(__le16, p)); 28} 29 30static inline u32 get_unaligned_le32(const void *p) 31{ 32 return le32_to_cpu(__get_unaligned_t(__le32, p)); 33} 34 35static inline u64 get_unaligned_le64(const void *p) 36{ 37 return le64_to_cpu(__get_unaligned_t(__le64, p)); 38} 39 40static inline void put_unaligned_le16(u16 val, void *p) 41{ 42 __put_unaligned_t(__le16, cpu_to_le16(val), p); 43} 44 45static inline void put_unaligned_le32(u32 val, void *p) 46{ 47 __put_unaligned_t(__le32, cpu_to_le32(val), p); 48} 49 50static inline void put_unaligned_le64(u64 val, void *p) 51{ 52 __put_unaligned_t(__le64, cpu_to_le64(val), p); 53} 54 55static inline u16 get_unaligned_be16(const void *p) 56{ 57 return be16_to_cpu(__get_unaligned_t(__be16, p)); 58} 59 60static inline u32 get_unaligned_be32(const void *p) 61{ 62 return be32_to_cpu(__get_unaligned_t(__be32, p)); 63} 64 65static inline u64 get_unaligned_be64(const void *p) 66{ 67 return be64_to_cpu(__get_unaligned_t(__be64, p)); 68} 69 70static inline void put_unaligned_be16(u16 val, void *p) 71{ 72 __put_unaligned_t(__be16, cpu_to_be16(val), p); 73} 74 75static inline void put_unaligned_be32(u32 val, void *p) 76{ 77 __put_unaligned_t(__be32, cpu_to_be32(val), p); 78} 79 80static inline void put_unaligned_be64(u64 val, void *p) 81{ 82 __put_unaligned_t(__be64, cpu_to_be64(val), p); 83} 84 85static inline u32 __get_unaligned_be24(const u8 *p) 86{ 87 return p[0] << 16 | p[1] << 8 | p[2]; 88} 89 90static inline u32 get_unaligned_be24(const void *p) 91{ 92 return __get_unaligned_be24(p); 93} 94 95static inline u32 __get_unaligned_le24(const u8 *p) 96{ 97 return p[0] | p[1] << 8 | p[2] << 16; 98} 99 100static inline u32 get_unaligned_le24(const void *p) 101{ 102 return __get_unaligned_le24(p); 103} 104 105static inline void __put_unaligned_be24(const u32 val, u8 *p) 106{ 107 *p++ = val >> 16; 108 *p++ = val >> 8; 109 *p++ = val; 110} 111 112static inline void put_unaligned_be24(const u32 val, void *p) 113{ 114 __put_unaligned_be24(val, p); 115} 116 117static inline void __put_unaligned_le24(const u32 val, u8 *p) 118{ 119 *p++ = val; 120 *p++ = val >> 8; 121 *p++ = val >> 16; 122} 123 124static inline void put_unaligned_le24(const u32 val, void *p) 125{ 126 __put_unaligned_le24(val, p); 127} 128 129static inline void __put_unaligned_be48(const u64 val, __u8 *p) 130{ 131 *p++ = val >> 40; 132 *p++ = val >> 32; 133 *p++ = val >> 24; 134 *p++ = val >> 16; 135 *p++ = val >> 8; 136 *p++ = val; 137} 138 139static inline void put_unaligned_be48(const u64 val, void *p) 140{ 141 __put_unaligned_be48(val, p); 142} 143 144static inline u64 __get_unaligned_be48(const u8 *p) 145{ 146 return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 | 147 p[3] << 16 | p[4] << 8 | p[5]; 148} 149 150static inline u64 get_unaligned_be48(const void *p) 151{ 152 return __get_unaligned_be48(p); 153} 154 155#endif /* __ASM_GENERIC_UNALIGNED_H */