2828#include <stdlib.h>
2929#include <inttypes.h>
3030
31+ #ifdef _MSC_VER
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+ typedef intptr_t ssize_t ;
50+ #else
3451#define likely (x ) __builtin_expect(!!(x), 1)
3552#define unlikely (x ) __builtin_expect(!!(x), 0)
3653#define force_inline inline __attribute__((always_inline))
3754#define no_inline __attribute__((noinline))
3855#define __maybe_unused __attribute__((unused))
56+ #endif
3957
4058#define xglue (x , y ) x ## y
4159#define glue (x , y ) xglue(x, y)
@@ -114,27 +132,91 @@ static inline int64_t min_int64(int64_t a, int64_t b)
114132/* WARNING: undefined if a = 0 */
115133static inline int clz32 (unsigned int a )
116134{
135+ #ifdef _MSC_VER
136+ unsigned long idx ;
137+ _BitScanReverse (& idx , a );
138+ return 31 ^ idx ;
139+ #else
117140 return __builtin_clz (a );
141+ #endif
118142}
119143
120144/* WARNING: undefined if a = 0 */
121145static inline int clz64 (uint64_t a )
122146{
123- return __builtin_clzll (a );
147+ #ifdef _MSC_VER
148+ unsigned long where ;
149+ // BitScanReverse scans from MSB to LSB for first set bit.
150+ // Returns 0 if no set bit is found.
151+ #if INTPTR_MAX >= INT64_MAX // 64-bit
152+ if (_BitScanReverse64 (& where , a ))
153+ return (int )(63 - where );
154+ #else
155+ // Scan the high 32 bits.
156+ if (_BitScanReverse (& where , (uint32_t )(a >> 32 )))
157+ return (int )(63 - (where + 32 )); // Create a bit offset from the MSB.
158+ // Scan the low 32 bits.
159+ if (_BitScanReverse (& where , (uint32_t )(a )))
160+ return (int )(63 - where );
161+ #endif
162+ return 64 ; // Undefined Behavior.
163+ #else
164+ return __builtin_clzll (a );
165+ #endif
124166}
125167
126168/* WARNING: undefined if a = 0 */
127169static inline int ctz32 (unsigned int a )
128170{
171+ #ifdef _MSC_VER
172+ unsigned long idx ;
173+ _BitScanForward (& idx , a );
174+ return idx ;
175+ #else
129176 return __builtin_ctz (a );
177+ #endif
130178}
131179
132180/* WARNING: undefined if a = 0 */
133181static inline int ctz64 (uint64_t a )
134182{
135- return __builtin_ctzll (a );
183+ #ifdef _MSC_VER
184+ unsigned long where ;
185+ // Search from LSB to MSB for first set bit.
186+ // Returns zero if no set bit is found.
187+ #if INTPTR_MAX >= INT64_MAX // 64-bit
188+ if (_BitScanForward64 (& where , a ))
189+ return (int )(where );
190+ #else
191+ // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
192+ // Scan the Low Word.
193+ if (_BitScanForward (& where , (uint32_t )(a )))
194+ return (int )(where );
195+ // Scan the High Word.
196+ if (_BitScanForward (& where , (uint32_t )(a >> 32 )))
197+ return (int )(where + 32 ); // Create a bit offset from the LSB.
198+ #endif
199+ return 64 ;
200+ #else
201+ return __builtin_ctzll (a );
202+ #endif
136203}
137204
205+ #ifdef _MSC_VER
206+ #pragma pack(push, 1)
207+ struct packed_u64 {
208+ uint64_t v ;
209+ };
210+
211+ struct packed_u32 {
212+ uint32_t v ;
213+ };
214+
215+ struct packed_u16 {
216+ uint16_t v ;
217+ };
218+ #pragma pack(pop)
219+ #else
138220struct __attribute__((packed )) packed_u64 {
139221 uint64_t v ;
140222};
@@ -146,6 +228,7 @@ struct __attribute__((packed)) packed_u32 {
146228struct __attribute__((packed )) packed_u16 {
147229 uint16_t v ;
148230};
231+ #endif
149232
150233static inline uint64_t get_u64 (const uint8_t * tab )
151234{
0 commit comments