| 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 | |