Monero
endian.h
Go to the documentation of this file.
1 #pragma once
2 #include <stdint.h>
3 #include <string.h>
4 
5 #if defined(_MSC_VER)
6 #define FORCE_INLINE __inline
7 #elif defined(__GNUC__) || defined(__clang__)
8 #define FORCE_INLINE __inline__
9 #else
10 #define FORCE_INLINE
11 #endif
12 
13  /* Argon2 Team - Begin Code */
14  /*
15  Not an exhaustive list, but should cover the majority of modern platforms
16  Additionally, the code will always be correct---this is only a performance
17  tweak.
18  */
19 #if (defined(__BYTE_ORDER__) && \
20  (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
21  defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
22  defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
23  defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
24  defined(_M_ARM)
25 #define NATIVE_LITTLE_ENDIAN
26 #endif
27  /* Argon2 Team - End Code */
28 
29 static FORCE_INLINE uint32_t load32(const void *src) {
30 #if defined(NATIVE_LITTLE_ENDIAN)
31  uint32_t w;
32  memcpy(&w, src, sizeof w);
33  return w;
34 #else
35  const uint8_t *p = (const uint8_t *)src;
36  uint32_t w = *p++;
37  w |= (uint32_t)(*p++) << 8;
38  w |= (uint32_t)(*p++) << 16;
39  w |= (uint32_t)(*p++) << 24;
40  return w;
41 #endif
42 }
43 
44 static FORCE_INLINE uint64_t load64_native(const void *src) {
45  uint64_t w;
46  memcpy(&w, src, sizeof w);
47  return w;
48 }
49 
50 static FORCE_INLINE uint64_t load64(const void *src) {
51 #if defined(NATIVE_LITTLE_ENDIAN)
52  return load64_native(src);
53 #else
54  const uint8_t *p = (const uint8_t *)src;
55  uint64_t w = *p++;
56  w |= (uint64_t)(*p++) << 8;
57  w |= (uint64_t)(*p++) << 16;
58  w |= (uint64_t)(*p++) << 24;
59  w |= (uint64_t)(*p++) << 32;
60  w |= (uint64_t)(*p++) << 40;
61  w |= (uint64_t)(*p++) << 48;
62  w |= (uint64_t)(*p++) << 56;
63  return w;
64 #endif
65 }
66 
67 static FORCE_INLINE void store32(void *dst, uint32_t w) {
68 #if defined(NATIVE_LITTLE_ENDIAN)
69  memcpy(dst, &w, sizeof w);
70 #else
71  uint8_t *p = (uint8_t *)dst;
72  *p++ = (uint8_t)w;
73  w >>= 8;
74  *p++ = (uint8_t)w;
75  w >>= 8;
76  *p++ = (uint8_t)w;
77  w >>= 8;
78  *p++ = (uint8_t)w;
79 #endif
80 }
81 
82 static FORCE_INLINE void store64_native(void *dst, uint64_t w) {
83  memcpy(dst, &w, sizeof w);
84 }
85 
86 static FORCE_INLINE void store64(void *dst, uint64_t w) {
87 #if defined(NATIVE_LITTLE_ENDIAN)
88  store64_native(dst, w);
89 #else
90  uint8_t *p = (uint8_t *)dst;
91  *p++ = (uint8_t)w;
92  w >>= 8;
93  *p++ = (uint8_t)w;
94  w >>= 8;
95  *p++ = (uint8_t)w;
96  w >>= 8;
97  *p++ = (uint8_t)w;
98  w >>= 8;
99  *p++ = (uint8_t)w;
100  w >>= 8;
101  *p++ = (uint8_t)w;
102  w >>= 8;
103  *p++ = (uint8_t)w;
104  w >>= 8;
105  *p++ = (uint8_t)w;
106 #endif
107 }
#define FORCE_INLINE
Definition: endian.h:10
unsigned char uint8_t
Definition: stdint.h:124
static FORCE_INLINE void store64_native(void *dst, uint64_t w)
Definition: endian.h:82
static FORCE_INLINE uint64_t load64(const void *src)
Definition: endian.h:50
unsigned int uint32_t
Definition: stdint.h:126
unsigned __int64 uint64_t
Definition: stdint.h:136
static FORCE_INLINE uint64_t load64_native(const void *src)
Definition: endian.h:44
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:16
static FORCE_INLINE void store32(void *dst, uint32_t w)
Definition: endian.h:67
static FORCE_INLINE void store64(void *dst, uint64_t w)
Definition: endian.h:86
p
Definition: pymoduletest.py:75
static FORCE_INLINE uint32_t load32(const void *src)
Definition: endian.h:29