|
46 | 46 | #include <malloc_np.h>
|
47 | 47 | #endif
|
48 | 48 |
|
49 |
| -#define likely(x) __builtin_expect(!!(x), 1) |
50 |
| -#define unlikely(x) __builtin_expect(!!(x), 0) |
51 |
| -#define force_inline inline __attribute__((always_inline)) |
52 |
| -#define no_inline __attribute__((noinline)) |
53 |
| -#define __maybe_unused __attribute__((unused)) |
| 49 | + |
| 50 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 51 | +# define likely(x) (x) |
| 52 | +# define unlikely(x) (x) |
| 53 | +# define force_inline __forceinline |
| 54 | +# define no_inline __declspec(noinline) |
| 55 | +# define __maybe_unused |
| 56 | +# define __attribute__(x) |
| 57 | +# define __attribute(x) |
| 58 | +# include <intrin.h> |
| 59 | +static void *__builtin_frame_address(unsigned int level) { |
| 60 | + return (void *)((char*)_AddressOfReturnAddress() - sizeof(int *) - level * sizeof(int *)); |
| 61 | +} |
| 62 | +#else |
| 63 | +# define likely(x) __builtin_expect(!!(x), 1) |
| 64 | +# define unlikely(x) __builtin_expect(!!(x), 0) |
| 65 | +# define force_inline inline __attribute__((always_inline)) |
| 66 | +# define no_inline __attribute__((noinline)) |
| 67 | +# define __maybe_unused __attribute__((unused)) |
| 68 | +#endif |
| 69 | + |
| 70 | +// https://stackoverflow.com/a/6849629 |
| 71 | +#undef FORMAT_STRING |
| 72 | +#if _MSC_VER >= 1400 |
| 73 | +# include <sal.h> |
| 74 | +# if _MSC_VER > 1400 |
| 75 | +# define FORMAT_STRING(p) _Printf_format_string_ p |
| 76 | +# else |
| 77 | +# define FORMAT_STRING(p) __format_string p |
| 78 | +# endif /* FORMAT_STRING */ |
| 79 | +#else |
| 80 | +# define FORMAT_STRING(p) p |
| 81 | +#endif /* _MSC_VER */ |
| 82 | + |
| 83 | +// https://stackoverflow.com/a/3312896 |
| 84 | +// https://stackoverflow.com/a/3312896 |
| 85 | +#if defined(__GNUC__) || defined(__clang__) // GCC, clang, clang-cl, and so on but not MSVC |
| 86 | +# define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) |
| 87 | +#elif defined(_MSC_VER) && !defined(__clang__) // MSVC |
| 88 | +# define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) |
| 89 | +#endif |
| 90 | + |
| 91 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 92 | +#include <math.h> |
| 93 | +#define INF INFINITY |
| 94 | +#define NEG_INF -INFINITY |
| 95 | +#else |
| 96 | +#define INF (1.0/0.0) |
| 97 | +#define NEG_INF (-1.0/0.0) |
| 98 | +#endif |
54 | 99 |
|
55 | 100 | #define xglue(x, y) x ## y
|
56 | 101 | #define glue(x, y) xglue(x, y)
|
@@ -136,38 +181,68 @@ static inline int64_t min_int64(int64_t a, int64_t b)
|
136 | 181 | /* WARNING: undefined if a = 0 */
|
137 | 182 | static inline int clz32(unsigned int a)
|
138 | 183 | {
|
| 184 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 185 | + unsigned long index; |
| 186 | + _BitScanReverse(&index, a); |
| 187 | + return 31 - index; |
| 188 | +#else |
139 | 189 | return __builtin_clz(a);
|
| 190 | +#endif |
140 | 191 | }
|
141 | 192 |
|
142 | 193 | /* WARNING: undefined if a = 0 */
|
143 | 194 | static inline int clz64(uint64_t a)
|
144 | 195 | {
|
| 196 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 197 | + unsigned long index; |
| 198 | + _BitScanReverse64(&index, a); |
| 199 | + return 63 - index; |
| 200 | +#else |
145 | 201 | return __builtin_clzll(a);
|
| 202 | +#endif |
146 | 203 | }
|
147 | 204 |
|
148 | 205 | /* WARNING: undefined if a = 0 */
|
149 | 206 | static inline int ctz32(unsigned int a)
|
150 | 207 | {
|
| 208 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 209 | + unsigned long index; |
| 210 | + _BitScanForward(&index, a); |
| 211 | + return index; |
| 212 | +#else |
151 | 213 | return __builtin_ctz(a);
|
| 214 | +#endif |
152 | 215 | }
|
153 | 216 |
|
154 | 217 | /* WARNING: undefined if a = 0 */
|
155 | 218 | static inline int ctz64(uint64_t a)
|
156 | 219 | {
|
| 220 | +#if defined(_MSC_VER) && !defined(__clang__) |
| 221 | + unsigned long index; |
| 222 | + _BitScanForward64(&index, a); |
| 223 | + return index; |
| 224 | +#else |
157 | 225 | return __builtin_ctzll(a);
|
| 226 | +#endif |
158 | 227 | }
|
159 | 228 |
|
160 |
| -struct __attribute__((packed)) packed_u64 { |
161 |
| - uint64_t v; |
162 |
| -}; |
| 229 | +PACK( |
| 230 | + struct packed_u64 { |
| 231 | + uint64_t v; |
| 232 | + } |
| 233 | +); |
163 | 234 |
|
164 |
| -struct __attribute__((packed)) packed_u32 { |
165 |
| - uint32_t v; |
166 |
| -}; |
| 235 | +PACK( |
| 236 | + struct packed_u32 { |
| 237 | + uint32_t v; |
| 238 | + } |
| 239 | +); |
167 | 240 |
|
168 |
| -struct __attribute__((packed)) packed_u16 { |
169 |
| - uint16_t v; |
170 |
| -}; |
| 241 | +PACK( |
| 242 | + struct packed_u16 { |
| 243 | + uint16_t v; |
| 244 | + } |
| 245 | +); |
171 | 246 |
|
172 | 247 | static inline uint64_t get_u64(const uint8_t *tab)
|
173 | 248 | {
|
@@ -299,7 +374,7 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
|
299 | 374 | return dbuf_put(s, (uint8_t *)&val, 8);
|
300 | 375 | }
|
301 | 376 | int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
302 |
| - const char *fmt, ...); |
| 377 | + FORMAT_STRING(const char *fmt), ...); |
303 | 378 | void dbuf_free(DynBuf *s);
|
304 | 379 | static inline BOOL dbuf_error(DynBuf *s) {
|
305 | 380 | return s->error;
|
|
0 commit comments