Skip to content

Commit f42a364

Browse files
committed
Fixes cutils.h for MSVC
Signed-off-by: Yonggang Luo <[email protected]>
1 parent b5e6289 commit f42a364

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

cutils.h

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,35 @@
2828
#include <stdlib.h>
2929
#include <inttypes.h>
3030

31+
#ifdef _WIN32
32+
#include <intrin.h>
33+
#include <malloc.h>
34+
#else
35+
#include <alloca.h>
36+
#endif
37+
3138
/* set if CPU is big endian */
3239
#undef WORDS_BIGENDIAN
3340

41+
#if defined(_MSC_VER)
42+
#define likely(x) (x)
43+
#define unlikely(x) (x)
44+
#define force_inline __forceinline
45+
#define no_inline __declspec(noinline)
46+
#define __maybe_unused
47+
#define __attribute__(x)
48+
#define __attribute(x)
49+
#ifndef SSIZE_MAX
50+
#define SSIZE_MAX INTPTR_MAX
51+
typedef intptr_t ssize_t;
52+
#endif
53+
#else
3454
#define likely(x) __builtin_expect(!!(x), 1)
3555
#define unlikely(x) __builtin_expect(!!(x), 0)
3656
#define force_inline inline __attribute__((always_inline))
3757
#define no_inline __attribute__((noinline))
3858
#define __maybe_unused __attribute__((unused))
59+
#endif
3960

4061
#define xglue(x, y) x ## y
4162
#define glue(x, y) xglue(x, y)
@@ -114,27 +135,91 @@ static inline int64_t min_int64(int64_t a, int64_t b)
114135
/* WARNING: undefined if a = 0 */
115136
static inline int clz32(unsigned int a)
116137
{
138+
#ifdef _MSC_VER
139+
unsigned long idx;
140+
_BitScanReverse(&idx, a);
141+
return 31 ^ idx;
142+
#else
117143
return __builtin_clz(a);
144+
#endif
118145
}
119146

120147
/* WARNING: undefined if a = 0 */
121148
static inline int clz64(uint64_t a)
122149
{
123-
return __builtin_clzll(a);
150+
#ifdef _MSC_VER
151+
unsigned long where;
152+
// BitScanReverse scans from MSB to LSB for first set bit.
153+
// Returns 0 if no set bit is found.
154+
#if INTPTR_MAX >= INT64_MAX // 64-bit
155+
if (_BitScanReverse64(&where, a))
156+
return (int)(63 - where);
157+
#else
158+
// Scan the high 32 bits.
159+
if (_BitScanReverse(&where, (uint32_t)(a >> 32)))
160+
return (int)(63 - (where + 32)); // Create a bit offset from the MSB.
161+
// Scan the low 32 bits.
162+
if (_BitScanReverse(&where, (uint32_t)(a)))
163+
return (int)(63 - where);
164+
#endif
165+
return 64; // Undefined Behavior.
166+
#else
167+
return __builtin_clzll(a);
168+
#endif
124169
}
125170

126171
/* WARNING: undefined if a = 0 */
127172
static inline int ctz32(unsigned int a)
128173
{
174+
#ifdef _MSC_VER
175+
unsigned long idx;
176+
_BitScanForward(&idx, a);
177+
return idx;
178+
#else
129179
return __builtin_ctz(a);
180+
#endif
130181
}
131182

132183
/* WARNING: undefined if a = 0 */
133184
static inline int ctz64(uint64_t a)
134185
{
135-
return __builtin_ctzll(a);
186+
#ifdef _MSC_VER
187+
unsigned long where;
188+
// Search from LSB to MSB for first set bit.
189+
// Returns zero if no set bit is found.
190+
#if INTPTR_MAX >= INT64_MAX // 64-bit
191+
if (_BitScanForward64(&where, a))
192+
return (int)(where);
193+
#else
194+
// Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
195+
// Scan the Low Word.
196+
if (_BitScanForward(&where, (uint32_t)(a)))
197+
return (int)(where);
198+
// Scan the High Word.
199+
if (_BitScanForward(&where, (uint32_t)(a >> 32)))
200+
return (int)(where + 32); // Create a bit offset from the LSB.
201+
#endif
202+
return 64;
203+
#else
204+
return __builtin_ctzll(a);
205+
#endif
136206
}
137207

208+
#ifdef _MSC_VER
209+
#pragma pack(push, 1)
210+
struct packed_u64 {
211+
uint64_t v;
212+
};
213+
214+
struct packed_u32 {
215+
uint32_t v;
216+
};
217+
218+
struct packed_u16 {
219+
uint16_t v;
220+
};
221+
#pragma pack(pop)
222+
#else
138223
struct __attribute__((packed)) packed_u64 {
139224
uint64_t v;
140225
};
@@ -146,6 +231,7 @@ struct __attribute__((packed)) packed_u32 {
146231
struct __attribute__((packed)) packed_u16 {
147232
uint16_t v;
148233
};
234+
#endif
149235

150236
static inline uint64_t get_u64(const uint8_t *tab)
151237
{

0 commit comments

Comments
 (0)