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 */
115136static 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 */
121148static 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 */
127172static 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 */
133184static 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
138223struct __attribute__((packed )) packed_u64 {
139224 uint64_t v ;
140225};
@@ -146,6 +231,7 @@ struct __attribute__((packed)) packed_u32 {
146231struct __attribute__((packed )) packed_u16 {
147232 uint16_t v ;
148233};
234+ #endif
149235
150236static inline uint64_t get_u64 (const uint8_t * tab )
151237{
0 commit comments