// Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef HIGHWAYHASH_ENDIANESS_H_ #define HIGHWAYHASH_ENDIANESS_H_ // WARNING: this is a "restricted" header because it is included from // translation units compiled with different flags. This header and its // dependencies must not define any function unless it is static inline and/or // within namespace HH_TARGET_NAME. See arch_specific.h for details. #include #if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) /* Someone has already included or equivalent. */ #elif defined(__LITTLE_ENDIAN__) # define HH_IS_LITTLE_ENDIAN 1 # define HH_IS_BIG_ENDIAN 0 # ifdef __BIG_ENDIAN__ # error "Platform is both little and big endian?" # endif #elif defined(__BIG_ENDIAN__) # define HH_IS_LITTLE_ENDIAN 0 # define HH_IS_BIG_ENDIAN 1 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ defined(__ORDER_LITTLE_ENDIAN__) # define HH_IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) # define HH_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #elif defined(__linux__) || defined(__CYGWIN__) || defined( __GNUC__ ) || \ defined( __GNU_LIBRARY__ ) # include #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || \ defined(__DragonFly__) # include #elif defined(_WIN32) #define HH_IS_LITTLE_ENDIAN 1 #define HH_IS_BIG_ENDIAN 0 #else # error "Unsupported platform. Cannot determine byte order." #endif #ifndef HH_IS_LITTLE_ENDIAN # define HH_IS_LITTLE_ENDIAN (BYTE_ORDER == LITTLE_ENDIAN) # define HH_IS_BIG_ENDIAN (BYTE_ORDER == BIG_ENDIAN) #endif namespace highwayhash { #if HH_IS_LITTLE_ENDIAN static inline uint32_t le32_from_host(uint32_t x) { return x; } static inline uint32_t host_from_le32(uint32_t x) { return x; } static inline uint64_t le64_from_host(uint64_t x) { return x; } static inline uint64_t host_from_le64(uint64_t x) { return x; } #elif !HH_IS_BIG_ENDIAN # error "Unsupported byte order." #elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) #include static inline uint32_t host_from_le32(uint32_t x) { return _byteswap_ulong(x); } static inline uint32_t le32_from_host(uint32_t x) { return _byteswap_ulong(x); } static inline uint64_t host_from_le64(uint64_t x) { return _byteswap_uint64(x); } static inline uint64_t le64_from_host(uint64_t x) { return _byteswap_uint64(x); } #else static inline uint32_t host_from_le32(uint32_t x) { return __builtin_bswap32(x); } static inline uint32_t le32_from_host(uint32_t x) { return __builtin_bswap32(x); } static inline uint64_t host_from_le64(uint64_t x) { return __builtin_bswap64(x); } static inline uint64_t le64_from_host(uint64_t x) { return __builtin_bswap64(x); } #endif } // namespace highwayhash #endif // HIGHWAYHASH_ENDIANESS_H_