-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3228e7c
commit 5e46998
Showing
2 changed files
with
232 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache 2.0 and MIT Licenses. */ | ||
|
||
#ifndef __LOWSTAR_ENDIANNESS_H | ||
#define __LOWSTAR_ENDIANNESS_H | ||
|
||
#include <inttypes.h> | ||
#include <string.h> | ||
|
||
/******************************************************************************/ | ||
/* Implementing C.fst (part 2: endian-ness macros) */ | ||
/******************************************************************************/ | ||
|
||
/* ... for Linux */ | ||
#if defined(__linux__) || defined(__CYGWIN__) || \ | ||
defined(__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__) | ||
#include <endian.h> | ||
|
||
/* ... for OSX */ | ||
#elif defined(__APPLE__) | ||
#include <libkern/OSByteOrder.h> | ||
#define htole64(x) OSSwapHostToLittleInt64(x) | ||
#define le64toh(x) OSSwapLittleToHostInt64(x) | ||
#define htobe64(x) OSSwapHostToBigInt64(x) | ||
#define be64toh(x) OSSwapBigToHostInt64(x) | ||
|
||
#define htole16(x) OSSwapHostToLittleInt16(x) | ||
#define le16toh(x) OSSwapLittleToHostInt16(x) | ||
#define htobe16(x) OSSwapHostToBigInt16(x) | ||
#define be16toh(x) OSSwapBigToHostInt16(x) | ||
|
||
#define htole32(x) OSSwapHostToLittleInt32(x) | ||
#define le32toh(x) OSSwapLittleToHostInt32(x) | ||
#define htobe32(x) OSSwapHostToBigInt32(x) | ||
#define be32toh(x) OSSwapBigToHostInt32(x) | ||
|
||
/* ... for Solaris */ | ||
#elif defined(__sun__) | ||
#include <sys/byteorder.h> | ||
#define htole64(x) LE_64(x) | ||
#define le64toh(x) LE_64(x) | ||
#define htobe64(x) BE_64(x) | ||
#define be64toh(x) BE_64(x) | ||
|
||
#define htole16(x) LE_16(x) | ||
#define le16toh(x) LE_16(x) | ||
#define htobe16(x) BE_16(x) | ||
#define be16toh(x) BE_16(x) | ||
|
||
#define htole32(x) LE_32(x) | ||
#define le32toh(x) LE_32(x) | ||
#define htobe32(x) BE_32(x) | ||
#define be32toh(x) BE_32(x) | ||
|
||
/* ... for the BSDs */ | ||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) | ||
#include <sys/endian.h> | ||
#elif defined(__OpenBSD__) | ||
#include <endian.h> | ||
|
||
/* ... for Windows (MSVC)... not targeting XBOX 360! */ | ||
#elif defined(_MSC_VER) | ||
|
||
#include <stdlib.h> | ||
#define htobe16(x) _byteswap_ushort(x) | ||
#define htole16(x) (x) | ||
#define be16toh(x) _byteswap_ushort(x) | ||
#define le16toh(x) (x) | ||
|
||
#define htobe32(x) _byteswap_ulong(x) | ||
#define htole32(x) (x) | ||
#define be32toh(x) _byteswap_ulong(x) | ||
#define le32toh(x) (x) | ||
|
||
#define htobe64(x) _byteswap_uint64(x) | ||
#define htole64(x) (x) | ||
#define be64toh(x) _byteswap_uint64(x) | ||
#define le64toh(x) (x) | ||
|
||
/* ... for Windows (GCC-like, e.g. mingw or clang) */ | ||
#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \ | ||
(defined(__GNUC__) || defined(__clang__)) | ||
|
||
#define htobe16(x) __builtin_bswap16(x) | ||
#define htole16(x) (x) | ||
#define be16toh(x) __builtin_bswap16(x) | ||
#define le16toh(x) (x) | ||
|
||
#define htobe32(x) __builtin_bswap32(x) | ||
#define htole32(x) (x) | ||
#define be32toh(x) __builtin_bswap32(x) | ||
#define le32toh(x) (x) | ||
|
||
#define htobe64(x) __builtin_bswap64(x) | ||
#define htole64(x) (x) | ||
#define be64toh(x) __builtin_bswap64(x) | ||
#define le64toh(x) (x) | ||
|
||
/* ... generic big-endian fallback code */ | ||
/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always | ||
* big-endian */ | ||
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ | ||
defined(_AIX) | ||
|
||
/* byte swapping code inspired by: | ||
* https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h | ||
* */ | ||
|
||
#define htobe32(x) (x) | ||
#define be32toh(x) (x) | ||
#define htole32(x) \ | ||
(__extension__({ \ | ||
uint32_t _temp = (x); \ | ||
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ | ||
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ | ||
})) | ||
#define le32toh(x) (htole32((x))) | ||
|
||
#define htobe64(x) (x) | ||
#define be64toh(x) (x) | ||
#define htole64(x) \ | ||
(__extension__({ \ | ||
uint64_t __temp = (x); \ | ||
uint32_t __low = htobe32((uint32_t)__temp); \ | ||
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ | ||
(((uint64_t)__low) << 32) | __high; \ | ||
})) | ||
#define le64toh(x) (htole64((x))) | ||
|
||
/* ... generic little-endian fallback code */ | ||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | ||
|
||
#define htole32(x) (x) | ||
#define le32toh(x) (x) | ||
#define htobe32(x) \ | ||
(__extension__({ \ | ||
uint32_t _temp = (x); \ | ||
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ | ||
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ | ||
})) | ||
#define be32toh(x) (htobe32((x))) | ||
|
||
#define htole64(x) (x) | ||
#define le64toh(x) (x) | ||
#define htobe64(x) \ | ||
(__extension__({ \ | ||
uint64_t __temp = (x); \ | ||
uint32_t __low = htobe32((uint32_t)__temp); \ | ||
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ | ||
(((uint64_t)__low) << 32) | __high; \ | ||
})) | ||
#define be64toh(x) (htobe64((x))) | ||
|
||
/* ... couldn't determine endian-ness of the target platform */ | ||
#else | ||
#error "Please define __BYTE_ORDER__!" | ||
|
||
#endif /* defined(__linux__) || ... */ | ||
|
||
/* Loads and stores. These avoid undefined behavior due to unaligned memory | ||
* accesses, via memcpy. */ | ||
|
||
inline static uint16_t load16(uint8_t *b) { | ||
uint16_t x; | ||
memcpy(&x, b, 2); | ||
return x; | ||
} | ||
|
||
inline static uint32_t load32(uint8_t *b) { | ||
uint32_t x; | ||
memcpy(&x, b, 4); | ||
return x; | ||
} | ||
|
||
inline static uint64_t load64(uint8_t *b) { | ||
uint64_t x; | ||
memcpy(&x, b, 8); | ||
return x; | ||
} | ||
|
||
inline static void store16(uint8_t *b, uint16_t i) { memcpy(b, &i, 2); } | ||
|
||
inline static void store32(uint8_t *b, uint32_t i) { memcpy(b, &i, 4); } | ||
|
||
inline static void store64(uint8_t *b, uint64_t i) { memcpy(b, &i, 8); } | ||
|
||
/* Legacy accessors so that this header can serve as an implementation of | ||
* C.Endianness */ | ||
#define load16_le(b) (le16toh(load16(b))) | ||
#define store16_le(b, i) (store16(b, htole16(i))) | ||
#define load16_be(b) (be16toh(load16(b))) | ||
#define store16_be(b, i) (store16(b, htobe16(i))) | ||
|
||
#define load32_le(b) (le32toh(load32(b))) | ||
#define store32_le(b, i) (store32(b, htole32(i))) | ||
#define load32_be(b) (be32toh(load32(b))) | ||
#define store32_be(b, i) (store32(b, htobe32(i))) | ||
|
||
#define load64_le(b) (le64toh(load64(b))) | ||
#define store64_le(b, i) (store64(b, htole64(i))) | ||
#define load64_be(b) (be64toh(load64(b))) | ||
#define store64_be(b, i) (store64(b, htobe64(i))) | ||
|
||
/* Co-existence of LowStar.Endianness and FStar.Endianness generates name | ||
* conflicts, because of course both insist on having no prefixes. Until a | ||
* prefix is added, or until we truly retire FStar.Endianness, solve this issue | ||
* in an elegant way. */ | ||
#define load16_le0 load16_le | ||
#define store16_le0 store16_le | ||
#define load16_be0 load16_be | ||
#define store16_be0 store16_be | ||
|
||
#define load32_le0 load32_le | ||
#define store32_le0 store32_le | ||
#define load32_be0 load32_be | ||
#define store32_be0 store32_be | ||
|
||
#define load64_le0 load64_le | ||
#define store64_le0 store64_le | ||
#define load64_be0 load64_be | ||
#define store64_be0 store64_be | ||
|
||
#define load128_le0 load128_le | ||
#define store128_le0 store128_le | ||
#define load128_be0 load128_be | ||
#define store128_be0 store128_be | ||
|
||
#endif |