cpython/Modules/_hacl/include/krml/lowstar_endianness.h

/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
   Licensed under the Apache 2.0 License. */

#ifndef __LOWSTAR_ENDIANNESS_H
#define __LOWSTAR_ENDIANNESS_H

#include <string.h>
#include <inttypes.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
#define le64toh
#define htobe64
#define be64toh

#define htole16
#define le16toh
#define htobe16
#define be16toh

#define htole32
#define le32toh
#define htobe32
#define be32toh

/* ... for Solaris */
#elif defined(__sun__)
#  include <sys/byteorder.h>
#define htole64
#define le64toh
#define htobe64
#define be64toh

#define htole16
#define le16toh
#define htobe16
#define be16toh

#define htole32
#define le32toh
#define htobe32
#define be32toh

/* ... 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
#define htole16
#define be16toh
#define le16toh

#define htobe32
#define htole32
#define be32toh
#define le32toh

#define htobe64
#define htole64
#define be64toh
#define le64toh

/* ... for Windows (GCC-like, e.g. mingw or clang) */
#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) &&       \
    (defined(__GNUC__) || defined(__clang__))

#define htobe16
#define htole16
#define be16toh
#define le16toh

#define htobe32
#define htole32
#define be32toh
#define le32toh

#define htobe64
#define htole64
#define be64toh
#define le64toh

/* ... 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
#define be32toh
#define htole32
#define le32toh

#define htobe64
#define be64toh
#define htole64
#define le64toh

/* ... generic little-endian fallback code */
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

#define htole32
#define le32toh
#define htobe32
#define be32toh

#define htole64
#define le64toh
#define htobe64
#define be64toh

/* ... 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) {}

inline static uint32_t load32(uint8_t *b) {}

inline static uint64_t load64(uint8_t *b) {}

inline static void store16(uint8_t *b, uint16_t i) {}

inline static void store32(uint8_t *b, uint32_t i) {}

inline static void store64(uint8_t *b, uint64_t i) {}

/* Legacy accessors so that this header can serve as an implementation of
 * C.Endianness */
#define load16_le(b)
#define store16_le(b, i)
#define load16_be(b)
#define store16_be(b, i)

#define load32_le(b)
#define store32_le(b, i)
#define load32_be(b)
#define store32_be(b, i)

#define load64_le(b)
#define store64_le(b, i)
#define load64_be(b)
#define store64_be(b, 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
#define store16_le0
#define load16_be0
#define store16_be0

#define load32_le0
#define store32_le0
#define load32_be0
#define store32_be0

#define load64_le0
#define store64_le0
#define load64_be0
#define store64_be0

#define load128_le0
#define store128_le0
#define load128_be0
#define store128_be0

#endif