ReactOS  0.4.13-dev-100-gc8611ae
mem.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10 
11 #ifndef MEM_H_MODULE
12 #define MEM_H_MODULE
13 
14 #if defined (__cplusplus)
15 extern "C" {
16 #endif
17 
18 /*-****************************************
19 * Dependencies
20 ******************************************/
21 #include <stddef.h> /* size_t, ptrdiff_t */
22 #include <string.h> /* memcpy */
23 
24 
25 /*-****************************************
26 * Compiler specifics
27 ******************************************/
28 #if defined(_MSC_VER) /* Visual Studio */
29 # include <stdlib.h> /* _byteswap_ulong */
30 # include <intrin.h> /* _byteswap_* */
31 #endif
32 #if defined(__GNUC__)
33 # define MEM_STATIC static __inline __attribute__((unused))
34 #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
35 # define MEM_STATIC static inline
36 #elif defined(_MSC_VER)
37 # define MEM_STATIC static __inline
38 #else
39 # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
40 #endif
41 
42 #ifndef __has_builtin
43 # define __has_builtin(x) 0 /* compat. with non-clang compilers */
44 #endif
45 
46 /* code only tested on 32 and 64 bits systems */
47 #define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
48 MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
49 
50 
51 /*-**************************************************************
52 * Basic Types
53 *****************************************************************/
54 #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
55 # include <stdint.h>
56  typedef uint8_t BYTE;
57  typedef uint16_t U16;
58  typedef int16_t S16;
59  typedef uint32_t U32;
60  typedef int32_t S32;
61  typedef uint64_t U64;
62  typedef int64_t S64;
63 #else
64 # include <limits.h>
65 #if CHAR_BIT != 8
66 # error "this implementation requires char to be exactly 8-bit type"
67 #endif
68  typedef unsigned char BYTE;
69 #if USHRT_MAX != 65535
70 # error "this implementation requires short to be exactly 16-bit type"
71 #endif
72  typedef unsigned short U16;
73  typedef signed short S16;
74 #if UINT_MAX != 4294967295
75 # error "this implementation requires int to be exactly 32-bit type"
76 #endif
77  typedef unsigned int U32;
78  typedef signed int S32;
79 /* note : there are no limits defined for long long type in C90.
80  * limits exist in C99, however, in such case, <stdint.h> is preferred */
81  typedef unsigned long long U64;
82  typedef signed long long S64;
83 #endif
84 
85 
86 /*-**************************************************************
87 * Memory I/O
88 *****************************************************************/
89 /* MEM_FORCE_MEMORY_ACCESS :
90  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
91  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
92  * The below switch allow to select different access method for improved performance.
93  * Method 0 (default) : use `memcpy()`. Safe and portable.
94  * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable).
95  * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
96  * Method 2 : direct access. This method is portable but violate C standard.
97  * It can generate buggy code on targets depending on alignment.
98  * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6)
99  * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
100  * Prefer these methods in priority order (0 > 1 > 2)
101  */
102 #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
103 # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
104 # define MEM_FORCE_MEMORY_ACCESS 2
105 # elif defined(__INTEL_COMPILER) || defined(__GNUC__)
106 # define MEM_FORCE_MEMORY_ACCESS 1
107 # endif
108 #endif
109 
110 MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
111 MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
112 
114 {
115  const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
116  return one.c[0];
117 }
118 
119 #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
120 
121 /* violates C standard, by lying on structure alignment.
122 Only use if no other choice to achieve best performance on target platform */
123 MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
124 MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
125 MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
126 MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
127 
128 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
129 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
130 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
131 
132 #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
133 
134 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
135 /* currently only defined for gcc and icc */
136 #if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
137  __pragma( pack(push, 1) )
138  typedef struct { U16 v; } unalign16;
139  typedef struct { U32 v; } unalign32;
140  typedef struct { U64 v; } unalign64;
141  typedef struct { size_t v; } unalignArch;
142  __pragma( pack(pop) )
143 #else
144  typedef struct { U16 v; } __attribute__((packed)) unalign16;
145  typedef struct { U32 v; } __attribute__((packed)) unalign32;
146  typedef struct { U64 v; } __attribute__((packed)) unalign64;
147  typedef struct { size_t v; } __attribute__((packed)) unalignArch;
148 #endif
149 
150 MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; }
151 MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; }
152 MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; }
153 MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; }
154 
155 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; }
156 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; }
157 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; }
158 
159 #else
160 
161 /* default method, safe and standard.
162  can sometimes prove slower */
163 
164 MEM_STATIC U16 MEM_read16(const void* memPtr)
165 {
166  U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
167 }
168 
169 MEM_STATIC U32 MEM_read32(const void* memPtr)
170 {
171  U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
172 }
173 
174 MEM_STATIC U64 MEM_read64(const void* memPtr)
175 {
176  U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
177 }
178 
179 MEM_STATIC size_t MEM_readST(const void* memPtr)
180 {
181  size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
182 }
183 
184 MEM_STATIC void MEM_write16(void* memPtr, U16 value)
185 {
186  memcpy(memPtr, &value, sizeof(value));
187 }
188 
189 MEM_STATIC void MEM_write32(void* memPtr, U32 value)
190 {
191  memcpy(memPtr, &value, sizeof(value));
192 }
193 
194 MEM_STATIC void MEM_write64(void* memPtr, U64 value)
195 {
196  memcpy(memPtr, &value, sizeof(value));
197 }
198 
199 #endif /* MEM_FORCE_MEMORY_ACCESS */
200 
202 {
203 #if (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
204  || (defined(__clang__) && __has_builtin(__builtin_bswap32))
205  return __builtin_bswap32(in);
206 #else
207  return ((in << 24) & 0xff000000 ) |
208  ((in << 8) & 0x00ff0000 ) |
209  ((in >> 8) & 0x0000ff00 ) |
210  ((in >> 24) & 0x000000ff );
211 #endif
212 }
213 
215 {
216 #if (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
217  || (defined(__clang__) && __has_builtin(__builtin_bswap64))
218  return __builtin_bswap64(in);
219 #else
220  return ((in << 56) & 0xff00000000000000ULL) |
221  ((in << 40) & 0x00ff000000000000ULL) |
222  ((in << 24) & 0x0000ff0000000000ULL) |
223  ((in << 8) & 0x000000ff00000000ULL) |
224  ((in >> 8) & 0x00000000ff000000ULL) |
225  ((in >> 24) & 0x0000000000ff0000ULL) |
226  ((in >> 40) & 0x000000000000ff00ULL) |
227  ((in >> 56) & 0x00000000000000ffULL);
228 #endif
229 }
230 
231 MEM_STATIC size_t MEM_swapST(size_t in)
232 {
233  if (MEM_32bits())
234  return (size_t)MEM_swap32((U32)in);
235  else
236  return (size_t)MEM_swap64((U64)in);
237 }
238 
239 /*=== Little endian r/w ===*/
240 
241 MEM_STATIC U16 MEM_readLE16(const void* memPtr)
242 {
243  if (MEM_isLittleEndian())
244  return MEM_read16(memPtr);
245  else {
246  const BYTE* p = (const BYTE*)memPtr;
247  return (U16)(p[0] + (p[1]<<8));
248  }
249 }
250 
251 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
252 {
253  if (MEM_isLittleEndian()) {
254  MEM_write16(memPtr, val);
255  } else {
256  BYTE* p = (BYTE*)memPtr;
257  p[0] = (BYTE)val;
258  p[1] = (BYTE)(val>>8);
259  }
260 }
261 
262 MEM_STATIC U32 MEM_readLE24(const void* memPtr)
263 {
264  return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
265 }
266 
267 MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
268 {
269  MEM_writeLE16(memPtr, (U16)val);
270  ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
271 }
272 
273 MEM_STATIC U32 MEM_readLE32(const void* memPtr)
274 {
275  if (MEM_isLittleEndian())
276  return MEM_read32(memPtr);
277  else
278  return MEM_swap32(MEM_read32(memPtr));
279 }
280 
281 MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
282 {
283  if (MEM_isLittleEndian())
284  MEM_write32(memPtr, val32);
285  else
286  MEM_write32(memPtr, MEM_swap32(val32));
287 }
288 
289 MEM_STATIC U64 MEM_readLE64(const void* memPtr)
290 {
291  if (MEM_isLittleEndian())
292  return MEM_read64(memPtr);
293  else
294  return MEM_swap64(MEM_read64(memPtr));
295 }
296 
297 MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
298 {
299  if (MEM_isLittleEndian())
300  MEM_write64(memPtr, val64);
301  else
302  MEM_write64(memPtr, MEM_swap64(val64));
303 }
304 
305 MEM_STATIC size_t MEM_readLEST(const void* memPtr)
306 {
307  if (MEM_32bits())
308  return (size_t)MEM_readLE32(memPtr);
309  else
310  return (size_t)MEM_readLE64(memPtr);
311 }
312 
313 MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
314 {
315  if (MEM_32bits())
316  MEM_writeLE32(memPtr, (U32)val);
317  else
318  MEM_writeLE64(memPtr, (U64)val);
319 }
320 
321 /*=== Big endian r/w ===*/
322 
323 MEM_STATIC U32 MEM_readBE32(const void* memPtr)
324 {
325  if (MEM_isLittleEndian())
326  return MEM_swap32(MEM_read32(memPtr));
327  else
328  return MEM_read32(memPtr);
329 }
330 
331 MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
332 {
333  if (MEM_isLittleEndian())
334  MEM_write32(memPtr, MEM_swap32(val32));
335  else
336  MEM_write32(memPtr, val32);
337 }
338 
339 MEM_STATIC U64 MEM_readBE64(const void* memPtr)
340 {
341  if (MEM_isLittleEndian())
342  return MEM_swap64(MEM_read64(memPtr));
343  else
344  return MEM_read64(memPtr);
345 }
346 
347 MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
348 {
349  if (MEM_isLittleEndian())
350  MEM_write64(memPtr, MEM_swap64(val64));
351  else
352  MEM_write64(memPtr, val64);
353 }
354 
355 MEM_STATIC size_t MEM_readBEST(const void* memPtr)
356 {
357  if (MEM_32bits())
358  return (size_t)MEM_readBE32(memPtr);
359  else
360  return (size_t)MEM_readBE64(memPtr);
361 }
362 
363 MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
364 {
365  if (MEM_32bits())
366  MEM_writeBE32(memPtr, (U32)val);
367  else
368  MEM_writeBE64(memPtr, (U64)val);
369 }
370 
371 
372 #if defined (__cplusplus)
373 }
374 #endif
375 
376 #endif /* MEM_H_MODULE */
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
unsigned short U16
Definition: mem.h:72
MEM_STATIC U64 MEM_swap64(U64 in)
Definition: mem.h:214
MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
Definition: mem.h:251
MEM_STATIC size_t MEM_readST(const void *memPtr)
Definition: mem.h:179
MEM_STATIC U64 MEM_readBE64(const void *memPtr)
Definition: mem.h:339
MEM_STATIC unsigned MEM_isLittleEndian(void)
Definition: mem.h:113
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
MEM_STATIC U32 MEM_readLE32(const void *memPtr)
Definition: mem.h:273
unsigned int U32
Definition: mem.h:77
MEM_STATIC size_t MEM_readLEST(const void *memPtr)
Definition: mem.h:305
MEM_STATIC unsigned MEM_32bits(void)
Definition: mem.h:110
MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
Definition: mem.h:297
MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
Definition: mem.h:363
unsigned short int uint16_t
Definition: acefiex.h:54
#define __attribute__(Spec)
Definition: hlsl.tab.c:1213
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
MEM_STATIC U64 MEM_readLE64(const void *memPtr)
Definition: mem.h:289
MEM_STATIC unsigned MEM_64bits(void)
Definition: mem.h:111
MEM_STATIC void MEM_write16(void *memPtr, U16 value)
Definition: mem.h:184
static double one
Definition: j0_y0.c:80
MEM_STATIC U64 MEM_read64(const void *memPtr)
Definition: mem.h:174
MEM_STATIC U32 MEM_swap32(U32 in)
Definition: mem.h:201
static PVOID ptr
Definition: dispmode.c:27
MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
Definition: mem.h:281
#define MEM_STATIC_ASSERT(c)
Definition: mem.h:47
GLuint GLfloat * val
Definition: glext.h:7180
MEM_STATIC U16 MEM_readLE16(const void *memPtr)
Definition: mem.h:241
__kernel_size_t size_t
Definition: linux.h:237
MEM_STATIC size_t MEM_swapST(size_t in)
Definition: mem.h:231
signed int S32
Definition: mem.h:78
MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
Definition: mem.h:347
MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
Definition: mem.h:313
#define MEM_STATIC
Definition: mem.h:39
MEM_STATIC size_t MEM_readBEST(const void *memPtr)
Definition: mem.h:355
const GLubyte * c
Definition: glext.h:8905
MEM_STATIC U32 MEM_read32(const void *memPtr)
Definition: mem.h:169
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
Definition: mem.h:331
BYTE uint8_t
Definition: msvideo1.c:66
GLsizei const GLfloat * value
Definition: glext.h:6069
INT32 int32_t
Definition: types.h:71
UINT64 uint64_t
Definition: types.h:77
const GLdouble * v
Definition: gl.h:2040
GLuint in
Definition: glext.h:9616
unsigned long long U64
Definition: mem.h:81
signed long long S64
Definition: mem.h:82
UINT32 uint32_t
Definition: types.h:75
MEM_STATIC void MEM_check(void)
Definition: mem.h:48
#define __pragma(x)
Definition: debug.h:260
MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
Definition: mem.h:267
MEM_STATIC U32 MEM_readBE32(const void *memPtr)
Definition: mem.h:323
signed short S16
Definition: mem.h:73
MEM_STATIC void MEM_write32(void *memPtr, U32 value)
Definition: mem.h:189
INT16 int16_t
Definition: types.h:70
GLfloat GLfloat p
Definition: glext.h:8902
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
MEM_STATIC void MEM_write64(void *memPtr, U64 value)
Definition: mem.h:194
MEM_STATIC U16 MEM_read16(const void *memPtr)
Definition: mem.h:164
INT64 int64_t
Definition: types.h:72
MEM_STATIC U32 MEM_readLE24(const void *memPtr)
Definition: mem.h:262