1 | // Copyright 2017 Google Inc. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef HIGHWAYHASH_ENDIANESS_H_ |
16 | #define HIGHWAYHASH_ENDIANESS_H_ |
17 | |
18 | // WARNING: this is a "restricted" header because it is included from |
19 | // translation units compiled with different flags. This header and its |
20 | // dependencies must not define any function unless it is static inline and/or |
21 | // within namespace HH_TARGET_NAME. See arch_specific.h for details. |
22 | |
23 | #include <stdint.h> |
24 | |
25 | #if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) |
26 | |
27 | /* Someone has already included <endian.h> or equivalent. */ |
28 | |
29 | #elif defined(__LITTLE_ENDIAN__) |
30 | |
31 | # define HH_IS_LITTLE_ENDIAN 1 |
32 | # define HH_IS_BIG_ENDIAN 0 |
33 | # ifdef __BIG_ENDIAN__ |
34 | # error "Platform is both little and big endian?" |
35 | # endif |
36 | |
37 | #elif defined(__BIG_ENDIAN__) |
38 | |
39 | # define HH_IS_LITTLE_ENDIAN 0 |
40 | # define HH_IS_BIG_ENDIAN 1 |
41 | |
42 | #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ |
43 | defined(__ORDER_LITTLE_ENDIAN__) |
44 | |
45 | # define HH_IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) |
46 | # define HH_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) |
47 | |
48 | #elif defined(__linux__) || defined(__CYGWIN__) || defined( __GNUC__ ) || \ |
49 | defined( __GNU_LIBRARY__ ) |
50 | |
51 | # include <endian.h> |
52 | |
53 | #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || \ |
54 | defined(__DragonFly__) |
55 | |
56 | # include <sys/endian.h> |
57 | |
58 | #elif defined(_WIN32) |
59 | |
60 | #define HH_IS_LITTLE_ENDIAN 1 |
61 | #define HH_IS_BIG_ENDIAN 0 |
62 | |
63 | #else |
64 | |
65 | # error "Unsupported platform. Cannot determine byte order." |
66 | |
67 | #endif |
68 | |
69 | |
70 | #ifndef HH_IS_LITTLE_ENDIAN |
71 | # define HH_IS_LITTLE_ENDIAN (BYTE_ORDER == LITTLE_ENDIAN) |
72 | # define HH_IS_BIG_ENDIAN (BYTE_ORDER == BIG_ENDIAN) |
73 | #endif |
74 | |
75 | |
76 | namespace highwayhash { |
77 | |
78 | #if HH_IS_LITTLE_ENDIAN |
79 | |
80 | static inline uint32_t le32_from_host(uint32_t x) { return x; } |
81 | static inline uint32_t host_from_le32(uint32_t x) { return x; } |
82 | static inline uint64_t le64_from_host(uint64_t x) { return x; } |
83 | static inline uint64_t host_from_le64(uint64_t x) { return x; } |
84 | |
85 | #elif !HH_IS_BIG_ENDIAN |
86 | |
87 | # error "Unsupported byte order." |
88 | |
89 | #elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) |
90 | |
91 | #include <intrin.h> |
92 | static inline uint32_t host_from_le32(uint32_t x) { return _byteswap_ulong(x); } |
93 | static inline uint32_t le32_from_host(uint32_t x) { return _byteswap_ulong(x); } |
94 | static inline uint64_t host_from_le64(uint64_t x) { return _byteswap_uint64(x);} |
95 | static inline uint64_t le64_from_host(uint64_t x) { return _byteswap_uint64(x);} |
96 | |
97 | #else |
98 | |
99 | static inline uint32_t host_from_le32(uint32_t x) {return __builtin_bswap32(x);} |
100 | static inline uint32_t le32_from_host(uint32_t x) {return __builtin_bswap32(x);} |
101 | static inline uint64_t host_from_le64(uint64_t x) {return __builtin_bswap64(x);} |
102 | static inline uint64_t le64_from_host(uint64_t x) {return __builtin_bswap64(x);} |
103 | |
104 | #endif |
105 | |
106 | } // namespace highwayhash |
107 | |
108 | #endif // HIGHWAYHASH_ENDIANESS_H_ |
109 | |