| ... | @@ -2796,6 +2796,10 @@ static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_ | ... | @@ -2796,6 +2796,10 @@ static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_ |
| 2796 | /* ========================= Floating Point Support ========================= */ | 2796 | /* ========================= Floating Point Support ========================= */ |
| 2797 | | 2797 | |
| 2798 | #if _MSC_VER | 2798 | #if _MSC_VER |
| | 2799 | float __cdecl nanf(char const* input); |
| | 2800 | double __cdecl nan(char const* input); |
| | 2801 | long double __cdecl nanl(char const* input); |
| | 2802 | |
| 2799 | #define zig_msvc_flt_inf ((double)(1e+300 * 1e+300)) | 2803 | #define zig_msvc_flt_inf ((double)(1e+300 * 1e+300)) |
| 2800 | #define zig_msvc_flt_inff ((float)(1e+300 * 1e+300)) | 2804 | #define zig_msvc_flt_inff ((float)(1e+300 * 1e+300)) |
| 2801 | #define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300)) | 2805 | #define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300)) |
| ... | @@ -3203,10 +3207,10 @@ zig_float_builtins(f128) | ... | @@ -3203,10 +3207,10 @@ zig_float_builtins(f128) |
| 3203 | | 3207 | |
| 3204 | // TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 | 3208 | // TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 |
| 3205 | | 3209 | |
| 3206 | #define zig_msvc_atomics(ZigType, Type, suffix) \ | 3210 | #define zig_msvc_atomics(ZigType, Type, SigType, suffix) \ |
| 3207 | static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \ | 3211 | static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \ |
| 3208 | Type comparand = *expected; \ | 3212 | Type comparand = *expected; \ |
| 3209 | Type initial = _InterlockedCompareExchange##suffix(obj, desired, comparand); \ | 3213 | Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \ |
| 3210 | bool exchanged = initial == comparand; \ | 3214 | bool exchanged = initial == comparand; \ |
| 3211 | if (!exchanged) { \ | 3215 | if (!exchanged) { \ |
| 3212 | *expected = initial; \ | 3216 | *expected = initial; \ |
| ... | @@ -3214,10 +3218,10 @@ zig_float_builtins(f128) | ... | @@ -3214,10 +3218,10 @@ zig_float_builtins(f128) |
| 3214 | return exchanged; \ | 3218 | return exchanged; \ |
| 3215 | } \ | 3219 | } \ |
| 3216 | static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \ | 3220 | static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \ |
| 3217 | return _InterlockedExchange##suffix(obj, value); \ | 3221 | return _InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3218 | } \ | 3222 | } \ |
| 3219 | static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \ | 3223 | static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \ |
| 3220 | return _InterlockedExchangeAdd##suffix(obj, value); \ | 3224 | return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3221 | } \ | 3225 | } \ |
| 3222 | static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \ | 3226 | static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \ |
| 3223 | bool success = false; \ | 3227 | bool success = false; \ |
| ... | @@ -3231,13 +3235,13 @@ zig_float_builtins(f128) | ... | @@ -3231,13 +3235,13 @@ zig_float_builtins(f128) |
| 3231 | return prev; \ | 3235 | return prev; \ |
| 3232 | } \ | 3236 | } \ |
| 3233 | static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \ | 3237 | static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \ |
| 3234 | return _InterlockedOr##suffix(obj, value); \ | 3238 | return _InterlockedOr##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3235 | } \ | 3239 | } \ |
| 3236 | static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \ | 3240 | static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \ |
| 3237 | return _InterlockedXor##suffix(obj, value); \ | 3241 | return _InterlockedXor##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3238 | } \ | 3242 | } \ |
| 3239 | static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \ | 3243 | static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \ |
| 3240 | return _InterlockedAnd##suffix(obj, value); \ | 3244 | return _InterlockedAnd##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3241 | } \ | 3245 | } \ |
| 3242 | static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \ | 3246 | static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \ |
| 3243 | bool success = false; \ | 3247 | bool success = false; \ |
| ... | @@ -3273,22 +3277,22 @@ zig_float_builtins(f128) | ... | @@ -3273,22 +3277,22 @@ zig_float_builtins(f128) |
| 3273 | return prev; \ | 3277 | return prev; \ |
| 3274 | } \ | 3278 | } \ |
| 3275 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ | 3279 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ |
| 3276 | _InterlockedExchange##suffix(obj, value); \ | 3280 | (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ |
| 3277 | } \ | 3281 | } \ |
| 3278 | static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \ | 3282 | static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \ |
| 3279 | return _InterlockedOr##suffix(obj, 0); \ | 3283 | return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \ |
| 3280 | } | 3284 | } |
| 3281 | | 3285 | |
| 3282 | zig_msvc_atomics( u8, uint8_t, 8) | 3286 | zig_msvc_atomics( u8, uint8_t, char, 8) |
| 3283 | zig_msvc_atomics( i8, int8_t, 8) | 3287 | zig_msvc_atomics( i8, int8_t, char, 8) |
| 3284 | zig_msvc_atomics(u16, uint16_t, 16) | 3288 | zig_msvc_atomics(u16, uint16_t, short, 16) |
| 3285 | zig_msvc_atomics(i16, int16_t, 16) | 3289 | zig_msvc_atomics(i16, int16_t, short, 16) |
| 3286 | zig_msvc_atomics(u32, uint32_t, ) | 3290 | zig_msvc_atomics(u32, uint32_t, long, ) |
| 3287 | zig_msvc_atomics(i32, int32_t, ) | 3291 | zig_msvc_atomics(i32, int32_t, long, ) |
| 3288 | | 3292 | |
| 3289 | #if _M_X64 | 3293 | #if _M_X64 |
| 3290 | zig_msvc_atomics(u64, uint64_t, 64) | 3294 | zig_msvc_atomics(u64, uint64_t, __int64, 64) |
| 3291 | zig_msvc_atomics(i64, int64_t, 64) | 3295 | zig_msvc_atomics(i64, int64_t, __int64, 64) |
| 3292 | #endif | 3296 | #endif |
| 3293 | | 3297 | |
| 3294 | #define zig_msvc_flt_atomics(Type, ReprType, suffix) \ | 3298 | #define zig_msvc_flt_atomics(Type, ReprType, suffix) \ |
| ... | @@ -3336,9 +3340,9 @@ zig_msvc_atomics(i64, int64_t, 64) | ... | @@ -3336,9 +3340,9 @@ zig_msvc_atomics(i64, int64_t, 64) |
| 3336 | return expected; \ | 3340 | return expected; \ |
| 3337 | } | 3341 | } |
| 3338 | | 3342 | |
| 3339 | zig_msvc_flt_atomics(f32, uint32_t, ) | 3343 | zig_msvc_flt_atomics(f32, long, ) |
| 3340 | #if _M_X64 | 3344 | #if _M_X64 |
| 3341 | zig_msvc_flt_atomics(f64, uint64_t, 64) | 3345 | zig_msvc_flt_atomics(f64, int64_t, 64) |
| 3342 | #endif | 3346 | #endif |
| 3343 | | 3347 | |
| 3344 | #if _M_IX86 | 3348 | #if _M_IX86 |
| ... | @@ -3349,56 +3353,52 @@ static inline void zig_msvc_atomic_barrier() { | ... | @@ -3349,56 +3353,52 @@ static inline void zig_msvc_atomic_barrier() { |
| 3349 | } | 3353 | } |
| 3350 | } | 3354 | } |
| 3351 | | 3355 | |
| 3352 | static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, void* arg) { | 3356 | static inline void* zig_msvc_atomicrmw_xchg_p32(void volatile* obj, void* arg) { |
| 3353 | return _InterlockedExchangePointer(obj, arg); | 3357 | return _InterlockedExchangePointer(obj, arg); |
| 3354 | } | 3358 | } |
| 3355 | | 3359 | |
| 3356 | static inline void zig_msvc_atomic_store_p32(void** obj, void* arg) { | 3360 | static inline void zig_msvc_atomic_store_p32(void volatile* obj, void* arg) { |
| 3357 | _InterlockedExchangePointer(obj, arg); | 3361 | (void)_InterlockedExchangePointer(obj, arg); |
| 3358 | } | 3362 | } |
| 3359 | | 3363 | |
| 3360 | static inline void* zig_msvc_atomic_load_p32(void** obj) { | 3364 | static inline void* zig_msvc_atomic_load_p32(void volatile* obj) { |
| 3361 | return (void*)_InterlockedOr((void*)obj, 0); | 3365 | return (void*)_InterlockedExchangeAdd(obj, 0); |
| 3362 | } | 3366 | } |
| 3363 | | 3367 | |
| 3364 | static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desired) { | 3368 | static inline bool zig_msvc_cmpxchg_p32(void volatile* obj, void* expected, void* desired) { |
| 3365 | void* comparand = *expected; | 3369 | void* comparand = *(void**)expected; |
| 3366 | void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); | 3370 | void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); |
| 3367 | bool exchanged = initial == comparand; | 3371 | bool success = initial == comparand; |
| 3368 | if (!exchanged) { | 3372 | if (!success) *(void**)expected = initial; |
| 3369 | *expected = initial; | 3373 | return success; |
| 3370 | } | | |
| 3371 | return exchanged; | | |
| 3372 | } | 3374 | } |
| 3373 | #else /* _M_IX86 */ | 3375 | #else /* _M_IX86 */ |
| 3374 | static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, void* arg) { | 3376 | static inline void* zig_msvc_atomicrmw_xchg_p64(void volatile* obj, void* arg) { |
| 3375 | return _InterlockedExchangePointer(obj, arg); | 3377 | return _InterlockedExchangePointer(obj, arg); |
| 3376 | } | 3378 | } |
| 3377 | | 3379 | |
| 3378 | static inline void zig_msvc_atomic_store_p64(void** obj, void* arg) { | 3380 | static inline void zig_msvc_atomic_store_p64(void volatile* obj, void* arg) { |
| 3379 | _InterlockedExchangePointer(obj, arg); | 3381 | (void)_InterlockedExchangePointer(obj, arg); |
| 3380 | } | 3382 | } |
| 3381 | | 3383 | |
| 3382 | static inline void* zig_msvc_atomic_load_p64(void** obj) { | 3384 | static inline void* zig_msvc_atomic_load_p64(void volatile* obj) { |
| 3383 | return (void*)_InterlockedOr64((void*)obj, 0); | 3385 | return (void*)_InterlockedExchangeAdd64(obj, 0); |
| 3384 | } | 3386 | } |
| 3385 | | 3387 | |
| 3386 | static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desired) { | 3388 | static inline bool zig_msvc_cmpxchg_p64(void volatile* obj, void* expected, void* desired) { |
| 3387 | void* comparand = *expected; | 3389 | void* comparand = *(void**)expected; |
| 3388 | void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); | 3390 | void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); |
| 3389 | bool exchanged = initial == comparand; | 3391 | bool success = initial == comparand; |
| 3390 | if (!exchanged) { | 3392 | if (!success) *(void**)expected = initial; |
| 3391 | *expected = initial; | 3393 | return success; |
| 3392 | } | | |
| 3393 | return exchanged; | | |
| 3394 | } | 3394 | } |
| 3395 | | 3395 | |
| 3396 | static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) { | 3396 | static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) { |
| 3397 | return _InterlockedCompareExchange128((int64_t volatile*)obj, desired.hi, desired.lo, (int64_t*)expected); | 3397 | return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected); |
| 3398 | } | 3398 | } |
| 3399 | | 3399 | |
| 3400 | static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { | 3400 | static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { |
| 3401 | return _InterlockedCompareExchange128((int64_t volatile*)obj, desired.hi, desired.lo, (uint64_t*)expected); | 3401 | return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected); |
| 3402 | } | 3402 | } |
| 3403 | | 3403 | |
| 3404 | #define zig_msvc_atomics_128xchg(Type) \ | 3404 | #define zig_msvc_atomics_128xchg(Type) \ |
| ... | @@ -3471,16 +3471,16 @@ static inline void* zig_x86_windows_teb(void) { | ... | @@ -3471,16 +3471,16 @@ static inline void* zig_x86_windows_teb(void) { |
| 3471 | #if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__) | 3471 | #if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__) |
| 3472 | | 3472 | |
| 3473 | static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { | 3473 | static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { |
| 3474 | uint32_t cpu_info[4]; | | |
| 3475 | #if _MSC_VER | 3474 | #if _MSC_VER |
| | 3475 | int cpu_info[4]; |
| 3476 | __cpuidex(cpu_info, leaf_id, subid); | 3476 | __cpuidex(cpu_info, leaf_id, subid); |
| | 3477 | *eax = (uint32_t)cpu_info[0]; |
| | 3478 | *ebx = (uint32_t)cpu_info[1]; |
| | 3479 | *ecx = (uint32_t)cpu_info[2]; |
| | 3480 | *edx = (uint32_t)cpu_info[3]; |
| 3477 | #else | 3481 | #else |
| 3478 | __cpuid_count(leaf_id, subid, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]); | 3482 | __cpuid_count(leaf_id, subid, *eax, *ebx, *ecx, *edx); |
| 3479 | #endif | 3483 | #endif |
| 3480 | *eax = cpu_info[0]; | | |
| 3481 | *ebx = cpu_info[1]; | | |
| 3482 | *ecx = cpu_info[2]; | | |
| 3483 | *edx = cpu_info[3]; | | |
| 3484 | } | 3484 | } |
| 3485 | | 3485 | |
| 3486 | static inline uint32_t zig_x86_get_xcr0(void) { | 3486 | static inline uint32_t zig_x86_get_xcr0(void) { |