1 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
3 * Copyright (c) Meta Platforms, Inc. and affiliates.
6 * This source code is licensed under both the BSD-style license (found in the
7 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
8 * in the COPYING file in the root directory of this source tree).
9 * You may select, at your option, one of the above-listed licenses.
15 /*-****************************************
17 ******************************************/
18 #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */
19 #include <linux/compiler.h> /* inline */
20 #include <linux/swab.h> /* swab32, swab64 */
21 #include <linux/types.h> /* size_t, ptrdiff_t */
22 #include "debug.h" /* DEBUG_STATIC_ASSERT */
24 /*-****************************************
26 ******************************************/
27 #undef MEM_STATIC /* may be already defined from common/compiler.h */
28 #define MEM_STATIC static inline
30 /*-**************************************************************
32 *****************************************************************/
43 /*-**************************************************************
45 *****************************************************************/
46 /*=== Static platform detection ===*/
47 MEM_STATIC unsigned MEM_32bits(void);
48 MEM_STATIC unsigned MEM_64bits(void);
49 MEM_STATIC unsigned MEM_isLittleEndian(void);
51 /*=== Native unaligned read/write ===*/
52 MEM_STATIC U16 MEM_read16(const void* memPtr);
53 MEM_STATIC U32 MEM_read32(const void* memPtr);
54 MEM_STATIC U64 MEM_read64(const void* memPtr);
55 MEM_STATIC size_t MEM_readST(const void* memPtr);
57 MEM_STATIC void MEM_write16(void* memPtr, U16 value);
58 MEM_STATIC void MEM_write32(void* memPtr, U32 value);
59 MEM_STATIC void MEM_write64(void* memPtr, U64 value);
61 /*=== Little endian unaligned read/write ===*/
62 MEM_STATIC U16 MEM_readLE16(const void* memPtr);
63 MEM_STATIC U32 MEM_readLE24(const void* memPtr);
64 MEM_STATIC U32 MEM_readLE32(const void* memPtr);
65 MEM_STATIC U64 MEM_readLE64(const void* memPtr);
66 MEM_STATIC size_t MEM_readLEST(const void* memPtr);
68 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
69 MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
70 MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
71 MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
72 MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
74 /*=== Big endian unaligned read/write ===*/
75 MEM_STATIC U32 MEM_readBE32(const void* memPtr);
76 MEM_STATIC U64 MEM_readBE64(const void* memPtr);
77 MEM_STATIC size_t MEM_readBEST(const void* memPtr);
79 MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
80 MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
81 MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
84 MEM_STATIC U32 MEM_swap32(U32 in);
85 MEM_STATIC U64 MEM_swap64(U64 in);
86 MEM_STATIC size_t MEM_swapST(size_t in);
88 /*-**************************************************************
89 * Memory I/O Implementation
90 *****************************************************************/
91 MEM_STATIC unsigned MEM_32bits(void)
93 return sizeof(size_t) == 4;
96 MEM_STATIC unsigned MEM_64bits(void)
98 return sizeof(size_t) == 8;
101 #if defined(__LITTLE_ENDIAN)
102 #define MEM_LITTLE_ENDIAN 1
104 #define MEM_LITTLE_ENDIAN 0
107 MEM_STATIC unsigned MEM_isLittleEndian(void)
109 return MEM_LITTLE_ENDIAN;
112 MEM_STATIC U16 MEM_read16(const void *memPtr)
114 return get_unaligned((const U16 *)memPtr);
117 MEM_STATIC U32 MEM_read32(const void *memPtr)
119 return get_unaligned((const U32 *)memPtr);
122 MEM_STATIC U64 MEM_read64(const void *memPtr)
124 return get_unaligned((const U64 *)memPtr);
127 MEM_STATIC size_t MEM_readST(const void *memPtr)
129 return get_unaligned((const size_t *)memPtr);
132 MEM_STATIC void MEM_write16(void *memPtr, U16 value)
134 put_unaligned(value, (U16 *)memPtr);
137 MEM_STATIC void MEM_write32(void *memPtr, U32 value)
139 put_unaligned(value, (U32 *)memPtr);
142 MEM_STATIC void MEM_write64(void *memPtr, U64 value)
144 put_unaligned(value, (U64 *)memPtr);
147 /*=== Little endian r/w ===*/
149 MEM_STATIC U16 MEM_readLE16(const void *memPtr)
151 return get_unaligned_le16(memPtr);
154 MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
156 put_unaligned_le16(val, memPtr);
159 MEM_STATIC U32 MEM_readLE24(const void *memPtr)
161 return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16);
164 MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
166 MEM_writeLE16(memPtr, (U16)val);
167 ((BYTE *)memPtr)[2] = (BYTE)(val >> 16);
170 MEM_STATIC U32 MEM_readLE32(const void *memPtr)
172 return get_unaligned_le32(memPtr);
175 MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
177 put_unaligned_le32(val32, memPtr);
180 MEM_STATIC U64 MEM_readLE64(const void *memPtr)
182 return get_unaligned_le64(memPtr);
185 MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
187 put_unaligned_le64(val64, memPtr);
190 MEM_STATIC size_t MEM_readLEST(const void *memPtr)
193 return (size_t)MEM_readLE32(memPtr);
195 return (size_t)MEM_readLE64(memPtr);
198 MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
201 MEM_writeLE32(memPtr, (U32)val);
203 MEM_writeLE64(memPtr, (U64)val);
206 /*=== Big endian r/w ===*/
208 MEM_STATIC U32 MEM_readBE32(const void *memPtr)
210 return get_unaligned_be32(memPtr);
213 MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
215 put_unaligned_be32(val32, memPtr);
218 MEM_STATIC U64 MEM_readBE64(const void *memPtr)
220 return get_unaligned_be64(memPtr);
223 MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
225 put_unaligned_be64(val64, memPtr);
228 MEM_STATIC size_t MEM_readBEST(const void *memPtr)
231 return (size_t)MEM_readBE32(memPtr);
233 return (size_t)MEM_readBE64(memPtr);
236 MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
239 MEM_writeBE32(memPtr, (U32)val);
241 MEM_writeBE64(memPtr, (U64)val);
244 MEM_STATIC U32 MEM_swap32(U32 in)
249 MEM_STATIC U64 MEM_swap64(U64 in)
254 MEM_STATIC size_t MEM_swapST(size_t in)
257 return (size_t)MEM_swap32((U32)in);
259 return (size_t)MEM_swap64((U64)in);
262 #endif /* MEM_H_MODULE */