From 964f5a01912c9fbe84d43f5a9faf040f85ffeddc Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Feb 2023 00:19:03 +0100 Subject: [PATCH] build: MSVC compatibility Signed-off-by: Anatol Belski --- ir.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++-- ir.h | 26 ++++++++++++++++++++++---- ir_emit.c | 27 +++++++++++++++++++++++--- ir_gcm.c | 2 +- ir_load.c | 2 ++ ir_main.c | 4 +++- ir_private.h | 30 +++++++++++++++++++++++------ ir_ra.c | 11 ++++++++++- ir_strtab.c | 2 +- 9 files changed, 138 insertions(+), 19 deletions(-) diff --git a/ir.c b/ir.c index dc7e79f..7e83ae3 100644 --- a/ir.c +++ b/ir.c @@ -18,7 +18,12 @@ # define _GNU_SOURCE #endif -#include +#ifndef _WIN32 +# include +#else +# define WIN32_LEAN_AND_MEAN +# include +#endif #include "ir.h" #include "ir_private.h" @@ -1125,7 +1130,7 @@ void ir_hashtab_init(ir_hashtab *tab, uint32_t size) void ir_hashtab_free(ir_hashtab *tab) { uint32_t hash_size = (uint32_t)(-(int32_t)tab->mask); - char *data = tab->data - (hash_size * sizeof(uint32_t)); + char *data = (char*)tab->data - (hash_size * sizeof(uint32_t)); ir_mem_free(data); tab->data = NULL; } @@ -1209,6 +1214,49 @@ void ir_hashtab_key_sort(ir_hashtab *tab) } /* Memory API */ +#ifdef _WIN32 +void *ir_mem_mmap(size_t size) +{ + void *ret; + +#ifdef _M_X64 + DWORD size_hi = size >> 32, size_lo = size & 0xffffffff; +#else + DWORD size_hi = size, size_lo = 0; +#endif + + HANDLE h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, size_hi, size_lo, NULL); + + ret = MapViewOfFile(h, FILE_MAP_COPY | FILE_MAP_EXECUTE, size_hi, size_lo, size); + if (!ret) { + CloseHandle(h); + } + + return ret; +} + +int ir_mem_unmap(void *ptr, size_t size) +{ + /* XXX file handle is leaked. */ + UnmapViewOfFile(ptr); + return 1; +} + +int ir_mem_protect(void *ptr, size_t size) +{ + return 1; +} + +int ir_mem_unprotect(void *ptr, size_t size) +{ + return 1; +} + +int ir_mem_flush(void *ptr, size_t size) +{ + return 1; +} +#else void *ir_mem_mmap(size_t size) { return mmap(NULL, size, PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -1242,6 +1290,7 @@ int ir_mem_flush(void *ptr, size_t size) #endif return 1; } +#endif /* Alias Analyses */ typedef enum _ir_alias { diff --git a/ir.h b/ir.h index 3bc34aa..0bd9090 100644 --- a/ir.h +++ b/ir.h @@ -16,6 +16,20 @@ #define IR_VERSION "0.0.1" +#ifdef _WIN32 +/* TODO Handle ARM, too. */ +# if defined(_M_X64) +# define __SIZEOF_SIZE_T__ 8 +# elif defined(_M_IX86) +# define __SIZEOF_SIZE_T__ 4 +# endif +/* Only supported is little endian for any arch on Windows, + so just fake the same for all. */ +# define __ORDER_LITTLE_ENDIAN__ 1 +# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +# define __has_builtin(arg) (0) +#endif + #if defined(IR_TARGET_X86) # define IR_TARGET "x86" #elif defined(IR_TARGET_X64) @@ -326,6 +340,11 @@ typedef int32_t ir_ref; #define IR_LAST_FOLDABLE_OP IR_COPY /* IR Constant Value */ +#ifndef IR_64 +# define ADDR_MEMBER uintptr_t addr; +#else +# define ADDR_MEMBER +#endif typedef union _ir_val { double d; uint64_t u64; @@ -338,9 +357,7 @@ typedef union _ir_val { uint32_t u32; int32_t i32; float f; -#ifndef IR_64 - uintptr_t addr; -#endif + ADDR_MEMBER IR_STRUCT_LOHI( union { uint16_t u16; @@ -361,6 +378,7 @@ typedef union _ir_val { uint32_t u32_hi ); } ir_val; +#undef ADDR_MEMBER /* IR constant flags */ #define IR_CONST_EMIT (1<<0) @@ -374,7 +392,7 @@ typedef struct _ir_insn { union { IR_STRUCT_LOHI( uint8_t op, - uint8_t type; + uint8_t type ); uint16_t opt; }, diff --git a/ir_emit.c b/ir_emit.c index 7bf62c0..9b60f8a 100644 --- a/ir_emit.c +++ b/ir_emit.c @@ -16,7 +16,13 @@ #endif #include "ir_private.h" -#include +#ifndef _WIN32 +# include +#else +# define WIN32_LEAN_AND_MEAN +# include +# include +#endif #define DASM_M_GROW(ctx, t, p, sz, need) \ do { \ @@ -202,10 +208,25 @@ static void *ir_resolve_sym_name(const char *name) void *handle = NULL; void *addr; -#ifdef RTLD_DEFAULT +#ifndef _WIN32 +# ifdef RTLD_DEFAULT handle = RTLD_DEFAULT; -#endif +# endif addr = dlsym(handle, name); +#else + HMODULE mods[256]; + DWORD cbNeeded; + uint32_t i = 0; + + addr = NULL; + + EnumProcessModules(GetCurrentProcess(), mods, sizeof(mods), &cbNeeded); + + while(!addr && i < (cbNeeded / sizeof(HMODULE))) { + addr = GetProcAddress(mods[i], name); + i++; + } +#endif IR_ASSERT(addr != NULL); return addr; } diff --git a/ir_gcm.c b/ir_gcm.c index 9ae8d31..3e49b4d 100644 --- a/ir_gcm.c +++ b/ir_gcm.c @@ -370,7 +370,7 @@ static void ir_xlat_binding(ir_ctx *ctx, ir_ref *_xlat) ir_hashtab *binding = ctx->binding; uint32_t hash_size = (uint32_t)(-(int32_t)binding->mask); - memset(binding->data - (hash_size * sizeof(uint32_t)), -1, hash_size * sizeof(uint32_t)); + memset((char*)binding->data - (hash_size * sizeof(uint32_t)), -1, hash_size * sizeof(uint32_t)); n1 = binding->count; n2 = 0; pos = 0; diff --git a/ir_load.c b/ir_load.c index ea28d16..b7fc1ef 100644 --- a/ir_load.c +++ b/ir_load.c @@ -15,7 +15,9 @@ #include #include +#ifndef _WIN32 #include +#endif const unsigned char *yy_buf; const unsigned char *yy_end; diff --git a/ir_main.c b/ir_main.c index 35722da..6c74fd9 100644 --- a/ir_main.c +++ b/ir_main.c @@ -355,7 +355,7 @@ int main(int argc, char **argv) return 1; } - f = fopen(input, "r"); + f = fopen(input, "rb"); if (!f) { fprintf(stderr, "ERROR: Cannot open input file '%s'\n", input); return 1; @@ -420,6 +420,7 @@ int main(int argc, char **argv) int (*func)(void) = entry; int ret; +#ifndef _WIN32 ir_perf_map_register("test", entry, size); ir_perf_jitdump_open(); ir_perf_jitdump_register("test", entry, size); @@ -427,6 +428,7 @@ int main(int argc, char **argv) ir_mem_unprotect(entry, 4096); ir_gdb_register("test", entry, size, sizeof(void*), 0); ir_mem_protect(entry, 4096); +#endif ret = func(); fflush(stdout); diff --git a/ir_private.h b/ir_private.h index dba6e89..7ba882b 100644 --- a/ir_private.h +++ b/ir_private.h @@ -17,6 +17,16 @@ # define IR_ASSERT(x) #endif +#ifdef _WIN32 +# include +# ifdef _M_X64 +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) +#endif + #ifdef __has_builtin # if __has_builtin(__builtin_expect) # define EXPECTED(condition) __builtin_expect(!!(condition), 1) @@ -104,7 +114,7 @@ IR_ALWAYS_INLINE uint32_t ir_ntz(uint32_t num) #elif defined(_WIN32) uint32_t index; - if (!BitScanForward(&index, num)) { + if (!_BitScanForward(&index, num)) { /* undefined behavior */ return 32; } @@ -133,9 +143,9 @@ IR_ALWAYS_INLINE uint32_t ir_ntzl(uint64_t num) unsigned long index; #if defined(_WIN64) - if (!BitScanForward64(&index, num)) { + if (!_BitScanForward64(&index, num)) { #else - if (!BitScanForward(&index, num)) { + if (!_BitScanForward(&index, num)) { #endif /* undefined behavior */ return 64; @@ -165,7 +175,7 @@ IR_ALWAYS_INLINE int ir_nlz(uint32_t num) #elif defined(_WIN32) uint32_t index; - if (!BitScanReverse(&index, num)) { + if (!_BitScanReverse(&index, num)) { /* undefined behavior */ return 32; } @@ -192,7 +202,11 @@ IR_ALWAYS_INLINE int ir_nlzl(uint64_t num) #elif defined(_WIN32) uint32_t index; - if (!BitScanReverse64(&index, num)) { +#if defined(_WIN64) + if (!_BitScanReverse64(&index, num)) { +#else + if (!_BitScanReverse(&index, num)) { +#endif /* undefined behavior */ return 64; } @@ -223,7 +237,11 @@ IR_ALWAYS_INLINE int ir_nlzl(uint64_t num) # define ir_bitset_ntz ir_ntz #else # define IR_BITSET_BITS 64 -# define IR_BITSET_ONE 1UL +# ifdef _M_X64 /* MSVC*/ +# define IR_BITSET_ONE 1ui64 +# else +# define IR_BITSET_ONE 1UL +# endif # define ir_bitset_base_t uint64_t # define ir_bitset_ntz ir_ntzl #endif diff --git a/ir_ra.c b/ir_ra.c index 1ae31f6..d4bfb05 100644 --- a/ir_ra.c +++ b/ir_ra.c @@ -862,7 +862,11 @@ static void ir_add_phi_move(ir_ctx *ctx, uint32_t b, ir_ref from, ir_ref to) } } +#ifndef _WIN32 static int ir_block_cmp(const void *b1, const void *b2, void *data) +#else +static int ir_block_cmp(void *data, const void *b1, const void *b2) +#endif { ir_ctx *ctx = data; int d1 = ctx->cfg_blocks[*(ir_ref*)b1].loop_depth; @@ -1047,7 +1051,12 @@ int ir_coalesce(ir_ctx *ctx) } } - qsort_r(blocks.l.a.refs, ir_worklist_len(&blocks), sizeof(ir_ref), ir_block_cmp, ctx); +#ifndef _WIN32 +# define qsort_fn qsort_r +#else +# define qsort_fn qsort_s +#endif + qsort_fn(blocks.l.a.refs, ir_worklist_len(&blocks), sizeof(ir_ref), ir_block_cmp, ctx); while (ir_worklist_len(&blocks)) { uint32_t i; diff --git a/ir_strtab.c b/ir_strtab.c index 8c68ab2..2ef502b 100644 --- a/ir_strtab.c +++ b/ir_strtab.c @@ -206,7 +206,7 @@ const char *ir_strtab_str(ir_strtab *strtab, ir_ref idx) void ir_strtab_free(ir_strtab *strtab) { uint32_t hash_size = (uint32_t)(-(int32_t)strtab->mask); - char *data = strtab->data - (hash_size * sizeof(uint32_t)); + char *data = (char*)strtab->data - (hash_size * sizeof(uint32_t)); ir_mem_free(data); strtab->data = NULL; if (strtab->buf) {