Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Modules/_hacl/include/krml/lowstar_endianness.h
12 views
1
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
2
Licensed under the Apache 2.0 License. */
3
4
#ifndef __LOWSTAR_ENDIANNESS_H
5
#define __LOWSTAR_ENDIANNESS_H
6
7
#include <string.h>
8
#include <inttypes.h>
9
10
/******************************************************************************/
11
/* Implementing C.fst (part 2: endian-ness macros) */
12
/******************************************************************************/
13
14
/* ... for Linux */
15
#if defined(__linux__) || defined(__CYGWIN__) || defined (__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__)
16
# include <endian.h>
17
18
/* ... for OSX */
19
#elif defined(__APPLE__)
20
# include <libkern/OSByteOrder.h>
21
# define htole64(x) OSSwapHostToLittleInt64(x)
22
# define le64toh(x) OSSwapLittleToHostInt64(x)
23
# define htobe64(x) OSSwapHostToBigInt64(x)
24
# define be64toh(x) OSSwapBigToHostInt64(x)
25
26
# define htole16(x) OSSwapHostToLittleInt16(x)
27
# define le16toh(x) OSSwapLittleToHostInt16(x)
28
# define htobe16(x) OSSwapHostToBigInt16(x)
29
# define be16toh(x) OSSwapBigToHostInt16(x)
30
31
# define htole32(x) OSSwapHostToLittleInt32(x)
32
# define le32toh(x) OSSwapLittleToHostInt32(x)
33
# define htobe32(x) OSSwapHostToBigInt32(x)
34
# define be32toh(x) OSSwapBigToHostInt32(x)
35
36
/* ... for Solaris */
37
#elif defined(__sun__)
38
# include <sys/byteorder.h>
39
# define htole64(x) LE_64(x)
40
# define le64toh(x) LE_64(x)
41
# define htobe64(x) BE_64(x)
42
# define be64toh(x) BE_64(x)
43
44
# define htole16(x) LE_16(x)
45
# define le16toh(x) LE_16(x)
46
# define htobe16(x) BE_16(x)
47
# define be16toh(x) BE_16(x)
48
49
# define htole32(x) LE_32(x)
50
# define le32toh(x) LE_32(x)
51
# define htobe32(x) BE_32(x)
52
# define be32toh(x) BE_32(x)
53
54
/* ... for the BSDs */
55
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
56
# include <sys/endian.h>
57
#elif defined(__OpenBSD__)
58
# include <endian.h>
59
60
/* ... for Windows (MSVC)... not targeting XBOX 360! */
61
#elif defined(_MSC_VER)
62
63
# include <stdlib.h>
64
# define htobe16(x) _byteswap_ushort(x)
65
# define htole16(x) (x)
66
# define be16toh(x) _byteswap_ushort(x)
67
# define le16toh(x) (x)
68
69
# define htobe32(x) _byteswap_ulong(x)
70
# define htole32(x) (x)
71
# define be32toh(x) _byteswap_ulong(x)
72
# define le32toh(x) (x)
73
74
# define htobe64(x) _byteswap_uint64(x)
75
# define htole64(x) (x)
76
# define be64toh(x) _byteswap_uint64(x)
77
# define le64toh(x) (x)
78
79
/* ... for Windows (GCC-like, e.g. mingw or clang) */
80
#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \
81
(defined(__GNUC__) || defined(__clang__))
82
83
# define htobe16(x) __builtin_bswap16(x)
84
# define htole16(x) (x)
85
# define be16toh(x) __builtin_bswap16(x)
86
# define le16toh(x) (x)
87
88
# define htobe32(x) __builtin_bswap32(x)
89
# define htole32(x) (x)
90
# define be32toh(x) __builtin_bswap32(x)
91
# define le32toh(x) (x)
92
93
# define htobe64(x) __builtin_bswap64(x)
94
# define htole64(x) (x)
95
# define be64toh(x) __builtin_bswap64(x)
96
# define le64toh(x) (x)
97
98
/* ... generic big-endian fallback code */
99
/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */
100
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX)
101
102
/* byte swapping code inspired by:
103
* https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h
104
* */
105
106
# define htobe32(x) (x)
107
# define be32toh(x) (x)
108
# define htole32(x) \
109
(__extension__({ \
110
uint32_t _temp = (x); \
111
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
112
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
113
}))
114
# define le32toh(x) (htole32((x)))
115
116
# define htobe64(x) (x)
117
# define be64toh(x) (x)
118
# define htole64(x) \
119
(__extension__({ \
120
uint64_t __temp = (x); \
121
uint32_t __low = htobe32((uint32_t)__temp); \
122
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
123
(((uint64_t)__low) << 32) | __high; \
124
}))
125
# define le64toh(x) (htole64((x)))
126
127
/* ... generic little-endian fallback code */
128
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
129
130
# define htole32(x) (x)
131
# define le32toh(x) (x)
132
# define htobe32(x) \
133
(__extension__({ \
134
uint32_t _temp = (x); \
135
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
136
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
137
}))
138
# define be32toh(x) (htobe32((x)))
139
140
# define htole64(x) (x)
141
# define le64toh(x) (x)
142
# define htobe64(x) \
143
(__extension__({ \
144
uint64_t __temp = (x); \
145
uint32_t __low = htobe32((uint32_t)__temp); \
146
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
147
(((uint64_t)__low) << 32) | __high; \
148
}))
149
# define be64toh(x) (htobe64((x)))
150
151
/* ... couldn't determine endian-ness of the target platform */
152
#else
153
# error "Please define __BYTE_ORDER__!"
154
155
#endif /* defined(__linux__) || ... */
156
157
/* Loads and stores. These avoid undefined behavior due to unaligned memory
158
* accesses, via memcpy. */
159
160
inline static uint16_t load16(uint8_t *b) {
161
uint16_t x;
162
memcpy(&x, b, 2);
163
return x;
164
}
165
166
inline static uint32_t load32(uint8_t *b) {
167
uint32_t x;
168
memcpy(&x, b, 4);
169
return x;
170
}
171
172
inline static uint64_t load64(uint8_t *b) {
173
uint64_t x;
174
memcpy(&x, b, 8);
175
return x;
176
}
177
178
inline static void store16(uint8_t *b, uint16_t i) {
179
memcpy(b, &i, 2);
180
}
181
182
inline static void store32(uint8_t *b, uint32_t i) {
183
memcpy(b, &i, 4);
184
}
185
186
inline static void store64(uint8_t *b, uint64_t i) {
187
memcpy(b, &i, 8);
188
}
189
190
/* Legacy accessors so that this header can serve as an implementation of
191
* C.Endianness */
192
#define load16_le(b) (le16toh(load16(b)))
193
#define store16_le(b, i) (store16(b, htole16(i)))
194
#define load16_be(b) (be16toh(load16(b)))
195
#define store16_be(b, i) (store16(b, htobe16(i)))
196
197
#define load32_le(b) (le32toh(load32(b)))
198
#define store32_le(b, i) (store32(b, htole32(i)))
199
#define load32_be(b) (be32toh(load32(b)))
200
#define store32_be(b, i) (store32(b, htobe32(i)))
201
202
#define load64_le(b) (le64toh(load64(b)))
203
#define store64_le(b, i) (store64(b, htole64(i)))
204
#define load64_be(b) (be64toh(load64(b)))
205
#define store64_be(b, i) (store64(b, htobe64(i)))
206
207
/* Co-existence of LowStar.Endianness and FStar.Endianness generates name
208
* conflicts, because of course both insist on having no prefixes. Until a
209
* prefix is added, or until we truly retire FStar.Endianness, solve this issue
210
* in an elegant way. */
211
#define load16_le0 load16_le
212
#define store16_le0 store16_le
213
#define load16_be0 load16_be
214
#define store16_be0 store16_be
215
216
#define load32_le0 load32_le
217
#define store32_le0 store32_le
218
#define load32_be0 load32_be
219
#define store32_be0 store32_be
220
221
#define load64_le0 load64_le
222
#define store64_le0 store64_le
223
#define load64_be0 load64_be
224
#define store64_be0 store64_be
225
226
#define load128_le0 load128_le
227
#define store128_le0 store128_le
228
#define load128_be0 load128_be
229
#define store128_be0 store128_be
230
231
#endif
232
233