| /* |
| * Copyright 2016 WebAssembly Community Group participants |
| * |
| * 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 WABT_CONFIG_H_ |
| #define WABT_CONFIG_H_ |
| |
| #include <stdint.h> |
| #include <stdlib.h> |
| |
| #cmakedefine WABT_VERSION_STRING "@WABT_VERSION_STRING@" |
| |
| #cmakedefine WABT_DEBUG @WABT_DEBUG@ |
| |
| /* TODO(binji): nice way to define these with WABT_ prefix? */ |
| |
| /* Whether <alloca.h> is available */ |
| #cmakedefine01 HAVE_ALLOCA_H |
| |
| /* Whether <unistd.h> is available */ |
| #cmakedefine01 HAVE_UNISTD_H |
| |
| /* Whether snprintf is defined by stdio.h */ |
| #cmakedefine01 HAVE_SNPRINTF |
| |
| /* Whether ssize_t is defined by stddef.h */ |
| #cmakedefine01 HAVE_SSIZE_T |
| |
| /* Whether strcasecmp is defined by strings.h */ |
| #cmakedefine01 HAVE_STRCASECMP |
| |
| /* Whether ENABLE_VIRTUAL_TERMINAL_PROCESSING is defined by windows.h */ |
| #cmakedefine01 HAVE_WIN32_VT100 |
| |
| /* Whether the target architecture is big endian */ |
| #cmakedefine01 WABT_BIG_ENDIAN |
| |
| /* Whether <openssl/sha.h> is available */ |
| #cmakedefine01 HAVE_OPENSSL_SHA_H |
| |
| #cmakedefine01 COMPILER_IS_CLANG |
| #cmakedefine01 COMPILER_IS_GNU |
| #cmakedefine01 COMPILER_IS_MSVC |
| |
| #cmakedefine01 WITH_EXCEPTIONS |
| |
| #define SIZEOF_SIZE_T @SIZEOF_SIZE_T@ |
| |
| #if HAVE_ALLOCA_H |
| #include <alloca.h> |
| #elif COMPILER_IS_MSVC |
| #include <malloc.h> |
| #define alloca _alloca |
| #elif defined(__MINGW32__) |
| #include <malloc.h> |
| #endif |
| |
| #if COMPILER_IS_CLANG || COMPILER_IS_GNU |
| |
| #define WABT_UNLIKELY(x) __builtin_expect(!!(x), 0) |
| #define WABT_LIKELY(x) __builtin_expect(!!(x), 1) |
| |
| #define WABT_VECTORCALL |
| |
| #if __MINGW32__ |
| // mingw defaults to printf format specifier being ms_printf (which doesn't |
| // understand 'llu', etc.) We always want gnu_printf, and force mingw to always |
| // use mingw_printf, mingw_vprintf, etc. |
| #define WABT_PRINTF_FORMAT(format_arg, first_arg) \ |
| __attribute__((format(gnu_printf, (format_arg), (first_arg)))) |
| #else |
| #define WABT_PRINTF_FORMAT(format_arg, first_arg) \ |
| __attribute__((format(printf, (format_arg), (first_arg)))) |
| #endif |
| |
| #ifdef __cplusplus |
| #define WABT_STATIC_ASSERT(x) static_assert((x), #x) |
| #else |
| #define WABT_STATIC_ASSERT(x) _Static_assert((x), #x) |
| #endif |
| |
| #elif COMPILER_IS_MSVC |
| |
| #include <intrin.h> |
| #include <string.h> |
| |
| #define WABT_STATIC_ASSERT(x) _STATIC_ASSERT(x) |
| #define WABT_UNLIKELY(x) (x) |
| #define WABT_LIKELY(x) (x) |
| #define WABT_PRINTF_FORMAT(format_arg, first_arg) |
| |
| #define WABT_VECTORCALL __vectorcall |
| |
| #else |
| |
| #error unknown compiler |
| |
| #endif |
| |
| #define WABT_UNREACHABLE abort() |
| |
| #ifdef __cplusplus |
| |
| namespace wabt { |
| |
| #if COMPILER_IS_CLANG || COMPILER_IS_GNU |
| |
| inline int Clz(unsigned x) { return x ? __builtin_clz(x) : sizeof(x) * 8; } |
| inline int Clz(unsigned long x) { return x ? __builtin_clzl(x) : sizeof(x) * 8; } |
| inline int Clz(unsigned long long x) { return x ? __builtin_clzll(x) : sizeof(x) * 8; } |
| |
| inline int Ctz(unsigned x) { return x ? __builtin_ctz(x) : sizeof(x) * 8; } |
| inline int Ctz(unsigned long x) { return x ? __builtin_ctzl(x) : sizeof(x) * 8; } |
| inline int Ctz(unsigned long long x) { return x ? __builtin_ctzll(x) : sizeof(x) * 8; } |
| |
| inline int Popcount(uint8_t x) { return __builtin_popcount(x); } |
| inline int Popcount(unsigned x) { return __builtin_popcount(x); } |
| inline int Popcount(unsigned long x) { return __builtin_popcountl(x); } |
| inline int Popcount(unsigned long long x) { return __builtin_popcountll(x); } |
| |
| #elif COMPILER_IS_MSVC |
| |
| #if _M_IX86 |
| inline unsigned long LowDword(unsigned __int64 value) { |
| return (unsigned long)value; |
| } |
| |
| inline unsigned long HighDword(unsigned __int64 value) { |
| unsigned long high; |
| memcpy(&high, (unsigned char*)&value + sizeof(high), sizeof(high)); |
| return high; |
| } |
| #endif |
| |
| inline int Clz(unsigned long mask) { |
| if (mask == 0) |
| return 32; |
| |
| unsigned long index; |
| _BitScanReverse(&index, mask); |
| return sizeof(unsigned long) * 8 - (index + 1); |
| } |
| |
| inline int Clz(unsigned int mask) { |
| return Clz((unsigned long)mask); |
| } |
| |
| inline int Clz(unsigned __int64 mask) { |
| #if _M_X64 || _M_ARM64 |
| if (mask == 0) |
| return 64; |
| |
| unsigned long index; |
| _BitScanReverse64(&index, mask); |
| return sizeof(unsigned __int64) * 8 - (index + 1); |
| #elif _M_IX86 |
| int result = Clz(HighDword(mask)); |
| if (result == 32) |
| result += Clz(LowDword(mask)); |
| |
| return result; |
| #else |
| #error unexpected architecture |
| #endif |
| } |
| |
| inline int Ctz(unsigned long mask) { |
| if (mask == 0) |
| return 32; |
| |
| unsigned long index; |
| _BitScanForward(&index, mask); |
| return index; |
| } |
| |
| inline int Ctz(unsigned int mask) { |
| return Ctz((unsigned long)mask); |
| } |
| |
| inline int Ctz(unsigned __int64 mask) { |
| #if _M_X64 || _M_ARM64 |
| if (mask == 0) |
| return 64; |
| |
| unsigned long index; |
| _BitScanForward64(&index, mask); |
| return index; |
| #elif _M_IX86 |
| int result = Ctz(LowDword(mask)); |
| if (result == 32) |
| result += Ctz(HighDword(mask)); |
| |
| return result; |
| #else |
| #error unexpected architecture |
| #endif |
| } |
| |
| #if _M_ARM64 |
| //https://stackoverflow.com/a/70012905 |
| template <typename T> |
| int BrianKernighanPopcount(T value) { |
| int count; |
| for(count = 0; value; count++) |
| { |
| value &= value - 1; |
| } |
| return count; |
| } |
| #endif |
| |
| inline int Popcount(unsigned long value) { |
| #if _M_X64 || _M_IX86 |
| return __popcnt(value); |
| #elif _M_ARM64 |
| return BrianKernighanPopcount(value); |
| #else |
| #error unexpected architecture |
| #endif |
| } |
| |
| inline int Popcount(uint8_t value) { |
| return Popcount((unsigned long)value); |
| } |
| |
| inline int Popcount(unsigned int value) { |
| return Popcount((unsigned long)value); |
| } |
| |
| inline int Popcount(unsigned __int64 value) { |
| #if _M_X64 |
| return __popcnt64(value); |
| #elif _M_IX86 |
| return Popcount(HighDword(value)) + Popcount(LowDword(value)); |
| #elif _M_ARM64 |
| return BrianKernighanPopcount(value); |
| #else |
| #error unexpected architecture |
| #endif |
| } |
| |
| #else |
| |
| #error unknown compiler |
| |
| #endif |
| |
| } // namespace wabt |
| |
| #if COMPILER_IS_MSVC |
| |
| /* print format specifier for size_t */ |
| #if SIZEOF_SIZE_T == 4 |
| #define PRIzd "d" |
| #define PRIzx "x" |
| #elif SIZEOF_SIZE_T == 8 |
| #define PRIzd "I64d" |
| #define PRIzx "I64x" |
| #else |
| #error "weird sizeof size_t" |
| #endif |
| |
| #elif COMPILER_IS_CLANG || COMPILER_IS_GNU |
| |
| /* print format specifier for size_t */ |
| #define PRIzd "zd" |
| #define PRIzx "zx" |
| |
| #else |
| |
| #error unknown compiler |
| |
| #endif |
| |
| #if HAVE_SNPRINTF |
| #define wabt_snprintf snprintf |
| #elif COMPILER_IS_MSVC |
| /* can't just use _snprintf because it doesn't always null terminate */ |
| #include <cstdarg> |
| int wabt_snprintf(char* str, size_t size, const char* format, ...); |
| #else |
| #error no snprintf |
| #endif |
| |
| #if COMPILER_IS_MSVC |
| /* can't just use vsnprintf because it doesn't always null terminate */ |
| int wabt_vsnprintf(char* str, size_t size, const char* format, va_list ap); |
| #else |
| #define wabt_vsnprintf vsnprintf |
| #endif |
| |
| #if !HAVE_SSIZE_T |
| #if COMPILER_IS_MSVC |
| /* define ssize_t identically to how LLVM does, to avoid conflicts if including both */ |
| #if defined(_WIN64) |
| typedef signed __int64 ssize_t; |
| #else |
| typedef signed int ssize_t; |
| #endif /* _WIN64 */ |
| #else |
| typedef long ssize_t; |
| #endif |
| #endif |
| |
| #if !HAVE_STRCASECMP |
| #if COMPILER_IS_MSVC |
| #define strcasecmp _stricmp |
| #else |
| #error no strcasecmp |
| #endif |
| #endif |
| |
| double wabt_convert_uint64_to_double(uint64_t x); |
| float wabt_convert_uint64_to_float(uint64_t x); |
| double wabt_convert_int64_to_double(int64_t x); |
| float wabt_convert_int64_to_float(int64_t x); |
| |
| #endif // __cplusplus |
| |
| #endif /* WABT_CONFIG_H_ */ |