diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index d64f371294..911c765a6e 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -177,40 +177,53 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string g.finish() // mut b := strings.new_builder(250000) - b.writeln(g.hashes()) - b.writeln(g.comptime_defines.str()) + b.write(g.hashes()) + b.write(g.comptime_defines.str()) b.writeln('\n// V typedefs:') - b.writeln(g.typedefs.str()) + b.write(g.typedefs.str()) b.writeln('\n// V typedefs2:') - b.writeln(g.typedefs2.str()) + b.write(g.typedefs2.str()) b.writeln('\n// V cheaders:') - b.writeln(g.cheaders.str()) + b.write(g.cheaders.str()) b.writeln('\n// V includes:') - b.writeln(g.includes.str()) + b.write(g.includes.str()) b.writeln('\n// Enum definitions:') - b.writeln(g.enum_typedefs.str()) + b.write(g.enum_typedefs.str()) b.writeln('\n// V type definitions:') - b.writeln(g.type_definitions.str()) + b.write(g.type_definitions.str()) b.writeln('\n// V Option_xxx definitions:') - b.writeln(g.options.str()) + b.write(g.options.str()) b.writeln('\n// V json forward decls:') - b.writeln(g.json_forward_decls.str()) + b.write(g.json_forward_decls.str()) b.writeln('\n// V definitions:') - b.writeln(g.definitions.str()) - b.writeln('\n// V profile counters:') - b.writeln(g.pcs_declarations.str()) - b.writeln('\n// V interface table:') - b.writeln(g.interface_table()) - b.writeln('\n// V gowrappers:') - b.writeln(g.gowrappers.str()) - b.writeln('\n// V hotcode definitions:') - b.writeln(g.hotcode_definitions.str()) - b.writeln('\n// V stringliterals:') - b.writeln(g.stringliterals.str()) - b.writeln('\n// V auto str functions:') - b.writeln(g.auto_str_funcs.str()) + b.write(g.definitions.str()) + if g.pcs_declarations.len > 0 { + b.writeln('\n// V profile counters:') + b.write(g.pcs_declarations.str()) + } + interface_table := g.interface_table() + if interface_table.len > 0 { + b.writeln('\n// V interface table:') + b.write(interface_table) + } + if g.gowrappers.len > 0 { + b.writeln('\n// V gowrappers:') + b.write(g.gowrappers.str()) + } + if g.hotcode_definitions.len > 0 { + b.writeln('\n// V hotcode definitions:') + b.write(g.hotcode_definitions.str()) + } + if g.stringliterals.len > 0 { + b.writeln('\n// V stringliterals:') + b.write(g.stringliterals.str()) + } + if g.auto_str_funcs.len > 0 { + b.writeln('\n// V auto str functions:') + b.write(g.auto_str_funcs.str()) + } b.writeln('\n// V out') - b.writeln(g.out.str()) + b.write(g.out.str()) b.writeln('\n// THE END.') return b.str() } @@ -2985,7 +2998,7 @@ fn (mut g Gen) write_init_function() { } g.writeln('\tbuiltin_init();') g.writeln('\tvinit_string_literals();') - g.writeln(g.inits.str()) + g.write(g.inits.str()) for mod_name in g.table.imports { init_fn_name := '${mod_name}.init' if _ := g.table.find_fn(init_fn_name) { diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index b85b1bd2fa..27f5295934 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -8,16 +8,14 @@ const ( // V_COMMIT_HASH is generated by cmd/tools/gen_vc.v . c_commit_hash_default = ' #ifndef V_COMMIT_HASH -#define V_COMMIT_HASH "@@@" + #define V_COMMIT_HASH "@@@" #endif - ' // V_CURRENT_COMMIT_HASH is updated, when V is rebuilt inside a git repo. c_current_commit_hash_default = ' #ifndef V_CURRENT_COMMIT_HASH -#define V_CURRENT_COMMIT_HASH "@@@" + #define V_CURRENT_COMMIT_HASH "@@@" #endif - ' c_common_macros = ' @@ -31,68 +29,66 @@ const ( #define __IRQHANDLER __attribute__((interrupt)) #ifdef __TINYC__ -#undef EMPTY_STRUCT_DECLARATION -#undef EMPTY_STRUCT_INITIALIZATION -#define EMPTY_STRUCT_DECLARATION char _dummy -#define EMPTY_STRUCT_INITIALIZATION 0 -#undef EMPTY_ARRAY_OF_ELEMS -#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) -#undef __NOINLINE -#undef __IRQHANDLER -// tcc does not support inlining at all -#define __NOINLINE -#define __IRQHANDLER -#undef TCCSKIP -#define TCCSKIP(x) -// #include + #undef EMPTY_STRUCT_DECLARATION + #undef EMPTY_STRUCT_INITIALIZATION + #define EMPTY_STRUCT_DECLARATION char _dummy + #define EMPTY_STRUCT_INITIALIZATION 0 + #undef EMPTY_ARRAY_OF_ELEMS + #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) + #undef __NOINLINE + #undef __IRQHANDLER + // tcc does not support inlining at all + #define __NOINLINE + #define __IRQHANDLER + #undef TCCSKIP + #define TCCSKIP(x) + // #include #endif // for __offset_of #ifndef __offsetof -#define __offsetof(s,memb) \\ + #define __offsetof(s,memb) \\ ((size_t)((char *)&((s *)0)->memb - (char *)0)) #endif #define OPTION_CAST(x) (x) #ifndef V64_PRINTFORMAT -#ifdef PRIx64 -#define V64_PRINTFORMAT "0x%"PRIx64 -#elif defined(__WIN32__) -#define V64_PRINTFORMAT "0x%I64x" -#elif defined(__linux__) && defined(__LP64__) -#define V64_PRINTFORMAT "0x%lx" -#else -#define V64_PRINTFORMAT "0x%llx" + #ifdef PRIx64 + #define V64_PRINTFORMAT "0x%"PRIx64 + #elif defined(__WIN32__) + #define V64_PRINTFORMAT "0x%I64x" + #elif defined(__linux__) && defined(__LP64__) + #define V64_PRINTFORMAT "0x%lx" + #else + #define V64_PRINTFORMAT "0x%llx" + #endif #endif -#endif - ' c_headers = ' - // c_headers typedef int (*qsort_callback_func)(const void*, const void*); #include // TODO remove all these includes, define all function signatures and types manually #include #ifdef __cplusplus -# include -# define _MOV std::move + #include + #define _MOV std::move #else -# define _MOV + #define _MOV #endif #ifndef _WIN32 -#if defined __has_include -#if __has_include () -# include -#else -// Most probably musl OR __ANDROID__ ... -int backtrace (void **__array, int __size) { return 0; } -char **backtrace_symbols (void *const *__array, int __size){ return 0; } -void backtrace_symbols_fd (void *const *__array, int __size, int __fd){} -#endif -#endif + #if defined __has_include + #if __has_include () + #include + #else + // Most probably musl OR __ANDROID__ ... + int backtrace (void **__array, int __size) { return 0; } + char **backtrace_symbols (void *const *__array, int __size){ return 0; } + void backtrace_symbols_fd (void *const *__array, int __size, int __fd){} + #endif + #endif #endif //#include "fns.h" @@ -101,116 +97,114 @@ void backtrace_symbols_fd (void *const *__array, int __size, int __fd){} #include // memcpy #if INTPTR_MAX == INT32_MAX - #define TARGET_IS_32BIT 1 + #define TARGET_IS_32BIT 1 #elif INTPTR_MAX == INT64_MAX - #define TARGET_IS_64BIT 1 + #define TARGET_IS_64BIT 1 #else - #error "The environment is not 32 or 64-bit." + #error "The environment is not 32 or 64-bit." #endif #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) - #define TARGET_ORDER_IS_BIG + #define TARGET_ORDER_IS_BIG #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86) - #define TARGET_ORDER_IS_LITTLE + #define TARGET_ORDER_IS_LITTLE #else - #error "Unknown architecture endianness" + #error "Unknown architecture endianness" #endif #ifndef _WIN32 -#include -#include // tolower -#include -#include // sleep -extern char **environ; + #include + #include // tolower + #include + #include // sleep + extern char **environ; #endif #if defined(__CYGWIN__) && !defined(_WIN32) -#error Cygwin is not supported, please use MinGW or Visual Studio. + #error Cygwin is not supported, please use MinGW or Visual Studio. #endif - #ifdef __linux__ -#include -#include // os__wait uses wait on nix + #include + #include // os__wait uses wait on nix #endif #ifdef __FreeBSD__ -#include -#include // os__wait uses wait on nix + #include + #include // os__wait uses wait on nix #endif #ifdef __DragonFly__ -#include -#include // os__wait uses wait on nix + #include + #include // os__wait uses wait on nix #endif #ifdef __OpenBSD__ -#include -#include -#include // os__wait uses wait on nix + #include + #include + #include // os__wait uses wait on nix #endif #ifdef __NetBSD__ -#include // os__wait uses wait on nix + #include // os__wait uses wait on nix #endif #ifdef __sun -#include -#include // os__wait uses wait on nix + #include + #include // os__wait uses wait on nix #endif $c_common_macros #ifdef _WIN32 -#define WINVER 0x0600 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0600 -#define WIN32_LEAN_AND_MEAN -#define _UNICODE -#define UNICODE -#include + #define WINVER 0x0600 + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + #define _WIN32_WINNT 0x0600 + #define WIN32_LEAN_AND_MEAN + #define _UNICODE + #define UNICODE + #include -#include // _waccess -#include // _wgetcwd -//#include -#ifdef _MSC_VER + #include // _waccess + #include // _wgetcwd + //#include -// On MSVC these are the same (as long as /volatile:ms is passed) -#define _Atomic volatile + #ifdef _MSC_VER + // On MSVC these are the same (as long as /volatile:ms is passed) + #define _Atomic volatile -// MSVC cannot parse some things properly -#undef EMPTY_STRUCT_DECLARATION -#undef OPTION_CAST + // MSVC cannot parse some things properly + #undef EMPTY_STRUCT_DECLARATION + #undef OPTION_CAST -#define EMPTY_STRUCT_DECLARATION int ____dummy_variable -#define OPTION_CAST(x) -#undef __NOINLINE -#undef __IRQHANDLER -#define __NOINLINE __declspec(noinline) -#define __IRQHANDLER __declspec(naked) + #define EMPTY_STRUCT_DECLARATION int ____dummy_variable + #define OPTION_CAST(x) + #undef __NOINLINE + #undef __IRQHANDLER + #define __NOINLINE __declspec(noinline) + #define __IRQHANDLER __declspec(naked) -#include -#pragma comment(lib, "Dbghelp.lib") - -extern wchar_t **_wenviron; -#elif !defined(SRWLOCK_INIT) -// these seem to be missing on Windows tcc -typedef struct SRWLOCK { void* SRWLOCK; } SRWLOCK; -void InitializeSRWLock(void*); -void AcquireSRWLockShared(void*); -void AcquireSRWLockExclusive(void*); -void ReleaseSRWLockShared(void*); -void ReleaseSRWLockExclusive(void*); -#endif + #include + #pragma comment(lib, "Dbghelp.lib") + extern wchar_t **_wenviron; + #elif !defined(SRWLOCK_INIT) + // these seem to be missing on Windows tcc + typedef struct SRWLOCK { void* SRWLOCK; } SRWLOCK; + void InitializeSRWLock(void*); + void AcquireSRWLockShared(void*); + void AcquireSRWLockExclusive(void*); + void ReleaseSRWLockShared(void*); + void ReleaseSRWLockExclusive(void*); + #endif #else -#include -#ifndef PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP -// musl does not have that -#define pthread_rwlockattr_setkind_np(a, b) -#endif + #include + #ifndef PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP + // musl does not have that + #define pthread_rwlockattr_setkind_np(a, b) + #endif #endif // g_live_info is used by live.info() @@ -224,7 +218,6 @@ void* g_live_info = NULL; #define _IN_MAP(val, m) map_exists(m, val) // unsigned/signed comparisons - static inline bool _us32_gt(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a > b; } static inline bool _us32_ge(uint32_t a, int32_t b) { return a >= INT32_MAX || (int32_t)a >= b; } static inline bool _us32_eq(uint32_t a, int32_t b) { return a <= INT32_MAX && (int32_t)a == b; } @@ -239,18 +232,18 @@ static inline bool _us64_le(uint64_t a, int64_t b) { return a <= INT64_MAX && (i static inline bool _us64_lt(uint64_t a, int64_t b) { return a < INT64_MAX && (int64_t)a < b; } #if defined(__MINGW32__) || defined(__MINGW64__) || (defined(_WIN32) && defined(__TINYC__)) -#undef PRId64 -#undef PRIi64 -#undef PRIo64 -#undef PRIu64 -#undef PRIx64 -#undef PRIX64 -#define PRId64 "lld" -#define PRIi64 "lli" -#define PRIo64 "llo" -#define PRIu64 "llu" -#define PRIx64 "llx" -#define PRIX64 "llX" + #undef PRId64 + #undef PRIi64 + #undef PRIo64 + #undef PRIu64 + #undef PRIx64 + #undef PRIX64 + #define PRId64 "lld" + #define PRIi64 "lli" + #define PRIo64 "llo" + #define PRIu64 "llu" + #define PRIx64 "llx" + #define PRIX64 "llX" #endif //================================== GLOBALS =================================*/ @@ -266,119 +259,115 @@ void _vcleanup(); // ============== wyhash ============== //Author: Wang Yi #ifndef wyhash_version_gamma -#define wyhash_version_gamma -#define WYHASH_CONDOM 0 -#include -#include -#if defined(_MSC_VER) && defined(_M_X64) -#include -#pragma intrinsic(_umul128) -#endif - -//const uint64_t _wyp0=0xa0761d6478bd642full, _wyp1=0xe7037ed1a0b428dbull; -#define _wyp0 ((uint64_t)0xa0761d6478bd642full) -#define _wyp1 ((uint64_t)0xe7037ed1a0b428dbull) - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) || defined(__TINYC__) -#define _likely_(x) __builtin_expect(x, 1) -#define _unlikely_(x) __builtin_expect((x), 0) -#else -#define _likely_(x) (x) -#define _unlikely_(x) (x) -#endif - -#if defined(TARGET_ORDER_IS_LITTLE) -#define WYHASH_LITTLE_ENDIAN 1 -#elif defined(TARGET_ORDER_IS_BIG) -#define WYHASH_LITTLE_ENDIAN 0 -#endif - -#if (WYHASH_LITTLE_ENDIAN) - static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;} - static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return v;} -#else -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) - static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);} - static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return __builtin_bswap32(v);} -#elif defined(_MSC_VER) - static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);} - static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return _byteswap_ulong(v);} -#elif defined(__TINYC__) - static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return bswap_64(v);} - static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return bswap_32(v);} -#endif -#endif - -static inline uint64_t _wyr3(const uint8_t *p, unsigned k) { return (((uint64_t)p[0]) << 16) | (((uint64_t)p[k >> 1]) << 8) | p[k - 1];} -static inline uint64_t _wyrotr(uint64_t v, unsigned k) { return (v >> k) | (v << (64 - k));} -static inline void _wymix128(uint64_t A, uint64_t B, uint64_t *C, uint64_t *D){ - A^=*C; B^=*D; -#ifdef UNOFFICIAL_WYHASH_32BIT - uint64_t hh=(A>>32)*(B>>32), hl=(A>>32)*(unsigned)B, lh=(unsigned)A*(B>>32), ll=(uint64_t)(unsigned)A*(unsigned)B; - *C=_wyrotr(hl,32)^hh; *D=_wyrotr(lh,32)^ll; -#else -#ifdef __SIZEOF_INT128__ - __uint128_t r=A; r*=B; *C=(uint64_t)r; *D=(uint64_t)(r>>64); -#elif defined(_MSC_VER) && defined(_M_X64) - A=_umul128(A,B,&B); *C=A; *D=B; -#else - uint64_t ha=A>>32, hb=B>>32, la=(uint32_t)A, lb=(uint32_t)B, hi, lo; - uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c; - *C=lo; *D=hi; -#endif -#endif -} -static inline uint64_t wyhash(const void *key, uint64_t len, uint64_t seed){ - const uint8_t *p=(const uint8_t *)key; - uint64_t i=len, see1=seed; - start: - if(_likely_(i<=16)){ - #ifndef WYHASH_CONDOM - uint64_t shift=(i<8)*((8-i)<<3); - //WARNING: intended reading outside buffer, trading for speed. - _wymix128((_wyr8(p)<>shift)^_wyp1, &seed, &see1); - #else - if(_likely_(i<=8)){ - if(_likely_(i>=4)) _wymix128(_wyr4(p)^_wyp0,_wyr4(p+i-4)^_wyp1, &seed, &see1); - else if (_likely_(i)) _wymix128(_wyr3(p,i)^_wyp0,_wyp1, &seed, &see1); - else _wymix128(_wyp0,_wyp1, &seed, &see1); - } - else _wymix128(_wyr8(p)^_wyp0,_wyr8(p+i-8)^_wyp1, &seed, &see1); + #define wyhash_version_gamma + #define WYHASH_CONDOM 0 + #include + #include + #if defined(_MSC_VER) && defined(_M_X64) + #include + #pragma intrinsic(_umul128) #endif - _wymix128(len,_wyp0, &seed, &see1); - return seed^see1; - } - _wymix128(_wyr8(p)^_wyp0,_wyr8(p+8)^_wyp1, &seed, &see1); - i-=16; p+=16; goto start; -} -static inline uint64_t wyhash64(uint64_t A, uint64_t B){ - _wymix128(_wyp0,_wyp1,&A,&B); - _wymix128(0,0,&A,&B); - return A^B; -} -static inline uint64_t wyrand(uint64_t *seed){ - *seed+=_wyp0; - uint64_t a=0, b=0; - _wymix128(*seed,*seed^_wyp1,&a,&b); - return a^b; -} -static inline double wy2u01(uint64_t r) { - const double _wynorm=1.0/(1ull<<52); - return (r>>12)*_wynorm; -} -static inline double wy2gau(uint64_t r) { - const double _wynorm=1.0/(1ull<<20); - return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0; -} -#endif + //const uint64_t _wyp0=0xa0761d6478bd642full, _wyp1=0xe7037ed1a0b428dbull; + #define _wyp0 ((uint64_t)0xa0761d6478bd642full) + #define _wyp1 ((uint64_t)0xe7037ed1a0b428dbull) + + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) || defined(__TINYC__) + #define _likely_(x) __builtin_expect(x, 1) + #define _unlikely_(x) __builtin_expect((x), 0) + #else + #define _likely_(x) (x) + #define _unlikely_(x) (x) + #endif + + #if defined(TARGET_ORDER_IS_LITTLE) + #define WYHASH_LITTLE_ENDIAN 1 + #elif defined(TARGET_ORDER_IS_BIG) + #define WYHASH_LITTLE_ENDIAN 0 + #endif + + #if (WYHASH_LITTLE_ENDIAN) + static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;} + static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return v;} + #else + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) + static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);} + static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return __builtin_bswap32(v);} + #elif defined(_MSC_VER) + static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);} + static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return _byteswap_ulong(v);} + #elif defined(__TINYC__) + static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return bswap_64(v);} + static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return bswap_32(v);} + #endif + #endif + + static inline uint64_t _wyr3(const uint8_t *p, unsigned k) { return (((uint64_t)p[0]) << 16) | (((uint64_t)p[k >> 1]) << 8) | p[k - 1];} + static inline uint64_t _wyrotr(uint64_t v, unsigned k) { return (v >> k) | (v << (64 - k));} + static inline void _wymix128(uint64_t A, uint64_t B, uint64_t *C, uint64_t *D){ + A^=*C; B^=*D; + #ifdef UNOFFICIAL_WYHASH_32BIT + uint64_t hh=(A>>32)*(B>>32), hl=(A>>32)*(unsigned)B, lh=(unsigned)A*(B>>32), ll=(uint64_t)(unsigned)A*(unsigned)B; + *C=_wyrotr(hl,32)^hh; *D=_wyrotr(lh,32)^ll; + #else + #ifdef __SIZEOF_INT128__ + __uint128_t r=A; r*=B; *C=(uint64_t)r; *D=(uint64_t)(r>>64); + #elif defined(_MSC_VER) && defined(_M_X64) + A=_umul128(A,B,&B); *C=A; *D=B; + #else + uint64_t ha=A>>32, hb=B>>32, la=(uint32_t)A, lb=(uint32_t)B, hi, lo; + uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c; + *C=lo; *D=hi; + #endif + #endif + } + static inline uint64_t wyhash(const void *key, uint64_t len, uint64_t seed){ + const uint8_t *p=(const uint8_t *)key; + uint64_t i=len, see1=seed; + start: + if (_likely_(i<=16)) { + #ifndef WYHASH_CONDOM + uint64_t shift = (i<8)*((8-i)<<3); + //WARNING: intended reading outside buffer, trading for speed. + _wymix128((_wyr8(p)<>shift)^_wyp1, &seed, &see1); + #else + if (_likely_(i<=8)) { + if (_likely_(i>=4)) _wymix128(_wyr4(p)^_wyp0,_wyr4(p+i-4)^_wyp1, &seed, &see1); + else if (_likely_(i)) _wymix128(_wyr3(p,i)^_wyp0,_wyp1, &seed, &see1); + else _wymix128(_wyp0,_wyp1, &seed, &see1); + } + else _wymix128(_wyr8(p)^_wyp0,_wyr8(p+i-8)^_wyp1, &seed, &see1); + #endif + _wymix128(len,_wyp0, &seed, &see1); + return seed^see1; + } + _wymix128(_wyr8(p)^_wyp0,_wyr8(p+8)^_wyp1, &seed, &see1); + i-=16; p+=16; goto start; + } + static inline uint64_t wyhash64(uint64_t A, uint64_t B){ + _wymix128(_wyp0,_wyp1,&A,&B); + _wymix128(0,0,&A,&B); + return A^B; + } + static inline uint64_t wyrand(uint64_t *seed){ + *seed+=_wyp0; + uint64_t a=0, b=0; + _wymix128(*seed,*seed^_wyp1,&a,&b); + return a^b; + } + static inline double wy2u01(uint64_t r) { + const double _wynorm=1.0/(1ull<<52); + return (r>>12)*_wynorm; + } + static inline double wy2gau(uint64_t r) { + const double _wynorm=1.0/(1ull<<20); + return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0; + } +#endif ' c_builtin_types = ' - //================================== builtin types ================================*/ - typedef int64_t i64; typedef int16_t i16; typedef int8_t i8; @@ -408,23 +397,21 @@ typedef map map_int; typedef map map_string; typedef byte array_fixed_byte_300 [300]; typedef byte array_fixed_byte_400 [400]; -#ifndef __cplusplus -#ifndef bool - typedef int bool; - #define true 1 - #define false 0 -#endif -#endif +#ifndef __cplusplus + #ifndef bool + typedef int bool; + #define true 1 + #define false 0 + #endif +#endif ' bare_c_headers = ' - $c_common_macros #ifndef exit #define exit(rc) sys_exit(rc) void sys_exit (int); #endif - ' )