1//
2// wasm3_defs.h
3//
4// Created by Volodymyr Shymanskyy on 11/20/19.
5// Copyright © 2019 Volodymyr Shymanskyy. All rights reserved.
6//
7
8#ifndef wasm3_defs_h
9#define wasm3_defs_h
10
11#define M3_STR__(x) #x
12#define M3_STR(x) M3_STR__(x)
13
14#define M3_CONCAT__(a,b) a##b
15#define M3_CONCAT(a,b) M3_CONCAT__(a,b)
16
17/*
18 * Detect compiler
19 */
20
21# if defined(__clang__)
22# define M3_COMPILER_CLANG 1
23# elif defined(__INTEL_COMPILER)
24# define M3_COMPILER_ICC 1
25# elif defined(__GNUC__) || defined(__GNUG__)
26# define M3_COMPILER_GCC 1
27# elif defined(_MSC_VER)
28# define M3_COMPILER_MSVC 1
29# else
30# warning "Compiler not detected"
31# endif
32
33# if defined(M3_COMPILER_CLANG)
34# if defined(WIN32)
35# define M3_COMPILER_VER __VERSION__ " for Windows"
36# else
37# define M3_COMPILER_VER __VERSION__
38# endif
39# elif defined(M3_COMPILER_GCC)
40# define M3_COMPILER_VER "GCC " __VERSION__
41# elif defined(M3_COMPILER_ICC)
42# define M3_COMPILER_VER __VERSION__
43# elif defined(M3_COMPILER_MSVC)
44# define M3_COMPILER_VER "MSVC " M3_STR(_MSC_VER)
45# else
46# define M3_COMPILER_VER "unknown"
47# endif
48
49# ifdef __has_feature
50# define M3_COMPILER_HAS_FEATURE(x) __has_feature(x)
51# else
52# define M3_COMPILER_HAS_FEATURE(x) 0
53# endif
54
55# ifdef __has_builtin
56# define M3_COMPILER_HAS_BUILTIN(x) __has_builtin(x)
57# else
58# define M3_COMPILER_HAS_BUILTIN(x) 0
59# endif
60
61/*
62 * Detect endianness
63 */
64
65# if defined(M3_COMPILER_MSVC)
66# define M3_LITTLE_ENDIAN
67# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
68# define M3_LITTLE_ENDIAN
69# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
70# define M3_BIG_ENDIAN
71# else
72# error "Byte order not detected"
73# endif
74
75/*
76 * Detect platform
77 */
78
79# if defined(M3_COMPILER_CLANG) || defined(M3_COMPILER_GCC) || defined(M3_COMPILER_ICC)
80# if defined(__wasm__)
81# define M3_ARCH "wasm"
82
83# elif defined(__x86_64__)
84# define M3_ARCH "x86_64"
85
86# elif defined(__i386__)
87# define M3_ARCH "i386"
88
89# elif defined(__aarch64__)
90# define M3_ARCH "arm64-v8a"
91
92# elif defined(__arm__)
93# if defined(__ARM_ARCH_7A__)
94# if defined(__ARM_NEON__)
95# if defined(__ARM_PCS_VFP)
96# define M3_ARCH "arm-v7a/NEON hard-float"
97# else
98# define M3_ARCH "arm-v7a/NEON"
99# endif
100# else
101# if defined(__ARM_PCS_VFP)
102# define M3_ARCH "arm-v7a hard-float"
103# else
104# define M3_ARCH "arm-v7a"
105# endif
106# endif
107# else
108# define M3_ARCH "arm"
109# endif
110
111# elif defined(__riscv)
112# if defined(__riscv_32e)
113# define _M3_ARCH_RV "rv32e"
114# elif __riscv_xlen == 128
115# define _M3_ARCH_RV "rv128i"
116# elif __riscv_xlen == 64
117# define _M3_ARCH_RV "rv64i"
118# elif __riscv_xlen == 32
119# define _M3_ARCH_RV "rv32i"
120# endif
121# if defined(__riscv_muldiv)
122# define _M3_ARCH_RV_M _M3_ARCH_RV "m"
123# else
124# define _M3_ARCH_RV_M _M3_ARCH_RV
125# endif
126# if defined(__riscv_atomic)
127# define _M3_ARCH_RV_A _M3_ARCH_RV_M "a"
128# else
129# define _M3_ARCH_RV_A _M3_ARCH_RV_M
130# endif
131# if defined(__riscv_flen)
132# define _M3_ARCH_RV_F _M3_ARCH_RV_A "f"
133# else
134# define _M3_ARCH_RV_F _M3_ARCH_RV_A
135# endif
136# if defined(__riscv_flen) && __riscv_flen >= 64
137# define _M3_ARCH_RV_D _M3_ARCH_RV_F "d"
138# else
139# define _M3_ARCH_RV_D _M3_ARCH_RV_F
140# endif
141# if defined(__riscv_compressed)
142# define _M3_ARCH_RV_C _M3_ARCH_RV_D "c"
143# else
144# define _M3_ARCH_RV_C _M3_ARCH_RV_D
145# endif
146# define M3_ARCH _M3_ARCH_RV_C
147
148# elif defined(__mips__)
149# if defined(__MIPSEB__) && defined(__mips64)
150# define M3_ARCH "mips64 " _MIPS_ARCH
151# elif defined(__MIPSEL__) && defined(__mips64)
152# define M3_ARCH "mips64el " _MIPS_ARCH
153# elif defined(__MIPSEB__)
154# define M3_ARCH "mips " _MIPS_ARCH
155# elif defined(__MIPSEL__)
156# define M3_ARCH "mipsel " _MIPS_ARCH
157# endif
158
159# elif defined(__PPC__)
160# if defined(__PPC64__) && defined(__LITTLE_ENDIAN__)
161# define M3_ARCH "ppc64le"
162# elif defined(__PPC64__)
163# define M3_ARCH "ppc64"
164# else
165# define M3_ARCH "ppc"
166# endif
167
168# elif defined(__sparc__)
169# if defined(__arch64__)
170# define M3_ARCH "sparc64"
171# else
172# define M3_ARCH "sparc"
173# endif
174
175# elif defined(__s390x__)
176# define M3_ARCH "s390x"
177
178# elif defined(__alpha__)
179# define M3_ARCH "alpha"
180
181# elif defined(__m68k__)
182# define M3_ARCH "m68k"
183
184# elif defined(__xtensa__)
185# define M3_ARCH "xtensa"
186
187# elif defined(__arc__)
188# define M3_ARCH "arc32"
189
190# elif defined(__AVR__)
191# define M3_ARCH "avr"
192# endif
193# endif
194
195# if defined(M3_COMPILER_MSVC)
196# if defined(_M_X64)
197# define M3_ARCH "x86_64"
198# elif defined(_M_IX86)
199# define M3_ARCH "i386"
200# elif defined(_M_ARM64)
201# define M3_ARCH "arm64"
202# elif defined(_M_ARM)
203# define M3_ARCH "arm"
204# endif
205# endif
206
207# if !defined(M3_ARCH)
208# warning "Architecture not detected"
209# define M3_ARCH "unknown"
210# endif
211
212/*
213 * Byte swapping (for Big-Endian systems only)
214 */
215
216# if defined(M3_COMPILER_MSVC)
217# define m3_bswap16(x) _byteswap_ushort((x))
218# define m3_bswap32(x) _byteswap_ulong((x))
219# define m3_bswap64(x) _byteswap_uint64((x))
220# elif defined(M3_COMPILER_GCC) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
221// __builtin_bswap32/64 added in gcc 4.3, __builtin_bswap16 added in gcc 4.8
222# define m3_bswap16(x) __builtin_bswap16((x))
223# define m3_bswap32(x) __builtin_bswap32((x))
224# define m3_bswap64(x) __builtin_bswap64((x))
225# elif defined(M3_COMPILER_CLANG) && M3_COMPILER_HAS_BUILTIN(__builtin_bswap16)
226# define m3_bswap16(x) __builtin_bswap16((x))
227# define m3_bswap32(x) __builtin_bswap32((x))
228# define m3_bswap64(x) __builtin_bswap64((x))
229# elif defined(M3_COMPILER_ICC)
230# define m3_bswap16(x) __builtin_bswap16((x))
231# define m3_bswap32(x) __builtin_bswap32((x))
232# define m3_bswap64(x) __builtin_bswap64((x))
233# else
234# ifdef __linux__
235# include <endian.h>
236# else
237# include <stdint.h>
238# endif
239# if defined(__bswap_16)
240# define m3_bswap16(x) __bswap_16((x))
241# define m3_bswap32(x) __bswap_32((x))
242# define m3_bswap64(x) __bswap_64((x))
243# else
244# warning "Using naive (probably slow) bswap operations"
245 static inline
246 uint16_t m3_bswap16(uint16_t x) {
247 return ((( x >> 8 ) & 0xffu ) | (( x & 0xffu ) << 8 ));
248 }
249 static inline
250 uint32_t m3_bswap32(uint32_t x) {
251 return ((( x & 0xff000000u ) >> 24 ) |
252 (( x & 0x00ff0000u ) >> 8 ) |
253 (( x & 0x0000ff00u ) << 8 ) |
254 (( x & 0x000000ffu ) << 24 ));
255 }
256 static inline
257 uint64_t m3_bswap64(uint64_t x) {
258 return ((( x & 0xff00000000000000ull ) >> 56 ) |
259 (( x & 0x00ff000000000000ull ) >> 40 ) |
260 (( x & 0x0000ff0000000000ull ) >> 24 ) |
261 (( x & 0x000000ff00000000ull ) >> 8 ) |
262 (( x & 0x00000000ff000000ull ) << 8 ) |
263 (( x & 0x0000000000ff0000ull ) << 24 ) |
264 (( x & 0x000000000000ff00ull ) << 40 ) |
265 (( x & 0x00000000000000ffull ) << 56 ));
266 }
267# endif
268# endif
269
270/*
271 * Other
272 */
273
274# if defined(M3_COMPILER_GCC) || defined(M3_COMPILER_CLANG) || defined(M3_COMPILER_ICC)
275# define M3_UNLIKELY(x) __builtin_expect(!!(x), 0)
276# define M3_LIKELY(x) __builtin_expect(!!(x), 1)
277# else
278# define M3_UNLIKELY(x) (x)
279# define M3_LIKELY(x) (x)
280# endif
281
282#endif // wasm3_defs_h
283