From 57ea6e8c9f204be6d38177024d3b8f1aba4e05b2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 13 Sep 2017 00:17:19 -0400 Subject: [PATCH] fix up msvc stuff to make it work on linux and macos too --- .gitignore | 8 +-- CMakeLists.txt | 124 +++++++++--------------------------------- cmake/Findclang.cmake | 63 +++++++++++++++++++++ cmake/Findllvm.cmake | 116 +++++++++++++++++++++++++++++++++++++++ src/bigfloat.hpp | 7 +-- src/bigint.cpp | 37 +++++-------- src/bigint.hpp | 2 +- src/buffer.hpp | 4 +- src/codegen.cpp | 15 +---- src/parsec.cpp | 2 +- src/parser.cpp | 10 ++-- src/parser.hpp | 2 +- src/quadmath.hpp | 64 +++++++++++----------- src/tokenizer.cpp | 2 +- src/util.hpp | 65 ++++++++++++---------- 15 files changed, 299 insertions(+), 222 deletions(-) create mode 100644 cmake/Findclang.cmake create mode 100644 cmake/Findllvm.cmake diff --git a/.gitignore b/.gitignore index 02980cf05..20b208975 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,3 @@ zig-cache/ build/ -build-release/ -build-windows/ -build-llvm4-debug/ -build-llvm5-debug/ -/.cproject -/.project -/.settings/ +build-*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 613fc5e0f..ccb6b9583 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,86 +26,11 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) # git log -p -- deps/lld option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF) -find_package(LLVM REQUIRED CONFIG) +find_package(llvm) include_directories(${LLVM_INCLUDE_DIRS}) -# TODO: this currently doesn't work, it currently defines UNICODE but zig -# uses MBCS -#add_definitions(${LLVM_DEFINITIONS}) - -link_directories(${LLVM_LIBRARY_DIRS}) -llvm_map_components_to_libnames(LLVM_LIBRARIES - LTO - Symbolize - XCoreDisassembler - XCoreCodeGen - XCoreAsmPrinter - SystemZDisassembler - SystemZCodeGen - SystemZAsmParser - SystemZAsmPrinter - SparcDisassembler - SparcCodeGen - SparcAsmParser - SparcAsmPrinter - PowerPCDisassembler - PowerPCCodeGen - PowerPCAsmParser - PowerPCAsmPrinter - NVPTXCodeGen - NVPTXAsmPrinter - MSP430CodeGen - MSP430AsmPrinter - MipsDisassembler - MipsCodeGen - MipsAsmParser - MipsAsmPrinter - LanaiDisassembler - LanaiCodeGen - LanaiAsmParser - LanaiAsmPrinter - HexagonDisassembler - HexagonCodeGen - HexagonAsmParser - BPFDisassembler - BPFCodeGen - BPFAsmPrinter - ARMDisassembler - ARMCodeGen - ARMAsmParser - ARMAsmPrinter - AMDGPUDisassembler - AMDGPUCodeGen - AMDGPUAsmParser - AMDGPUAsmPrinter - AArch64Disassembler - AArch64CodeGen - AArch64AsmParser - AArch64AsmPrinter - LibDriver - X86Disassembler - X86AsmParser - X86CodeGen - X86AsmPrinter - Core -) - -find_package(CLANG REQUIRED CONFIG) +find_package(clang) include_directories(${CLANG_INCLUDE_DIRS}) -set(CLANG_LIBRARIES - clangFrontend - clangDriver - clangSerialization - clangSema - clangAnalysis - clangAST - clangParse - clangSema - clangBasic - clangEdit - clangLex -) - if(ZIG_FORCE_EXTERNAL_LLD) find_package(lld) @@ -203,21 +128,21 @@ else() add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES}) - if(MINGW) - set(UNIQUE_COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-comment") - elseif(MSVC) - set(UNIQUE_COMPILE_FLAGS "-D_MSVC") + if(MSVC) + set(ZIG_LLD_COMPILE_FLAGS "-std=c++11") + else() + set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment") endif() set_target_properties(embedded_lld_lib PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) set_target_properties(embedded_lld_elf PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) set_target_properties(embedded_lld_coff PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) target_include_directories(embedded_lld_lib PUBLIC @@ -289,17 +214,20 @@ include_directories( "${CMAKE_SOURCE_DIR}/src" ) -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") -if(MINGW) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") +if(MSVC) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -W4") +elseif(MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") +else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") endif() -set(EXE_CFLAGS "-std=c++11") -if(MINGW) - set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") -elseif(MSVC) - set(EXE_CFLAGS "${EXE_CFLAGS} -D_MSVC") +if(MSVC) + set(EXE_CFLAGS "-std=c++11") +else() + set(EXE_CFLAGS "-std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") endif() + set(EXE_LDFLAGS " ") if(ZIG_TEST_COVERAGE) set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage") @@ -312,9 +240,6 @@ set_target_properties(zig PROPERTIES LINK_FLAGS ${EXE_LDFLAGS} ) -if(MINGW) - set(PLATFORM_LIBRARIES quadmath) -endif() target_link_libraries(zig LINK_PUBLIC ${CLANG_LIBRARIES} ${LLD_LIBRARIES} @@ -322,11 +247,12 @@ target_link_libraries(zig LINK_PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${PLATFORM_LIBRARIES} ) -if(MINGW OR MSVC) - target_link_libraries(zig LINK_PUBLIC version) -endif() if(MSVC) - target_link_libraries(zig LINK_PUBLIC "C:/Program Files (x86)/Microsoft Visual Studio 14.0/DIA SDK/lib/diaguids.lib") + target_link_libraries(zig LINK_PUBLIC version) +elseif(MINGW) + target_link_libraries(zig LINK_PUBLIC version quadmath) +else() + target_link_libraries(zig LINK_PUBLIC quadmath) endif() install(TARGETS zig DESTINATION bin) diff --git a/cmake/Findclang.cmake b/cmake/Findclang.cmake new file mode 100644 index 000000000..4c4a13e6c --- /dev/null +++ b/cmake/Findclang.cmake @@ -0,0 +1,63 @@ +# Copyright (c) 2016 Andrew Kelley +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# CLANG_FOUND +# CLANG_INCLUDE_DIRS +# CLANG_LIBRARIES + +if(MSVC) + find_package(CLANG REQUIRED CONFIG) + + set(CLANG_LIBRARIES + clangFrontend + clangDriver + clangSerialization + clangSema + clangAnalysis + clangAST + clangParse + clangSema + clangBasic + clangEdit + clangLex + ) + +else() + find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h + PATHS + /usr/lib/llvm/5/include + /usr/lib/llvm-5.0/include + /mingw64/include) + + macro(FIND_AND_ADD_CLANG_LIB _libname_) + string(TOUPPER ${_libname_} _prettylibname_) + find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} + PATHS + /usr/lib/llvm/5/lib + /usr/lib/llvm-5.0/lib + /mingw64/lib + /c/msys64/mingw64/lib + c:\\msys64\\mingw64\\lib) + if(CLANG_${_prettylibname_}_LIB) + set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB}) + endif() + endmacro(FIND_AND_ADD_CLANG_LIB) + + FIND_AND_ADD_CLANG_LIB(clangFrontend) + FIND_AND_ADD_CLANG_LIB(clangDriver) + FIND_AND_ADD_CLANG_LIB(clangSerialization) + FIND_AND_ADD_CLANG_LIB(clangSema) + FIND_AND_ADD_CLANG_LIB(clangAnalysis) + FIND_AND_ADD_CLANG_LIB(clangAST) + FIND_AND_ADD_CLANG_LIB(clangParse) + FIND_AND_ADD_CLANG_LIB(clangSema) + FIND_AND_ADD_CLANG_LIB(clangBasic) + FIND_AND_ADD_CLANG_LIB(clangEdit) + FIND_AND_ADD_CLANG_LIB(clangLex) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS) + +mark_as_advanced(CLANG_INCLUDE_DIRS CLANG_LIBRARIES) diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake new file mode 100644 index 000000000..b57107ca3 --- /dev/null +++ b/cmake/Findllvm.cmake @@ -0,0 +1,116 @@ +# Copyright (c) 2014 Andrew Kelley +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# LLVM_FOUND +# LLVM_INCLUDE_DIRS +# LLVM_LIBRARIES +# LLVM_LIBDIRS + +if(MSVC) + find_package(LLVM REQUIRED CONFIG) + + # TODO: this currently doesn't work, it currently defines UNICODE but zig + # uses MBCS + #add_definitions(${LLVM_DEFINITIONS}) + + link_directories(${LLVM_LIBRARY_DIRS}) + llvm_map_components_to_libnames(LLVM_LIBRARIES + LTO + Symbolize + XCoreDisassembler + XCoreCodeGen + XCoreAsmPrinter + SystemZDisassembler + SystemZCodeGen + SystemZAsmParser + SystemZAsmPrinter + SparcDisassembler + SparcCodeGen + SparcAsmParser + SparcAsmPrinter + PowerPCDisassembler + PowerPCCodeGen + PowerPCAsmParser + PowerPCAsmPrinter + NVPTXCodeGen + NVPTXAsmPrinter + MSP430CodeGen + MSP430AsmPrinter + MipsDisassembler + MipsCodeGen + MipsAsmParser + MipsAsmPrinter + LanaiDisassembler + LanaiCodeGen + LanaiAsmParser + LanaiAsmPrinter + HexagonDisassembler + HexagonCodeGen + HexagonAsmParser + BPFDisassembler + BPFCodeGen + BPFAsmPrinter + ARMDisassembler + ARMCodeGen + ARMAsmParser + ARMAsmPrinter + AMDGPUDisassembler + AMDGPUCodeGen + AMDGPUAsmParser + AMDGPUAsmPrinter + AArch64Disassembler + AArch64CodeGen + AArch64AsmParser + AArch64AsmPrinter + LibDriver + X86Disassembler + X86AsmParser + X86CodeGen + X86AsmPrinter + Core + ) + +else() + find_program(LLVM_CONFIG_EXE + NAMES llvm-config-5.0 llvm-config + PATHS + "/mingw64/bin" + "/c/msys64/mingw64/bin" + "c:/msys64/mingw64/bin" + "C:/Libraries/llvm-5.0.0/bin") + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --libs + OUTPUT_VARIABLE LLVM_LIBRARIES + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --system-libs + OUTPUT_VARIABLE LLVM_SYSTEM_LIBS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --libdir + OUTPUT_VARIABLE LLVM_LIBDIRS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --includedir + OUTPUT_VARIABLE LLVM_INCLUDE_DIRS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + find_library(LLVM_LIBRARY NAMES LLVM) + + set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS}) + + if(LLVM_LIBRARY) + set(LLVM_LIBRARIES ${LLVM_LIBRARY}) + endif() +endif() + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS) + +mark_as_advanced(LLVM_INCLUDE_DIRS LLVM_LIBRARIES LLVM_LIBDIRS) diff --git a/src/bigfloat.hpp b/src/bigfloat.hpp index 7355b0d5c..0dba7cf15 100644 --- a/src/bigfloat.hpp +++ b/src/bigfloat.hpp @@ -13,11 +13,8 @@ #include #include -#if defined(_MSVC) -/* - * For now this is a placeholder until a better solution comes along to - * support 128-bit floats with MSVC. - */ +#if defined(_MSC_VER) +// TODO support 128 bit floats with msvc typedef long double __float128; #endif diff --git a/src/bigint.cpp b/src/bigint.cpp index 66d4068d7..4da9ec2c7 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -377,39 +377,30 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co } } -#if defined(_MSVC) -/* - * Inneficient implmentations for now - */ +#if defined(_MSC_VER) static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 + op2; - if(*result - op2 != op1) { - return true; // overflow - } - return false; // no overflow + return *result < op1 || *result < op2; } static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 - op2; - if(*result > op1) - { - return true; // overflow - } - return false; // no overflow + return *result > op1; } bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 * op2; - if(op1 <= op2) { - if(*result / op1 != op2) { - return true; // overflow - } - } else { - if(*result / op2 != op1) { - return true; // overflow - } - } - return false; // no overflow + + if (op1 == 0 || op2 == 0) + return false; + + if (op1 > UINT64_MAX / op2) + return true; + + if (op2 > UINT64_MAX / op1) + return true; + + return false; } #else static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { diff --git a/src/bigint.hpp b/src/bigint.hpp index 242b64052..bb5550634 100644 --- a/src/bigint.hpp +++ b/src/bigint.hpp @@ -11,7 +11,7 @@ #include #include -#if defined(_MSVC) +#if defined(_MSC_VER) // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128 typedef long long int128_t; typedef unsigned long long uint128_t; diff --git a/src/buffer.hpp b/src/buffer.hpp index 67f7ab758..c12d71956 100644 --- a/src/buffer.hpp +++ b/src/buffer.hpp @@ -24,7 +24,7 @@ struct Buf { }; Buf *buf_sprintf(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); + ATTRIBUTE_PRINTF(1, 2); Buf *buf_vprintf(const char *format, va_list ap); static inline size_t buf_len(Buf *buf) { @@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) { } void buf_appendf(Buf *buf, const char *format, ...) - ATTRIBUTE_FORMAT(printf, 2, 3); + ATTRIBUTE_PRINTF(2, 3); static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { assert(buf->list.length); diff --git a/src/codegen.cpp b/src/codegen.cpp index 5a273375f..3d34eaacb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5194,8 +5194,7 @@ void codegen_add_object(CodeGen *g, Buf *object_path) { g->link_objects.append(object_path); } -#if defined(_MSVC) -// MSVC doesn't seem to support "designators" for array initialization +// Must be coordinated with with CIntType enum static const char *c_int_type_names[] = { "short", "unsigned short", @@ -5206,18 +5205,6 @@ static const char *c_int_type_names[] = { "long long", "unsigned long long", }; -#else -static const char *c_int_type_names[] = { - [CIntTypeShort] = "short", - [CIntTypeUShort] = "unsigned short", - [CIntTypeInt] = "int", - [CIntTypeUInt] = "unsigned int", - [CIntTypeLong] = "long", - [CIntTypeULong] = "unsigned long", - [CIntTypeLongLong] = "long long", - [CIntTypeULongLong] = "unsigned long long", -}; -#endif static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { assert(type_entry); diff --git a/src/parsec.cpp b/src/parsec.cpp index 9bfb34ce7..22f613613 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); -ATTRIBUTE_FORMAT(printf, 3, 4) +ATTRIBUTE_PRINTF(3, 4) static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { if (!c->warnings_on) { return; diff --git a/src/parser.cpp b/src/parser.cpp index 9e63911a2..ba1fd99e5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -24,8 +24,8 @@ struct ParseContext { Buf *void_buf; }; -ATTRIBUTE_FORMAT(printf, 4, 5) -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(4, 5) +ATTRIBUTE_NORETURN static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) { assert(node->type == NodeTypeAsmExpr); @@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const exit(EXIT_FAILURE); } -ATTRIBUTE_FORMAT(printf, 3, 4) -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(3, 4) +ATTRIBUTE_NORETURN static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { va_list ap; va_start(ap, format); @@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) { } } -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_NORETURN static void ast_invalid_token_error(ParseContext *pc, Token *token) { Buf token_value = BUF_INIT; ast_buf_from_token(pc, token, &token_value); diff --git a/src/parser.hpp b/src/parser.hpp index 1434871ad..6e9f00299 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -12,7 +12,7 @@ #include "tokenizer.hpp" #include "errmsg.hpp" -ATTRIBUTE_FORMAT(printf, 2, 3) +ATTRIBUTE_PRINTF(2, 3) void ast_token_error(Token *token, const char *format, ...); diff --git a/src/quadmath.hpp b/src/quadmath.hpp index 1c5621cbd..4fefda228 100644 --- a/src/quadmath.hpp +++ b/src/quadmath.hpp @@ -8,46 +8,44 @@ #ifndef ZIG_QUADMATH_HPP #define ZIG_QUADMATH_HPP -#if defined(_MSVC) - #include - #include - #include - #include -#endif +#if defined(_MSC_VER) +#include +#include +#include +#include + +static inline __float128 fmodq(__float128 a, __float128 b) { + return fmodl(a, b); +} + +static inline __float128 ceilq(__float128 a) { + return ceill(a); +} + +static inline __float128 floorq(__float128 a) { + return floorl(a); +} + +static inline __float128 strtoflt128(const char *s, char **sp) { + return strtold(s, sp); +} + +static inline int quadmath_snprintf(char *s, size_t size, const char *format, ...) { + va_list args; + va_start(format, args); + int result = vsnprintf(s, size, format, args); + va_end(args); + return result; +} -extern "C" { -#if defined(_MSVC) - static __float128 fmodq(__float128 a, __float128 b) - { - return fmod(a, b); - } - static __float128 ceilq(__float128 a) - { - return ceil(a); - } - static __float128 floorq(__float128 a) - { - return floor(a); - } - static __float128 strtoflt128(const char *s, char **sp) - { - return strtold(s, sp); - } - static int quadmath_snprintf(char *s, size_t size, const char *format, ...) - { - va_list args; - va_start(format, args); - int result = vsnprintf(s, size, format, args); - va_end(args); - return result; - } #else +extern "C" { __float128 fmodq(__float128 a, __float128 b); __float128 ceilq(__float128 a); __float128 floorq(__float128 a); __float128 strtoflt128 (const char *s, char **sp); int quadmath_snprintf (char *s, size_t size, const char *format, ...); -#endif } +#endif #endif diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index e99ad43f8..a7820678d 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -234,7 +234,7 @@ struct Tokenize { BigInt significand; }; -ATTRIBUTE_FORMAT(printf, 2, 3) +ATTRIBUTE_PRINTF(2, 3) static void tokenize_error(Tokenize *t, const char *format, ...) { t->state = TokenizeStateError; diff --git a/src/util.hpp b/src/util.hpp index 338170ce9..5ef63bed4 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -12,52 +12,57 @@ #include #include #include -#include #include -#if defined(_MSVC) - #define ATTRIBUTE_COLD - #define ATTRIBUTE_FORMAT(args) - static inline uint32_t popcnt(unsigned long long x) - { - x -= ((x >> 1) & 0x55555555); - x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); - x = (((x >> 4) + x) & 0x0f0f0f0f); - x += (x >> 8); - x += (x >> 16); - return x & 0x0000003f; - } - static inline uint32_t clzll(unsigned long long x) - { - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - return 32 - popcnt(x); - } +#if defined(_MSC_VER) + +#include + +#define ATTRIBUTE_COLD __declspec(noinline) +#define ATTRIBUTE_PRINTF(a, b) +#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict) +#define ATTRIBUTE_NORETURN __declspec(noreturn) + +static inline int clzll(unsigned long long mask) { + unsigned long lz; +#if defined(_WIN64) + if (_BitScanReverse64(&lz, mask)) + return static_cast(63-lz); + zig_unreachable(); #else - #define ATTRIBUTE_COLD __attribute__((cold)) - #define ATTRIBUTE_FORMAT(args) __attribute__((format (args))) - #define clzll(x) __builtin_clzll(x) + if (_BitScanReverse(&lz, mask >> 32)) + lz += 32; + else + _BitScanReverse(&lz, mask & 0xffffffff); + return 63 - lz; +#endif +} +#else + +#define ATTRIBUTE_COLD __attribute__((cold)) +#define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b))) +#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) +#define ATTRIBUTE_NORETURN __attribute__((noreturn)) +#define clzll(x) __builtin_clzll(x) + #endif #define BREAKPOINT __asm("int $0x03") -LLVM_ATTRIBUTE_NOINLINE ATTRIBUTE_COLD -ATTRIBUTE_FORMAT(printf, 1, 2) +ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(1, 2) void zig_panic(const char *format, ...); ATTRIBUTE_COLD -LLVM_ATTRIBUTE_NOINLINE +ATTRIBUTE_NORETURN static inline void zig_unreachable(void) { zig_panic("unreachable"); } template -LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { +ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { T *ptr = reinterpret_cast(malloc(count * sizeof(T))); if (!ptr) zig_panic("allocation failed"); @@ -65,7 +70,7 @@ LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { } template -LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { +ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { T *ptr = reinterpret_cast(calloc(count, sizeof(T))); if (!ptr) zig_panic("allocation failed");