Path: blob/main/Modules/_hacl/include/krml/lowstar_endianness.h
12 views
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.1Licensed under the Apache 2.0 License. */23#ifndef __LOWSTAR_ENDIANNESS_H4#define __LOWSTAR_ENDIANNESS_H56#include <string.h>7#include <inttypes.h>89/******************************************************************************/10/* Implementing C.fst (part 2: endian-ness macros) */11/******************************************************************************/1213/* ... for Linux */14#if defined(__linux__) || defined(__CYGWIN__) || defined (__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__)15# include <endian.h>1617/* ... for OSX */18#elif defined(__APPLE__)19# include <libkern/OSByteOrder.h>20# define htole64(x) OSSwapHostToLittleInt64(x)21# define le64toh(x) OSSwapLittleToHostInt64(x)22# define htobe64(x) OSSwapHostToBigInt64(x)23# define be64toh(x) OSSwapBigToHostInt64(x)2425# define htole16(x) OSSwapHostToLittleInt16(x)26# define le16toh(x) OSSwapLittleToHostInt16(x)27# define htobe16(x) OSSwapHostToBigInt16(x)28# define be16toh(x) OSSwapBigToHostInt16(x)2930# define htole32(x) OSSwapHostToLittleInt32(x)31# define le32toh(x) OSSwapLittleToHostInt32(x)32# define htobe32(x) OSSwapHostToBigInt32(x)33# define be32toh(x) OSSwapBigToHostInt32(x)3435/* ... for Solaris */36#elif defined(__sun__)37# include <sys/byteorder.h>38# define htole64(x) LE_64(x)39# define le64toh(x) LE_64(x)40# define htobe64(x) BE_64(x)41# define be64toh(x) BE_64(x)4243# define htole16(x) LE_16(x)44# define le16toh(x) LE_16(x)45# define htobe16(x) BE_16(x)46# define be16toh(x) BE_16(x)4748# define htole32(x) LE_32(x)49# define le32toh(x) LE_32(x)50# define htobe32(x) BE_32(x)51# define be32toh(x) BE_32(x)5253/* ... for the BSDs */54#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)55# include <sys/endian.h>56#elif defined(__OpenBSD__)57# include <endian.h>5859/* ... for Windows (MSVC)... not targeting XBOX 360! */60#elif defined(_MSC_VER)6162# include <stdlib.h>63# define htobe16(x) _byteswap_ushort(x)64# define htole16(x) (x)65# define be16toh(x) _byteswap_ushort(x)66# define le16toh(x) (x)6768# define htobe32(x) _byteswap_ulong(x)69# define htole32(x) (x)70# define be32toh(x) _byteswap_ulong(x)71# define le32toh(x) (x)7273# define htobe64(x) _byteswap_uint64(x)74# define htole64(x) (x)75# define be64toh(x) _byteswap_uint64(x)76# define le64toh(x) (x)7778/* ... for Windows (GCC-like, e.g. mingw or clang) */79#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \80(defined(__GNUC__) || defined(__clang__))8182# define htobe16(x) __builtin_bswap16(x)83# define htole16(x) (x)84# define be16toh(x) __builtin_bswap16(x)85# define le16toh(x) (x)8687# define htobe32(x) __builtin_bswap32(x)88# define htole32(x) (x)89# define be32toh(x) __builtin_bswap32(x)90# define le32toh(x) (x)9192# define htobe64(x) __builtin_bswap64(x)93# define htole64(x) (x)94# define be64toh(x) __builtin_bswap64(x)95# define le64toh(x) (x)9697/* ... generic big-endian fallback code */98/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */99#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX)100101/* byte swapping code inspired by:102* https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h103* */104105# define htobe32(x) (x)106# define be32toh(x) (x)107# define htole32(x) \108(__extension__({ \109uint32_t _temp = (x); \110((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \111((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \112}))113# define le32toh(x) (htole32((x)))114115# define htobe64(x) (x)116# define be64toh(x) (x)117# define htole64(x) \118(__extension__({ \119uint64_t __temp = (x); \120uint32_t __low = htobe32((uint32_t)__temp); \121uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \122(((uint64_t)__low) << 32) | __high; \123}))124# define le64toh(x) (htole64((x)))125126/* ... generic little-endian fallback code */127#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__128129# define htole32(x) (x)130# define le32toh(x) (x)131# define htobe32(x) \132(__extension__({ \133uint32_t _temp = (x); \134((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \135((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \136}))137# define be32toh(x) (htobe32((x)))138139# define htole64(x) (x)140# define le64toh(x) (x)141# define htobe64(x) \142(__extension__({ \143uint64_t __temp = (x); \144uint32_t __low = htobe32((uint32_t)__temp); \145uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \146(((uint64_t)__low) << 32) | __high; \147}))148# define be64toh(x) (htobe64((x)))149150/* ... couldn't determine endian-ness of the target platform */151#else152# error "Please define __BYTE_ORDER__!"153154#endif /* defined(__linux__) || ... */155156/* Loads and stores. These avoid undefined behavior due to unaligned memory157* accesses, via memcpy. */158159inline static uint16_t load16(uint8_t *b) {160uint16_t x;161memcpy(&x, b, 2);162return x;163}164165inline static uint32_t load32(uint8_t *b) {166uint32_t x;167memcpy(&x, b, 4);168return x;169}170171inline static uint64_t load64(uint8_t *b) {172uint64_t x;173memcpy(&x, b, 8);174return x;175}176177inline static void store16(uint8_t *b, uint16_t i) {178memcpy(b, &i, 2);179}180181inline static void store32(uint8_t *b, uint32_t i) {182memcpy(b, &i, 4);183}184185inline static void store64(uint8_t *b, uint64_t i) {186memcpy(b, &i, 8);187}188189/* Legacy accessors so that this header can serve as an implementation of190* C.Endianness */191#define load16_le(b) (le16toh(load16(b)))192#define store16_le(b, i) (store16(b, htole16(i)))193#define load16_be(b) (be16toh(load16(b)))194#define store16_be(b, i) (store16(b, htobe16(i)))195196#define load32_le(b) (le32toh(load32(b)))197#define store32_le(b, i) (store32(b, htole32(i)))198#define load32_be(b) (be32toh(load32(b)))199#define store32_be(b, i) (store32(b, htobe32(i)))200201#define load64_le(b) (le64toh(load64(b)))202#define store64_le(b, i) (store64(b, htole64(i)))203#define load64_be(b) (be64toh(load64(b)))204#define store64_be(b, i) (store64(b, htobe64(i)))205206/* Co-existence of LowStar.Endianness and FStar.Endianness generates name207* conflicts, because of course both insist on having no prefixes. Until a208* prefix is added, or until we truly retire FStar.Endianness, solve this issue209* in an elegant way. */210#define load16_le0 load16_le211#define store16_le0 store16_le212#define load16_be0 load16_be213#define store16_be0 store16_be214215#define load32_le0 load32_le216#define store32_le0 store32_le217#define load32_be0 load32_be218#define store32_be0 store32_be219220#define load64_le0 load64_le221#define store64_le0 store64_le222#define load64_be0 load64_be223#define store64_be0 store64_be224225#define load128_le0 load128_le226#define store128_le0 store128_le227#define load128_be0 load128_be228#define store128_be0 store128_be229230#endif231232233