xref: /aosp_15_r20/external/zstd/lib/common/mem.h (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1*01826a49SYabin Cui /*
2*01826a49SYabin Cui  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui  * All rights reserved.
4*01826a49SYabin Cui  *
5*01826a49SYabin Cui  * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui  * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui  * You may select, at your option, one of the above-listed licenses.
9*01826a49SYabin Cui  */
10*01826a49SYabin Cui 
11*01826a49SYabin Cui #ifndef MEM_H_MODULE
12*01826a49SYabin Cui #define MEM_H_MODULE
13*01826a49SYabin Cui 
14*01826a49SYabin Cui #if defined (__cplusplus)
15*01826a49SYabin Cui extern "C" {
16*01826a49SYabin Cui #endif
17*01826a49SYabin Cui 
18*01826a49SYabin Cui /*-****************************************
19*01826a49SYabin Cui *  Dependencies
20*01826a49SYabin Cui ******************************************/
21*01826a49SYabin Cui #include <stddef.h>  /* size_t, ptrdiff_t */
22*01826a49SYabin Cui #include "compiler.h"  /* __has_builtin */
23*01826a49SYabin Cui #include "debug.h"  /* DEBUG_STATIC_ASSERT */
24*01826a49SYabin Cui #include "zstd_deps.h"  /* ZSTD_memcpy */
25*01826a49SYabin Cui 
26*01826a49SYabin Cui 
27*01826a49SYabin Cui /*-****************************************
28*01826a49SYabin Cui *  Compiler specifics
29*01826a49SYabin Cui ******************************************/
30*01826a49SYabin Cui #if defined(_MSC_VER)   /* Visual Studio */
31*01826a49SYabin Cui #   include <stdlib.h>  /* _byteswap_ulong */
32*01826a49SYabin Cui #   include <intrin.h>  /* _byteswap_* */
33*01826a49SYabin Cui #endif
34*01826a49SYabin Cui 
35*01826a49SYabin Cui /*-**************************************************************
36*01826a49SYabin Cui *  Basic Types
37*01826a49SYabin Cui *****************************************************************/
38*01826a49SYabin Cui #if  !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
39*01826a49SYabin Cui #  if defined(_AIX)
40*01826a49SYabin Cui #    include <inttypes.h>
41*01826a49SYabin Cui #  else
42*01826a49SYabin Cui #    include <stdint.h> /* intptr_t */
43*01826a49SYabin Cui #  endif
44*01826a49SYabin Cui   typedef   uint8_t BYTE;
45*01826a49SYabin Cui   typedef   uint8_t U8;
46*01826a49SYabin Cui   typedef    int8_t S8;
47*01826a49SYabin Cui   typedef  uint16_t U16;
48*01826a49SYabin Cui   typedef   int16_t S16;
49*01826a49SYabin Cui   typedef  uint32_t U32;
50*01826a49SYabin Cui   typedef   int32_t S32;
51*01826a49SYabin Cui   typedef  uint64_t U64;
52*01826a49SYabin Cui   typedef   int64_t S64;
53*01826a49SYabin Cui #else
54*01826a49SYabin Cui # include <limits.h>
55*01826a49SYabin Cui #if CHAR_BIT != 8
56*01826a49SYabin Cui #  error "this implementation requires char to be exactly 8-bit type"
57*01826a49SYabin Cui #endif
58*01826a49SYabin Cui   typedef unsigned char      BYTE;
59*01826a49SYabin Cui   typedef unsigned char      U8;
60*01826a49SYabin Cui   typedef   signed char      S8;
61*01826a49SYabin Cui #if USHRT_MAX != 65535
62*01826a49SYabin Cui #  error "this implementation requires short to be exactly 16-bit type"
63*01826a49SYabin Cui #endif
64*01826a49SYabin Cui   typedef unsigned short      U16;
65*01826a49SYabin Cui   typedef   signed short      S16;
66*01826a49SYabin Cui #if UINT_MAX != 4294967295
67*01826a49SYabin Cui #  error "this implementation requires int to be exactly 32-bit type"
68*01826a49SYabin Cui #endif
69*01826a49SYabin Cui   typedef unsigned int        U32;
70*01826a49SYabin Cui   typedef   signed int        S32;
71*01826a49SYabin Cui /* note : there are no limits defined for long long type in C90.
72*01826a49SYabin Cui  * limits exist in C99, however, in such case, <stdint.h> is preferred */
73*01826a49SYabin Cui   typedef unsigned long long  U64;
74*01826a49SYabin Cui   typedef   signed long long  S64;
75*01826a49SYabin Cui #endif
76*01826a49SYabin Cui 
77*01826a49SYabin Cui 
78*01826a49SYabin Cui /*-**************************************************************
79*01826a49SYabin Cui *  Memory I/O API
80*01826a49SYabin Cui *****************************************************************/
81*01826a49SYabin Cui /*=== Static platform detection ===*/
82*01826a49SYabin Cui MEM_STATIC unsigned MEM_32bits(void);
83*01826a49SYabin Cui MEM_STATIC unsigned MEM_64bits(void);
84*01826a49SYabin Cui MEM_STATIC unsigned MEM_isLittleEndian(void);
85*01826a49SYabin Cui 
86*01826a49SYabin Cui /*=== Native unaligned read/write ===*/
87*01826a49SYabin Cui MEM_STATIC U16 MEM_read16(const void* memPtr);
88*01826a49SYabin Cui MEM_STATIC U32 MEM_read32(const void* memPtr);
89*01826a49SYabin Cui MEM_STATIC U64 MEM_read64(const void* memPtr);
90*01826a49SYabin Cui MEM_STATIC size_t MEM_readST(const void* memPtr);
91*01826a49SYabin Cui 
92*01826a49SYabin Cui MEM_STATIC void MEM_write16(void* memPtr, U16 value);
93*01826a49SYabin Cui MEM_STATIC void MEM_write32(void* memPtr, U32 value);
94*01826a49SYabin Cui MEM_STATIC void MEM_write64(void* memPtr, U64 value);
95*01826a49SYabin Cui 
96*01826a49SYabin Cui /*=== Little endian unaligned read/write ===*/
97*01826a49SYabin Cui MEM_STATIC U16 MEM_readLE16(const void* memPtr);
98*01826a49SYabin Cui MEM_STATIC U32 MEM_readLE24(const void* memPtr);
99*01826a49SYabin Cui MEM_STATIC U32 MEM_readLE32(const void* memPtr);
100*01826a49SYabin Cui MEM_STATIC U64 MEM_readLE64(const void* memPtr);
101*01826a49SYabin Cui MEM_STATIC size_t MEM_readLEST(const void* memPtr);
102*01826a49SYabin Cui 
103*01826a49SYabin Cui MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
104*01826a49SYabin Cui MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
105*01826a49SYabin Cui MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
106*01826a49SYabin Cui MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
107*01826a49SYabin Cui MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
108*01826a49SYabin Cui 
109*01826a49SYabin Cui /*=== Big endian unaligned read/write ===*/
110*01826a49SYabin Cui MEM_STATIC U32 MEM_readBE32(const void* memPtr);
111*01826a49SYabin Cui MEM_STATIC U64 MEM_readBE64(const void* memPtr);
112*01826a49SYabin Cui MEM_STATIC size_t MEM_readBEST(const void* memPtr);
113*01826a49SYabin Cui 
114*01826a49SYabin Cui MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
115*01826a49SYabin Cui MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
116*01826a49SYabin Cui MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
117*01826a49SYabin Cui 
118*01826a49SYabin Cui /*=== Byteswap ===*/
119*01826a49SYabin Cui MEM_STATIC U32 MEM_swap32(U32 in);
120*01826a49SYabin Cui MEM_STATIC U64 MEM_swap64(U64 in);
121*01826a49SYabin Cui MEM_STATIC size_t MEM_swapST(size_t in);
122*01826a49SYabin Cui 
123*01826a49SYabin Cui 
124*01826a49SYabin Cui /*-**************************************************************
125*01826a49SYabin Cui *  Memory I/O Implementation
126*01826a49SYabin Cui *****************************************************************/
127*01826a49SYabin Cui /* MEM_FORCE_MEMORY_ACCESS : For accessing unaligned memory:
128*01826a49SYabin Cui  * Method 0 : always use `memcpy()`. Safe and portable.
129*01826a49SYabin Cui  * Method 1 : Use compiler extension to set unaligned access.
130*01826a49SYabin Cui  * Method 2 : direct access. This method is portable but violate C standard.
131*01826a49SYabin Cui  *            It can generate buggy code on targets depending on alignment.
132*01826a49SYabin Cui  * Default  : method 1 if supported, else method 0
133*01826a49SYabin Cui  */
134*01826a49SYabin Cui #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */
135*01826a49SYabin Cui #  ifdef __GNUC__
136*01826a49SYabin Cui #    define MEM_FORCE_MEMORY_ACCESS 1
137*01826a49SYabin Cui #  endif
138*01826a49SYabin Cui #endif
139*01826a49SYabin Cui 
MEM_32bits(void)140*01826a49SYabin Cui MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
MEM_64bits(void)141*01826a49SYabin Cui MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
142*01826a49SYabin Cui 
MEM_isLittleEndian(void)143*01826a49SYabin Cui MEM_STATIC unsigned MEM_isLittleEndian(void)
144*01826a49SYabin Cui {
145*01826a49SYabin Cui #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
146*01826a49SYabin Cui     return 1;
147*01826a49SYabin Cui #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
148*01826a49SYabin Cui     return 0;
149*01826a49SYabin Cui #elif defined(__clang__) && __LITTLE_ENDIAN__
150*01826a49SYabin Cui     return 1;
151*01826a49SYabin Cui #elif defined(__clang__) && __BIG_ENDIAN__
152*01826a49SYabin Cui     return 0;
153*01826a49SYabin Cui #elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86)
154*01826a49SYabin Cui     return 1;
155*01826a49SYabin Cui #elif defined(__DMC__) && defined(_M_IX86)
156*01826a49SYabin Cui     return 1;
157*01826a49SYabin Cui #else
158*01826a49SYabin Cui     const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */
159*01826a49SYabin Cui     return one.c[0];
160*01826a49SYabin Cui #endif
161*01826a49SYabin Cui }
162*01826a49SYabin Cui 
163*01826a49SYabin Cui #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
164*01826a49SYabin Cui 
165*01826a49SYabin Cui /* violates C standard, by lying on structure alignment.
166*01826a49SYabin Cui Only use if no other choice to achieve best performance on target platform */
MEM_read16(const void * memPtr)167*01826a49SYabin Cui MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
MEM_read32(const void * memPtr)168*01826a49SYabin Cui MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
MEM_read64(const void * memPtr)169*01826a49SYabin Cui MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
MEM_readST(const void * memPtr)170*01826a49SYabin Cui MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
171*01826a49SYabin Cui 
MEM_write16(void * memPtr,U16 value)172*01826a49SYabin Cui MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
MEM_write32(void * memPtr,U32 value)173*01826a49SYabin Cui MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
MEM_write64(void * memPtr,U64 value)174*01826a49SYabin Cui MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
175*01826a49SYabin Cui 
176*01826a49SYabin Cui #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
177*01826a49SYabin Cui 
178*01826a49SYabin Cui typedef __attribute__((aligned(1))) U16 unalign16;
179*01826a49SYabin Cui typedef __attribute__((aligned(1))) U32 unalign32;
180*01826a49SYabin Cui typedef __attribute__((aligned(1))) U64 unalign64;
181*01826a49SYabin Cui typedef __attribute__((aligned(1))) size_t unalignArch;
182*01826a49SYabin Cui 
MEM_read16(const void * ptr)183*01826a49SYabin Cui MEM_STATIC U16 MEM_read16(const void* ptr) { return *(const unalign16*)ptr; }
MEM_read32(const void * ptr)184*01826a49SYabin Cui MEM_STATIC U32 MEM_read32(const void* ptr) { return *(const unalign32*)ptr; }
MEM_read64(const void * ptr)185*01826a49SYabin Cui MEM_STATIC U64 MEM_read64(const void* ptr) { return *(const unalign64*)ptr; }
MEM_readST(const void * ptr)186*01826a49SYabin Cui MEM_STATIC size_t MEM_readST(const void* ptr) { return *(const unalignArch*)ptr; }
187*01826a49SYabin Cui 
MEM_write16(void * memPtr,U16 value)188*01826a49SYabin Cui MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(unalign16*)memPtr = value; }
MEM_write32(void * memPtr,U32 value)189*01826a49SYabin Cui MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(unalign32*)memPtr = value; }
MEM_write64(void * memPtr,U64 value)190*01826a49SYabin Cui MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(unalign64*)memPtr = value; }
191*01826a49SYabin Cui 
192*01826a49SYabin Cui #else
193*01826a49SYabin Cui 
194*01826a49SYabin Cui /* default method, safe and standard.
195*01826a49SYabin Cui    can sometimes prove slower */
196*01826a49SYabin Cui 
MEM_read16(const void * memPtr)197*01826a49SYabin Cui MEM_STATIC U16 MEM_read16(const void* memPtr)
198*01826a49SYabin Cui {
199*01826a49SYabin Cui     U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
200*01826a49SYabin Cui }
201*01826a49SYabin Cui 
MEM_read32(const void * memPtr)202*01826a49SYabin Cui MEM_STATIC U32 MEM_read32(const void* memPtr)
203*01826a49SYabin Cui {
204*01826a49SYabin Cui     U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
205*01826a49SYabin Cui }
206*01826a49SYabin Cui 
MEM_read64(const void * memPtr)207*01826a49SYabin Cui MEM_STATIC U64 MEM_read64(const void* memPtr)
208*01826a49SYabin Cui {
209*01826a49SYabin Cui     U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
210*01826a49SYabin Cui }
211*01826a49SYabin Cui 
MEM_readST(const void * memPtr)212*01826a49SYabin Cui MEM_STATIC size_t MEM_readST(const void* memPtr)
213*01826a49SYabin Cui {
214*01826a49SYabin Cui     size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
215*01826a49SYabin Cui }
216*01826a49SYabin Cui 
MEM_write16(void * memPtr,U16 value)217*01826a49SYabin Cui MEM_STATIC void MEM_write16(void* memPtr, U16 value)
218*01826a49SYabin Cui {
219*01826a49SYabin Cui     ZSTD_memcpy(memPtr, &value, sizeof(value));
220*01826a49SYabin Cui }
221*01826a49SYabin Cui 
MEM_write32(void * memPtr,U32 value)222*01826a49SYabin Cui MEM_STATIC void MEM_write32(void* memPtr, U32 value)
223*01826a49SYabin Cui {
224*01826a49SYabin Cui     ZSTD_memcpy(memPtr, &value, sizeof(value));
225*01826a49SYabin Cui }
226*01826a49SYabin Cui 
MEM_write64(void * memPtr,U64 value)227*01826a49SYabin Cui MEM_STATIC void MEM_write64(void* memPtr, U64 value)
228*01826a49SYabin Cui {
229*01826a49SYabin Cui     ZSTD_memcpy(memPtr, &value, sizeof(value));
230*01826a49SYabin Cui }
231*01826a49SYabin Cui 
232*01826a49SYabin Cui #endif /* MEM_FORCE_MEMORY_ACCESS */
233*01826a49SYabin Cui 
MEM_swap32_fallback(U32 in)234*01826a49SYabin Cui MEM_STATIC U32 MEM_swap32_fallback(U32 in)
235*01826a49SYabin Cui {
236*01826a49SYabin Cui     return  ((in << 24) & 0xff000000 ) |
237*01826a49SYabin Cui             ((in <<  8) & 0x00ff0000 ) |
238*01826a49SYabin Cui             ((in >>  8) & 0x0000ff00 ) |
239*01826a49SYabin Cui             ((in >> 24) & 0x000000ff );
240*01826a49SYabin Cui }
241*01826a49SYabin Cui 
MEM_swap32(U32 in)242*01826a49SYabin Cui MEM_STATIC U32 MEM_swap32(U32 in)
243*01826a49SYabin Cui {
244*01826a49SYabin Cui #if defined(_MSC_VER)     /* Visual Studio */
245*01826a49SYabin Cui     return _byteswap_ulong(in);
246*01826a49SYabin Cui #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
247*01826a49SYabin Cui   || (defined(__clang__) && __has_builtin(__builtin_bswap32))
248*01826a49SYabin Cui     return __builtin_bswap32(in);
249*01826a49SYabin Cui #else
250*01826a49SYabin Cui     return MEM_swap32_fallback(in);
251*01826a49SYabin Cui #endif
252*01826a49SYabin Cui }
253*01826a49SYabin Cui 
MEM_swap64_fallback(U64 in)254*01826a49SYabin Cui MEM_STATIC U64 MEM_swap64_fallback(U64 in)
255*01826a49SYabin Cui {
256*01826a49SYabin Cui      return  ((in << 56) & 0xff00000000000000ULL) |
257*01826a49SYabin Cui             ((in << 40) & 0x00ff000000000000ULL) |
258*01826a49SYabin Cui             ((in << 24) & 0x0000ff0000000000ULL) |
259*01826a49SYabin Cui             ((in << 8)  & 0x000000ff00000000ULL) |
260*01826a49SYabin Cui             ((in >> 8)  & 0x00000000ff000000ULL) |
261*01826a49SYabin Cui             ((in >> 24) & 0x0000000000ff0000ULL) |
262*01826a49SYabin Cui             ((in >> 40) & 0x000000000000ff00ULL) |
263*01826a49SYabin Cui             ((in >> 56) & 0x00000000000000ffULL);
264*01826a49SYabin Cui }
265*01826a49SYabin Cui 
MEM_swap64(U64 in)266*01826a49SYabin Cui MEM_STATIC U64 MEM_swap64(U64 in)
267*01826a49SYabin Cui {
268*01826a49SYabin Cui #if defined(_MSC_VER)     /* Visual Studio */
269*01826a49SYabin Cui     return _byteswap_uint64(in);
270*01826a49SYabin Cui #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
271*01826a49SYabin Cui   || (defined(__clang__) && __has_builtin(__builtin_bswap64))
272*01826a49SYabin Cui     return __builtin_bswap64(in);
273*01826a49SYabin Cui #else
274*01826a49SYabin Cui     return MEM_swap64_fallback(in);
275*01826a49SYabin Cui #endif
276*01826a49SYabin Cui }
277*01826a49SYabin Cui 
MEM_swapST(size_t in)278*01826a49SYabin Cui MEM_STATIC size_t MEM_swapST(size_t in)
279*01826a49SYabin Cui {
280*01826a49SYabin Cui     if (MEM_32bits())
281*01826a49SYabin Cui         return (size_t)MEM_swap32((U32)in);
282*01826a49SYabin Cui     else
283*01826a49SYabin Cui         return (size_t)MEM_swap64((U64)in);
284*01826a49SYabin Cui }
285*01826a49SYabin Cui 
286*01826a49SYabin Cui /*=== Little endian r/w ===*/
287*01826a49SYabin Cui 
MEM_readLE16(const void * memPtr)288*01826a49SYabin Cui MEM_STATIC U16 MEM_readLE16(const void* memPtr)
289*01826a49SYabin Cui {
290*01826a49SYabin Cui     if (MEM_isLittleEndian())
291*01826a49SYabin Cui         return MEM_read16(memPtr);
292*01826a49SYabin Cui     else {
293*01826a49SYabin Cui         const BYTE* p = (const BYTE*)memPtr;
294*01826a49SYabin Cui         return (U16)(p[0] + (p[1]<<8));
295*01826a49SYabin Cui     }
296*01826a49SYabin Cui }
297*01826a49SYabin Cui 
MEM_writeLE16(void * memPtr,U16 val)298*01826a49SYabin Cui MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
299*01826a49SYabin Cui {
300*01826a49SYabin Cui     if (MEM_isLittleEndian()) {
301*01826a49SYabin Cui         MEM_write16(memPtr, val);
302*01826a49SYabin Cui     } else {
303*01826a49SYabin Cui         BYTE* p = (BYTE*)memPtr;
304*01826a49SYabin Cui         p[0] = (BYTE)val;
305*01826a49SYabin Cui         p[1] = (BYTE)(val>>8);
306*01826a49SYabin Cui     }
307*01826a49SYabin Cui }
308*01826a49SYabin Cui 
MEM_readLE24(const void * memPtr)309*01826a49SYabin Cui MEM_STATIC U32 MEM_readLE24(const void* memPtr)
310*01826a49SYabin Cui {
311*01826a49SYabin Cui     return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16);
312*01826a49SYabin Cui }
313*01826a49SYabin Cui 
MEM_writeLE24(void * memPtr,U32 val)314*01826a49SYabin Cui MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
315*01826a49SYabin Cui {
316*01826a49SYabin Cui     MEM_writeLE16(memPtr, (U16)val);
317*01826a49SYabin Cui     ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
318*01826a49SYabin Cui }
319*01826a49SYabin Cui 
MEM_readLE32(const void * memPtr)320*01826a49SYabin Cui MEM_STATIC U32 MEM_readLE32(const void* memPtr)
321*01826a49SYabin Cui {
322*01826a49SYabin Cui     if (MEM_isLittleEndian())
323*01826a49SYabin Cui         return MEM_read32(memPtr);
324*01826a49SYabin Cui     else
325*01826a49SYabin Cui         return MEM_swap32(MEM_read32(memPtr));
326*01826a49SYabin Cui }
327*01826a49SYabin Cui 
MEM_writeLE32(void * memPtr,U32 val32)328*01826a49SYabin Cui MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
329*01826a49SYabin Cui {
330*01826a49SYabin Cui     if (MEM_isLittleEndian())
331*01826a49SYabin Cui         MEM_write32(memPtr, val32);
332*01826a49SYabin Cui     else
333*01826a49SYabin Cui         MEM_write32(memPtr, MEM_swap32(val32));
334*01826a49SYabin Cui }
335*01826a49SYabin Cui 
MEM_readLE64(const void * memPtr)336*01826a49SYabin Cui MEM_STATIC U64 MEM_readLE64(const void* memPtr)
337*01826a49SYabin Cui {
338*01826a49SYabin Cui     if (MEM_isLittleEndian())
339*01826a49SYabin Cui         return MEM_read64(memPtr);
340*01826a49SYabin Cui     else
341*01826a49SYabin Cui         return MEM_swap64(MEM_read64(memPtr));
342*01826a49SYabin Cui }
343*01826a49SYabin Cui 
MEM_writeLE64(void * memPtr,U64 val64)344*01826a49SYabin Cui MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
345*01826a49SYabin Cui {
346*01826a49SYabin Cui     if (MEM_isLittleEndian())
347*01826a49SYabin Cui         MEM_write64(memPtr, val64);
348*01826a49SYabin Cui     else
349*01826a49SYabin Cui         MEM_write64(memPtr, MEM_swap64(val64));
350*01826a49SYabin Cui }
351*01826a49SYabin Cui 
MEM_readLEST(const void * memPtr)352*01826a49SYabin Cui MEM_STATIC size_t MEM_readLEST(const void* memPtr)
353*01826a49SYabin Cui {
354*01826a49SYabin Cui     if (MEM_32bits())
355*01826a49SYabin Cui         return (size_t)MEM_readLE32(memPtr);
356*01826a49SYabin Cui     else
357*01826a49SYabin Cui         return (size_t)MEM_readLE64(memPtr);
358*01826a49SYabin Cui }
359*01826a49SYabin Cui 
MEM_writeLEST(void * memPtr,size_t val)360*01826a49SYabin Cui MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
361*01826a49SYabin Cui {
362*01826a49SYabin Cui     if (MEM_32bits())
363*01826a49SYabin Cui         MEM_writeLE32(memPtr, (U32)val);
364*01826a49SYabin Cui     else
365*01826a49SYabin Cui         MEM_writeLE64(memPtr, (U64)val);
366*01826a49SYabin Cui }
367*01826a49SYabin Cui 
368*01826a49SYabin Cui /*=== Big endian r/w ===*/
369*01826a49SYabin Cui 
MEM_readBE32(const void * memPtr)370*01826a49SYabin Cui MEM_STATIC U32 MEM_readBE32(const void* memPtr)
371*01826a49SYabin Cui {
372*01826a49SYabin Cui     if (MEM_isLittleEndian())
373*01826a49SYabin Cui         return MEM_swap32(MEM_read32(memPtr));
374*01826a49SYabin Cui     else
375*01826a49SYabin Cui         return MEM_read32(memPtr);
376*01826a49SYabin Cui }
377*01826a49SYabin Cui 
MEM_writeBE32(void * memPtr,U32 val32)378*01826a49SYabin Cui MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
379*01826a49SYabin Cui {
380*01826a49SYabin Cui     if (MEM_isLittleEndian())
381*01826a49SYabin Cui         MEM_write32(memPtr, MEM_swap32(val32));
382*01826a49SYabin Cui     else
383*01826a49SYabin Cui         MEM_write32(memPtr, val32);
384*01826a49SYabin Cui }
385*01826a49SYabin Cui 
MEM_readBE64(const void * memPtr)386*01826a49SYabin Cui MEM_STATIC U64 MEM_readBE64(const void* memPtr)
387*01826a49SYabin Cui {
388*01826a49SYabin Cui     if (MEM_isLittleEndian())
389*01826a49SYabin Cui         return MEM_swap64(MEM_read64(memPtr));
390*01826a49SYabin Cui     else
391*01826a49SYabin Cui         return MEM_read64(memPtr);
392*01826a49SYabin Cui }
393*01826a49SYabin Cui 
MEM_writeBE64(void * memPtr,U64 val64)394*01826a49SYabin Cui MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
395*01826a49SYabin Cui {
396*01826a49SYabin Cui     if (MEM_isLittleEndian())
397*01826a49SYabin Cui         MEM_write64(memPtr, MEM_swap64(val64));
398*01826a49SYabin Cui     else
399*01826a49SYabin Cui         MEM_write64(memPtr, val64);
400*01826a49SYabin Cui }
401*01826a49SYabin Cui 
MEM_readBEST(const void * memPtr)402*01826a49SYabin Cui MEM_STATIC size_t MEM_readBEST(const void* memPtr)
403*01826a49SYabin Cui {
404*01826a49SYabin Cui     if (MEM_32bits())
405*01826a49SYabin Cui         return (size_t)MEM_readBE32(memPtr);
406*01826a49SYabin Cui     else
407*01826a49SYabin Cui         return (size_t)MEM_readBE64(memPtr);
408*01826a49SYabin Cui }
409*01826a49SYabin Cui 
MEM_writeBEST(void * memPtr,size_t val)410*01826a49SYabin Cui MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
411*01826a49SYabin Cui {
412*01826a49SYabin Cui     if (MEM_32bits())
413*01826a49SYabin Cui         MEM_writeBE32(memPtr, (U32)val);
414*01826a49SYabin Cui     else
415*01826a49SYabin Cui         MEM_writeBE64(memPtr, (U64)val);
416*01826a49SYabin Cui }
417*01826a49SYabin Cui 
418*01826a49SYabin Cui /* code only tested on 32 and 64 bits systems */
MEM_check(void)419*01826a49SYabin Cui MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
420*01826a49SYabin Cui 
421*01826a49SYabin Cui 
422*01826a49SYabin Cui #if defined (__cplusplus)
423*01826a49SYabin Cui }
424*01826a49SYabin Cui #endif
425*01826a49SYabin Cui 
426*01826a49SYabin Cui #endif /* MEM_H_MODULE */
427