diff --git a/decode.c b/decode.c index c0cbef0..8d750ad 100644 --- a/decode.c +++ b/decode.c @@ -6,8 +6,13 @@ #include +#ifdef __GNUC__ #define LIKELY(x) __builtin_expect((x), 1) #define UNLIKELY(x) __builtin_expect((x), 0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif // Defines FD_TABLE_OFFSET_32 and FD_TABLE_OFFSET_64, if available #define FD_DECODE_TABLE_DEFINES @@ -33,7 +38,7 @@ typedef enum DecodeMode DecodeMode; static unsigned table_walk(unsigned cur_idx, unsigned entry_idx, unsigned* out_kind) { - static __attribute__((aligned(16))) const uint16_t _decode_table[] = { + static _Alignas(16) const uint16_t _decode_table[] = { #define FD_DECODE_TABLE_DATA #include #undef FD_DECODE_TABLE_DATA @@ -65,7 +70,7 @@ struct InstrDesc uint16_t operand_indices; uint16_t operand_sizes; uint16_t reg_types; -} __attribute__((packed)); +}; #define DESC_HAS_MODRM(desc) (((desc)->operand_indices & (3 << 0)) != 0) #define DESC_MODRM_IDX(desc) ((((desc)->operand_indices >> 0) & 3) ^ 3) @@ -271,7 +276,7 @@ prefix_end: if (UNLIKELY(kind != ENTRY_INSTR)) return kind == 0 ? FD_ERR_UD : FD_ERR_PARTIAL; - static __attribute__((aligned(16))) const struct InstrDesc descs[] = { + static _Alignas(16) const struct InstrDesc descs[] = { #define FD_DECODE_TABLE_DESCS #include #undef FD_DECODE_TABLE_DESCS @@ -301,7 +306,8 @@ prefix_end: if (prefix_rex & PREFIX_VEXL) vec_size = 32; - __builtin_memset(instr->operands, 0, sizeof(instr->operands)); + for (unsigned i = 0; i < sizeof(instr->operands) / sizeof(FdOp); i++) + instr->operands[i] = (FdOp) {0}; if (DESC_MODRM(desc) && UNLIKELY(off++ >= len)) return FD_ERR_PARTIAL; diff --git a/encode.c b/encode.c index ebaac3a..06b2072 100644 --- a/encode.c +++ b/encode.c @@ -6,8 +6,13 @@ #include +#ifdef __GNUC__ #define LIKELY(x) __builtin_expect((x), 1) #define UNLIKELY(x) __builtin_expect((x), 0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif enum { // 16:17 = escape diff --git a/format.c b/format.c index 1169723..553ac63 100644 --- a/format.c +++ b/format.c @@ -2,12 +2,24 @@ #include #include #include +#ifdef _MSC_VER +#include +#endif #include +#ifdef __GNUC__ #define LIKELY(x) __builtin_expect((x), 1) #define UNLIKELY(x) __builtin_expect((x), 0) +#define DECLARE_ARRAY_SIZE(n) static n +#define DECLARE_RESTRICTED_ARRAY_SIZE(n) restrict static n +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#define DECLARE_ARRAY_SIZE(n) n +#define DECLARE_RESTRICTED_ARRAY_SIZE(n) n +#endif struct FdStr { const char* s; @@ -27,7 +39,11 @@ fd_strplcpy(char* restrict dst, const char* src, size_t size) { static char* fd_strpcat(char* restrict dst, struct FdStr src) { +#ifdef __GNUC__ unsigned lim = __builtin_constant_p(src.sz) && src.sz <= 8 ? 8 : 16; +#else + unsigned lim = 16; +#endif for (unsigned i = 0; i < lim; i++) dst[i] = src.s[i]; // __builtin_memcpy(dst, src.s, 16); @@ -36,7 +52,24 @@ fd_strpcat(char* restrict dst, struct FdStr src) { static unsigned fd_clz64(uint64_t v) { +#if defined(__GNUC__) return __builtin_clzl(v); +#elif defined(_MSC_VER) + unsigned long index; + +#if INTPTR_MAX == INT64_MAX + _BitScanReverse64(&index, v); +#else + if (_BitScanReverse(&index, v >> 32)) + return 31 - index; + + _BitScanReverse(&index, v & 0xffffffff); +#endif + + return 63 - index; +#else +#error Unsupported compiler. +#endif } #if defined(__SSE2__) @@ -44,7 +77,7 @@ fd_clz64(uint64_t v) { #endif static char* -fd_strpcatnum(char dst[static 18], uint64_t val) { +fd_strpcatnum(char dst[DECLARE_ARRAY_SIZE(18)], uint64_t val) { unsigned lz = fd_clz64(val|1); unsigned numbytes = 16 - (lz / 4); #if defined(__SSE2__) @@ -132,7 +165,7 @@ fdi_name(FdInstrType ty) { } static char* -fd_mnemonic(char buf[restrict static 48], const FdInstr* instr) { +fd_mnemonic(char buf[DECLARE_RESTRICTED_ARRAY_SIZE(48)], const FdInstr* instr) { #define FD_DECODE_TABLE_STRTAB1 static const char* mnemonic_str = #include @@ -281,7 +314,7 @@ fd_mnemonic(char buf[restrict static 48], const FdInstr* instr) { } static char* -fd_format_impl(char buf[restrict static 128], const FdInstr* instr, uint64_t addr) { +fd_format_impl(char buf[DECLARE_RESTRICTED_ARRAY_SIZE(128)], const FdInstr* instr, uint64_t addr) { buf = fd_mnemonic(buf, instr); for (int i = 0; i < 4; i++) diff --git a/meson.build b/meson.build index 582d2af..136f853 100644 --- a/meson.build +++ b/meson.build @@ -51,6 +51,22 @@ if get_option('with_encode2') sources += files('encode2.c') endif +if cc.get_argument_syntax() == 'msvc' + # Disable some warnings to align warnings with GCC and Clang: + add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', + '/wd4018', # - Signed/unsigned comparison + '/wd4146', # - Unary minus operator applied to unsigned + # type, result still unsigned + '/wd4244', # - Possible loss of data in conversion + # from integer type to smaller integer type + '/wd4245', # - Signed/unsigned assignment + '/wd4267', # - Possible loss of data in conversion + # from size_t to smaller type + '/wd4310', # - Possible loss of data in conversion + # of constant value to smaller type + language: 'c') +endif + generate_args = [] if get_option('archmode') != 'only64' generate_args += ['--32']