xref: /aosp_15_r20/external/zstd/contrib/linux-kernel/mem.h (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
2 /*
3  * Copyright (c) Meta Platforms, Inc. and affiliates.
4  * All rights reserved.
5  *
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.
10  */
11 
12 #ifndef MEM_H_MODULE
13 #define MEM_H_MODULE
14 
15 /*-****************************************
16 *  Dependencies
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 */
23 
24 /*-****************************************
25 *  Compiler specifics
26 ******************************************/
27 #undef MEM_STATIC /* may be already defined from common/compiler.h */
28 #define MEM_STATIC static inline
29 
30 /*-**************************************************************
31 *  Basic Types
32 *****************************************************************/
33 typedef uint8_t  BYTE;
34 typedef uint8_t  U8;
35 typedef int8_t   S8;
36 typedef uint16_t U16;
37 typedef int16_t  S16;
38 typedef uint32_t U32;
39 typedef int32_t  S32;
40 typedef uint64_t U64;
41 typedef int64_t  S64;
42 
43 /*-**************************************************************
44 *  Memory I/O API
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);
50 
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);
56 
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);
60 
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);
67 
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);
73 
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);
78 
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);
82 
83 /*=== Byteswap ===*/
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);
87 
88 /*-**************************************************************
89 *  Memory I/O Implementation
90 *****************************************************************/
MEM_32bits(void)91 MEM_STATIC unsigned MEM_32bits(void)
92 {
93     return sizeof(size_t) == 4;
94 }
95 
MEM_64bits(void)96 MEM_STATIC unsigned MEM_64bits(void)
97 {
98     return sizeof(size_t) == 8;
99 }
100 
101 #if defined(__LITTLE_ENDIAN)
102 #define MEM_LITTLE_ENDIAN 1
103 #else
104 #define MEM_LITTLE_ENDIAN 0
105 #endif
106 
MEM_isLittleEndian(void)107 MEM_STATIC unsigned MEM_isLittleEndian(void)
108 {
109     return MEM_LITTLE_ENDIAN;
110 }
111 
MEM_read16(const void * memPtr)112 MEM_STATIC U16 MEM_read16(const void *memPtr)
113 {
114     return get_unaligned((const U16 *)memPtr);
115 }
116 
MEM_read32(const void * memPtr)117 MEM_STATIC U32 MEM_read32(const void *memPtr)
118 {
119     return get_unaligned((const U32 *)memPtr);
120 }
121 
MEM_read64(const void * memPtr)122 MEM_STATIC U64 MEM_read64(const void *memPtr)
123 {
124     return get_unaligned((const U64 *)memPtr);
125 }
126 
MEM_readST(const void * memPtr)127 MEM_STATIC size_t MEM_readST(const void *memPtr)
128 {
129     return get_unaligned((const size_t *)memPtr);
130 }
131 
MEM_write16(void * memPtr,U16 value)132 MEM_STATIC void MEM_write16(void *memPtr, U16 value)
133 {
134     put_unaligned(value, (U16 *)memPtr);
135 }
136 
MEM_write32(void * memPtr,U32 value)137 MEM_STATIC void MEM_write32(void *memPtr, U32 value)
138 {
139     put_unaligned(value, (U32 *)memPtr);
140 }
141 
MEM_write64(void * memPtr,U64 value)142 MEM_STATIC void MEM_write64(void *memPtr, U64 value)
143 {
144     put_unaligned(value, (U64 *)memPtr);
145 }
146 
147 /*=== Little endian r/w ===*/
148 
MEM_readLE16(const void * memPtr)149 MEM_STATIC U16 MEM_readLE16(const void *memPtr)
150 {
151     return get_unaligned_le16(memPtr);
152 }
153 
MEM_writeLE16(void * memPtr,U16 val)154 MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
155 {
156     put_unaligned_le16(val, memPtr);
157 }
158 
MEM_readLE24(const void * memPtr)159 MEM_STATIC U32 MEM_readLE24(const void *memPtr)
160 {
161     return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16);
162 }
163 
MEM_writeLE24(void * memPtr,U32 val)164 MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
165 {
166 	MEM_writeLE16(memPtr, (U16)val);
167 	((BYTE *)memPtr)[2] = (BYTE)(val >> 16);
168 }
169 
MEM_readLE32(const void * memPtr)170 MEM_STATIC U32 MEM_readLE32(const void *memPtr)
171 {
172     return get_unaligned_le32(memPtr);
173 }
174 
MEM_writeLE32(void * memPtr,U32 val32)175 MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
176 {
177     put_unaligned_le32(val32, memPtr);
178 }
179 
MEM_readLE64(const void * memPtr)180 MEM_STATIC U64 MEM_readLE64(const void *memPtr)
181 {
182     return get_unaligned_le64(memPtr);
183 }
184 
MEM_writeLE64(void * memPtr,U64 val64)185 MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
186 {
187     put_unaligned_le64(val64, memPtr);
188 }
189 
MEM_readLEST(const void * memPtr)190 MEM_STATIC size_t MEM_readLEST(const void *memPtr)
191 {
192 	if (MEM_32bits())
193 		return (size_t)MEM_readLE32(memPtr);
194 	else
195 		return (size_t)MEM_readLE64(memPtr);
196 }
197 
MEM_writeLEST(void * memPtr,size_t val)198 MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
199 {
200 	if (MEM_32bits())
201 		MEM_writeLE32(memPtr, (U32)val);
202 	else
203 		MEM_writeLE64(memPtr, (U64)val);
204 }
205 
206 /*=== Big endian r/w ===*/
207 
MEM_readBE32(const void * memPtr)208 MEM_STATIC U32 MEM_readBE32(const void *memPtr)
209 {
210     return get_unaligned_be32(memPtr);
211 }
212 
MEM_writeBE32(void * memPtr,U32 val32)213 MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
214 {
215     put_unaligned_be32(val32, memPtr);
216 }
217 
MEM_readBE64(const void * memPtr)218 MEM_STATIC U64 MEM_readBE64(const void *memPtr)
219 {
220     return get_unaligned_be64(memPtr);
221 }
222 
MEM_writeBE64(void * memPtr,U64 val64)223 MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
224 {
225     put_unaligned_be64(val64, memPtr);
226 }
227 
MEM_readBEST(const void * memPtr)228 MEM_STATIC size_t MEM_readBEST(const void *memPtr)
229 {
230 	if (MEM_32bits())
231 		return (size_t)MEM_readBE32(memPtr);
232 	else
233 		return (size_t)MEM_readBE64(memPtr);
234 }
235 
MEM_writeBEST(void * memPtr,size_t val)236 MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
237 {
238 	if (MEM_32bits())
239 		MEM_writeBE32(memPtr, (U32)val);
240 	else
241 		MEM_writeBE64(memPtr, (U64)val);
242 }
243 
MEM_swap32(U32 in)244 MEM_STATIC U32 MEM_swap32(U32 in)
245 {
246     return swab32(in);
247 }
248 
MEM_swap64(U64 in)249 MEM_STATIC U64 MEM_swap64(U64 in)
250 {
251     return swab64(in);
252 }
253 
MEM_swapST(size_t in)254 MEM_STATIC size_t MEM_swapST(size_t in)
255 {
256     if (MEM_32bits())
257         return (size_t)MEM_swap32((U32)in);
258     else
259         return (size_t)MEM_swap64((U64)in);
260 }
261 
262 #endif /* MEM_H_MODULE */
263