authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-21 15:05:41-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-21 15:46:34-05:00
log248fb40dcc5eb50cf19e711197c5d1b210abf1b3
tree1ab5f7d2749f8a884d0d067d95faf17818d60c22
parent434c6f42cad5aef9112b576c685521a9763bef9b

CBE: fix windows test failures


4 files changed, 129 insertions(+), 102 deletions(-)

lib/zig.h+68-63
...@@ -316,7 +316,7 @@ zig_extern void *memset (void *, int, size_t);...@@ -316,7 +316,7 @@ zig_extern void *memset (void *, int, size_t);
316316
317/* ===================== 8/16/32/64-bit Integer Support ===================== */317/* ===================== 8/16/32/64-bit Integer Support ===================== */
318318
319#if __STDC_VERSION__ >= 199901L319#if __STDC_VERSION__ >= 199901L || _MSC_VER
320#include <stdint.h>320#include <stdint.h>
321#else321#else
322322
...@@ -1923,6 +1923,7 @@ typedef double zig_f16;...@@ -1923,6 +1923,7 @@ typedef double zig_f16;
1923#define zig_make_f16(fp, repr) fp1923#define zig_make_f16(fp, repr) fp
1924#elif LDBL_MANT_DIG == 111924#elif LDBL_MANT_DIG == 11
1925#define zig_bitSizeOf_c_longdouble 161925#define zig_bitSizeOf_c_longdouble 16
1926typedef uint16_t zig_repr_c_longdouble;
1926typedef long double zig_f16;1927typedef long double zig_f16;
1927#define zig_make_f16(fp, repr) fp##l1928#define zig_make_f16(fp, repr) fp##l
1928#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))1929#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
...@@ -1959,6 +1960,7 @@ typedef double zig_f32;...@@ -1959,6 +1960,7 @@ typedef double zig_f32;
1959#define zig_make_f32(fp, repr) fp1960#define zig_make_f32(fp, repr) fp
1960#elif LDBL_MANT_DIG == 241961#elif LDBL_MANT_DIG == 24
1961#define zig_bitSizeOf_c_longdouble 321962#define zig_bitSizeOf_c_longdouble 32
1963typedef uint32_t zig_repr_c_longdouble;
1962typedef long double zig_f32;1964typedef long double zig_f32;
1963#define zig_make_f32(fp, repr) fp##l1965#define zig_make_f32(fp, repr) fp##l
1964#elif FLT32_MANT_DIG == 241966#elif FLT32_MANT_DIG == 24
...@@ -1982,6 +1984,7 @@ typedef int32_t zig_f32;...@@ -1982,6 +1984,7 @@ typedef int32_t zig_f32;
1982#if _MSC_VER1984#if _MSC_VER
1983#ifdef ZIG_TARGET_ABI_MSVC1985#ifdef ZIG_TARGET_ABI_MSVC
1984#define zig_bitSizeOf_c_longdouble 641986#define zig_bitSizeOf_c_longdouble 64
1987typedef uint64_t zig_repr_c_longdouble;
1985#endif1988#endif
1986#define zig_make_special_constant_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )1989#define zig_make_special_constant_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
1987#else /* _MSC_VER */1990#else /* _MSC_VER */
...@@ -1995,6 +1998,7 @@ typedef double zig_f64;...@@ -1995,6 +1998,7 @@ typedef double zig_f64;
1995#define zig_make_f64(fp, repr) fp1998#define zig_make_f64(fp, repr) fp
1996#elif LDBL_MANT_DIG == 531999#elif LDBL_MANT_DIG == 53
1997#define zig_bitSizeOf_c_longdouble 642000#define zig_bitSizeOf_c_longdouble 64
2001typedef uint64_t zig_repr_c_longdouble;
1998typedef long double zig_f64;2002typedef long double zig_f64;
1999#define zig_make_f64(fp, repr) fp##l2003#define zig_make_f64(fp, repr) fp##l
2000#elif FLT64_MANT_DIG == 532004#elif FLT64_MANT_DIG == 53
...@@ -2027,6 +2031,7 @@ typedef double zig_f80;...@@ -2027,6 +2031,7 @@ typedef double zig_f80;
2027#define zig_make_f80(fp, repr) fp2031#define zig_make_f80(fp, repr) fp
2028#elif LDBL_MANT_DIG == 642032#elif LDBL_MANT_DIG == 64
2029#define zig_bitSizeOf_c_longdouble 802033#define zig_bitSizeOf_c_longdouble 80
2034typedef zig_u128 zig_repr_c_longdouble;
2030typedef long double zig_f80;2035typedef long double zig_f80;
2031#define zig_make_f80(fp, repr) fp##l2036#define zig_make_f80(fp, repr) fp##l
2032#elif FLT80_MANT_DIG == 642037#elif FLT80_MANT_DIG == 64
...@@ -2062,6 +2067,7 @@ typedef double zig_f128;...@@ -2062,6 +2067,7 @@ typedef double zig_f128;
2062#define zig_make_f128(fp, repr) fp2067#define zig_make_f128(fp, repr) fp
2063#elif LDBL_MANT_DIG == 1132068#elif LDBL_MANT_DIG == 113
2064#define zig_bitSizeOf_c_longdouble 1282069#define zig_bitSizeOf_c_longdouble 128
2070typedef zig_u128 zig_repr_c_longdouble;
2065typedef long double zig_f128;2071typedef long double zig_f128;
2066#define zig_make_f128(fp, repr) fp##l2072#define zig_make_f128(fp, repr) fp##l
2067#elif FLT128_MANT_DIG == 1132073#elif FLT128_MANT_DIG == 113
...@@ -2099,9 +2105,10 @@ typedef zig_i128 zig_f128;...@@ -2099,9 +2105,10 @@ typedef zig_i128 zig_f128;
2099#ifdef zig_bitSizeOf_c_longdouble2105#ifdef zig_bitSizeOf_c_longdouble
21002106
2101#ifdef ZIG_TARGET_ABI_MSVC2107#ifdef ZIG_TARGET_ABI_MSVC
2102typedef double zig_c_longdouble;
2103#undef zig_bitSizeOf_c_longdouble2108#undef zig_bitSizeOf_c_longdouble
2104#define zig_bitSizeOf_c_longdouble 642109#define zig_bitSizeOf_c_longdouble 64
2110typedef uint64_t zig_repr_c_longdouble;
2111typedef zig_f64 zig_c_longdouble;
2105#define zig_make_c_longdouble(fp, repr) fp2112#define zig_make_c_longdouble(fp, repr) fp
2106#else2113#else
2107typedef long double zig_c_longdouble;2114typedef long double zig_c_longdouble;
...@@ -2113,6 +2120,7 @@ typedef long double zig_c_longdouble;...@@ -2113,6 +2120,7 @@ typedef long double zig_c_longdouble;
2113#undef zig_has_c_longdouble2120#undef zig_has_c_longdouble
2114#define zig_has_c_longdouble 02121#define zig_has_c_longdouble 0
2115#define zig_bitSizeOf_c_longdouble 802122#define zig_bitSizeOf_c_longdouble 80
2123typedef zig_u128 zig_repr_c_longdouble;
2116#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f802124#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f80
2117#define zig_bitSizeOf_repr_c_longdouble 1282125#define zig_bitSizeOf_repr_c_longdouble 128
2118typedef zig_i128 zig_c_longdouble;2126typedef zig_i128 zig_c_longdouble;
...@@ -2126,21 +2134,18 @@ typedef zig_i128 zig_c_longdouble;...@@ -2126,21 +2134,18 @@ typedef zig_i128 zig_c_longdouble;
21262134
2127#if !zig_has_float_builtins2135#if !zig_has_float_builtins
2128#define zig_float_from_repr(Type, ReprType) \2136#define zig_float_from_repr(Type, ReprType) \
2129 static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \2137 static inline zig_##Type zig_float_from_repr_##Type(ReprType repr) { \
2130 return *((zig_##Type*)&repr); \2138 zig_##Type result; \
2139 memcpy(&result, &repr, sizeof(result)); \
2140 return result; \
2131 }2141 }
21322142
2133zig_float_from_repr(f16, u16)2143zig_float_from_repr(f16, uint16_t)
2134zig_float_from_repr(f32, u32)2144zig_float_from_repr(f32, uint32_t)
2135zig_float_from_repr(f64, u64)2145zig_float_from_repr(f64, uint64_t)
2136zig_float_from_repr(f80, u128)2146zig_float_from_repr(f80, zig_u128)
2137zig_float_from_repr(f128, u128)2147zig_float_from_repr(f128, zig_u128)
2138#if zig_bitSizeOf_c_longdouble == 802148zig_float_from_repr(c_longdouble, zig_repr_c_longdouble)
2139zig_float_from_repr(c_longdouble, u128)
2140#else
2141#define zig_expand_float_from_repr(Type, ReprType) zig_float_from_repr(Type, ReprType)
2142zig_expand_float_from_repr(c_longdouble, zig_expand_concat(u, zig_bitSizeOf_c_longdouble))
2143#endif
2144#endif2149#endif
21452150
2146#define zig_cast_f16 (zig_f16)2151#define zig_cast_f16 (zig_f16)
...@@ -2288,98 +2293,98 @@ zig_float_builtins(c_longdouble)...@@ -2288,98 +2293,98 @@ zig_float_builtins(c_longdouble)
22882293
2289// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x642294// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64
22902295
2291#define zig_msvc_atomics(Type, suffix) \2296#define zig_msvc_atomics(ZigType, Type, suffix) \
2292 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \2297 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
2293 zig_##Type comparand = *expected; \2298 Type comparand = *expected; \
2294 zig_##Type initial = _InterlockedCompareExchange##suffix(obj, desired, comparand); \2299 Type initial = _InterlockedCompareExchange##suffix(obj, desired, comparand); \
2295 bool exchanged = initial == comparand; \2300 bool exchanged = initial == comparand; \
2296 if (!exchanged) { \2301 if (!exchanged) { \
2297 *expected = initial; \2302 *expected = initial; \
2298 } \2303 } \
2299 return exchanged; \2304 return exchanged; \
2300 } \2305 } \
2301 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \2306 static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \
2302 return _InterlockedExchange##suffix(obj, value); \2307 return _InterlockedExchange##suffix(obj, value); \
2303 } \2308 } \
2304 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \2309 static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \
2305 return _InterlockedExchangeAdd##suffix(obj, value); \2310 return _InterlockedExchangeAdd##suffix(obj, value); \
2306 } \2311 } \
2307 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \2312 static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \
2308 bool success = false; \2313 bool success = false; \
2309 zig_##Type new; \2314 Type new; \
2310 zig_##Type prev; \2315 Type prev; \
2311 while (!success) { \2316 while (!success) { \
2312 prev = *obj; \2317 prev = *obj; \
2313 new = prev - value; \2318 new = prev - value; \
2314 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \2319 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
2315 } \2320 } \
2316 return prev; \2321 return prev; \
2317 } \2322 } \
2318 static inline zig_##Type zig_msvc_atomicrmw_or_##Type(zig_##Type volatile* obj, zig_##Type value) { \2323 static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \
2319 return _InterlockedOr##suffix(obj, value); \2324 return _InterlockedOr##suffix(obj, value); \
2320 } \2325 } \
2321 static inline zig_##Type zig_msvc_atomicrmw_xor_##Type(zig_##Type volatile* obj, zig_##Type value) { \2326 static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \
2322 return _InterlockedXor##suffix(obj, value); \2327 return _InterlockedXor##suffix(obj, value); \
2323 } \2328 } \
2324 static inline zig_##Type zig_msvc_atomicrmw_and_##Type(zig_##Type volatile* obj, zig_##Type value) { \2329 static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \
2325 return _InterlockedAnd##suffix(obj, value); \2330 return _InterlockedAnd##suffix(obj, value); \
2326 } \2331 } \
2327 static inline zig_##Type zig_msvc_atomicrmw_nand_##Type(zig_##Type volatile* obj, zig_##Type value) { \2332 static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \
2328 bool success = false; \2333 bool success = false; \
2329 zig_##Type new; \2334 Type new; \
2330 zig_##Type prev; \2335 Type prev; \
2331 while (!success) { \2336 while (!success) { \
2332 prev = *obj; \2337 prev = *obj; \
2333 new = ~(prev & value); \2338 new = ~(prev & value); \
2334 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \2339 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
2335 } \2340 } \
2336 return prev; \2341 return prev; \
2337 } \2342 } \
2338 static inline zig_##Type zig_msvc_atomicrmw_min_##Type(zig_##Type volatile* obj, zig_##Type value) { \2343 static inline Type zig_msvc_atomicrmw_min_##ZigType(Type volatile* obj, Type value) { \
2339 bool success = false; \2344 bool success = false; \
2340 zig_##Type new; \2345 Type new; \
2341 zig_##Type prev; \2346 Type prev; \
2342 while (!success) { \2347 while (!success) { \
2343 prev = *obj; \2348 prev = *obj; \
2344 new = value < prev ? value : prev; \2349 new = value < prev ? value : prev; \
2345 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \2350 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
2346 } \2351 } \
2347 return prev; \2352 return prev; \
2348 } \2353 } \
2349 static inline zig_##Type zig_msvc_atomicrmw_max_##Type(zig_##Type volatile* obj, zig_##Type value) { \2354 static inline Type zig_msvc_atomicrmw_max_##ZigType(Type volatile* obj, Type value) { \
2350 bool success = false; \2355 bool success = false; \
2351 zig_##Type new; \2356 Type new; \
2352 zig_##Type prev; \2357 Type prev; \
2353 while (!success) { \2358 while (!success) { \
2354 prev = *obj; \2359 prev = *obj; \
2355 new = value > prev ? value : prev; \2360 new = value > prev ? value : prev; \
2356 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \2361 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
2357 } \2362 } \
2358 return prev; \2363 return prev; \
2359 } \2364 } \
2360 static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type value) { \2365 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
2361 _InterlockedExchange##suffix(obj, value); \2366 _InterlockedExchange##suffix(obj, value); \
2362 } \2367 } \
2363 static inline zig_##Type zig_msvc_atomic_load_##Type(zig_##Type volatile* obj) { \2368 static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \
2364 return _InterlockedOr##suffix(obj, 0); \2369 return _InterlockedOr##suffix(obj, 0); \
2365 }2370 }
23662371
2367zig_msvc_atomics(u8, 8)2372zig_msvc_atomics( u8, uint8_t, 8)
2368zig_msvc_atomics(i8, 8)2373zig_msvc_atomics( i8, int8_t, 8)
2369zig_msvc_atomics(u16, 16)2374zig_msvc_atomics(u16, uint16_t, 16)
2370zig_msvc_atomics(i16, 16)2375zig_msvc_atomics(i16, int16_t, 16)
2371zig_msvc_atomics(u32, )2376zig_msvc_atomics(u32, uint32_t, )
2372zig_msvc_atomics(i32, )2377zig_msvc_atomics(i32, int32_t, )
23732378
2374#if _M_X642379#if _M_X64
2375zig_msvc_atomics(u64, 64)2380zig_msvc_atomics(u64, uint64_t, 64)
2376zig_msvc_atomics(i64, 64)2381zig_msvc_atomics(i64, int64_t, 64)
2377#endif2382#endif
23782383
2379#define zig_msvc_flt_atomics(Type, ReprType, suffix) \2384#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
2380 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \2385 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
2381 zig_##ReprType comparand = *((zig_##ReprType*)expected); \2386 ReprType comparand = *((ReprType*)expected); \
2382 zig_##ReprType initial = _InterlockedCompareExchange##suffix((zig_##ReprType volatile*)obj, *((zig_##ReprType*)&desired), comparand); \2387 ReprType initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, *((ReprType*)&desired), comparand); \
2383 bool exchanged = initial == comparand; \2388 bool exchanged = initial == comparand; \
2384 if (!exchanged) { \2389 if (!exchanged) { \
2385 *expected = *((zig_##Type*)&initial); \2390 *expected = *((zig_##Type*)&initial); \
...@@ -2387,35 +2392,35 @@ zig_msvc_atomics(i64, 64)...@@ -2387,35 +2392,35 @@ zig_msvc_atomics(i64, 64)
2387 return exchanged; \2392 return exchanged; \
2388 } \2393 } \
2389 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \2394 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2390 zig_##ReprType initial = _InterlockedExchange##suffix((zig_##ReprType volatile*)obj, *((zig_##ReprType*)&value)); \2395 ReprType initial = _InterlockedExchange##suffix((ReprType volatile*)obj, *((ReprType*)&value)); \
2391 return *((zig_##Type*)&initial); \2396 return *((zig_##Type*)&initial); \
2392 } \2397 } \
2393 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \2398 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2394 bool success = false; \2399 bool success = false; \
2395 zig_##ReprType new; \2400 ReprType new; \
2396 zig_##Type prev; \2401 zig_##Type prev; \
2397 while (!success) { \2402 while (!success) { \
2398 prev = *obj; \2403 prev = *obj; \
2399 new = prev + value; \2404 new = prev + value; \
2400 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((zig_##ReprType*)&new)); \2405 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((ReprType*)&new)); \
2401 } \2406 } \
2402 return prev; \2407 return prev; \
2403 } \2408 } \
2404 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \2409 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2405 bool success = false; \2410 bool success = false; \
2406 zig_##ReprType new; \2411 ReprType new; \
2407 zig_##Type prev; \2412 zig_##Type prev; \
2408 while (!success) { \2413 while (!success) { \
2409 prev = *obj; \2414 prev = *obj; \
2410 new = prev - value; \2415 new = prev - value; \
2411 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((zig_##ReprType*)&new)); \2416 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((ReprType*)&new)); \
2412 } \2417 } \
2413 return prev; \2418 return prev; \
2414 }2419 }
24152420
2416zig_msvc_flt_atomics(f32, u32, )2421zig_msvc_flt_atomics(f32, uint32_t, )
2417#if _M_X642422#if _M_X64
2418zig_msvc_flt_atomics(f64, u64, 64)2423zig_msvc_flt_atomics(f64, uint64_t, 64)
2419#endif2424#endif
24202425
2421#if _M_IX862426#if _M_IX86
...@@ -2426,11 +2431,11 @@ static inline void zig_msvc_atomic_barrier() {...@@ -2426,11 +2431,11 @@ static inline void zig_msvc_atomic_barrier() {
2426 }2431 }
2427}2432}
24282433
2429static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, uint32_t* arg) {2434static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, void* arg) {
2430 return _InterlockedExchangePointer(obj, arg);2435 return _InterlockedExchangePointer(obj, arg);
2431}2436}
24322437
2433static inline void zig_msvc_atomic_store_p32(void** obj, uint32_t* arg) {2438static inline void zig_msvc_atomic_store_p32(void** obj, void* arg) {
2434 _InterlockedExchangePointer(obj, arg);2439 _InterlockedExchangePointer(obj, arg);
2435}2440}
24362441
...@@ -2448,11 +2453,11 @@ static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desir...@@ -2448,11 +2453,11 @@ static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desir
2448 return exchanged;2453 return exchanged;
2449}2454}
2450#else /* _M_IX86 */2455#else /* _M_IX86 */
2451static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, uint64_t* arg) {2456static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, void* arg) {
2452 return _InterlockedExchangePointer(obj, arg);2457 return _InterlockedExchangePointer(obj, arg);
2453}2458}
24542459
2455static inline void zig_msvc_atomic_store_p64(void** obj, uint64_t* arg) {2460static inline void zig_msvc_atomic_store_p64(void** obj, void* arg) {
2456 _InterlockedExchangePointer(obj, arg);2461 _InterlockedExchangePointer(obj, arg);
2457}2462}
24582463
src/codegen/c.zig+41-37
...@@ -2058,6 +2058,7 @@ fn renderTypePrefix(...@@ -2058,6 +2058,7 @@ fn renderTypePrefix(
2058 .zig_f64,2058 .zig_f64,
2059 .zig_f80,2059 .zig_f80,
2060 .zig_f128,2060 .zig_f128,
2061 .zig_c_longdouble,
2061 => |tag| try w.writeAll(@tagName(tag)),2062 => |tag| try w.writeAll(@tagName(tag)),
20622063
2063 .pointer,2064 .pointer,
...@@ -2225,6 +2226,7 @@ fn renderTypeSuffix(...@@ -2225,6 +2226,7 @@ fn renderTypeSuffix(
2225 .zig_f64,2226 .zig_f64,
2226 .zig_f80,2227 .zig_f80,
2227 .zig_f128,2228 .zig_f128,
2229 .zig_c_longdouble,
2228 => {},2230 => {},
22292231
2230 .pointer,2232 .pointer,
...@@ -3062,6 +3064,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3062,6 +3064,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3062 return CValue.none;3064 return CValue.none;
3063 }3065 }
30643066
3067 const inst_ty = f.air.typeOfIndex(inst);
3065 const ptr_ty = f.air.typeOf(bin_op.lhs);3068 const ptr_ty = f.air.typeOf(bin_op.lhs);
3066 const child_ty = ptr_ty.childType();3069 const child_ty = ptr_ty.childType();
30673070
...@@ -3076,7 +3079,9 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3076,7 +3079,9 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3076 const writer = f.object.writer();3079 const writer = f.object.writer();
3077 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));3080 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
3078 try f.writeCValue(writer, local, .Other);3081 try f.writeCValue(writer, local, .Other);
3079 try writer.writeAll(" = &(");3082 try writer.writeAll(" = (");
3083 try f.renderTypecast(writer, inst_ty);
3084 try writer.writeAll(")&(");
3080 if (ptr_ty.ptrSize() == .One) {3085 if (ptr_ty.ptrSize() == .One) {
3081 // It's a pointer to an array, so we need to de-reference.3086 // It's a pointer to an array, so we need to de-reference.
3082 try f.writeCValueDeref(writer, ptr);3087 try f.writeCValueDeref(writer, ptr);
...@@ -3902,32 +3907,31 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -3902,32 +3907,31 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3902 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3907 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
39033908
3904 const inst_ty = f.air.typeOfIndex(inst);3909 const inst_ty = f.air.typeOfIndex(inst);
3905 const elem_ty = switch (inst_ty.ptrSize()) {3910 const elem_ty = inst_ty.elemType2();
3906 .One => blk: {
3907 const array_ty = inst_ty.childType();
3908 break :blk array_ty.childType();
3909 },
3910 else => inst_ty.childType(),
3911 };
39123911
3913 // We must convert to and from integer types to prevent UB if the operation
3914 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
3915 // if the result is NULL and then dereferenced.
3916 const local = try f.allocLocal(inst, inst_ty);3912 const local = try f.allocLocal(inst, inst_ty);
3917 const writer = f.object.writer();3913 const writer = f.object.writer();
3918 try f.writeCValue(writer, local, .Other);3914 try f.writeCValue(writer, local, .Other);
3919 try writer.writeAll(" = (");3915 try writer.writeAll(" = ");
3920 try f.renderTypecast(writer, inst_ty);3916
3921 try writer.writeAll(")(((uintptr_t)");3917 if (elem_ty.hasRuntimeBitsIgnoreComptime()) {
3922 try f.writeCValue(writer, lhs, .Other);3918 // We must convert to and from integer types to prevent UB if the operation
3923 try writer.writeAll(") ");3919 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
3924 try writer.writeByte(operator);3920 // if the result is NULL and then dereferenced.
3925 try writer.writeAll(" (");3921 try writer.writeByte('(');
3926 try f.writeCValue(writer, rhs, .Other);3922 try f.renderTypecast(writer, inst_ty);
3927 try writer.writeAll("*sizeof(");3923 try writer.writeAll(")(((uintptr_t)");
3928 try f.renderTypecast(writer, elem_ty);3924 try f.writeCValue(writer, lhs, .Other);
3929 try writer.writeAll(")));\n");3925 try writer.writeAll(") ");
3926 try writer.writeByte(operator);
3927 try writer.writeAll(" (");
3928 try f.writeCValue(writer, rhs, .Other);
3929 try writer.writeAll("*sizeof(");
3930 try f.renderTypecast(writer, elem_ty);
3931 try writer.writeAll(")))");
3932 } else try f.writeCValue(writer, lhs, .Initializer);
39303933
3934 try writer.writeAll(";\n");
3931 return local;3935 return local;
3932}3936}
39333937
...@@ -5264,21 +5268,21 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -5264,21 +5268,21 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
5264 else => unreachable,5268 else => unreachable,
5265 };5269 };
52665270
5267 try writer.writeByte('&');5271 if (struct_ty.hasRuntimeBitsIgnoreComptime()) {
5268 switch (field_loc) {5272 try writer.writeByte('&');
5269 .begin, .end => {5273 switch (field_loc) {
5270 try writer.writeByte('(');5274 .begin, .end => {
5271 try f.writeCValue(writer, struct_ptr, .Other);5275 try writer.writeByte('(');
5272 try writer.print(")[{}]", .{5276 try f.writeCValue(writer, struct_ptr, .Other);
5273 @boolToInt(field_loc == .end and struct_ty.hasRuntimeBitsIgnoreComptime()),5277 try writer.print(")[{}]", .{@boolToInt(field_loc == .end)});
5274 });5278 },
5275 },5279 .field => |field| if (extra_name != .none) {
5276 .field => |field| if (extra_name != .none) {5280 try f.writeCValueDerefMember(writer, struct_ptr, extra_name);
5277 try f.writeCValueDerefMember(writer, struct_ptr, extra_name);5281 try writer.writeByte('.');
5278 try writer.writeByte('.');5282 try f.writeCValue(writer, field, .Other);
5279 try f.writeCValue(writer, field, .Other);5283 } else try f.writeCValueDerefMember(writer, struct_ptr, field),
5280 } else try f.writeCValueDerefMember(writer, struct_ptr, field),5284 }
5281 }5285 } else try f.writeCValue(writer, struct_ptr, .Other);
5282 try writer.writeAll(";\n");5286 try writer.writeAll(";\n");
5283 return local;5287 return local;
5284}5288}
src/codegen/c/type.zig+7-2
...@@ -102,6 +102,7 @@ pub const CType = extern union {...@@ -102,6 +102,7 @@ pub const CType = extern union {
102 zig_f64,102 zig_f64,
103 zig_f80,103 zig_f80,
104 zig_f128,104 zig_f128,
105 zig_c_longdouble, // Keep last_no_payload_tag updated!
105106
106 // After this, the tag requires a payload.107 // After this, the tag requires a payload.
107 pointer,108 pointer,
...@@ -127,7 +128,7 @@ pub const CType = extern union {...@@ -127,7 +128,7 @@ pub const CType = extern union {
127 function,128 function,
128 varargs_function,129 varargs_function,
129130
130 pub const last_no_payload_tag = Tag.zig_f128;131 pub const last_no_payload_tag = Tag.zig_c_longdouble;
131 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;132 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
132133
133 pub fn hasPayload(self: Tag) bool {134 pub fn hasPayload(self: Tag) bool {
...@@ -177,6 +178,7 @@ pub const CType = extern union {...@@ -177,6 +178,7 @@ pub const CType = extern union {
177 .zig_f64,178 .zig_f64,
178 .zig_f80,179 .zig_f80,
179 .zig_f128,180 .zig_f128,
181 .zig_c_longdouble,
180 => @compileError("Type Tag " ++ @tagName(self) ++ " has no payload"),182 => @compileError("Type Tag " ++ @tagName(self) ++ " has no payload"),
181183
182 .pointer,184 .pointer,
...@@ -557,6 +559,7 @@ pub const CType = extern union {...@@ -557,6 +559,7 @@ pub const CType = extern union {
557 .zig_f64,559 .zig_f64,
558 .zig_f80,560 .zig_f80,
559 .zig_f128,561 .zig_f128,
562 .zig_c_longdouble,
560 => false,563 => false,
561564
562 .pointer,565 .pointer,
...@@ -674,6 +677,7 @@ pub const CType = extern union {...@@ -674,6 +677,7 @@ pub const CType = extern union {
674 .zig_f64,677 .zig_f64,
675 .zig_f80,678 .zig_f80,
676 .zig_f128,679 .zig_f128,
680 .zig_c_longdouble,
677 => {},681 => {},
678682
679 .pointer,683 .pointer,
...@@ -980,7 +984,7 @@ pub const CType = extern union {...@@ -980,7 +984,7 @@ pub const CType = extern union {
980 .f64 => .zig_f64,984 .f64 => .zig_f64,
981 .f80 => .zig_f80,985 .f80 => .zig_f80,
982 .f128 => .zig_f128,986 .f128 => .zig_f128,
983 .c_longdouble => .@"long double",987 .c_longdouble => .zig_c_longdouble,
984 else => unreachable,988 else => unreachable,
985 }),989 }),
986990
...@@ -1374,6 +1378,7 @@ pub const CType = extern union {...@@ -1374,6 +1378,7 @@ pub const CType = extern union {
1374 .zig_f64,1378 .zig_f64,
1375 .zig_f80,1379 .zig_f80,
1376 .zig_f128,1380 .zig_f128,
1381 .zig_c_longdouble,
1377 => return self,1382 => return self,
13781383
1379 .pointer,1384 .pointer,
test/behavior/asm.zig+13
...@@ -7,6 +7,7 @@ const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux...@@ -7,6 +7,7 @@ const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux
7comptime {7comptime {
8 if (builtin.zig_backend != .stage2_arm and8 if (builtin.zig_backend != .stage2_arm and
9 builtin.zig_backend != .stage2_aarch64 and9 builtin.zig_backend != .stage2_aarch64 and
10 !(builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) and // MSVC doesn't support inline assembly
10 is_x86_64_linux)11 is_x86_64_linux)
11 {12 {
12 asm (13 asm (
...@@ -24,6 +25,8 @@ test "module level assembly" {...@@ -24,6 +25,8 @@ test "module level assembly" {
24 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO26 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2627
28 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
29
27 if (is_x86_64_linux) {30 if (is_x86_64_linux) {
28 try expect(this_is_my_alias() == 1234);31 try expect(this_is_my_alias() == 1234);
29 }32 }
...@@ -36,6 +39,8 @@ test "output constraint modifiers" {...@@ -36,6 +39,8 @@ test "output constraint modifiers" {
36 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO39 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO40 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3841
42 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
43
39 // This is only testing compilation.44 // This is only testing compilation.
40 var a: u32 = 3;45 var a: u32 = 3;
41 asm volatile (""46 asm volatile (""
...@@ -57,6 +62,8 @@ test "alternative constraints" {...@@ -57,6 +62,8 @@ test "alternative constraints" {
57 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO62 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO63 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5964
65 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
66
60 // Make sure we allow commas as a separator for alternative constraints.67 // Make sure we allow commas as a separator for alternative constraints.
61 var a: u32 = 3;68 var a: u32 = 3;
62 asm volatile (""69 asm volatile (""
...@@ -73,6 +80,8 @@ test "sized integer/float in asm input" {...@@ -73,6 +80,8 @@ test "sized integer/float in asm input" {
73 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO80 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
74 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO81 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7582
83 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
84
76 asm volatile (""85 asm volatile (""
77 :86 :
78 : [_] "m" (@as(usize, 3)),87 : [_] "m" (@as(usize, 3)),
...@@ -122,6 +131,8 @@ test "struct/array/union types as input values" {...@@ -122,6 +131,8 @@ test "struct/array/union types as input values" {
122 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO131 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO132 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
124133
134 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
135
125 asm volatile (""136 asm volatile (""
126 :137 :
127 : [_] "m" (@as([1]u32, undefined)),138 : [_] "m" (@as([1]u32, undefined)),
...@@ -146,6 +157,8 @@ test "asm modifiers (AArch64)" {...@@ -146,6 +157,8 @@ test "asm modifiers (AArch64)" {
146 if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest;157 if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO158 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
148159
160 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
161
149 var x: u32 = 15;162 var x: u32 = 15;
150 const double = asm ("add %[ret:w], %[in:w], %[in:w]"163 const double = asm ("add %[ret:w], %[in:w], %[in:w]"
151 : [ret] "=r" (-> u32),164 : [ret] "=r" (-> u32),