authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-29 23:06:59-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-10-29 23:06:59-04:00
log5f5a20ebaf646fe629da370ec56ad86dd2761290
tree07153eefc0a6441ae3306202590ff93d21d475a6
parent09a96cdfce0540e4c02dd3b0917de6b59edbc95c
parent4364f5147697f3c6a9147efd74eec82586cf568c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13093 from jacobly0/backend-fixes

C backend fixes

99 files changed, 4277 insertions(+), 3390 deletions(-)

lib/include/zig.h+1219-1319
...@@ -1,97 +1,109 @@...@@ -1,97 +1,109 @@
1#undef linux1#undef linux
22
3#define __STDC_WANT_IEC_60559_TYPES_EXT__
4#include <float.h>
5#include <limits.h>
6#include <stddef.h>
7#include <stdint.h>
8
9#if defined(__has_builtin)
10#define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin)
11#else
12#define zig_has_builtin(builtin) 0
13#endif
14
15#if defined(__has_attribute)
16#define zig_has_attribute(attribute) __has_attribute(attribute)
17#else
18#define zig_has_attribute(attribute) 0
19#endif
20
3#if __STDC_VERSION__ >= 201112L21#if __STDC_VERSION__ >= 201112L
4#define zig_noreturn _Noreturn
5#define zig_threadlocal thread_local22#define zig_threadlocal thread_local
6#elif __GNUC__23#elif __GNUC__
7#define zig_noreturn __attribute__ ((noreturn))
8#define zig_threadlocal __thread24#define zig_threadlocal __thread
9#elif _MSC_VER25#elif _MSC_VER
10#define zig_noreturn __declspec(noreturn)
11#define zig_threadlocal __declspec(thread)26#define zig_threadlocal __declspec(thread)
12#else27#else
13#define zig_noreturn
14#define zig_threadlocal zig_threadlocal_unavailable28#define zig_threadlocal zig_threadlocal_unavailable
15#endif29#endif
1630
17#if __GNUC__31#if zig_has_attribute(naked)
18#define ZIG_COLD __attribute__ ((cold))32#define zig_naked __attribute__((naked))
33#elif defined(_MSC_VER)
34#define zig_naked __declspec(naked)
19#else35#else
20#define ZIG_COLD36#define zig_naked zig_naked_unavailable
21#endif37#endif
2238
23#if __STDC_VERSION__ >= 199901L39#if zig_has_attribute(cold)
24#define ZIG_RESTRICT restrict40#define zig_cold __attribute__((cold))
25#elif defined(__GNUC__)
26#define ZIG_RESTRICT __restrict
27#else41#else
28#define ZIG_RESTRICT42#define zig_cold
29#endif43#endif
3044
31#if __STDC_VERSION__ >= 201112L45#if __STDC_VERSION__ >= 199901L
32#include <stdalign.h>46#define zig_restrict restrict
33#define ZIG_ALIGN(alignment) alignas(alignment)
34#elif defined(__GNUC__)47#elif defined(__GNUC__)
35#define ZIG_ALIGN(alignment) __attribute__((aligned(alignment)))48#define zig_restrict __restrict
36#else49#else
37#define ZIG_ALIGN(alignment) zig_compile_error("the C compiler being used does not support aligning variables")50#define zig_restrict
38#endif51#endif
3952
40#if __STDC_VERSION__ >= 199901L53#if __STDC_VERSION__ >= 201112L
41#include <stdbool.h>54#define zig_align(alignment) _Alignas(alignment)
55#elif zig_has_attribute(aligned)
56#define zig_align(alignment) __attribute__((aligned(alignment)))
57#elif _MSC_VER
42#else58#else
43#define bool unsigned char59#error the C compiler being used does not support aligning variables
44#define true 1
45#define false 0
46#endif60#endif
4761
48#if defined(__GNUC__)62#if zig_has_builtin(unreachable)
49#define zig_unreachable() __builtin_unreachable()63#define zig_unreachable() __builtin_unreachable()
50#else64#else
51#define zig_unreachable()65#define zig_unreachable()
52#endif66#endif
5367
54#ifdef __cplusplus68#if defined(__cplusplus)
55#define ZIG_EXTERN_C extern "C"69#define zig_extern_c extern "C"
56#else70#else
57#define ZIG_EXTERN_C71#define zig_extern_c
58#endif72#endif
5973
60#if defined(_MSC_VER)74#if zig_has_builtin(debugtrap)
61#define zig_breakpoint() __debugbreak()
62#elif defined(__MINGW32__) || defined(__MINGW64__)
63#define zig_breakpoint() __debugbreak()
64#elif defined(__clang__)
65#define zig_breakpoint() __builtin_debugtrap()75#define zig_breakpoint() __builtin_debugtrap()
66#elif defined(__GNUC__)76#elif zig_has_builtin(trap)
67#define zig_breakpoint() __builtin_trap()77#define zig_breakpoint() __builtin_trap()
78#elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
79#define zig_breakpoint() __debugbreak()
68#elif defined(__i386__) || defined(__x86_64__)80#elif defined(__i386__) || defined(__x86_64__)
69#define zig_breakpoint() __asm__ volatile("int $0x03");81#define zig_breakpoint() __asm__ volatile("int $0x03");
70#else82#else
71#define zig_breakpoint() raise(SIGTRAP)83#define zig_breakpoint() raise(SIGTRAP)
72#endif84#endif
7385
74#if defined(_MSC_VER)86#if zig_has_builtin(return_address)
75#define zig_return_address() _ReturnAddress()
76#elif defined(__GNUC__)
77#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))87#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
88#elif defined(_MSC_VER)
89#define zig_return_address() _ReturnAddress()
78#else90#else
79#define zig_return_address() 091#define zig_return_address() 0
80#endif92#endif
8193
82#if defined(__GNUC__)94#if zig_has_builtin(frame_address)
83#define zig_frame_address() __builtin_frame_address(0)95#define zig_frame_address() __builtin_frame_address(0)
84#else96#else
85#define zig_frame_address() 097#define zig_frame_address() 0
86#endif98#endif
8799
88#if defined(__GNUC__)100#if zig_has_builtin(prefetch)
89#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)101#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
90#else102#else
91#define zig_prefetch(addr, rw, locality)103#define zig_prefetch(addr, rw, locality)
92#endif104#endif
93105
94#if defined(__clang__)106#if zig_has_builtin(memory_size) && zig_has_builtin(memory_grow)
95#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index)107#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index)
96#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta)108#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta)
97#else109#else
...@@ -101,19 +113,20 @@...@@ -101,19 +113,20 @@
101113
102#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)114#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
103#include <stdatomic.h>115#include <stdatomic.h>
116#define zig_atomic(type) _Atomic(type)
104#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)117#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
105#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)118#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
106#define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order)119#define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order)
107#define zig_atomicrmw_add (obj, arg, order) atomic_fetch_add_explicit (obj, arg, order)120#define zig_atomicrmw_add(obj, arg, order) atomic_fetch_add_explicit (obj, arg, order)
108#define zig_atomicrmw_sub (obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order)121#define zig_atomicrmw_sub(obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order)
109#define zig_atomicrmw_or (obj, arg, order) atomic_fetch_or_explicit (obj, arg, order)122#define zig_atomicrmw_or(obj, arg, order) atomic_fetch_or_explicit (obj, arg, order)
110#define zig_atomicrmw_xor (obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order)123#define zig_atomicrmw_xor(obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order)
111#define zig_atomicrmw_and (obj, arg, order) atomic_fetch_and_explicit (obj, arg, order)124#define zig_atomicrmw_and(obj, arg, order) atomic_fetch_and_explicit (obj, arg, order)
112#define zig_atomicrmw_nand(obj, arg, order) atomic_fetch_nand_explicit(obj, arg, order)125#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand (obj, arg, order)
113#define zig_atomicrmw_min (obj, arg, order) atomic_fetch_min_explicit (obj, arg, order)126#define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order)
114#define zig_atomicrmw_max (obj, arg, order) atomic_fetch_max_explicit (obj, arg, order)127#define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order)
115#define zig_atomic_store (obj, arg, order) atomic_store_explicit (obj, arg, order)128#define zig_atomic_store(obj, arg, order) atomic_store_explicit (obj, arg, order)
116#define zig_atomic_load (obj, order) atomic_load_explicit (obj, order)129#define zig_atomic_load(obj, order) atomic_load_explicit (obj, order)
117#define zig_fence(order) atomic_thread_fence(order)130#define zig_fence(order) atomic_thread_fence(order)
118#elif __GNUC__131#elif __GNUC__
119#define memory_order_relaxed __ATOMIC_RELAXED132#define memory_order_relaxed __ATOMIC_RELAXED
...@@ -122,19 +135,20 @@...@@ -122,19 +135,20 @@
122#define memory_order_release __ATOMIC_RELEASE135#define memory_order_release __ATOMIC_RELEASE
123#define memory_order_acq_rel __ATOMIC_ACQ_REL136#define memory_order_acq_rel __ATOMIC_ACQ_REL
124#define memory_order_seq_cst __ATOMIC_SEQ_CST137#define memory_order_seq_cst __ATOMIC_SEQ_CST
125#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)138#define zig_atomic(type) type
126#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)139#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, zig_false, succ, fail)
140#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, zig_true , succ, fail)
127#define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order)141#define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order)
128#define zig_atomicrmw_add (obj, arg, order) __atomic_fetch_add (obj, arg, order)142#define zig_atomicrmw_add(obj, arg, order) __atomic_fetch_add (obj, arg, order)
129#define zig_atomicrmw_sub (obj, arg, order) __atomic_fetch_sub (obj, arg, order)143#define zig_atomicrmw_sub(obj, arg, order) __atomic_fetch_sub (obj, arg, order)
130#define zig_atomicrmw_or (obj, arg, order) __atomic_fetch_or (obj, arg, order)144#define zig_atomicrmw_or(obj, arg, order) __atomic_fetch_or (obj, arg, order)
131#define zig_atomicrmw_xor (obj, arg, order) __atomic_fetch_xor (obj, arg, order)145#define zig_atomicrmw_xor(obj, arg, order) __atomic_fetch_xor (obj, arg, order)
132#define zig_atomicrmw_and (obj, arg, order) __atomic_fetch_and (obj, arg, order)146#define zig_atomicrmw_and(obj, arg, order) __atomic_fetch_and (obj, arg, order)
133#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order)147#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order)
134#define zig_atomicrmw_min (obj, arg, order) __atomic_fetch_min (obj, arg, order)148#define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order)
135#define zig_atomicrmw_max (obj, arg, order) __atomic_fetch_max (obj, arg, order)149#define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order)
136#define zig_atomic_store (obj, arg, order) __atomic_store (obj, arg, order)150#define zig_atomic_store(obj, arg, order) __atomic_store_n (obj, arg, order)
137#define zig_atomic_load (obj, order) __atomic_load (obj, order)151#define zig_atomic_load(obj, order) __atomic_load_n (obj, order)
138#define zig_fence(order) __atomic_thread_fence(order)152#define zig_fence(order) __atomic_thread_fence(order)
139#else153#else
140#define memory_order_relaxed 0154#define memory_order_relaxed 0
...@@ -143,1457 +157,1343 @@...@@ -143,1457 +157,1343 @@
143#define memory_order_release 3157#define memory_order_release 3
144#define memory_order_acq_rel 4158#define memory_order_acq_rel 4
145#define memory_order_seq_cst 5159#define memory_order_seq_cst 5
160#define zig_atomic(type) type
146#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()161#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()
147#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) zig_unimplemented()162#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) zig_unimplemented()
148#define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented()163#define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented()
149#define zig_atomicrmw_add (obj, arg, order) zig_unimplemented()164#define zig_atomicrmw_add(obj, arg, order) zig_unimplemented()
150#define zig_atomicrmw_sub (obj, arg, order) zig_unimplemented()165#define zig_atomicrmw_sub(obj, arg, order) zig_unimplemented()
151#define zig_atomicrmw_or (obj, arg, order) zig_unimplemented()166#define zig_atomicrmw_or(obj, arg, order) zig_unimplemented()
152#define zig_atomicrmw_xor (obj, arg, order) zig_unimplemented()167#define zig_atomicrmw_xor(obj, arg, order) zig_unimplemented()
153#define zig_atomicrmw_and (obj, arg, order) zig_unimplemented()168#define zig_atomicrmw_and(obj, arg, order) zig_unimplemented()
154#define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented()169#define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented()
155#define zig_atomicrmw_min (obj, arg, order) zig_unimplemented()170#define zig_atomicrmw_min(obj, arg, order) zig_unimplemented()
156#define zig_atomicrmw_max (obj, arg, order) zig_unimplemented()171#define zig_atomicrmw_max(obj, arg, order) zig_unimplemented()
157#define zig_atomic_store (obj, arg, order) zig_unimplemented()172#define zig_atomic_store(obj, arg, order) zig_unimplemented()
158#define zig_atomic_load (obj, order) zig_unimplemented()173#define zig_atomic_load(obj, order) zig_unimplemented()
159#define zig_fence(order) zig_unimplemented()174#define zig_fence(order) zig_unimplemented()
160#endif175#endif
161176
162#include <stdint.h>177#if __STDC_VERSION__ >= 201112L
163#include <stddef.h>178#define zig_noreturn _Noreturn void
164#include <limits.h>179#elif zig_has_attribute(noreturn)
180#define zig_noreturn __attribute__((noreturn)) void
181#elif _MSC_VER
182#define zig_noreturn __declspec(noreturn) void
183#else
184#define zig_noreturn void
185#endif
165186
166#define int128_t __int128187#define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T))
167#define uint128_t unsigned __int128188
168#define UINT128_MAX ((uint128_t)(0xffffffffffffffffull) | 0xffffffffffffffffull)189typedef void zig_void;
169ZIG_EXTERN_C void *memcpy (void *ZIG_RESTRICT, const void *ZIG_RESTRICT, size_t);190
170ZIG_EXTERN_C void *memset (void *, int, size_t);191#if defined(__cplusplus)
171ZIG_EXTERN_C int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow);192typedef bool zig_bool;
172ZIG_EXTERN_C int128_t __addoti4(int128_t lhs, int128_t rhs, int *overflow);193#define zig_false false
173ZIG_EXTERN_C uint64_t __uaddodi4(uint64_t lhs, uint64_t rhs, int *overflow);194#define zig_true true
174ZIG_EXTERN_C uint128_t __uaddoti4(uint128_t lhs, uint128_t rhs, int *overflow);195#else
175ZIG_EXTERN_C int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow);196#if __STDC_VERSION__ >= 199901L
176ZIG_EXTERN_C int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow);197typedef _Bool zig_bool;
177ZIG_EXTERN_C int128_t __suboti4(int128_t lhs, int128_t rhs, int *overflow);198#else
178ZIG_EXTERN_C uint32_t __usubosi4(uint32_t lhs, uint32_t rhs, int *overflow);199typedef char zig_bool;
179ZIG_EXTERN_C uint64_t __usubodi4(uint64_t lhs, uint64_t rhs, int *overflow);200#endif
180ZIG_EXTERN_C uint128_t __usuboti4(uint128_t lhs, uint128_t rhs, int *overflow);201#define zig_false ((zig_bool)0)
181ZIG_EXTERN_C int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);202#define zig_true ((zig_bool)1)
182ZIG_EXTERN_C int128_t __muloti4(int128_t lhs, int128_t rhs, int *overflow);203#endif
183ZIG_EXTERN_C uint64_t __umulodi4(uint64_t lhs, uint64_t rhs, int *overflow);204
184ZIG_EXTERN_C uint128_t __umuloti4(uint128_t lhs, uint128_t rhs, int *overflow);205typedef uintptr_t zig_usize;
185206typedef intptr_t zig_isize;
186207typedef signed short int zig_c_short;
187static inline uint8_t zig_addw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {208typedef unsigned short int zig_c_ushort;
188 uint8_t thresh = max - rhs;209typedef signed int zig_c_int;
189 if (lhs > thresh) {210typedef unsigned int zig_c_uint;
190 return lhs - thresh - 1;211typedef signed long int zig_c_long;
191 } else {212typedef unsigned long int zig_c_ulong;
192 return lhs + rhs;213typedef signed long long int zig_c_longlong;
193 }214typedef unsigned long long int zig_c_ulonglong;
215
216typedef uint8_t zig_u8;
217typedef int8_t zig_i8;
218typedef uint16_t zig_u16;
219typedef int16_t zig_i16;
220typedef uint16_t zig_u16;
221typedef int16_t zig_i16;
222typedef uint32_t zig_u32;
223typedef int32_t zig_i32;
224typedef uint64_t zig_u64;
225typedef int64_t zig_i64;
226
227#define zig_as_u8(val) UINT8_C(val)
228#define zig_as_i8(val) INT8_C(val)
229#define zig_as_u16(val) UINT16_C(val)
230#define zig_as_i16(val) INT16_C(val)
231#define zig_as_u32(val) UINT32_C(val)
232#define zig_as_i32(val) INT32_C(val)
233#define zig_as_u64(val) UINT64_C(val)
234#define zig_as_i64(val) INT64_C(val)
235
236#define zig_minInt_u8 zig_as_u8(0)
237#define zig_maxInt_u8 UINT8_MAX
238#define zig_minInt_i8 INT8_MIN
239#define zig_maxInt_i8 INT8_MAX
240#define zig_minInt_u16 zig_as_u16(0)
241#define zig_maxInt_u16 UINT16_MAX
242#define zig_minInt_i16 INT16_MIN
243#define zig_maxInt_i16 INT16_MAX
244#define zig_minInt_u32 zig_as_u32(0)
245#define zig_maxInt_u32 UINT32_MAX
246#define zig_minInt_i32 INT32_MIN
247#define zig_maxInt_i32 INT32_MAX
248#define zig_minInt_u64 zig_as_u64(0)
249#define zig_maxInt_u64 UINT64_MAX
250#define zig_minInt_i64 INT64_MIN
251#define zig_maxInt_i64 INT64_MAX
252
253#define zig_builtin_f16(name) __##name##h
254#define zig_builtin_constant_f16(name) zig_suffix_f16(__builtin_##name)
255#if FLT_MANT_DIG == 11
256typedef float zig_f16;
257#define zig_suffix_f16(x) x##f
258#elif DBL_MANT_DIG == 11
259typedef double zig_f16;
260#define zig_suffix_f16(x) x
261#elif LDBL_MANT_DIG == 11
262typedef long double zig_f16;
263#define zig_suffix_f16(x) x##l
264#elif FLT16_MANT_DIG == 11
265typedef _Float16 zig_f16;
266#define zig_suffix_f16(x) x##f16
267#elif defined(__SIZEOF_FP16__)
268typedef __fp16 zig_f16;
269#define zig_suffix_f16(x) x##f16
270#endif
271
272#define zig_builtin_f32(name) name##f
273#define zig_builtin_constant_f32(name) zig_suffix_f32(__builtin_##name)
274#if FLT_MANT_DIG == 24
275typedef float zig_f32;
276#define zig_suffix_f32(x) x##f
277#elif DBL_MANT_DIG == 24
278typedef double zig_f32;
279#define zig_suffix_f32(x) x
280#elif LDBL_MANT_DIG == 24
281typedef long double zig_f32;
282#define zig_suffix_f32(x) x##l
283#elif FLT32_MANT_DIG == 24
284typedef _Float32 zig_f32;
285#define zig_suffix_f32(x) x##f32
286#endif
287
288#define zig_builtin_f64(name) name
289#define zig_builtin_constant_f64(name) zig_suffix_f64(__builtin_##name)
290#if FLT_MANT_DIG == 53
291typedef float zig_f64;
292#define zig_suffix_f64(x) x##f
293#elif DBL_MANT_DIG == 53
294typedef double zig_f64;
295#define zig_suffix_f64(x) x
296#elif LDBL_MANT_DIG == 53
297typedef long double zig_f64;
298#define zig_suffix_f64(x) x##l
299#elif FLT64_MANT_DIG == 53
300typedef _Float64 zig_f64;
301#define zig_suffix_f64(x) x##f64
302#elif FLT32X_MANT_DIG == 53
303typedef _Float32x zig_f64;
304#define zig_suffix_f64(x) x##f32x
305#endif
306
307#define zig_builtin_f80(name) __##name##x
308#define zig_builtin_constant_f80(name) zig_suffix_f80(__builtin_##name)
309#if FLT_MANT_DIG == 64
310typedef float zig_f80;
311#define zig_suffix_f80(x) x##f
312#elif DBL_MANT_DIG == 64
313typedef double zig_f80;
314#define zig_suffix_f80(x) x
315#elif LDBL_MANT_DIG == 64
316typedef long double zig_f80;
317#define zig_suffix_f80(x) x##l
318#elif FLT80_MANT_DIG == 64
319typedef _Float80 zig_f80;
320#define zig_suffix_f80(x) x##f80
321#elif FLT64X_MANT_DIG == 64
322typedef _Float64x zig_f80;
323#define zig_suffix_f80(x) x##f64x
324#elif defined(__SIZEOF_FLOAT80__)
325typedef __float80 zig_f80;
326#define zig_suffix_f80(x) x##l
327#endif
328
329#define zig_builtin_f128(name) name##q
330#define zig_builtin_constant_f128(name) zig_suffix_f80(__builtin_##name)
331#if FLT_MANT_DIG == 113
332typedef float zig_f128;
333#define zig_suffix_f128(x) x##f
334#elif DBL_MANT_DIG == 113
335typedef double zig_f128;
336#define zig_suffix_f128(x) x
337#elif LDBL_MANT_DIG == 113
338typedef long double zig_f128;
339#define zig_suffix_f128(x) x##l
340#elif FLT128_MANT_DIG == 113
341typedef _Float128 zig_f128;
342#define zig_suffix_f128(x) x##f128
343#elif FLT64X_MANT_DIG == 113
344typedef _Float64x zig_f128;
345#define zig_suffix_f128(x) x##f64x
346#elif defined(__SIZEOF_FLOAT128__)
347typedef __float128 zig_f128;
348#define zig_suffix_f128(x) x##q
349#undef zig_builtin_constant_f128
350#define zig_builtin_constant_f128(name) __builtin_##name##f128
351#endif
352
353typedef long double zig_c_longdouble;
354#define zig_suffix_c_longdouble(x) x##l
355#define zig_builtin_c_longdouble(name) zig_suffix_c_longdouble(name)
356#define zig_builtin_constant_c_longdouble(name) zig_suffix_c_longdouble(__builtin_##name)
357
358zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);
359zig_extern_c void *memset (void *, int, zig_usize);
360
361/* ==================== 8/16/32/64-bit Integer Routines ===================== */
362
363#define zig_maxInt(Type, bits) zig_shr_##Type(zig_maxInt_##Type, (zig_bitSizeOf(zig_##Type) - bits))
364#define zig_minInt(Type, bits) zig_not_##Type(zig_maxInt(Type, bits), bits)
365
366#define zig_int_operator(Type, RhsType, operation, operator) \
367 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \
368 return lhs operator rhs; \
369 }
370#define zig_int_operators(w) \
371 zig_int_operator(u##w, u##w, and, &) \
372 zig_int_operator(i##w, i##w, and, &) \
373 zig_int_operator(u##w, u##w, or, |) \
374 zig_int_operator(i##w, i##w, or, |) \
375 zig_int_operator(u##w, u##w, xor, ^) \
376 zig_int_operator(i##w, i##w, xor, ^) \
377 zig_int_operator(u##w, u8, shl, <<) \
378 zig_int_operator(i##w, u8, shl, <<) \
379 zig_int_operator(u##w, u8, shr, >>) \
380 zig_int_operator(u##w, u##w, div_floor, /) \
381 zig_int_operator(u##w, u##w, mod, %)
382zig_int_operators(8)
383zig_int_operators(16)
384zig_int_operators(32)
385zig_int_operators(64)
386
387#define zig_int_helpers(w) \
388 static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \
389 zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \
390 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
391 } \
392\
393 static inline zig_u##w zig_not_u##w(zig_u##w val, zig_u8 bits) { \
394 return val ^ zig_maxInt(u##w, bits); \
395 } \
396\
397 static inline zig_i##w zig_not_i##w(zig_i##w val, zig_u8 bits) { \
398 (void)bits; \
399 return ~val; \
400 } \
401\
402 static inline zig_u##w zig_wrap_u##w(zig_u##w val, zig_u8 bits) { \
403 return val & zig_maxInt(u##w, bits); \
404 } \
405\
406 static inline zig_i##w zig_wrap_i##w(zig_i##w val, zig_u8 bits) { \
407 return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \
408 ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \
409 } \
410\
411 static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \
412 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \
413 } \
414\
415 static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \
416 zig_i##w rem = lhs % rhs; \
417 return rem + (((lhs ^ rhs) & rem) < zig_as_i##w(0) ? rhs : zig_as_i##w(0)); \
418 }
419zig_int_helpers(8)
420zig_int_helpers(16)
421zig_int_helpers(32)
422zig_int_helpers(64)
423
424static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
425#if zig_has_builtin(add_overflow)
426 zig_u32 full_res;
427 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
428 *res = zig_wrap_u32(full_res, bits);
429 return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits);
430#else
431 *res = zig_addw_u32(lhs, rhs, bits);
432 return *res < lhs;
433#endif
194}434}
195435
196static inline int8_t zig_addw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {436zig_extern_c zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
197 if ((lhs > 0) && (rhs > 0)) {437static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
198 int8_t thresh = max - rhs;438#if zig_has_builtin(add_overflow)
199 if (lhs > thresh) {439 zig_i32 full_res;
200 return min + lhs - thresh - 1;440 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
201 }441#else
202 } else if ((lhs < 0) && (rhs < 0)) {442 zig_c_int overflow_int;
203 int8_t thresh = min - rhs;443 zig_u32 full_res = __addosi4(lhs, rhs, &overflow_int);
204 if (lhs < thresh) {444 zig_bool overflow = overflow_int != 0;
205 return max + lhs - thresh + 1;445#endif
206 }446 *res = zig_wrap_i32(full_res, bits);
207 }447 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
208 return lhs + rhs;
209}448}
210449
211static inline uint16_t zig_addw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {450static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
212 uint16_t thresh = max - rhs;451#if zig_has_builtin(add_overflow)
213 if (lhs > thresh) {452 zig_u64 full_res;
214 return lhs - thresh - 1;453 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
215 } else {454 *res = zig_wrap_u64(full_res, bits);
216 return lhs + rhs;455 return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits);
217 }456#else
457 *res = zig_addw_u64(lhs, rhs, bits);
458 return *res < lhs;
459#endif
218}460}
219461
220static inline int16_t zig_addw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {462zig_extern_c zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
221 if ((lhs > 0) && (rhs > 0)) {463static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
222 int16_t thresh = max - rhs;464#if zig_has_builtin(add_overflow)
223 if (lhs > thresh) {465 zig_i64 full_res;
224 return min + lhs - thresh - 1;466 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
225 }467#else
226 } else if ((lhs < 0) && (rhs < 0)) {468 zig_c_int overflow_int;
227 int16_t thresh = min - rhs;469 zig_u64 full_res = __addodi4(lhs, rhs, &overflow_int);
228 if (lhs < thresh) {470 zig_bool overflow = overflow_int != 0;
229 return max + lhs - thresh + 1;471#endif
230 }472 *res = zig_wrap_i64(full_res, bits);
231 }473 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
232 return lhs + rhs;
233}474}
234475
235static inline uint32_t zig_addw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {476static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
236 uint32_t thresh = max - rhs;477#if zig_has_builtin(add_overflow)
237 if (lhs > thresh) {478 zig_u8 full_res;
238 return lhs - thresh - 1;479 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
239 } else {480 *res = zig_wrap_u8(full_res, bits);
240 return lhs + rhs;481 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
241 }482#else
483 return zig_addo_u32(res, lhs, rhs, bits);
484#endif
242}485}
243486
244static inline int32_t zig_addw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {487static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
245 if ((lhs > 0) && (rhs > 0)) {488#if zig_has_builtin(add_overflow)
246 int32_t thresh = max - rhs;489 zig_i8 full_res;
247 if (lhs > thresh) {490 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
248 return min + lhs - thresh - 1;491 *res = zig_wrap_i8(full_res, bits);
249 }492 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
250 } else if ((lhs < 0) && (rhs < 0)) {493#else
251 int32_t thresh = min - rhs;494 return zig_addo_i32(res, lhs, rhs, bits);
252 if (lhs < thresh) {495#endif
253 return max + lhs - thresh + 1;
254 }
255 }
256 return lhs + rhs;
257}496}
258497
259static inline uint64_t zig_addw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {498static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
260 uint64_t thresh = max - rhs;499#if zig_has_builtin(add_overflow)
261 if (lhs > thresh) {500 zig_u16 full_res;
262 return lhs - thresh - 1;501 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
263 } else {502 *res = zig_wrap_u16(full_res, bits);
264 return lhs + rhs;503 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
265 }504#else
505 return zig_addo_u32(res, lhs, rhs, bits);
506#endif
266}507}
267508
268static inline int64_t zig_addw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {509static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
269 if ((lhs > 0) && (rhs > 0)) {510#if zig_has_builtin(add_overflow)
270 int64_t thresh = max - rhs;511 zig_i16 full_res;
271 if (lhs > thresh) {512 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
272 return min + lhs - thresh - 1;513 *res = zig_wrap_i16(full_res, bits);
273 }514 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
274 } else if ((lhs < 0) && (rhs < 0)) {515#else
275 int64_t thresh = min - rhs;516 return zig_addo_i32(res, lhs, rhs, bits);
276 if (lhs < thresh) {517#endif
277 return max + lhs - thresh + 1;
278 }
279 }
280 return lhs + rhs;
281}518}
282519
283static inline intptr_t zig_addw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {520static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
284 return (intptr_t)(((uintptr_t)lhs) + ((uintptr_t)rhs));521#if zig_has_builtin(sub_overflow)
522 zig_u32 full_res;
523 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
524 *res = zig_wrap_u32(full_res, bits);
525 return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits);
526#else
527 *res = zig_subw_u32(lhs, rhs, bits);
528 return *res > lhs;
529#endif
285}530}
286531
287static inline short zig_addw_short(short lhs, short rhs, short min, short max) {532zig_extern_c zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
288 return (short)(((unsigned short)lhs) + ((unsigned short)rhs));533static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
534#if zig_has_builtin(sub_overflow)
535 zig_i32 full_res;
536 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
537#else
538 zig_c_int overflow_int;
539 zig_u32 full_res = __subosi4(lhs, rhs, &overflow_int);
540 zig_bool overflow = overflow_int != 0;
541#endif
542 *res = zig_wrap_i32(full_res, bits);
543 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
289}544}
290545
291static inline int zig_addw_int(int lhs, int rhs, int min, int max) {546static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
292 return (int)(((unsigned)lhs) + ((unsigned)rhs));547#if zig_has_builtin(sub_overflow)
548 zig_u64 full_res;
549 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
550 *res = zig_wrap_u64(full_res, bits);
551 return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits);
552#else
553 *res = zig_subw_u64(lhs, rhs, bits);
554 return *res > lhs;
555#endif
293}556}
294557
295static inline long zig_addw_long(long lhs, long rhs, long min, long max) {558zig_extern_c zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
296 return (long)(((unsigned long)lhs) + ((unsigned long)rhs));559static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
560#if zig_has_builtin(sub_overflow)
561 zig_i64 full_res;
562 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
563#else
564 zig_c_int overflow_int;
565 zig_u64 full_res = __subodi4(lhs, rhs, &overflow_int);
566 zig_bool overflow = overflow_int != 0;
567#endif
568 *res = zig_wrap_i64(full_res, bits);
569 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
297}570}
298571
299static inline long long zig_addw_longlong(long long lhs, long long rhs, long long min, long long max) {572static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
300 return (long long)(((unsigned long long)lhs) + ((unsigned long long)rhs));573#if zig_has_builtin(sub_overflow)
574 zig_u8 full_res;
575 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
576 *res = zig_wrap_u8(full_res, bits);
577 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
578#else
579 return zig_subo_u32(res, lhs, rhs, bits);
580#endif
301}581}
302582
303static inline uint8_t zig_subw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {583static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
304 if (lhs < rhs) {584#if zig_has_builtin(sub_overflow)
305 return max - rhs - lhs + 1;585 zig_i8 full_res;
306 } else {586 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
307 return lhs - rhs;587 *res = zig_wrap_i8(full_res, bits);
308 }588 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
589#else
590 return zig_subo_i32(res, lhs, rhs, bits);
591#endif
309}592}
310593
311static inline int8_t zig_subw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {594static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
312 if ((lhs > 0) && (rhs < 0)) {595#if zig_has_builtin(sub_overflow)
313 int8_t thresh = lhs - max;596 zig_u16 full_res;
314 if (rhs < thresh) {597 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
315 return min + (thresh - rhs - 1);598 *res = zig_wrap_u16(full_res, bits);
316 }599 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
317 } else if ((lhs < 0) && (rhs > 0)) {600#else
318 int8_t thresh = lhs - min;601 return zig_subo_u32(res, lhs, rhs, bits);
319 if (rhs > thresh) {602#endif
320 return max - (rhs - thresh - 1);
321 }
322 }
323 return lhs - rhs;
324}603}
325604
326static inline uint16_t zig_subw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {605static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
327 if (lhs < rhs) {606#if zig_has_builtin(sub_overflow)
328 return max - rhs - lhs + 1;607 zig_i16 full_res;
329 } else {608 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
330 return lhs - rhs;609 *res = zig_wrap_i16(full_res, bits);
331 }610 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
611#else
612 return zig_subo_i32(res, lhs, rhs, bits);
613#endif
332}614}
333615
334static inline int16_t zig_subw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {616static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
335 if ((lhs > 0) && (rhs < 0)) {617#if zig_has_builtin(mul_overflow)
336 int16_t thresh = lhs - max;618 zig_u32 full_res;
337 if (rhs < thresh) {619 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
338 return min + (thresh - rhs - 1);620 *res = zig_wrap_u32(full_res, bits);
339 }621 return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits);
340 } else if ((lhs < 0) && (rhs > 0)) {622#else
341 int16_t thresh = lhs - min;623 *res = zig_mulw_u32(lhs, rhs, bits);
342 if (rhs > thresh) {624 return rhs != zig_as_u32(0) && lhs > zig_maxInt(u32, bits) / rhs;
343 return max - (rhs - thresh - 1);625#endif
344 }
345 }
346 return lhs - rhs;
347}626}
348627
349static inline uint32_t zig_subw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {628zig_extern_c zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
350 if (lhs < rhs) {629static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
351 return max - rhs - lhs + 1;630#if zig_has_builtin(mul_overflow)
352 } else {631 zig_i32 full_res;
353 return lhs - rhs;632 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
354 }633#else
634 zig_c_int overflow_int;
635 zig_u32 full_res = __mulosi4(lhs, rhs, &overflow_int);
636 zig_bool overflow = overflow_int != 0;
637#endif
638 *res = zig_wrap_i32(full_res, bits);
639 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
355}640}
356641
357static inline int32_t zig_subw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {642static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
358 if ((lhs > 0) && (rhs < 0)) {643#if zig_has_builtin(mul_overflow)
359 int32_t thresh = lhs - max;644 zig_u64 full_res;
360 if (rhs < thresh) {645 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
361 return min + (thresh - rhs - 1);646 *res = zig_wrap_u64(full_res, bits);
362 }647 return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits);
363 } else if ((lhs < 0) && (rhs > 0)) {648#else
364 int32_t thresh = lhs - min;649 *res = zig_mulw_u64(lhs, rhs, bits);
365 if (rhs > thresh) {650 return rhs != zig_as_u64(0) && lhs > zig_maxInt(u64, bits) / rhs;
366 return max - (rhs - thresh - 1);651#endif
367 }
368 }
369 return lhs - rhs;
370}652}
371653
372static inline uint64_t zig_subw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {654zig_extern_c zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
373 if (lhs < rhs) {655static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
374 return max - rhs - lhs + 1;656#if zig_has_builtin(mul_overflow)
375 } else {657 zig_i64 full_res;
376 return lhs - rhs;658 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
377 }659#else
660 zig_c_int overflow_int;
661 zig_u64 full_res = __mulodi4(lhs, rhs, &overflow_int);
662 zig_bool overflow = overflow_int != 0;
663#endif
664 *res = zig_wrap_i64(full_res, bits);
665 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
378}666}
379667
380static inline int64_t zig_subw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {668static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
381 if ((lhs > 0) && (rhs < 0)) {669#if zig_has_builtin(mul_overflow)
382 int64_t thresh = lhs - max;670 zig_u8 full_res;
383 if (rhs < thresh) {671 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
384 return min + (thresh - rhs - 1);672 *res = zig_wrap_u8(full_res, bits);
385 }673 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
386 } else if ((lhs < 0) && (rhs > 0)) {674#else
387 int64_t thresh = lhs - min;675 return zig_mulo_u32(res, lhs, rhs, bits);
388 if (rhs > thresh) {676#endif
389 return max - (rhs - thresh - 1);
390 }
391 }
392 return lhs - rhs;
393}677}
394678
395static inline intptr_t zig_subw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {679static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
396 return (intptr_t)(((uintptr_t)lhs) - ((uintptr_t)rhs));680#if zig_has_builtin(mul_overflow)
681 zig_i8 full_res;
682 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
683 *res = zig_wrap_i8(full_res, bits);
684 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
685#else
686 return zig_mulo_i32(res, lhs, rhs, bits);
687#endif
397}688}
398689
399static inline short zig_subw_short(short lhs, short rhs, short min, short max) {690static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
400 return (short)(((unsigned short)lhs) - ((unsigned short)rhs));691#if zig_has_builtin(mul_overflow)
692 zig_u16 full_res;
693 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
694 *res = zig_wrap_u16(full_res, bits);
695 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
696#else
697 return zig_mulo_u32(res, lhs, rhs, bits);
698#endif
401}699}
402700
403static inline int zig_subw_int(int lhs, int rhs, int min, int max) {701static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
404 return (int)(((unsigned)lhs) - ((unsigned)rhs));702#if zig_has_builtin(mul_overflow)
703 zig_i16 full_res;
704 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
705 *res = zig_wrap_i16(full_res, bits);
706 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
707#else
708 return zig_mulo_i32(res, lhs, rhs, bits);
709#endif
405}710}
406711
407static inline long zig_subw_long(long lhs, long rhs, long min, long max) {712#define zig_int_builtins(w) \
408 return (long)(((unsigned long)lhs) - ((unsigned long)rhs));713 static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
714 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \
715 } \
716\
717 static inline zig_i##w zig_shlw_i##w(zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \
718 return zig_wrap_i##w((zig_i##w)zig_shl_u##w((zig_u##w)lhs, (zig_u##w)rhs), bits); \
719 } \
720\
721 static inline zig_u##w zig_addw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
722 return zig_wrap_u##w(lhs + rhs, bits); \
723 } \
724\
725 static inline zig_i##w zig_addw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
726 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs + (zig_u##w)rhs), bits); \
727 } \
728\
729 static inline zig_u##w zig_subw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
730 return zig_wrap_u##w(lhs - rhs, bits); \
731 } \
732\
733 static inline zig_i##w zig_subw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
734 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs - (zig_u##w)rhs), bits); \
735 } \
736\
737 static inline zig_u##w zig_mulw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
738 return zig_wrap_u##w(lhs * rhs, bits); \
739 } \
740\
741 static inline zig_i##w zig_mulw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
742 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs * (zig_u##w)rhs), bits); \
743 } \
744\
745 static inline zig_bool zig_shlo_u##w(zig_u##w *res, zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
746 *res = zig_shlw_u##w(lhs, rhs, bits); \
747 return (lhs & zig_maxInt_u##w << (bits - rhs)) != zig_as_u##w(0); \
748 } \
749\
750 static inline zig_bool zig_shlo_i##w(zig_i##w *res, zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \
751 *res = zig_shlw_i##w(lhs, rhs, bits); \
752 zig_i##w mask = (zig_i##w)(zig_maxInt_u##w << (bits - rhs - 1)); \
753 return (lhs & mask) != zig_as_i##w(0) && (lhs & mask) != mask; \
754 } \
755\
756 static inline zig_u##w zig_shls_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
757 zig_u##w res; \
758 if (rhs >= bits) return lhs != zig_as_u##w(0) ? zig_maxInt(u##w, bits) : lhs; \
759 return zig_shlo_u##w(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u##w, bits) : res; \
760 } \
761\
762 static inline zig_i##w zig_shls_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
763 zig_i##w res; \
764 if ((zig_u##w)rhs < (zig_u##w)bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
765 return lhs < zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \
766 } \
767\
768 static inline zig_u##w zig_adds_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
769 zig_u##w res; \
770 return zig_addo_u##w(&res, lhs, rhs, bits) ? zig_maxInt(u##w, bits) : res; \
771 } \
772\
773 static inline zig_i##w zig_adds_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
774 zig_i##w res; \
775 if (!zig_addo_i##w(&res, lhs, rhs, bits)) return res; \
776 return res >= zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \
777 } \
778\
779 static inline zig_u##w zig_subs_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
780 zig_u##w res; \
781 return zig_subo_u##w(&res, lhs, rhs, bits) ? zig_minInt(u##w, bits) : res; \
782 } \
783\
784 static inline zig_i##w zig_subs_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
785 zig_i##w res; \
786 if (!zig_subo_i##w(&res, lhs, rhs, bits)) return res; \
787 return res >= zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \
788 } \
789\
790 static inline zig_u##w zig_muls_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
791 zig_u##w res; \
792 return zig_mulo_u##w(&res, lhs, rhs, bits) ? zig_maxInt(u##w, bits) : res; \
793 } \
794\
795 static inline zig_i##w zig_muls_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
796 zig_i##w res; \
797 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \
798 return (lhs ^ rhs) < zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \
799 }
800zig_int_builtins(8)
801zig_int_builtins(16)
802zig_int_builtins(32)
803zig_int_builtins(64)
804
805#define zig_builtin8(name, val) __builtin_##name(val)
806typedef zig_c_uint zig_Builtin8;
807
808#define zig_builtin16(name, val) __builtin_##name(val)
809typedef zig_c_uint zig_Builtin16;
810
811#if INT_MIN <= INT32_MIN
812#define zig_builtin32(name, val) __builtin_##name(val)
813typedef zig_c_uint zig_Builtin32;
814#elif LONG_MIN <= INT32_MIN
815#define zig_builtin32(name, val) __builtin_##name##l(val)
816typedef zig_c_ulong zig_Builtin32;
817#endif
818
819#if INT_MIN <= INT64_MIN
820#define zig_builtin64(name, val) __builtin_##name(val)
821typedef zig_c_uint zig_Builtin64;
822#elif LONG_MIN <= INT64_MIN
823#define zig_builtin64(name, val) __builtin_##name##l(val)
824typedef zig_c_ulong zig_Builtin64;
825#elif LLONG_MIN <= INT64_MIN
826#define zig_builtin64(name, val) __builtin_##name##ll(val)
827typedef zig_c_ulonglong zig_Builtin64;
828#endif
829
830#if zig_has_builtin(clz)
831#define zig_builtin_clz(w) \
832 static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \
833 if (val == 0) return bits; \
834 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
835 } \
836\
837 static inline zig_u8 zig_clz_i##w(zig_i##w val, zig_u8 bits) { \
838 return zig_clz_u##w((zig_u##w)val, bits); \
839 }
840zig_builtin_clz(8)
841zig_builtin_clz(16)
842zig_builtin_clz(32)
843zig_builtin_clz(64)
844#endif
845
846#if zig_has_builtin(ctz)
847#define zig_builtin_ctz(w) \
848 static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \
849 if (val == 0) return bits; \
850 return zig_builtin##w(ctz, val); \
851 } \
852\
853 static inline zig_u8 zig_ctz_i##w(zig_i##w val, zig_u8 bits) { \
854 return zig_ctz_u##w((zig_u##w)val, bits); \
855 }
856zig_builtin_ctz(8)
857zig_builtin_ctz(16)
858zig_builtin_ctz(32)
859zig_builtin_ctz(64)
860#endif
861
862#if zig_has_builtin(popcount)
863#define zig_builtin_popcount(w) \
864 static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \
865 (void)bits; \
866 return zig_builtin##w(popcount, val); \
867 } \
868\
869 static inline zig_u8 zig_popcount_i##w(zig_i##w val, zig_u8 bits) { \
870 \
871 return zig_popcount_u##w((zig_u##w)val, bits); \
872 }
873zig_builtin_popcount(8)
874zig_builtin_popcount(16)
875zig_builtin_popcount(32)
876zig_builtin_popcount(64)
877#endif
878
879static inline zig_u8 zig_byte_swap_u8(zig_u8 val, zig_u8 bits) {
880 return zig_wrap_u8(val >> (8 - bits), bits);
409}881}
410882
411static inline long long zig_subw_longlong(long long lhs, long long rhs, long long min, long long max) {883static inline zig_i8 zig_byte_swap_i8(zig_i8 val, zig_u8 bits) {
412 return (long long)(((unsigned long long)lhs) - ((unsigned long long)rhs));884 return zig_wrap_i8((zig_i8)zig_byte_swap_u8((zig_u8)val, bits), bits);
413}885}
414886
415static inline bool zig_addo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {887static inline zig_u16 zig_byte_swap_u16(zig_u16 val, zig_u8 bits) {
416#if defined(__GNUC__) && INT8_MAX == INT_MAX888 zig_u16 full_res;
417 if (min == INT8_MIN && max == INT8_MAX) {889#if zig_has_builtin(bswap16)
418 return __builtin_sadd_overflow(lhs, rhs, (int*)res);890 full_res = __builtin_bswap16(val);
419 }891#else
420#elif defined(__GNUC__) && INT8_MAX == LONG_MAX892 full_res = (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 0)) << 8 |
421 if (min == INT8_MIN && max == INT8_MAX) {893 (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 8)) >> 0;
422 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
423 }
424#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
425 if (min == INT8_MIN && max == INT8_MAX) {
426 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
427 }
428#endif894#endif
429 int16_t big_result = (int16_t)lhs + (int16_t)rhs;895 return zig_wrap_u16(full_res >> (16 - bits), bits);
430 if (big_result > max) {
431 *res = big_result - ((int16_t)max - (int16_t)min);
432 return true;
433 }
434 if (big_result < min) {
435 *res = big_result + ((int16_t)max - (int16_t)min);
436 return true;
437 }
438 *res = big_result;
439 return false;
440}896}
441897
442static inline bool zig_addo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {898static inline zig_i16 zig_byte_swap_i16(zig_i16 val, zig_u8 bits) {
443#if defined(__GNUC__) && INT16_MAX == INT_MAX899 return zig_wrap_i16((zig_i16)zig_byte_swap_u16((zig_u16)val, bits), bits);
444 if (min == INT16_MIN && max == INT16_MAX) {
445 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
446 }
447#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
448 if (min == INT16_MIN && max == INT16_MAX) {
449 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
450 }
451#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
452 if (min == INT16_MIN && max == INT16_MAX) {
453 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
454 }
455#endif
456 int32_t big_result = (int32_t)lhs + (int32_t)rhs;
457 if (big_result > max) {
458 *res = big_result - ((int32_t)max - (int32_t)min);
459 return true;
460 }
461 if (big_result < min) {
462 *res = big_result + ((int32_t)max - (int32_t)min);
463 return true;
464 }
465 *res = big_result;
466 return false;
467}900}
468901
469static inline bool zig_addo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {902static inline zig_u32 zig_byte_swap_u32(zig_u32 val, zig_u8 bits) {
470#if defined(__GNUC__) && INT32_MAX == INT_MAX903 zig_u32 full_res;
471 if (min == INT32_MIN && max == INT32_MAX) {904#if zig_has_builtin(bswap32)
472 return __builtin_sadd_overflow(lhs, rhs, (int*)res);905 full_res = __builtin_bswap32(val);
473 }
474#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
475 if (min == INT32_MIN && max == INT32_MAX) {
476 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
477 }
478#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
479 if (min == INT32_MIN && max == INT32_MAX) {
480 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
481 }
482#endif
483 int64_t big_result = (int64_t)lhs + (int64_t)rhs;
484 if (big_result > max) {
485 *res = big_result - ((int64_t)max - (int64_t)min);
486 return true;
487 }
488 if (big_result < min) {
489 *res = big_result + ((int64_t)max - (int64_t)min);
490 return true;
491 }
492 *res = big_result;
493 return false;
494}
495
496static inline bool zig_addo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
497 bool overflow;
498#if defined(__GNUC__) && INT64_MAX == INT_MAX
499 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
500#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
501 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
502#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
503 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
504#else906#else
505 int int_overflow;907 full_res = (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 0)) << 16 |
506 *res = __addodi4(lhs, rhs, &int_overflow);908 (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 16)) >> 0;
507 overflow = int_overflow != 0;909#endif
508#endif910 return zig_wrap_u32(full_res >> (32 - bits), bits);
509 if (!overflow) {
510 if (*res > max) {
511 // TODO adjust the result to be the truncated bits
512 return true;
513 } else if (*res < min) {
514 // TODO adjust the result to be the truncated bits
515 return true;
516 }
517 }
518 return overflow;
519}911}
520912
521static inline bool zig_addo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {913static inline zig_i32 zig_byte_swap_i32(zig_i32 val, zig_u8 bits) {
522 bool overflow;914 return zig_wrap_i32((zig_i32)zig_byte_swap_u32((zig_u32)val, bits), bits);
523#if defined(__GNUC__) && INT128_MAX == INT_MAX
524 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
525#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
526 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
527#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
528 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
529#else
530 int int_overflow;
531 *res = __addoti4(lhs, rhs, &int_overflow);
532 overflow = int_overflow != 0;
533#endif
534 if (!overflow) {
535 if (*res > max) {
536 // TODO adjust the result to be the truncated bits
537 return true;
538 } else if (*res < min) {
539 // TODO adjust the result to be the truncated bits
540 return true;
541 }
542 }
543 return overflow;
544}915}
545916
546static inline bool zig_addo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {917static inline zig_u64 zig_byte_swap_u64(zig_u64 val, zig_u8 bits) {
547#if defined(__GNUC__) && UINT8_MAX == UINT_MAX918 zig_u64 full_res;
548 if (max == UINT8_MAX) {919#if zig_has_builtin(bswap64)
549 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);920 full_res = __builtin_bswap64(val);
550 }921#else
551#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX922 full_res = (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 0)) << 32 |
552 if (max == UINT8_MAX) {923 (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 32)) >> 0;
553 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
554 }
555#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
556 if (max == UINT8_MAX) {
557 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
558 }
559#endif924#endif
560 uint16_t big_result = (uint16_t)lhs + (uint16_t)rhs;925 return zig_wrap_u64(full_res >> (64 - bits), bits);
561 if (big_result > max) {
562 *res = big_result - max - 1;
563 return true;
564 }
565 *res = big_result;
566 return false;
567}926}
568927
569static inline uint16_t zig_addo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {928static inline zig_i64 zig_byte_swap_i64(zig_i64 val, zig_u8 bits) {
570#if defined(__GNUC__) && UINT16_MAX == UINT_MAX929 return zig_wrap_i64((zig_i64)zig_byte_swap_u64((zig_u64)val, bits), bits);
571 if (max == UINT16_MAX) {
572 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
573 }
574#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
575 if (max == UINT16_MAX) {
576 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
577 }
578#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
579 if (max == UINT16_MAX) {
580 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
581 }
582#endif
583 uint32_t big_result = (uint32_t)lhs + (uint32_t)rhs;
584 if (big_result > max) {
585 *res = big_result - max - 1;
586 return true;
587 }
588 *res = big_result;
589 return false;
590}930}
591931
592static inline uint32_t zig_addo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {932static inline zig_u8 zig_bit_reverse_u8(zig_u8 val, zig_u8 bits) {
593#if defined(__GNUC__) && UINT32_MAX == UINT_MAX933 zig_u8 full_res;
594 if (max == UINT32_MAX) {934#if zig_has_builtin(bitreverse8)
595 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);935 full_res = __builtin_bitreverse8(val);
596 }936#else
597#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX937 static zig_u8 const lut[0x10] = {
598 if (max == UINT32_MAX) {938 0b0000, 0b1000, 0b0100, 0b1100,
599 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);939 0b0010, 0b1010, 0b0110, 0b1110,
600 }940 0b0001, 0b1001, 0b0101, 0b1101,
601#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX941 0b0011, 0b1011, 0b0111, 0b1111,
602 if (max == UINT32_MAX) {942 };
603 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);943 full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0;
604 }
605#endif944#endif
606 uint64_t big_result = (uint64_t)lhs + (uint64_t)rhs;945 return zig_wrap_u8(full_res >> (8 - bits), bits);
607 if (big_result > max) {946}
608 *res = big_result - max - 1;947
609 return true;948static inline zig_i8 zig_bit_reverse_i8(zig_i8 val, zig_u8 bits) {
610 }949 return zig_wrap_i8((zig_i8)zig_bit_reverse_u8((zig_u8)val, bits), bits);
611 *res = big_result;950}
612 return false;951
613}952static inline zig_u16 zig_bit_reverse_u16(zig_u16 val, zig_u8 bits) {
614953 zig_u16 full_res;
615static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {954#if zig_has_builtin(bitreverse16)
616 bool overflow;955 full_res = __builtin_bitreverse16(val);
617#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
618 overflow = __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
619#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
620 overflow = __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
621#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
622 overflow = __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
623#else956#else
624 int int_overflow;957 full_res = (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 0)) << 8 |
625 *res = __uaddodi4(lhs, rhs, &int_overflow);958 (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 8)) >> 0;
626 overflow = int_overflow != 0;
627#endif959#endif
628 if (*res > max && !overflow) {960 return zig_wrap_u16(full_res >> (16 - bits), bits);
629 *res -= max - 1;
630 return true;
631 }
632 return overflow;
633}961}
634962
635static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {963static inline zig_i16 zig_bit_reverse_i16(zig_i16 val, zig_u8 bits) {
636 int overflow;964 return zig_wrap_i16((zig_i16)zig_bit_reverse_u16((zig_u16)val, bits), bits);
637 *res = __uaddoti4(lhs, rhs, &overflow);
638 if (*res > max && overflow == 0) {
639 *res -= max - 1;
640 return true;
641 }
642 return overflow != 0;
643}965}
644966
645static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {967static inline zig_u32 zig_bit_reverse_u32(zig_u32 val, zig_u8 bits) {
646#if defined(__GNUC__) && INT8_MAX == INT_MAX968 zig_u32 full_res;
647 if (min == INT8_MIN && max == INT8_MAX) {969#if zig_has_builtin(bitreverse32)
648 return __builtin_ssub_overflow(lhs, rhs, (int*)res);970 full_res = __builtin_bitreverse32(val);
649 }971#else
650#elif defined(__GNUC__) && INT8_MAX == LONG_MAX972 full_res = (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 0)) << 16 |
651 if (min == INT8_MIN && max == INT8_MAX) {973 (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 16)) >> 0;
652 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
653 }
654#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
655 if (min == INT8_MIN && max == INT8_MAX) {
656 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
657 }
658#endif974#endif
659 int16_t big_result = (int16_t)lhs - (int16_t)rhs;975 return zig_wrap_u32(full_res >> (32 - bits), bits);
660 if (big_result > max) {
661 *res = big_result - ((int16_t)max - (int16_t)min);
662 return true;
663 }
664 if (big_result < min) {
665 *res = big_result + ((int16_t)max - (int16_t)min);
666 return true;
667 }
668 *res = big_result;
669 return false;
670}976}
671977
672static inline bool zig_subo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {978static inline zig_i32 zig_bit_reverse_i32(zig_i32 val, zig_u8 bits) {
673#if defined(__GNUC__) && INT16_MAX == INT_MAX979 return zig_wrap_i32((zig_i32)zig_bit_reverse_u32((zig_u32)val, bits), bits);
674 if (min == INT16_MIN && max == INT16_MAX) {980}
675 return __builtin_ssub_overflow(lhs, rhs, (int*)res);981
676 }982static inline zig_u64 zig_bit_reverse_u64(zig_u64 val, zig_u8 bits) {
677#elif defined(__GNUC__) && INT16_MAX == LONG_MAX983 zig_u64 full_res;
678 if (min == INT16_MIN && max == INT16_MAX) {984#if zig_has_builtin(bitreverse64)
679 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);985 full_res = __builtin_bitreverse64(val);
680 }986#else
681#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX987 full_res = (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 0)) << 32 |
682 if (min == INT16_MIN && max == INT16_MAX) {988 (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 32)) >> 0;
683 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
684 }
685#endif989#endif
686 int32_t big_result = (int32_t)lhs - (int32_t)rhs;990 return zig_wrap_u64(full_res >> (64 - bits), bits);
687 if (big_result > max) {
688 *res = big_result - ((int32_t)max - (int32_t)min);
689 return true;
690 }
691 if (big_result < min) {
692 *res = big_result + ((int32_t)max - (int32_t)min);
693 return true;
694 }
695 *res = big_result;
696 return false;
697}991}
698992
699static inline bool zig_subo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {993static inline zig_i64 zig_bit_reverse_i64(zig_i64 val, zig_u8 bits) {
700#if defined(__GNUC__) && INT32_MAX == INT_MAX994 return zig_wrap_i64((zig_i64)zig_bit_reverse_u64((zig_u64)val, bits), bits);
701 if (min == INT32_MIN && max == INT32_MAX) {995}
702 return __builtin_ssub_overflow(lhs, rhs, (int*)res);996
703 }997/* ======================== 128-bit Integer Routines ======================== */
704#elif defined(__GNUC__) && INT32_MAX == LONG_MAX998
705 if (min == INT32_MIN && max == INT32_MAX) {999#if !defined(zig_has_int128)
706 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);1000# if defined(__SIZEOF_INT128__)
707 }1001# define zig_has_int128 1
708#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX1002# else
709 if (min == INT32_MIN && max == INT32_MAX) {1003# define zig_has_int128 0
710 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);1004# endif
711 }
712#endif1005#endif
713 int64_t big_result = (int64_t)lhs - (int64_t)rhs;1006
714 if (big_result > max) {1007#if zig_has_int128
715 *res = big_result - ((int64_t)max - (int64_t)min);1008
716 return true;1009typedef unsigned __int128 zig_u128;
1010typedef signed __int128 zig_i128;
1011
1012#define zig_as_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1013#define zig_as_i128(hi, lo) ((zig_i128)zig_as_u128(hi, lo))
1014#define zig_hi_u128(val) ((zig_u64)((val) >> 64))
1015#define zig_lo_u128(val) ((zig_u64)((val) >> 0))
1016#define zig_hi_i128(val) ((zig_i64)((val) >> 64))
1017#define zig_lo_i128(val) ((zig_u64)((val) >> 0))
1018#define zig_bitcast_u128(val) ((zig_u128)(val))
1019#define zig_bitcast_i128(val) ((zig_i128)(val))
1020#define zig_cmp_int128(Type) \
1021 static inline zig_i8 zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1022 return (lhs > rhs) - (lhs < rhs); \
717 }1023 }
718 if (big_result < min) {1024#define zig_bit_int128(Type, operation, operator) \
719 *res = big_result + ((int64_t)max - (int64_t)min);1025 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
720 return true;1026 return lhs operator rhs; \
721 }1027 }
722 *res = big_result;1028
723 return false;1029#else /* zig_has_int128 */
724}1030
7251031#if __LITTLE_ENDIAN__ || _MSC_VER
726static inline bool zig_subo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {1032typedef struct { zig_align(16) zig_u64 lo; zig_u64 hi; } zig_u128;
727 bool overflow;1033typedef struct { zig_align(16) zig_u64 lo; zig_i64 hi; } zig_i128;
728#if defined(__GNUC__) && INT64_MAX == INT_MAX
729 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
730#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
731 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
732#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
733 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
734#else1034#else
735 int int_overflow;1035typedef struct { zig_align(16) zig_u64 hi; zig_u64 lo; } zig_u128;
736 *res = __subodi4(lhs, rhs, &int_overflow);1036typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128;
737 overflow = int_overflow != 0;1037#endif
738#endif1038
739 if (!overflow) {1039#define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })
740 if (*res > max) {1040#define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
741 // TODO adjust the result to be the truncated bits1041#define zig_hi_u128(val) ((val).hi)
742 return true;1042#define zig_lo_u128(val) ((val).lo)
743 } else if (*res < min) {1043#define zig_hi_i128(val) ((val).hi)
744 // TODO adjust the result to be the truncated bits1044#define zig_lo_i128(val) ((val).lo)
745 return true;1045#define zig_bitcast_u128(val) zig_as_u128((zig_u64)(val).hi, (val).lo)
746 }1046#define zig_bitcast_i128(val) zig_as_i128((zig_i64)(val).hi, (val).lo)
1047#define zig_cmp_int128(Type) \
1048 static inline zig_i8 zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1049 return (lhs.hi == rhs.hi) \
1050 ? (lhs.lo > rhs.lo) - (lhs.lo < rhs.lo) \
1051 : (lhs.hi > rhs.hi) - (lhs.hi < rhs.hi); \
747 }1052 }
748 return overflow;1053#define zig_bit_int128(Type, operation, operator) \
1054 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
1055 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \
1056 }
1057
1058#endif /* zig_has_int128 */
1059
1060#define zig_minInt_u128 zig_as_u128(zig_minInt_u64, zig_minInt_u64)
1061#define zig_maxInt_u128 zig_as_u128(zig_maxInt_u64, zig_maxInt_u64)
1062#define zig_minInt_i128 zig_as_i128(zig_minInt_i64, zig_minInt_u64)
1063#define zig_maxInt_i128 zig_as_i128(zig_maxInt_i64, zig_maxInt_u64)
1064
1065zig_cmp_int128(u128)
1066zig_cmp_int128(i128)
1067
1068zig_bit_int128(u128, and, &)
1069zig_bit_int128(i128, and, &)
1070
1071zig_bit_int128(u128, or, |)
1072zig_bit_int128(i128, or, |)
1073
1074zig_bit_int128(u128, xor, ^)
1075zig_bit_int128(i128, xor, ^)
1076
1077static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs);
1078
1079#if zig_has_int128
1080
1081static inline zig_u128 zig_not_u128(zig_u128 val, zig_u8 bits) {
1082 return val ^ zig_maxInt(u128, bits);
749}1083}
7501084
751static inline bool zig_subo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {1085static inline zig_i128 zig_not_i128(zig_i128 val, zig_u8 bits) {
752 bool overflow;1086 (void)bits;
753#if defined(__GNUC__) && INT128_MAX == INT_MAX1087 return ~val;
754 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
755#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
756 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
757#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
758 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
759#else
760 int int_overflow;
761 *res = __suboti4(lhs, rhs, &int_overflow);
762 overflow = int_overflow != 0;
763#endif
764 if (!overflow) {
765 if (*res > max) {
766 // TODO adjust the result to be the truncated bits
767 return true;
768 } else if (*res < min) {
769 // TODO adjust the result to be the truncated bits
770 return true;
771 }
772 }
773 return overflow;
774}1088}
7751089
776static inline bool zig_subo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {1090static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) {
777#if defined(__GNUC__) && UINT8_MAX == UINT_MAX1091 return lhs >> rhs;
778 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
779#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
780 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
781#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
782 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
783#endif
784 if (rhs > lhs) {
785 *res = max - (rhs - lhs - 1);
786 return true;
787 }
788 *res = lhs - rhs;
789 return false;
790}1092}
7911093
792static inline uint16_t zig_subo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {1094static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) {
793#if defined(__GNUC__) && UINT16_MAX == UINT_MAX1095 return lhs << rhs;
794 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
795#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
796 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
797#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
798 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
799#endif
800 if (rhs > lhs) {
801 *res = max - (rhs - lhs - 1);
802 return true;
803 }
804 *res = lhs - rhs;
805 return false;
806}
807
808static inline uint32_t zig_subo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
809 if (max == UINT32_MAX) {
810#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
811 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
812#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
813 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
814#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
815 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
816#endif
817 int int_overflow;
818 *res = __usubosi4(lhs, rhs, &int_overflow);
819 return int_overflow != 0;
820 } else {
821 if (rhs > lhs) {
822 *res = max - (rhs - lhs - 1);
823 return true;
824 }
825 *res = lhs - rhs;
826 return false;
827 }
828}1096}
8291097
830static inline uint64_t zig_subo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {1098static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) {
831 if (max == UINT64_MAX) {1099 return lhs << rhs;
832#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
833 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
834#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
835 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
836#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
837 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
838#else
839 int int_overflow;
840 *res = __usubodi4(lhs, rhs, &int_overflow);
841 return int_overflow != 0;
842#endif
843 } else {
844 if (rhs > lhs) {
845 *res = max - (rhs - lhs - 1);
846 return true;
847 }
848 *res = lhs - rhs;
849 return false;
850 }
851}1100}
8521101
853static inline uint128_t zig_subo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {1102static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
854 if (max == UINT128_MAX) {1103 return lhs + rhs;
855 int int_overflow;
856 *res = __usuboti4(lhs, rhs, &int_overflow);
857 return int_overflow != 0;
858 } else {
859 if (rhs > lhs) {
860 *res = max - (rhs - lhs - 1);
861 return true;
862 }
863 *res = lhs - rhs;
864 return false;
865 }
866}1104}
8671105
868static inline bool zig_mulo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {1106static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) {
869#if defined(__GNUC__) && INT8_MAX == INT_MAX1107 return lhs + rhs;
870 if (min == INT8_MIN && max == INT8_MAX) {
871 return __builtin_smul_overflow(lhs, rhs, (int*)res);
872 }
873#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
874 if (min == INT8_MIN && max == INT8_MAX) {
875 return __builtin_smull_overflow(lhs, rhs, (long*)res);
876 }
877#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
878 if (min == INT8_MIN && max == INT8_MAX) {
879 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
880 }
881#endif
882 int16_t big_result = (int16_t)lhs * (int16_t)rhs;
883 if (big_result > max) {
884 *res = big_result - ((int16_t)max - (int16_t)min);
885 return true;
886 }
887 if (big_result < min) {
888 *res = big_result + ((int16_t)max - (int16_t)min);
889 return true;
890 }
891 *res = big_result;
892 return false;
893}1108}
8941109
895static inline bool zig_mulo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {1110static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) {
896#if defined(__GNUC__) && INT16_MAX == INT_MAX1111 return lhs - rhs;
897 if (min == INT16_MIN && max == INT16_MAX) {
898 return __builtin_smul_overflow(lhs, rhs, (int*)res);
899 }
900#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
901 if (min == INT16_MIN && max == INT16_MAX) {
902 return __builtin_smull_overflow(lhs, rhs, (long*)res);
903 }
904#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
905 if (min == INT16_MIN && max == INT16_MAX) {
906 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
907 }
908#endif
909 int32_t big_result = (int32_t)lhs * (int32_t)rhs;
910 if (big_result > max) {
911 *res = big_result - ((int32_t)max - (int32_t)min);
912 return true;
913 }
914 if (big_result < min) {
915 *res = big_result + ((int32_t)max - (int32_t)min);
916 return true;
917 }
918 *res = big_result;
919 return false;
920}1112}
9211113
922static inline bool zig_mulo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {1114static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
923#if defined(__GNUC__) && INT32_MAX == INT_MAX1115 return lhs - rhs;
924 if (min == INT32_MIN && max == INT32_MAX) {
925 return __builtin_smul_overflow(lhs, rhs, (int*)res);
926 }
927#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
928 if (min == INT32_MIN && max == INT32_MAX) {
929 return __builtin_smull_overflow(lhs, rhs, (long*)res);
930 }
931#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
932 if (min == INT32_MIN && max == INT32_MAX) {
933 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
934 }
935#endif
936 int64_t big_result = (int64_t)lhs * (int64_t)rhs;
937 if (big_result > max) {
938 *res = big_result - ((int64_t)max - (int64_t)min);
939 return true;
940 }
941 if (big_result < min) {
942 *res = big_result + ((int64_t)max - (int64_t)min);
943 return true;
944 }
945 *res = big_result;
946 return false;
947}
948
949static inline bool zig_mulo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
950 bool overflow;
951#if defined(__GNUC__) && INT64_MAX == INT_MAX
952 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
953#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
954 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
955#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
956 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
957#else
958 int int_overflow;
959 *res = __mulodi4(lhs, rhs, &int_overflow);
960 overflow = int_overflow != 0;
961#endif
962 if (!overflow) {
963 if (*res > max) {
964 // TODO adjust the result to be the truncated bits
965 return true;
966 } else if (*res < min) {
967 // TODO adjust the result to be the truncated bits
968 return true;
969 }
970 }
971 return overflow;
972}1116}
9731117
974static inline bool zig_mulo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {1118static inline zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
975 bool overflow;1119 return lhs * rhs;
976#if defined(__GNUC__) && INT128_MAX == INT_MAX
977 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
978#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
979 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
980#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
981 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
982#else
983 int int_overflow;
984 *res = __muloti4(lhs, rhs, &int_overflow);
985 overflow = int_overflow != 0;
986#endif
987 if (!overflow) {
988 if (*res > max) {
989 // TODO adjust the result to be the truncated bits
990 return true;
991 } else if (*res < min) {
992 // TODO adjust the result to be the truncated bits
993 return true;
994 }
995 }
996 return overflow;
997}1120}
9981121
999static inline bool zig_mulo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {1122static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
1000#if defined(__GNUC__) && UINT8_MAX == UINT_MAX1123 return lhs * rhs;
1001 if (max == UINT8_MAX) {
1002 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1003 }
1004#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
1005 if (max == UINT8_MAX) {
1006 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1007 }
1008#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
1009 if (max == UINT8_MAX) {
1010 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1011 }
1012#endif
1013 uint16_t big_result = (uint16_t)lhs * (uint16_t)rhs;
1014 if (big_result > max) {
1015 *res = big_result - max - 1;
1016 return true;
1017 }
1018 *res = big_result;
1019 return false;
1020}1124}
10211125
1022static inline uint16_t zig_mulo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {1126static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
1023#if defined(__GNUC__) && UINT16_MAX == UINT_MAX1127 return lhs / rhs;
1024 if (max == UINT16_MAX) {
1025 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1026 }
1027#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
1028 if (max == UINT16_MAX) {
1029 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1030 }
1031#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
1032 if (max == UINT16_MAX) {
1033 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1034 }
1035#endif
1036 uint32_t big_result = (uint32_t)lhs * (uint32_t)rhs;
1037 if (big_result > max) {
1038 *res = big_result - max - 1;
1039 return true;
1040 }
1041 *res = big_result;
1042 return false;
1043}1128}
10441129
1045static inline uint32_t zig_mulo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {1130static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
1046#if defined(__GNUC__) && UINT32_MAX == UINT_MAX1131 return lhs / rhs;
1047 if (max == UINT32_MAX) {
1048 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1049 }
1050#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
1051 if (max == UINT32_MAX) {
1052 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1053 }
1054#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
1055 if (max == UINT32_MAX) {
1056 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1057 }
1058#endif
1059 uint64_t big_result = (uint64_t)lhs * (uint64_t)rhs;
1060 if (big_result > max) {
1061 *res = big_result - max - 1;
1062 return true;
1063 }
1064 *res = big_result;
1065 return false;
1066}
1067
1068static inline uint64_t zig_mulo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
1069 bool overflow;
1070#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
1071 overflow = __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1072#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
1073 overflow = __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1074#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
1075 overflow = __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1076#else
1077 int int_overflow;
1078 *res = __umulodi4(lhs, rhs, &int_overflow);
1079 overflow = int_overflow != 0;
1080#endif
1081 if (*res > max && !overflow) {
1082 *res -= max - 1;
1083 return true;
1084 }
1085 return overflow;
1086}1132}
10871133
1088static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {1134static inline zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
1089 int overflow;1135 return lhs % rhs;
1090 *res = __umuloti4(lhs, rhs, &overflow);1136}
1091 if (*res > max && overflow == 0) {1137
1092 *res -= max - 1;1138static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
1093 return true;1139 return lhs % rhs;
1094 }1140}
1095 return overflow != 0;1141
1142static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
1143 return zig_div_trunc_i128(lhs, rhs) - (((lhs ^ rhs) & zig_rem_i128(lhs, rhs)) < zig_as_i128(0, 0));
1144}
1145
1146static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) {
1147 zig_i128 rem = zig_rem_i128(lhs, rhs);
1148 return rem + (((lhs ^ rhs) & rem) < zig_as_i128(0, 0) ? rhs : zig_as_i128(0, 0));
1149}
1150
1151#else /* zig_has_int128 */
1152
1153static inline zig_u128 zig_not_u128(zig_u128 val, zig_u8 bits) {
1154 return (zig_u128){ .hi = zig_not_u64(val.hi, bits - zig_as_u8(64)), .lo = zig_not_u64(val.lo, zig_as_u8(64)) };
1096}1155}
10971156
1098static inline float zig_bitcast_f32_u32(uint32_t arg) {1157static inline zig_i128 zig_not_i128(zig_i128 val, zig_u8 bits) {
1099 float dest;1158 return (zig_i128){ .hi = zig_not_i64(val.hi, bits - zig_as_u8(64)), .lo = zig_not_u64(val.lo, zig_as_u8(64)) };
1100 memcpy(&dest, &arg, sizeof dest);
1101 return dest;
1102}
1103
1104static inline float zig_bitcast_f64_u64(uint64_t arg) {
1105 double dest;
1106 memcpy(&dest, &arg, sizeof dest);
1107 return dest;
1108}
1109
1110#define zig_add_sat_u(ZT, T) static inline T zig_adds_##ZT(T x, T y, T max) { \
1111 return (x > max - y) ? max : x + y; \
1112}
1113
1114#define zig_add_sat_s(ZT, T, T2) static inline T zig_adds_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1115 T2 res = x + y; \
1116 return (res < min) ? min : (res > max) ? max : res; \
1117}1159}
11181160
1119zig_add_sat_u( u8, uint8_t)1161static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) {
1120zig_add_sat_s( i8, int8_t, int16_t)1162 if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
1121zig_add_sat_u(u16, uint16_t)1163 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
1122zig_add_sat_s(i16, int16_t, int32_t)
1123zig_add_sat_u(u32, uint32_t)
1124zig_add_sat_s(i32, int32_t, int64_t)
1125zig_add_sat_u(u64, uint64_t)
1126zig_add_sat_s(i64, int64_t, int128_t)
1127zig_add_sat_s(isize, intptr_t, int128_t)
1128zig_add_sat_s(short, short, int)
1129zig_add_sat_s(int, int, long)
1130zig_add_sat_s(long, long, long long)
1131
1132#define zig_sub_sat_u(ZT, T) static inline T zig_subs_##ZT(T x, T y, T max) { \
1133 return (x > max + y) ? max : x - y; \
1134}1164}
11351165
1136#define zig_sub_sat_s(ZT, T, T2) static inline T zig_subs_##ZT(T2 x, T2 y, T2 min, T2 max) { \1166static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) {
1137 T2 res = x - y; \1167 if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
1138 return (res < min) ? min : (res > max) ? max : res; \1168 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
1139}1169}
1140
1141zig_sub_sat_u( u8, uint8_t)
1142zig_sub_sat_s( i8, int8_t, int16_t)
1143zig_sub_sat_u(u16, uint16_t)
1144zig_sub_sat_s(i16, int16_t, int32_t)
1145zig_sub_sat_u(u32, uint32_t)
1146zig_sub_sat_s(i32, int32_t, int64_t)
1147zig_sub_sat_u(u64, uint64_t)
1148zig_sub_sat_s(i64, int64_t, int128_t)
1149zig_sub_sat_s(isize, intptr_t, int128_t)
1150zig_sub_sat_s(short, short, int)
1151zig_sub_sat_s(int, int, long)
1152zig_sub_sat_s(long, long, long long)
11531170
1171static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) {
1172 if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 };
1173 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs };
1174}
1175
1176static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
1177 zig_u128 res;
1178 res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64);
1179 return res;
1180}
11541181
1155#define zig_mul_sat_u(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 max) { \1182static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) {
1156 T2 res = x * y; \1183 zig_i128 res;
1157 return (res > max) ? max : res; \1184 res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64);
1185 return res;
1158}1186}
11591187
1160#define zig_mul_sat_s(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 min, T2 max) { \1188static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) {
1161 T2 res = x * y; \1189 zig_u128 res;
1162 return (res < min) ? min : (res > max) ? max : res; \1190 res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64);
1191 return res;
1163}1192}
11641193
1165zig_mul_sat_u(u8, uint8_t, uint16_t)1194static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
1166zig_mul_sat_s(i8, int8_t, int16_t)1195 zig_i128 res;
1167zig_mul_sat_u(u16, uint16_t, uint32_t)1196 res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64);
1168zig_mul_sat_s(i16, int16_t, int32_t)1197 return res;
1169zig_mul_sat_u(u32, uint32_t, uint64_t)1198}
1170zig_mul_sat_s(i32, int32_t, int64_t)
1171zig_mul_sat_u(u64, uint64_t, uint128_t)
1172zig_mul_sat_s(i64, int64_t, int128_t)
1173zig_mul_sat_s(isize, intptr_t, int128_t)
1174zig_mul_sat_s(short, short, int)
1175zig_mul_sat_s(int, int, long)
1176zig_mul_sat_s(long, long, long long)
11771199
1178#define zig_shl_sat_u(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T max) { \1200static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
1179 if(x == 0) return 0; \1201 return zig_sub_i128(zig_div_trunc_i128(lhs, rhs), (((lhs.hi ^ rhs.hi) & zig_rem_i128(lhs, rhs).hi) < zig_as_i64(0)) ? zig_as_i128(0, 1) : zig_as_i128(0, 0));
1180 T bits_set = 64 - __builtin_clzll(x); \
1181 return (bits_set + y > bits) ? max : x << y; \
1182}1202}
11831203
1184#define zig_shl_sat_s(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T min, T max) { \1204static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) {
1185 if(x == 0) return 0; \1205 zig_i128 rem = zig_rem_i128(lhs, rhs);
1186 T x_twos_comp = x < 0 ? -x : x; \1206 return rem + (((lhs.hi ^ rhs.hi) & rem.hi) < zig_as_i64(0) ? rhs : zig_as_i128(0, 0));
1187 T bits_set = 64 - __builtin_clzll(x_twos_comp); \
1188 T min_or_max = (x < 0) ? min : max; \
1189 return (y + bits_set > bits ) ? min_or_max : x << y; \
1190}1207}
11911208
1192zig_shl_sat_u(u8, uint8_t, 8)1209#endif /* zig_has_int128 */
1193zig_shl_sat_s(i8, int8_t, 7)
1194zig_shl_sat_u(u16, uint16_t, 16)
1195zig_shl_sat_s(i16, int16_t, 15)
1196zig_shl_sat_u(u32, uint32_t, 32)
1197zig_shl_sat_s(i32, int32_t, 31)
1198zig_shl_sat_u(u64, uint64_t, 64)
1199zig_shl_sat_s(i64, int64_t, 63)
1200zig_shl_sat_s(isize, intptr_t, ((sizeof(intptr_t)) * CHAR_BIT - 1))
1201zig_shl_sat_s(short, short, ((sizeof(short )) * CHAR_BIT - 1))
1202zig_shl_sat_s(int, int, ((sizeof(int )) * CHAR_BIT - 1))
1203zig_shl_sat_s(long, long, ((sizeof(long )) * CHAR_BIT - 1))
12041210
1205#define zig_bitsizeof(T) (CHAR_BIT * sizeof(T))1211#define zig_div_floor_u128 zig_div_trunc_u128
1206#define zig_bit_mask(T, bit_width) \1212#define zig_mod_u128 zig_rem_u128
1207 ((bit_width) == zig_bitsizeof(T) \
1208 ? ((T)-1) \
1209 : (((T)1 << (T)(bit_width)) - 1))
12101213
1211static inline int zig_clz(unsigned int value, uint8_t zig_type_bit_width) {1214static inline zig_i128 zig_shr_i128(zig_i128 lhs, zig_u8 rhs) {
1212 if (value == 0) return zig_type_bit_width;1215 zig_i128 sign_mask = zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i8(0) ? -zig_as_i128(0, 1) : zig_as_i128(0, 0);
1213 return __builtin_clz(value) - zig_bitsizeof(unsigned int) + zig_type_bit_width;1216 return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask);
1214}1217}
12151218
1216static inline int zig_clzl(unsigned long value, uint8_t zig_type_bit_width) {1219static inline zig_u128 zig_wrap_u128(zig_u128 val, zig_u8 bits) {
1217 if (value == 0) return zig_type_bit_width;1220 return zig_and_u128(val, zig_maxInt(u128, bits));
1218 return __builtin_clzl(value) - zig_bitsizeof(unsigned long) + zig_type_bit_width;
1219}1221}
12201222
1221static inline int zig_clzll(unsigned long long value, uint8_t zig_type_bit_width) {1223static inline zig_i128 zig_wrap_i128(zig_i128 val, zig_u8 bits) {
1222 if (value == 0) return zig_type_bit_width;1224 return zig_as_i128(zig_wrap_i64(zig_hi_i128(val), bits - zig_as_u8(64)), zig_lo_i128(val));
1223 return __builtin_clzll(value) - zig_bitsizeof(unsigned long long) + zig_type_bit_width;
1224}1225}
12251226
1226#define zig_clz_u8 zig_clz1227static inline zig_u128 zig_shlw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) {
1227#define zig_clz_i8 zig_clz1228 return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits);
1228#define zig_clz_u16 zig_clz1229}
1229#define zig_clz_i16 zig_clz
1230#define zig_clz_u32 zig_clzl
1231#define zig_clz_i32 zig_clzl
1232#define zig_clz_u64 zig_clzll
1233#define zig_clz_i64 zig_clzll
12341230
1235static inline int zig_clz_u128(uint128_t value, uint8_t zig_type_bit_width) {1231static inline zig_i128 zig_shlw_i128(zig_i128 lhs, zig_u8 rhs, zig_u8 bits) {
1236 if (value == 0) return zig_type_bit_width;1232 return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1237 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1238 const uint64_t hi = (value & mask) >> 64;
1239 const uint64_t lo = (value & mask);
1240 const int leading_zeroes = (
1241 hi != 0 ? __builtin_clzll(hi) : 64 + (lo != 0 ? __builtin_clzll(lo) : 64));
1242 return leading_zeroes - zig_bitsizeof(uint128_t) + zig_type_bit_width;
1243}1233}
12441234
1245#define zig_clz_i128 zig_clz_u1281235static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) {
1236 return zig_wrap_u128(zig_add_u128(lhs, rhs), bits);
1237}
12461238
1247static inline int zig_ctz(unsigned int value, uint8_t zig_type_bit_width) {1239static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1248 if (value == 0) return zig_type_bit_width;1240 return zig_wrap_i128(zig_bitcast_i128(zig_add_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1249 return __builtin_ctz(value & zig_bit_mask(unsigned int, zig_type_bit_width));
1250}1241}
12511242
1252static inline int zig_ctzl(unsigned long value, uint8_t zig_type_bit_width) {1243static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1253 if (value == 0) return zig_type_bit_width;1244 return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits);
1254 return __builtin_ctzl(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1255}1245}
12561246
1257static inline int zig_ctzll(unsigned long value, uint8_t zig_type_bit_width) {1247static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1258 if (value == 0) return zig_type_bit_width;1248 return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1259 return __builtin_ctzll(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1260}1249}
12611250
1262#define zig_ctz_u8 zig_ctz1251static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1263#define zig_ctz_i8 zig_ctz1252 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);
1264#define zig_ctz_u16 zig_ctz1253}
1265#define zig_ctz_i16 zig_ctz
1266#define zig_ctz_u32 zig_ctzl
1267#define zig_ctz_i32 zig_ctzl
1268#define zig_ctz_u64 zig_ctzll
1269#define zig_ctz_i64 zig_ctzll
12701254
1271static inline int zig_ctz_u128(uint128_t value, uint8_t zig_type_bit_width) {1255static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1272 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);1256 return zig_wrap_i128(zig_bitcast_i128(zig_mul_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1273 const uint64_t hi = (value & mask) >> 64;
1274 const uint64_t lo = (value & mask);
1275 return (lo != 0 ? __builtin_ctzll(lo) : 64 + (hi != 0 ? __builtin_ctzll(hi) : 64));
1276}1257}
12771258
1278#define zig_ctz_i128 zig_ctz_u1281259#if zig_has_int128
12791260
1280static inline int zig_popcount(unsigned int value, uint8_t zig_type_bit_width) {1261static inline zig_bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, zig_u8 rhs, zig_u8 bits) {
1281 return __builtin_popcount(value & zig_bit_mask(unsigned int, zig_type_bit_width));1262 *res = zig_shlw_u128(lhs, rhs, bits);
1263 return zig_and_u128(lhs, zig_shl_u128(zig_maxInt_u128, bits - rhs)) != zig_as_u128(0, 0);
1282}1264}
12831265
1284static inline int zig_popcountl(unsigned long value, uint8_t zig_type_bit_width) {1266static inline zig_bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, zig_u8 rhs, zig_u8 bits) {
1285 return __builtin_popcountl(value & zig_bit_mask(unsigned long, zig_type_bit_width));1267 *res = zig_shlw_i128(lhs, rhs, bits);
1268 zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - zig_as_u8(1)));
1269 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_as_i128(0, 0)) != zig_as_i8(0) &&
1270 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != zig_as_i8(0);
1286}1271}
12871272
1288static inline int zig_popcountll(unsigned long value, uint8_t zig_type_bit_width) {1273static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1289 return __builtin_popcountll(value & zig_bit_mask(unsigned long, zig_type_bit_width));1274#if zig_has_builtin(add_overflow)
1275 zig_u128 full_res;
1276 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1277 *res = zig_wrap_u128(full_res, bits);
1278 return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits);
1279#else
1280 *res = zig_addw_u128(lhs, rhs, bits);
1281 return *res < lhs;
1282#endif
1290}1283}
12911284
1292#define zig_popcount_u8 zig_popcount1285zig_extern_c zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1293#define zig_popcount_i8 zig_popcount1286static inline zig_bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1294#define zig_popcount_u16 zig_popcount1287#if zig_has_builtin(add_overflow)
1295#define zig_popcount_i16 zig_popcount1288 zig_i128 full_res;
1296#define zig_popcount_u32 zig_popcountl1289 zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1297#define zig_popcount_i32 zig_popcountl1290#else
1298#define zig_popcount_u64 zig_popcountll1291 zig_c_int overflow_int;
1299#define zig_popcount_i64 zig_popcountll1292 zig_i128 full_res = __addoti4(lhs, rhs, &overflow_int);
1293 zig_bool overflow = overflow_int != 0;
1294#endif
1295 *res = zig_wrap_i128(full_res, bits);
1296 return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits);
1297}
13001298
1301static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width) {1299static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1302 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);1300#if zig_has_builtin(sub_overflow)
1303 const uint64_t hi = (value & mask) >> 64;1301 zig_u128 full_res;
1304 const uint64_t lo = (value & mask);1302 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1305 return __builtin_popcountll(hi) + __builtin_popcountll(lo);1303 *res = zig_wrap_u128(full_res, bits);
1304 return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits);
1305#else
1306 *res = zig_subw_u128(lhs, rhs, bits);
1307 return *res > lhs;
1308#endif
1306}1309}
13071310
1308#define zig_popcount_i128 zig_popcount_u1281311zig_extern_c zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1312static inline zig_bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1313#if zig_has_builtin(sub_overflow)
1314 zig_i128 full_res;
1315 zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1316#else
1317 zig_c_int overflow_int;
1318 zig_i128 full_res = __suboti4(lhs, rhs, &overflow_int);
1319 zig_bool overflow = overflow_int != 0;
1320#endif
1321 *res = zig_wrap_i128(full_res, bits);
1322 return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits);
1323}
13091324
1310static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, uint8_t bits) {1325static inline zig_bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1311 *res = lhs << rhs;1326#if zig_has_builtin(mul_overflow)
1312 if (zig_clz_i8(lhs, bits) >= rhs) return false;1327 zig_u128 full_res;
1313 *res &= UINT8_MAX >> (8 - bits);1328 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1314 return true;1329 *res = zig_wrap_u128(full_res, bits);
1330 return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits);
1331#else
1332 *res = zig_mulw_u128(lhs, rhs, bits);
1333 return rhs != zig_as_u128(0, 0) && lhs > zig_maxInt(u128, bits) / rhs;
1334#endif
1315}1335}
13161336
1317static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, uint8_t bits) {1337zig_extern_c zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1318 *res = lhs << rhs;1338static inline zig_bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1319 if (zig_clz_i16(lhs, bits) >= rhs) return false;1339#if zig_has_builtin(mul_overflow)
1320 *res &= UINT16_MAX >> (16 - bits);1340 zig_i128 full_res;
1321 return true;1341 zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1342#else
1343 zig_c_int overflow_int;
1344 zig_i128 full_res = __muloti4(lhs, rhs, &overflow);
1345 zig_bool overflow = overflow_int != 0;
1346#endif
1347 *res = zig_wrap_i128(full_res, bits);
1348 return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits);
1322}1349}
13231350
1324static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, uint8_t bits) {1351#else /* zig_has_int128 */
1325 *res = lhs << rhs;1352
1326 if (zig_clz_i32(lhs, bits) >= rhs) return false;1353static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) {
1327 *res &= UINT32_MAX >> (32 - bits);1354 return zig_addo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) |
1328 return true;1355 zig_addo_u64(&res->hi, res->hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX));
1329}1356}
13301357
1331static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, uint8_t bits) {1358static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) {
1332 *res = lhs << rhs;1359 return zig_subo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) |
1333 if (zig_clz_i64(lhs, bits) >= rhs) return false;1360 zig_subo_u64(&res->hi, res->hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX));
1334 *res &= UINT64_MAX >> (64 - bits);
1335 return true;
1336}1361}
13371362
1338static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, uint8_t bits) {1363#endif /* zig_has_int128 */
1339 *res = lhs << rhs;1364
1340 if (zig_clz_i128(lhs, bits) >= rhs) return false;1365static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1341 *res &= UINT128_MAX >> (128 - bits);1366 zig_u128 res;
1342 return true;1367 if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i8(0))
1368 return zig_cmp_u128(lhs, zig_as_u128(0, 0)) != zig_as_i8(0) ? zig_maxInt(u128, bits) : lhs;
1369 return zig_shlo_u128(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u128, bits) : res;
1343}1370}
13441371
1345static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t bits) {1372static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1346 *res = lhs << rhs;1373 zig_i128 res;
1347 if (zig_clz_u8(lhs, bits) >= rhs) return false;1374 if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_as_u128(0, bits)) < zig_as_i8(0) && !zig_shlo_i128(&res, lhs, rhs, bits)) return res;
1348 *res &= UINT8_MAX >> (8 - bits);1375 return zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);
1349 return true;
1350}1376}
13511377
1352static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint8_t bits) {1378static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1353 *res = lhs << rhs;1379 zig_u128 res;
1354 if (zig_clz_u16(lhs, bits) >= rhs) return false;1380 return zig_addo_u128(&res, lhs, rhs, bits) ? zig_maxInt(u128, bits) : res;
1355 *res &= UINT16_MAX >> (16 - bits);
1356 return true;
1357}1381}
13581382
1359static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint8_t bits) {1383static inline zig_i128 zig_adds_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1360 *res = lhs << rhs;1384 zig_i128 res;
1361 if (zig_clz_u32(lhs, bits) >= rhs) return false;1385 if (!zig_addo_i128(&res, lhs, rhs, bits)) return res;
1362 *res &= UINT32_MAX >> (32 - bits);1386 return zig_cmp_i128(res, zig_as_i128(0, 0)) >= zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);
1363 return true;
1364}1387}
13651388
1366static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint8_t bits) {1389static inline zig_u128 zig_subs_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1367 *res = lhs << rhs;1390 zig_u128 res;
1368 if (zig_clz_u64(lhs, bits) >= rhs) return false;1391 return zig_subo_u128(&res, lhs, rhs, bits) ? zig_minInt(u128, bits) : res;
1369 *res &= UINT64_MAX >> (64 - bits);
1370 return true;
1371}1392}
13721393
1373static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint8_t bits) {1394static inline zig_i128 zig_subs_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1374 *res = lhs << rhs;1395 zig_i128 res;
1375 if (zig_clz_u128(lhs, bits) >= rhs) return false;1396 if (!zig_subo_i128(&res, lhs, rhs, bits)) return res;
1376 *res &= UINT128_MAX >> (128 - bits);1397 return zig_cmp_i128(res, zig_as_i128(0, 0)) >= zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);
1377 return true;
1378}1398}
13791399
1380#define zig_sign_extend(T) \1400static inline zig_u128 zig_muls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1381 static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \1401 zig_u128 res;
1382 const T m = (T)1 << (T)(zig_type_bit_width - 1); \1402 return zig_mulo_u128(&res, lhs, rhs, bits) ? zig_maxInt(u128, bits) : res;
1383 return (value ^ m) - m; \1403}
1384 }
13851404
1386zig_sign_extend(uint8_t)1405static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1387zig_sign_extend(uint16_t)1406 zig_i128 res;
1388zig_sign_extend(uint32_t)1407 if (!zig_mulo_i128(&res, lhs, rhs, bits)) return res;
1389zig_sign_extend(uint64_t)1408 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_as_i128(0, 0)) < zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);
1390zig_sign_extend(uint128_t)1409}
13911410
1392#define zig_byte_swap_u(ZigTypeBits, CTypeBits) \1411static inline zig_u8 zig_clz_u128(zig_u128 val, zig_u8 bits) {
1393 static inline uint##CTypeBits##_t zig_byte_swap_u##ZigTypeBits(uint##CTypeBits##_t value, uint8_t zig_type_bit_width) { \1412 if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - zig_as_u8(64));
1394 return __builtin_bswap##CTypeBits(value) >> (CTypeBits - zig_type_bit_width); \1413 return zig_clz_u64(zig_lo_u128(val), zig_as_u8(64)) + zig_as_u8(64);
1395 }1414}
13961415
1397#define zig_byte_swap_s(ZigTypeBits, CTypeBits) \1416static inline zig_u8 zig_clz_i128(zig_i128 val, zig_u8 bits) {
1398 static inline int##CTypeBits##_t zig_byte_swap_i##ZigTypeBits(int##CTypeBits##_t value, uint8_t zig_type_bit_width) { \1417 return zig_clz_u128(zig_bitcast_u128(val), bits);
1399 const uint##CTypeBits##_t swapped = zig_byte_swap_u##ZigTypeBits(value, zig_type_bit_width); \1418}
1400 return zig_sign_extend_uint##CTypeBits##_t(swapped, zig_type_bit_width); \
1401 }
14021419
1403#define zig_byte_swap(ZigTypeBits, CTypeBits) \1420static inline zig_u8 zig_ctz_u128(zig_u128 val, zig_u8 bits) {
1404 zig_byte_swap_u(ZigTypeBits, CTypeBits) \1421 if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), zig_as_u8(64));
1405 zig_byte_swap_s(ZigTypeBits, CTypeBits)1422 return zig_ctz_u64(zig_hi_u128(val), bits - zig_as_u8(64)) + zig_as_u8(64);
14061423}
1407zig_byte_swap( 8, 16)
1408zig_byte_swap(16, 16)
1409zig_byte_swap(32, 32)
1410zig_byte_swap(64, 64)
1411
1412static inline uint128_t zig_byte_swap_u128(uint128_t value, uint8_t zig_type_bit_width) {
1413 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1414 const uint128_t hi = __builtin_bswap64((uint64_t)(value >> 64));
1415 const uint128_t lo = __builtin_bswap64((uint64_t)value);
1416 return (((lo << 64 | hi) >> (128 - zig_type_bit_width))) & mask;
1417}
1418
1419zig_byte_swap_s(128, 128)
1420
1421static const uint8_t zig_bit_reverse_lut[256] = {
1422 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
1423 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1424 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
1425 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1426 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
1427 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1428 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
1429 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1430 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
1431 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1432 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
1433 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1434 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
1435 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1436 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
1437 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1438 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
1439 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1440 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
1441 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1442 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
1443 0x3f, 0xbf, 0x7f, 0xff
1444};
1445
1446static inline uint8_t zig_bit_reverse_u8(uint8_t value, uint8_t zig_type_bit_width) {
1447 const uint8_t reversed = zig_bit_reverse_lut[value] >> (8 - zig_type_bit_width);
1448 return zig_sign_extend_uint8_t(reversed, zig_type_bit_width);
1449}
1450
1451#define zig_bit_reverse_i8 zig_bit_reverse_u8
1452
1453static inline uint16_t zig_bit_reverse_u16(uint16_t value, uint8_t zig_type_bit_width) {
1454 const uint16_t swapped = zig_byte_swap_u16(value, zig_type_bit_width);
1455 const uint16_t reversed = (
1456 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1457 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1458 return zig_sign_extend_uint16_t(
1459 reversed & zig_bit_mask(uint16_t, zig_type_bit_width),
1460 zig_type_bit_width);
1461}
1462
1463#define zig_bit_reverse_i16 zig_bit_reverse_u16
1464
1465static inline uint32_t zig_bit_reverse_u32(uint32_t value, uint8_t zig_type_bit_width) {
1466 const uint32_t swapped = zig_byte_swap_u32(value, zig_type_bit_width);
1467 const uint32_t reversed = (
1468 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1469 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1470 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1471 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1472 return zig_sign_extend_uint32_t(
1473 reversed & zig_bit_mask(uint32_t, zig_type_bit_width),
1474 zig_type_bit_width);
1475}
1476
1477#define zig_bit_reverse_i32 zig_bit_reverse_u32
1478
1479static inline uint64_t zig_bit_reverse_u64(uint64_t value, uint8_t zig_type_bit_width) {
1480 const uint64_t swapped = zig_byte_swap_u64(value, zig_type_bit_width);
1481 const uint64_t reversed = (
1482 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1483 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1484 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1485 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1486 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1487 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1488 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1489 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1490 return zig_sign_extend_uint64_t(
1491 reversed & zig_bit_mask(uint64_t, zig_type_bit_width),
1492 zig_type_bit_width);
1493}
1494
1495#define zig_bit_reverse_i64 zig_bit_reverse_u64
1496
1497static inline uint128_t zig_bit_reverse_u128(uint128_t value, uint8_t zig_type_bit_width) {
1498 const uint128_t swapped = zig_byte_swap_u128(value, zig_type_bit_width);
1499 const uint128_t reversed = (
1500 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x78) & 0xff] << 0x78) |
1501 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x70) & 0xff] << 0x70) |
1502 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x68) & 0xff] << 0x68) |
1503 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x60) & 0xff] << 0x60) |
1504 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x58) & 0xff] << 0x58) |
1505 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x50) & 0xff] << 0x50) |
1506 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x48) & 0xff] << 0x48) |
1507 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x40) & 0xff] << 0x40) |
1508 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1509 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1510 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1511 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1512 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1513 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1514 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1515 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1516 return zig_sign_extend_uint128_t(
1517 reversed & zig_bit_mask(uint128_t, zig_type_bit_width),
1518 zig_type_bit_width);
1519}
1520
1521#define zig_bit_reverse_i128 zig_bit_reverse_u128
1522
1523static inline float zig_div_truncf(float numerator, float denominator) {
1524 return __builtin_truncf(numerator / denominator);
1525}
1526
1527static inline double zig_div_trunc(double numerator, double denominator) {
1528 return __builtin_trunc(numerator / denominator);
1529}
1530
1531static inline long double zig_div_truncl(long double numerator, long double denominator) {
1532 return __builtin_truncf(numerator / denominator);
1533}
1534
1535#define zig_div_trunc_f16 zig_div_truncf
1536#define zig_div_trunc_f32 zig_div_truncf
1537#define zig_div_trunc_f64 zig_div_trunc
1538#define zig_div_trunc_f80 zig_div_truncl
1539#define zig_div_trunc_f128 zig_div_truncl
1540
1541#define zig_div_floorf(numerator, denominator) \
1542 __builtin_floorf((float)(numerator) / (float)(denominator))
1543
1544#define zig_div_floor(numerator, denominator) \
1545 __builtin_floor((double)(numerator) / (double)(denominator))
1546
1547#define zig_div_floorl(numerator, denominator) \
1548 __builtin_floorl((long double)(numerator) / (long double)(denominator))
15491424
1550#define zig_div_floor_f16 zig_div_floorf1425static inline zig_u8 zig_ctz_i128(zig_i128 val, zig_u8 bits) {
1551#define zig_div_floor_f32 zig_div_floorf1426 return zig_ctz_u128(zig_bitcast_u128(val), bits);
1552#define zig_div_floor_f64 zig_div_floor
1553#define zig_div_floor_f80 zig_div_floorl
1554#define zig_div_floor_f128 zig_div_floorl
1555
1556#define zig_div_floor_u8 zig_div_floorf
1557#define zig_div_floor_i8 zig_div_floorf
1558#define zig_div_floor_u16 zig_div_floorf
1559#define zig_div_floor_i16 zig_div_floorf
1560#define zig_div_floor_u32 zig_div_floor
1561#define zig_div_floor_i32 zig_div_floor
1562#define zig_div_floor_u64 zig_div_floor
1563#define zig_div_floor_i64 zig_div_floor
1564#define zig_div_floor_u128 zig_div_floorl
1565#define zig_div_floor_i128 zig_div_floorl
1566
1567static inline float zig_modf(float numerator, float denominator) {
1568 return (numerator - (zig_div_floorf(numerator, denominator) * denominator));
1569}
1570
1571static inline double zig_mod(double numerator, double denominator) {
1572 return (numerator - (zig_div_floor(numerator, denominator) * denominator));
1573}1427}
15741428
1575static inline long double zig_modl(long double numerator, long double denominator) {1429static inline zig_u8 zig_popcount_u128(zig_u128 val, zig_u8 bits) {
1576 return (numerator - (zig_div_floorl(numerator, denominator) * denominator));1430 return zig_popcount_u64(zig_hi_u128(val), bits - zig_as_u8(64)) +
1577}1431 zig_popcount_u64(zig_lo_u128(val), zig_as_u8(64));
15781432}
1579#define zig_mod_f16 zig_modf
1580#define zig_mod_f32 zig_modf
1581#define zig_mod_f64 zig_mod
1582#define zig_mod_f80 zig_modl
1583#define zig_mod_f128 zig_modl
1584
1585#define zig_mod_int(ZigType, CType) \
1586 static inline CType zig_mod_##ZigType(CType numerator, CType denominator) { \
1587 return (numerator - (zig_div_floor_##ZigType(numerator, denominator) * denominator)); \
1588 }
15891433
1590zig_mod_int( u8, uint8_t)1434static inline zig_u8 zig_popcount_i128(zig_i128 val, zig_u8 bits) {
1591zig_mod_int( i8, int8_t)1435 return zig_popcount_u128(zig_bitcast_u128(val), bits);
1592zig_mod_int( u16, uint16_t)1436}
1593zig_mod_int( i16, int16_t)1437
1594zig_mod_int( u32, uint32_t)1438static inline zig_u128 zig_byte_swap_u128(zig_u128 val, zig_u8 bits) {
1595zig_mod_int( i32, int32_t)1439 zig_u128 full_res;
1596zig_mod_int( u64, uint64_t)1440#if zig_has_builtin(bswap128)
1597zig_mod_int( i64, int64_t)1441 full_res = __builtin_bswap128(val);
1598zig_mod_int(u128, uint128_t)1442#else
1599zig_mod_int(i128, int128_t)1443 full_res = zig_as_u128(zig_byte_swap_u64(zig_lo_u128(val), zig_as_u8(64)),
1444 zig_byte_swap_u64(zig_hi_u128(val), zig_as_u8(64)));
1445#endif
1446 return zig_shr_u128(full_res, zig_as_u8(128) - bits);
1447}
1448
1449static inline zig_i128 zig_byte_swap_i128(zig_i128 val, zig_u8 bits) {
1450 return zig_byte_swap_u128(zig_bitcast_u128(val), bits);
1451}
1452
1453static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) {
1454 return zig_shr_u128(zig_as_u128(zig_bit_reverse_u64(zig_lo_u128(val), zig_as_u8(64)),
1455 zig_bit_reverse_u64(zig_hi_u128(val), zig_as_u8(64))),
1456 zig_as_u8(128) - bits);
1457}
1458
1459static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) {
1460 return zig_bit_reverse_u128(zig_bitcast_u128(val), bits);
1461}
1462
1463/* ========================== Float Point Routines ========================== */
1464
1465#define zig_float_builtins(Type) \
1466 zig_extern_c zig_##Type zig_builtin_##Type(sqrt)(zig_##Type); \
1467 zig_extern_c zig_##Type zig_builtin_##Type(sin)(zig_##Type); \
1468 zig_extern_c zig_##Type zig_builtin_##Type(cos)(zig_##Type); \
1469 zig_extern_c zig_##Type zig_builtin_##Type(tan)(zig_##Type); \
1470 zig_extern_c zig_##Type zig_builtin_##Type(exp)(zig_##Type); \
1471 zig_extern_c zig_##Type zig_builtin_##Type(exp2)(zig_##Type); \
1472 zig_extern_c zig_##Type zig_builtin_##Type(log)(zig_##Type); \
1473 zig_extern_c zig_##Type zig_builtin_##Type(log2)(zig_##Type); \
1474 zig_extern_c zig_##Type zig_builtin_##Type(log10)(zig_##Type); \
1475 zig_extern_c zig_##Type zig_builtin_##Type(fabs)(zig_##Type); \
1476 zig_extern_c zig_##Type zig_builtin_##Type(floor)(zig_##Type); \
1477 zig_extern_c zig_##Type zig_builtin_##Type(ceil)(zig_##Type); \
1478 zig_extern_c zig_##Type zig_builtin_##Type(round)(zig_##Type); \
1479 zig_extern_c zig_##Type zig_builtin_##Type(trunc)(zig_##Type); \
1480 zig_extern_c zig_##Type zig_builtin_##Type(fmod)(zig_##Type, zig_##Type); \
1481 zig_extern_c zig_##Type zig_builtin_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \
1482\
1483 static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \
1484 return zig_builtin_##Type(trunc)(lhs / rhs); \
1485 } \
1486\
1487 static inline zig_##Type zig_div_floor_##Type(zig_##Type lhs, zig_##Type rhs) { \
1488 return zig_builtin_##Type(floor)(lhs / rhs); \
1489 } \
1490\
1491 static inline zig_##Type zig_mod_##Type(zig_##Type lhs, zig_##Type rhs) { \
1492 return lhs - zig_div_floor_##Type(lhs, rhs) * rhs; \
1493 }
1494zig_float_builtins(f16)
1495zig_float_builtins(f32)
1496zig_float_builtins(f64)
1497zig_float_builtins(f80)
1498zig_float_builtins(f128)
1499zig_float_builtins(c_longdouble)
lib/std/debug.zig+7-1
...@@ -1222,7 +1222,13 @@ pub const DebugInfo = struct {...@@ -1222,7 +1222,13 @@ pub const DebugInfo = struct {
1222 }1222 }
12231223
1224 pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo {1224 pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
1225 if (comptime builtin.target.isDarwin()) {1225 if (builtin.zig_backend == .stage2_c) {
1226 return @as(error{
1227 InvalidDebugInfo,
1228 MissingDebugInfo,
1229 UnsupportedBackend,
1230 }, error.UnsupportedBackend);
1231 } else if (comptime builtin.target.isDarwin()) {
1226 return self.lookupModuleDyld(address);1232 return self.lookupModuleDyld(address);
1227 } else if (native_os == .windows) {1233 } else if (native_os == .windows) {
1228 return self.lookupModuleWin32(address);1234 return self.lookupModuleWin32(address);
lib/std/os/linux/arm64.zig+14-5
...@@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *...@@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *
106pub const restore = restore_rt;106pub const restore = restore_rt;
107107
108pub fn restore_rt() callconv(.Naked) void {108pub fn restore_rt() callconv(.Naked) void {
109 return asm volatile ("svc #0"109 switch (@import("builtin").zig_backend) {
110 :110 .stage2_c => return asm volatile (
111 : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)),111 \\ mov x8, %[number]
112 : "memory", "cc"112 \\ svc #0
113 );113 :
114 : [number] "i" (@enumToInt(SYS.rt_sigreturn)),
115 : "memory", "cc"
116 ),
117 else => return asm volatile ("svc #0"
118 :
119 : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)),
120 : "memory", "cc"
121 ),
122 }
114}123}
115124
116pub const O = struct {125pub const O = struct {
lib/std/os/linux/i386.zig+28-10
...@@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8);...@@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8);
124pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;124pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
125125
126pub fn restore() callconv(.Naked) void {126pub fn restore() callconv(.Naked) void {
127 return asm volatile ("int $0x80"127 switch (@import("builtin").zig_backend) {
128 :128 .stage2_c => return asm volatile (
129 : [number] "{eax}" (@enumToInt(SYS.sigreturn)),129 \\ movl %[number], %%eax
130 : "memory"130 \\ int $0x80
131 );131 :
132 : [number] "i" (@enumToInt(SYS.sigreturn)),
133 : "memory"
134 ),
135 else => return asm volatile ("int $0x80"
136 :
137 : [number] "{eax}" (@enumToInt(SYS.sigreturn)),
138 : "memory"
139 ),
140 }
132}141}
133142
134pub fn restore_rt() callconv(.Naked) void {143pub fn restore_rt() callconv(.Naked) void {
135 return asm volatile ("int $0x80"144 switch (@import("builtin").zig_backend) {
136 :145 .stage2_c => return asm volatile (
137 : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)),146 \\ movl %[number], %%eax
138 : "memory"147 \\ int $0x80
139 );148 :
149 : [number] "i" (@enumToInt(SYS.rt_sigreturn)),
150 : "memory"
151 ),
152 else => return asm volatile ("int $0x80"
153 :
154 : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)),
155 : "memory"
156 ),
157 }
140}158}
141159
142pub const O = struct {160pub const O = struct {
lib/std/os/linux/x86_64.zig+15-5
...@@ -108,11 +108,21 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid:...@@ -108,11 +108,21 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid:
108pub const restore = restore_rt;108pub const restore = restore_rt;
109109
110pub fn restore_rt() callconv(.Naked) void {110pub fn restore_rt() callconv(.Naked) void {
111 return asm volatile ("syscall"111 switch (@import("builtin").zig_backend) {
112 :112 .stage2_c => return asm volatile (
113 : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)),113 \\ movl %[number], %%eax
114 : "rcx", "r11", "memory"114 \\ syscall
115 );115 \\ retq
116 :
117 : [number] "i" (@enumToInt(SYS.rt_sigreturn)),
118 : "rcx", "r11", "memory"
119 ),
120 else => return asm volatile ("syscall"
121 :
122 : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)),
123 : "rcx", "r11", "memory"
124 ),
125 }
116}126}
117127
118pub const mode_t = usize;128pub const mode_t = usize;
lib/std/start.zig+101-73
...@@ -23,7 +23,6 @@ comptime {...@@ -23,7 +23,6 @@ comptime {
23 // Until then, we have simplified logic here for self-hosted. TODO remove this once23 // Until then, we have simplified logic here for self-hosted. TODO remove this once
24 // self-hosted is capable enough to handle all of the real start.zig logic.24 // self-hosted is capable enough to handle all of the real start.zig logic.
25 if (builtin.zig_backend == .stage2_wasm or25 if (builtin.zig_backend == .stage2_wasm or
26 builtin.zig_backend == .stage2_c or
27 builtin.zig_backend == .stage2_x86_64 or26 builtin.zig_backend == .stage2_x86_64 or
28 builtin.zig_backend == .stage2_x86 or27 builtin.zig_backend == .stage2_x86 or
29 builtin.zig_backend == .stage2_aarch64 or28 builtin.zig_backend == .stage2_aarch64 or
...@@ -265,75 +264,104 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv...@@ -265,75 +264,104 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv
265}264}
266265
267fn _start() callconv(.Naked) noreturn {266fn _start() callconv(.Naked) noreturn {
268 switch (native_arch) {267 switch (builtin.zig_backend) {
269 .x86_64 => {268 .stage2_c => {
270 argc_argv_ptr = asm volatile (269 @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" });
271 \\ xor %%rbp, %%rbp270 @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" });
272 : [argc] "={rsp}" (-> [*]usize),271 switch (native_arch) {
273 );272 .x86_64 => asm volatile (
274 },273 \\ xorl %%ebp, %%ebp
275 .i386 => {274 \\ movq %%rsp, argc_argv_ptr
276 argc_argv_ptr = asm volatile (275 \\ andq $-16, %%rsp
277 \\ xor %%ebp, %%ebp276 \\ call _posixCallMainAndExit
278 : [argc] "={esp}" (-> [*]usize),277 ),
279 );278 .i386 => asm volatile (
280 },279 \\ xorl %%ebp, %%ebp
281 .aarch64, .aarch64_be, .arm, .armeb, .thumb => {280 \\ movl %%esp, argc_argv_ptr
282 argc_argv_ptr = asm volatile (281 \\ andl $-16, %%esp
283 \\ mov fp, #0282 \\ jmp _posixCallMainAndExit
284 \\ mov lr, #0283 ),
285 : [argc] "={sp}" (-> [*]usize),284 .aarch64, .aarch64_be, .arm, .armeb, .thumb => asm volatile (
286 );285 \\ mov fp, #0
287 },286 \\ mov lr, #0
288 .riscv64 => {287 \\ str sp, argc_argv_ptr
289 argc_argv_ptr = asm volatile (288 \\ and sp, #-16
290 \\ li s0, 0289 \\ b _posixCallMainAndExit
291 \\ li ra, 0290 ),
292 : [argc] "={sp}" (-> [*]usize),291 else => @compileError("unsupported arch"),
293 );292 }
294 },293 unreachable;
295 .mips, .mipsel => {
296 // The lr is already zeroed on entry, as specified by the ABI.
297 argc_argv_ptr = asm volatile (
298 \\ move $fp, $0
299 : [argc] "={sp}" (-> [*]usize),
300 );
301 },
302 .powerpc => {
303 // Setup the initial stack frame and clear the back chain pointer.
304 argc_argv_ptr = asm volatile (
305 \\ mr 4, 1
306 \\ li 0, 0
307 \\ stwu 1,-16(1)
308 \\ stw 0, 0(1)
309 \\ mtlr 0
310 : [argc] "={r4}" (-> [*]usize),
311 :
312 : "r0"
313 );
314 },
315 .powerpc64le => {
316 // Setup the initial stack frame and clear the back chain pointer.
317 // TODO: Support powerpc64 (big endian) on ELFv2.
318 argc_argv_ptr = asm volatile (
319 \\ mr 4, 1
320 \\ li 0, 0
321 \\ stdu 0, -32(1)
322 \\ mtlr 0
323 : [argc] "={r4}" (-> [*]usize),
324 :
325 : "r0"
326 );
327 },294 },
328 .sparc64 => {295 else => switch (native_arch) {
329 // argc is stored after a register window (16 registers) plus stack bias296 .x86_64 => {
330 argc_argv_ptr = asm (297 argc_argv_ptr = asm volatile (
331 \\ mov %%g0, %%i6298 \\ xor %%ebp, %%ebp
332 \\ add %%o6, 2175, %[argc]299 : [argc] "={rsp}" (-> [*]usize),
333 : [argc] "=r" (-> [*]usize),300 );
334 );301 },
302 .i386 => {
303 argc_argv_ptr = asm volatile (
304 \\ xor %%ebp, %%ebp
305 : [argc] "={esp}" (-> [*]usize),
306 );
307 },
308 .aarch64, .aarch64_be, .arm, .armeb, .thumb => {
309 argc_argv_ptr = asm volatile (
310 \\ mov fp, #0
311 \\ mov lr, #0
312 : [argc] "={sp}" (-> [*]usize),
313 );
314 },
315 .riscv64 => {
316 argc_argv_ptr = asm volatile (
317 \\ li s0, 0
318 \\ li ra, 0
319 : [argc] "={sp}" (-> [*]usize),
320 );
321 },
322 .mips, .mipsel => {
323 // The lr is already zeroed on entry, as specified by the ABI.
324 argc_argv_ptr = asm volatile (
325 \\ move $fp, $0
326 : [argc] "={sp}" (-> [*]usize),
327 );
328 },
329 .powerpc => {
330 // Setup the initial stack frame and clear the back chain pointer.
331 argc_argv_ptr = asm volatile (
332 \\ mr 4, 1
333 \\ li 0, 0
334 \\ stwu 1,-16(1)
335 \\ stw 0, 0(1)
336 \\ mtlr 0
337 : [argc] "={r4}" (-> [*]usize),
338 :
339 : "r0"
340 );
341 },
342 .powerpc64le => {
343 // Setup the initial stack frame and clear the back chain pointer.
344 // TODO: Support powerpc64 (big endian) on ELFv2.
345 argc_argv_ptr = asm volatile (
346 \\ mr 4, 1
347 \\ li 0, 0
348 \\ stdu 0, -32(1)
349 \\ mtlr 0
350 : [argc] "={r4}" (-> [*]usize),
351 :
352 : "r0"
353 );
354 },
355 .sparc64 => {
356 // argc is stored after a register window (16 registers) plus stack bias
357 argc_argv_ptr = asm (
358 \\ mov %%g0, %%i6
359 \\ add %%o6, 2175, %[argc]
360 : [argc] "=r" (-> [*]usize),
361 );
362 },
363 else => @compileError("unsupported arch"),
335 },364 },
336 else => @compileError("unsupported arch"),
337 }365 }
338 // If LLVM inlines stack variables into _start, they will overwrite366 // If LLVM inlines stack variables into _start, they will overwrite
339 // the command line argument data.367 // the command line argument data.
...@@ -363,7 +391,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {...@@ -363,7 +391,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {
363 std.os.windows.kernel32.ExitProcess(@bitCast(std.os.windows.UINT, result));391 std.os.windows.kernel32.ExitProcess(@bitCast(std.os.windows.UINT, result));
364}392}
365393
366fn posixCallMainAndExit() noreturn {394fn posixCallMainAndExit() callconv(.C) noreturn {
367 @setAlignStack(16);395 @setAlignStack(16);
368396
369 const argc = argc_argv_ptr[0];397 const argc = argc_argv_ptr[0];
...@@ -462,7 +490,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {...@@ -462,7 +490,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
462 return initEventLoopAndCallMain();490 return initEventLoopAndCallMain();
463}491}
464492
465fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) i32 {493fn main(c_argc: c_int, c_argv: [*c][*c]u8, c_envp: [*c][*c]u8) callconv(.C) c_int {
466 var env_count: usize = 0;494 var env_count: usize = 0;
467 while (c_envp[env_count] != null) : (env_count += 1) {}495 while (c_envp[env_count] != null) : (env_count += 1) {}
468 const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count];496 const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count];
...@@ -474,11 +502,11 @@ fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C)...@@ -474,11 +502,11 @@ fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C)
474 expandStackSize(phdrs);502 expandStackSize(phdrs);
475 }503 }
476504
477 return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), c_argv, envp });505 return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), @ptrCast([*][*:0]u8, c_argv), envp });
478}506}
479507
480fn mainWithoutEnv(c_argc: i32, c_argv: [*][*:0]u8) callconv(.C) usize {508fn mainWithoutEnv(c_argc: c_int, c_argv: [*c][*c]u8) callconv(.C) c_int {
481 std.os.argv = c_argv[0..@intCast(usize, c_argc)];509 std.os.argv = @ptrCast([*][*:0]u8, c_argv)[0..@intCast(usize, c_argc)];
482 return @call(.{ .modifier = .always_inline }, callMain, .{});510 return @call(.{ .modifier = .always_inline }, callMain, .{});
483}511}
484512
lib/test_runner.zig+2-1
...@@ -8,7 +8,8 @@ var log_err_count: usize = 0;...@@ -8,7 +8,8 @@ var log_err_count: usize = 0;
88
9pub fn main() void {9pub fn main() void {
10 if (builtin.zig_backend != .stage1 and10 if (builtin.zig_backend != .stage1 and
11 (builtin.zig_backend != .stage2_llvm or builtin.cpu.arch == .wasm32))11 (builtin.zig_backend != .stage2_llvm or builtin.cpu.arch == .wasm32) and
12 builtin.zig_backend != .stage2_c)
12 {13 {
13 return main2() catch @panic("test failure");14 return main2() catch @panic("test failure");
14 }15 }
src/Compilation.zig+8-5
...@@ -3103,13 +3103,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3103,13 +3103,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3103 .decl_index = decl_index,3103 .decl_index = decl_index,
3104 .decl = decl,3104 .decl = decl,
3105 .fwd_decl = fwd_decl.toManaged(gpa),3105 .fwd_decl = fwd_decl.toManaged(gpa),
3106 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{3106 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{ .mod = module }),
3107 .mod = module,
3108 }),
3109 .typedefs_arena = typedefs_arena.allocator(),3107 .typedefs_arena = typedefs_arena.allocator(),
3110 };3108 };
3111 defer dg.fwd_decl.deinit();3109 defer {
3112 defer dg.typedefs.deinit();3110 for (dg.typedefs.values()) |typedef| {
3111 module.gpa.free(typedef.rendered);
3112 }
3113 dg.typedefs.deinit();
3114 dg.fwd_decl.deinit();
3115 }
31133116
3114 c_codegen.genHeader(&dg) catch |err| switch (err) {3117 c_codegen.genHeader(&dg) catch |err| switch (err) {
3115 error.AnalysisFail => {3118 error.AnalysisFail => {
src/codegen/c.zig+2694-1470
...@@ -18,8 +18,8 @@ const Air = @import("../Air.zig");...@@ -18,8 +18,8 @@ const Air = @import("../Air.zig");
18const Liveness = @import("../Liveness.zig");18const Liveness = @import("../Liveness.zig");
19const CType = @import("../type.zig").CType;19const CType = @import("../type.zig").CType;
2020
21const Mutability = enum { Const, Mut };21const Mutability = enum { Const, ConstArgument, Mut };
22const BigIntConst = std.math.big.int.Const;22const BigInt = std.math.big.int;
2323
24pub const CValue = union(enum) {24pub const CValue = union(enum) {
25 none: void,25 none: void,
...@@ -34,8 +34,8 @@ pub const CValue = union(enum) {...@@ -34,8 +34,8 @@ pub const CValue = union(enum) {
34 /// By-value34 /// By-value
35 decl: Decl.Index,35 decl: Decl.Index,
36 decl_ref: Decl.Index,36 decl_ref: Decl.Index,
37 /// An undefined (void *) pointer (cannot be dereferenced)37 /// An undefined value (cannot be dereferenced)
38 undefined_ptr: void,38 undef: Type,
39 /// Render the slice as an identifier (using fmtIdent)39 /// Render the slice as an identifier (using fmtIdent)
40 identifier: []const u8,40 identifier: []const u8,
41 /// Render these bytes literally.41 /// Render these bytes literally.
...@@ -48,6 +48,11 @@ const BlockData = struct {...@@ -48,6 +48,11 @@ const BlockData = struct {
48 result: CValue,48 result: CValue,
49};49};
5050
51const TypedefKind = enum {
52 Forward,
53 Complete,
54};
55
51pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);56pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);
52pub const TypedefMap = std.ArrayHashMap(57pub const TypedefMap = std.ArrayHashMap(
53 Type,58 Type,
...@@ -63,9 +68,16 @@ const FormatTypeAsCIdentContext = struct {...@@ -63,9 +68,16 @@ const FormatTypeAsCIdentContext = struct {
6368
64const ValueRenderLocation = enum {69const ValueRenderLocation = enum {
65 FunctionArgument,70 FunctionArgument,
71 Initializer,
66 Other,72 Other,
67};73};
6874
75const BuiltinInfo = enum {
76 None,
77 Range,
78 Bits,
79};
80
69/// TODO make this not cut off at 128 bytes81/// TODO make this not cut off at 128 bytes
70fn formatTypeAsCIdentifier(82fn formatTypeAsCIdentifier(
71 data: FormatTypeAsCIdentContext,83 data: FormatTypeAsCIdentContext,
...@@ -73,11 +85,11 @@ fn formatTypeAsCIdentifier(...@@ -73,11 +85,11 @@ fn formatTypeAsCIdentifier(
73 options: std.fmt.FormatOptions,85 options: std.fmt.FormatOptions,
74 writer: anytype,86 writer: anytype,
75) !void {87) !void {
76 _ = fmt;88 var stack = std.heap.stackFallback(128, data.mod.gpa);
77 _ = options;89 const allocator = stack.get();
78 var buffer = [1]u8{0} ** 128;90 const str = std.fmt.allocPrint(allocator, "{}", .{data.ty.fmt(data.mod)}) catch "";
79 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.mod)}) catch &buffer;91 defer allocator.free(str);
80 return formatIdent(buf, "", .{}, writer);92 return formatIdent(str, fmt, options, writer);
81}93}
8294
83pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) {95pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) {
...@@ -88,23 +100,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC...@@ -88,23 +100,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC
88}100}
89101
90const reserved_idents = std.ComptimeStringMap(void, .{102const reserved_idents = std.ComptimeStringMap(void, .{
91 .{ "_Alignas", {103 .{ "alignas", {
92 @setEvalBranchQuota(4000);104 @setEvalBranchQuota(4000);
93 } },105 } },
94 .{ "_Alignof", {} },
95 .{ "_Atomic", {} },
96 .{ "_Bool", {} },
97 .{ "_Complex", {} },
98 .{ "_Decimal128", {} },
99 .{ "_Decimal32", {} },
100 .{ "_Decimal64", {} },
101 .{ "_Generic", {} },
102 .{ "_Imaginary", {} },
103 .{ "_Noreturn", {} },
104 .{ "_Pragma", {} },
105 .{ "_Static_assert", {} },
106 .{ "_Thread_local", {} },
107 .{ "alignas", {} },
108 .{ "alignof", {} },106 .{ "alignof", {} },
109 .{ "asm", {} },107 .{ "asm", {} },
110 .{ "atomic_bool", {} },108 .{ "atomic_bool", {} },
...@@ -199,6 +197,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{...@@ -199,6 +197,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{
199 .{ "while ", {} },197 .{ "while ", {} },
200});198});
201199
200fn isReservedIdent(ident: []const u8) bool {
201 if (ident.len >= 2 and ident[0] == '_') {
202 switch (ident[1]) {
203 'A'...'Z', '_' => return true,
204 else => return false,
205 }
206 } else return reserved_idents.has(ident);
207}
208
202fn formatIdent(209fn formatIdent(
203 ident: []const u8,210 ident: []const u8,
204 comptime fmt: []const u8,211 comptime fmt: []const u8,
...@@ -207,7 +214,7 @@ fn formatIdent(...@@ -207,7 +214,7 @@ fn formatIdent(
207) !void {214) !void {
208 _ = options;215 _ = options;
209 const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.216 const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
210 if (solo and reserved_idents.has(ident)) {217 if (solo and isReservedIdent(ident)) {
211 try writer.writeAll("zig_e_");218 try writer.writeAll("zig_e_");
212 }219 }
213 for (ident) |c, i| {220 for (ident) |c, i| {
...@@ -247,30 +254,27 @@ pub const Function = struct {...@@ -247,30 +254,27 @@ pub const Function = struct {
247254
248 const val = f.air.value(inst).?;255 const val = f.air.value(inst).?;
249 const ty = f.air.typeOf(inst);256 const ty = f.air.typeOf(inst);
250 switch (ty.zigTypeTag()) {257
251 .Array => {258 const result = if (lowersToArray(ty, f.object.dg.module.getTarget())) result: {
252 const writer = f.object.code_header.writer();259 const writer = f.object.code_header.writer();
253 const decl_c_value = f.allocLocalValue();260 const decl_c_value = f.allocLocalValue();
254 gop.value_ptr.* = decl_c_value;261 try writer.writeAll("static ");
255 try writer.writeAll("static ");262 try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const, 0, .Complete);
256 try f.object.dg.renderTypeAndName(263 try writer.writeAll(" = ");
257 writer,264 try f.object.dg.renderValue(writer, ty, val, .Initializer);
258 ty,265 try writer.writeAll(";\n ");
259 decl_c_value,266 break :result decl_c_value;
260 .Const,267 } else CValue{ .constant = inst };
261 0,268
262 );269 gop.value_ptr.* = result;
263 try writer.writeAll(" = ");270 return result;
264 try f.object.dg.renderValue(writer, ty, val, .Other);271 }
265 try writer.writeAll(";\n ");272
266 return decl_c_value;273 fn wantSafety(f: *Function) bool {
267 },274 return switch (f.object.dg.module.optimizeMode()) {
268 else => {275 .Debug, .ReleaseSafe => true,
269 const result = CValue{ .constant = inst };276 .ReleaseFast, .ReleaseSmall => false,
270 gop.value_ptr.* = result;277 };
271 return result;
272 },
273 }
274 }278 }
275279
276 fn allocLocalValue(f: *Function) CValue {280 fn allocLocalValue(f: *Function) CValue {
...@@ -291,17 +295,19 @@ pub const Function = struct {...@@ -291,17 +295,19 @@ pub const Function = struct {
291 local_value,295 local_value,
292 mutability,296 mutability,
293 alignment,297 alignment,
298 .Complete,
294 );299 );
295 return local_value;300 return local_value;
296 }301 }
297302
298 fn writeCValue(f: *Function, w: anytype, c_value: CValue) !void {303 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
299 switch (c_value) {304 switch (c_value) {
300 .constant => |inst| {305 .constant => |inst| {
301 const ty = f.air.typeOf(inst);306 const ty = f.air.typeOf(inst);
302 const val = f.air.value(inst).?;307 const val = f.air.value(inst).?;
303 return f.object.dg.renderValue(w, ty, val, .Other);308 return f.object.dg.renderValue(w, ty, val, location);
304 },309 },
310 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
305 else => return f.object.dg.writeCValue(w, c_value),311 else => return f.object.dg.writeCValue(w, c_value),
306 }312 }
307 }313 }
...@@ -319,17 +325,48 @@ pub const Function = struct {...@@ -319,17 +325,48 @@ pub const Function = struct {
319 }325 }
320 }326 }
321327
328 fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
329 switch (c_value) {
330 .constant => |inst| {
331 const ty = f.air.typeOf(inst);
332 const val = f.air.value(inst).?;
333 try f.object.dg.renderValue(w, ty, val, .Other);
334 try w.writeByte('.');
335 return f.writeCValue(w, member, .Other);
336 },
337 else => return f.object.dg.writeCValueMember(w, c_value, member),
338 }
339 }
340
341 fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
342 switch (c_value) {
343 .constant => |inst| {
344 const ty = f.air.typeOf(inst);
345 const val = f.air.value(inst).?;
346 try w.writeByte('(');
347 try f.object.dg.renderValue(w, ty, val, .Other);
348 try w.writeAll(")->");
349 return f.writeCValue(w, member, .Other);
350 },
351 else => return f.object.dg.writeCValueDerefMember(w, c_value, member),
352 }
353 }
354
322 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {355 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
323 return f.object.dg.fail(format, args);356 return f.object.dg.fail(format, args);
324 }357 }
325358
326 fn renderType(f: *Function, w: anytype, t: Type) !void {359 fn renderType(f: *Function, w: anytype, t: Type) !void {
327 return f.object.dg.renderType(w, t);360 return f.object.dg.renderType(w, t, .Complete);
328 }361 }
329362
330 fn renderTypecast(f: *Function, w: anytype, t: Type) !void {363 fn renderTypecast(f: *Function, w: anytype, t: Type) !void {
331 return f.object.dg.renderTypecast(w, t);364 return f.object.dg.renderTypecast(w, t);
332 }365 }
366
367 fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
368 return f.object.dg.fmtIntLiteral(ty, val);
369 }
333};370};
334371
335/// This data is available when outputting .c code for a `Module`.372/// This data is available when outputting .c code for a `Module`.
...@@ -362,13 +399,13 @@ pub const DeclGen = struct {...@@ -362,13 +399,13 @@ pub const DeclGen = struct {
362 @setCold(true);399 @setCold(true);
363 const src = LazySrcLoc.nodeOffset(0);400 const src = LazySrcLoc.nodeOffset(0);
364 const src_loc = src.toSrcLoc(dg.decl);401 const src_loc = src.toSrcLoc(dg.decl);
365 dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args);402 dg.error_msg = try Module.ErrorMsg.create(dg.gpa, src_loc, format, args);
366 return error.AnalysisFail;403 return error.AnalysisFail;
367 }404 }
368405
369 fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 {406 fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 {
370 if (dg.typedefs.get(t)) |some| {407 if (dg.typedefs.get(t)) |typedef| {
371 return some.name;408 return typedef.name;
372 } else {409 } else {
373 return null;410 return null;
374 }411 }
...@@ -381,86 +418,49 @@ pub const DeclGen = struct {...@@ -381,86 +418,49 @@ pub const DeclGen = struct {
381 val: Value,418 val: Value,
382 decl_index: Decl.Index,419 decl_index: Decl.Index,
383 ) error{ OutOfMemory, AnalysisFail }!void {420 ) error{ OutOfMemory, AnalysisFail }!void {
421 const decl = dg.module.declPtr(decl_index);
422 assert(decl.has_tv);
423
424 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
425 if (ty.isPtrAtRuntime() and !decl.ty.isFnOrHasRuntimeBits()) {
426 return dg.writeCValue(writer, CValue{ .undef = ty });
427 }
428
429 // Chase function values in order to be able to reference the original function.
430 inline for (.{ .function, .extern_fn }) |tag|
431 if (decl.val.castTag(tag)) |func|
432 if (func.data.owner_decl != decl_index)
433 return dg.renderDeclValue(writer, ty, val, func.data.owner_decl);
434
384 if (ty.isSlice()) {435 if (ty.isSlice()) {
385 try writer.writeByte('(');436 try writer.writeByte('(');
386 try dg.renderTypecast(writer, ty);437 try dg.renderTypecast(writer, ty);
387 try writer.writeAll("){");438 try writer.writeAll("){ .ptr = ");
439
388 var buf: Type.SlicePtrFieldTypeBuffer = undefined;440 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
389 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other);441 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer);
390 try writer.writeAll(", ");442
391 try writer.print("{d}", .{val.sliceLen(dg.module)});443 var len_pl: Value.Payload.U64 = .{
392 try writer.writeAll("}");444 .base = .{ .tag = .int_u64 },
393 return;445 .data = val.sliceLen(dg.module),
446 };
447 const len_val = Value.initPayload(&len_pl.base);
448 return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)});
394 }449 }
395450
396 const decl = dg.module.declPtr(decl_index);
397 assert(decl.has_tv);
398 // We shouldn't cast C function pointers as this is UB (when you call451 // We shouldn't cast C function pointers as this is UB (when you call
399 // them). The analysis until now should ensure that the C function452 // them). The analysis until now should ensure that the C function
400 // pointers are compatible. If they are not, then there is a bug453 // pointers are compatible. If they are not, then there is a bug
401 // somewhere and we should let the C compiler tell us about it.454 // somewhere and we should let the C compiler tell us about it.
402 if (ty.castPtrToFn() == null) {455 const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module);
403 // Determine if we must pointer cast.456 if (need_typecast) {
404 if (ty.eql(decl.ty, dg.module)) {
405 try writer.writeByte('&');
406 try dg.renderDeclName(writer, decl_index);
407 return;
408 }
409
410 try writer.writeAll("((");457 try writer.writeAll("((");
411 try dg.renderTypecast(writer, ty);458 try dg.renderTypecast(writer, ty);
412 try writer.writeAll(")&");
413 try dg.renderDeclName(writer, decl_index);
414 try writer.writeByte(')');459 try writer.writeByte(')');
415 return;
416 }460 }
417461 try writer.writeByte('&');
418 try dg.renderDeclName(writer, decl_index);462 try dg.renderDeclName(writer, decl_index);
419 }463 if (need_typecast) try writer.writeByte(')');
420
421 fn renderInt128(
422 writer: anytype,
423 int_val: anytype,
424 ) error{ OutOfMemory, AnalysisFail }!void {
425 const int_info = @typeInfo(@TypeOf(int_val)).Int;
426 const is_signed = int_info.signedness == .signed;
427 const is_neg = int_val < 0;
428 comptime assert(int_info.bits > 64 and int_info.bits <= 128);
429
430 // Clang and GCC don't support 128-bit integer constants but will hopefully unfold them
431 // if we construct one manually.
432 const magnitude = std.math.absCast(int_val);
433
434 const high = @truncate(u64, magnitude >> 64);
435 const low = @truncate(u64, magnitude);
436
437 // (int128_t)/<->( ( (uint128_t)( val_high << 64 )u ) + (uint128_t)val_low/u )
438 if (is_signed) try writer.writeAll("(int128_t)");
439 if (is_neg) try writer.writeByte('-');
440
441 try writer.print("(((uint128_t)0x{x}u<<64)", .{high});
442
443 if (low > 0)
444 try writer.print("+(uint128_t)0x{x}u", .{low});
445
446 return writer.writeByte(')');
447 }
448
449 fn renderBigIntConst(
450 dg: *DeclGen,
451 writer: anytype,
452 val: BigIntConst,
453 signed: bool,
454 ) error{ OutOfMemory, AnalysisFail }!void {
455 if (signed) {
456 try renderInt128(writer, val.to(i128) catch {
457 return dg.fail("TODO implement integer constants larger than 128 bits", .{});
458 });
459 } else {
460 try renderInt128(writer, val.to(u128) catch {
461 return dg.fail("TODO implement integer constants larger than 128 bits", .{});
462 });
463 }
464 }464 }
465465
466 // Renders a "parent" pointer by recursing to the root decl/variable466 // Renders a "parent" pointer by recursing to the root decl/variable
...@@ -468,9 +468,11 @@ pub const DeclGen = struct {...@@ -468,9 +468,11 @@ pub const DeclGen = struct {
468 //468 //
469 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr469 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr
470 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type) error{ OutOfMemory, AnalysisFail }!void {470 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type) error{ OutOfMemory, AnalysisFail }!void {
471 try writer.writeByte('(');471 if (!ptr_ty.isSlice()) {
472 try dg.renderTypecast(writer, ptr_ty);472 try writer.writeByte('(');
473 try writer.writeByte(')');473 try dg.renderTypecast(writer, ptr_ty);
474 try writer.writeByte(')');
475 }
474 switch (ptr_val.tag()) {476 switch (ptr_val.tag()) {
475 .decl_ref_mut, .decl_ref, .variable => {477 .decl_ref_mut, .decl_ref, .variable => {
476 const decl_index = switch (ptr_val.tag()) {478 const decl_index = switch (ptr_val.tag()) {
...@@ -482,43 +484,80 @@ pub const DeclGen = struct {...@@ -482,43 +484,80 @@ pub const DeclGen = struct {
482 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index);484 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index);
483 },485 },
484 .field_ptr => {486 .field_ptr => {
487 const ptr_info = ptr_ty.ptrInfo();
485 const field_ptr = ptr_val.castTag(.field_ptr).?.data;488 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
486 const container_ty = field_ptr.container_ty;489 const container_ty = field_ptr.container_ty;
487 const index = field_ptr.field_index;490 const index = field_ptr.field_index;
491
492 var container_ptr_ty_pl: Type.Payload.ElemType = .{
493 .base = .{ .tag = .c_mut_pointer },
494 .data = field_ptr.container_ty,
495 };
496 const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base);
497
488 const FieldInfo = struct { name: []const u8, ty: Type };498 const FieldInfo = struct { name: []const u8, ty: Type };
489 const field_info: FieldInfo = switch (container_ty.zigTypeTag()) {499 const field_info: FieldInfo = switch (container_ty.zigTypeTag()) {
490 .Struct => .{500 .Struct => switch (container_ty.containerLayout()) {
491 .name = container_ty.structFields().keys()[index],501 .Auto, .Extern => FieldInfo{
492 .ty = container_ty.structFields().values()[index].ty,502 .name = container_ty.structFields().keys()[index],
503 .ty = container_ty.structFields().values()[index].ty,
504 },
505 .Packed => if (ptr_info.data.host_size == 0) {
506 const target = dg.module.getTarget();
507
508 const byte_offset = container_ty.packedStructFieldByteOffset(index, target);
509 var byte_offset_pl = Value.Payload.U64{
510 .base = .{ .tag = .int_u64 },
511 .data = byte_offset,
512 };
513 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
514
515 var u8_ptr_pl = ptr_info;
516 u8_ptr_pl.data.pointee_type = Type.u8;
517 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
518
519 try writer.writeAll("&((");
520 try dg.renderTypecast(writer, u8_ptr_ty);
521 try writer.writeByte(')');
522 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
523 return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)});
524 } else {
525 var host_pl = Type.Payload.Bits{
526 .base = .{ .tag = .int_unsigned },
527 .data = ptr_info.data.host_size * 8,
528 };
529 const host_ty = Type.initPayload(&host_pl.base);
530
531 try writer.writeByte('(');
532 try dg.renderTypecast(writer, ptr_ty);
533 try writer.writeByte(')');
534 return dg.renderParentPtr(writer, field_ptr.container_ptr, host_ty);
535 },
493 },536 },
494 .Union => .{537 .Union => FieldInfo{
495 .name = container_ty.unionFields().keys()[index],538 .name = container_ty.unionFields().keys()[index],
496 .ty = container_ty.unionFields().values()[index].ty,539 .ty = container_ty.unionFields().values()[index].ty,
497 },540 },
498 .Pointer => switch (container_ty.ptrSize()) {541 .Pointer => field_info: {
499 .Slice => switch (index) {542 assert(container_ty.isSlice());
543 break :field_info switch (index) {
500 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() },544 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() },
501 1 => FieldInfo{ .name = "len", .ty = Type.usize },545 1 => FieldInfo{ .name = "len", .ty = Type.usize },
502 else => unreachable,546 else => unreachable,
503 },547 };
504 else => unreachable,
505 },548 },
506 else => unreachable,549 else => unreachable,
507 };550 };
508 var container_ptr_ty_pl: Type.Payload.ElemType = .{
509 .base = .{ .tag = .c_mut_pointer },
510 .data = field_ptr.container_ty,
511 };
512 const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base);
513551
514 if (field_info.ty.hasRuntimeBitsIgnoreComptime()) {552 if (field_info.ty.hasRuntimeBitsIgnoreComptime()) {
515 try writer.writeAll("&(");553 try writer.writeAll("&(");
516 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);554 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
517 if (field_ptr.container_ty.tag() == .union_tagged or field_ptr.container_ty.tag() == .union_safety_tagged) {555 try writer.writeAll(")->");
518 try writer.print(")->payload.{ }", .{fmtIdent(field_info.name)});556 switch (field_ptr.container_ty.tag()) {
519 } else {557 .union_tagged, .union_safety_tagged => try writer.writeAll("payload."),
520 try writer.print(")->{ }", .{fmtIdent(field_info.name)});558 else => {},
521 }559 }
560 try writer.print("{ }", .{fmtIdent(field_info.name)});
522 } else {561 } else {
523 try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty);562 try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty);
524 }563 }
...@@ -565,49 +604,162 @@ pub const DeclGen = struct {...@@ -565,49 +604,162 @@ pub const DeclGen = struct {
565 const target = dg.module.getTarget();604 const target = dg.module.getTarget();
566 if (val.isUndefDeep()) {605 if (val.isUndefDeep()) {
567 switch (ty.zigTypeTag()) {606 switch (ty.zigTypeTag()) {
568 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)607 // bool b = 0xaa; evals to true, but memcpy(&b, 0xaa, 1); evals to false.
569 // with 'error: expected expression' (including when built with 'zig cc')608 .Bool => return dg.renderValue(writer, ty, Value.@"false", location),
570 .Int => {609 .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val)}),
571 const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse610 .Float => {
572 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});611 try writer.writeByte('(');
573 switch (c_bits) {612 try dg.renderTypecast(writer, ty);
574 8 => return writer.writeAll("0xaau"),613 try writer.writeAll(")zig_suffix_");
575 16 => return writer.writeAll("0xaaaau"),614 try dg.renderTypeForBuiltinFnName(writer, ty);
576 32 => return writer.writeAll("0xaaaaaaaau"),615 try writer.writeByte('(');
577 64 => return writer.writeAll("0xaaaaaaaaaaaaaaaau"),616 switch (ty.floatBits(target)) {
578 128 => return renderInt128(writer, @as(u128, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),617 16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(u16))}),
618 32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(u32))}),
619 64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}),
620 80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(u80))}),
621 128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(u128))}),
579 else => unreachable,622 else => unreachable,
580 }623 }
624 return writer.writeByte(')');
581 },625 },
582 .Float => {626 .Pointer => if (ty.isSlice()) {
583 switch (ty.floatBits(dg.module.getTarget())) {627 if (location != .Initializer) {
584 32 => return writer.writeAll("zig_bitcast_f32_u32(0xaaaaaaaau)"),628 try writer.writeByte('(');
585 64 => return writer.writeAll("zig_bitcast_f64_u64(0xaaaaaaaaaaaaaaaau)"),629 try dg.renderTypecast(writer, ty);
586 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),630 try writer.writeByte(')');
587 }631 }
632
633 try writer.writeAll("{(");
634 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
635 const ptr_ty = ty.slicePtrFieldType(&buf);
636 try dg.renderTypecast(writer, ptr_ty);
637 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)});
638 } else {
639 try writer.writeAll("((");
640 try dg.renderTypecast(writer, ty);
641 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
588 },642 },
589 .Pointer => switch (dg.module.getTarget().cpu.arch.ptrBitWidth()) {643 .Optional => {
590 32 => return writer.writeAll("(void *)0xaaaaaaaa"),644 var opt_buf: Type.Payload.ElemType = undefined;
591 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaa"),645 const payload_ty = ty.optionalChild(&opt_buf);
592 else => unreachable,646
647 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
648 return dg.renderValue(writer, Type.bool, val, location);
649 }
650
651 if (ty.optionalReprIsPayload()) {
652 return dg.renderValue(writer, payload_ty, val, location);
653 }
654
655 if (location != .Initializer) {
656 try writer.writeByte('(');
657 try dg.renderTypecast(writer, ty);
658 try writer.writeByte(')');
659 }
660
661 try writer.writeAll("{ .payload = ");
662 try dg.renderValue(writer, payload_ty, val, .Initializer);
663 try writer.writeAll(", .is_null = ");
664 try dg.renderValue(writer, Type.bool, val, .Initializer);
665 return writer.writeAll(" }");
593 },666 },
594 .Struct, .ErrorUnion => {667 .Struct => switch (ty.containerLayout()) {
595 try writer.writeByte('(');668 .Auto, .Extern => {
596 try dg.renderTypecast(writer, ty);669 if (location != .Initializer) {
597 return writer.writeAll("){0xaa}");670 try writer.writeByte('(');
671 try dg.renderTypecast(writer, ty);
672 try writer.writeByte(')');
673 }
674
675 try writer.writeByte('{');
676 var empty = true;
677 for (ty.structFields().values()) |field| {
678 if (!field.ty.hasRuntimeBits()) continue;
679
680 if (!empty) try writer.writeByte(',');
681 try dg.renderValue(writer, field.ty, val, .Initializer);
682
683 empty = false;
684 }
685 if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
686 return writer.writeByte('}');
687 },
688 .Packed => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, Value.undef)}),
689 },
690 .Union => {
691 if (location != .Initializer) {
692 try writer.writeByte('(');
693 try dg.renderTypecast(writer, ty);
694 try writer.writeByte(')');
695 }
696
697 try writer.writeByte('{');
698 if (ty.unionTagTypeSafety()) |tag_ty| {
699 try writer.writeAll(" .tag = ");
700 try dg.renderValue(writer, tag_ty, val, .Initializer);
701 try writer.writeAll(", .payload = {");
702 }
703 for (ty.unionFields().values()) |field| {
704 if (!field.ty.hasRuntimeBits()) continue;
705 try dg.renderValue(writer, field.ty, val, .Initializer);
706 break;
707 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
708 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
709 return writer.writeByte('}');
710 },
711 .ErrorUnion => {
712 if (location != .Initializer) {
713 try writer.writeByte('(');
714 try dg.renderTypecast(writer, ty);
715 try writer.writeByte(')');
716 }
717
718 try writer.writeAll("{ .payload = ");
719 try dg.renderValue(writer, ty.errorUnionPayload(), val, .Initializer);
720 return writer.print(", .error = {x} }}", .{
721 try dg.fmtIntLiteral(ty.errorUnionSet(), val),
722 });
598 },723 },
599 else => {724 .Array => {
600 // This should lower to 0xaa bytes in safe modes, and for unsafe modes should725 if (location != .Initializer) {
601 // lower to leaving variables uninitialized (that might need to be implemented726 try writer.writeByte('(');
602 // outside of this function).727 try dg.renderTypecast(writer, ty);
603 return writer.writeAll("{}");728 try writer.writeByte(')');
729 }
730
731 try writer.writeByte('{');
732 const c_len = ty.arrayLenIncludingSentinel();
733 var index: usize = 0;
734 while (index < c_len) : (index += 1) {
735 if (index > 0) try writer.writeAll(", ");
736 try dg.renderValue(writer, ty.childType(), val, .Initializer);
737 }
738 return writer.writeByte('}');
604 },739 },
740 .ComptimeInt,
741 .ComptimeFloat,
742 .Type,
743 .EnumLiteral,
744 .Void,
745 .NoReturn,
746 .Undefined,
747 .Null,
748 .BoundFn,
749 .Opaque,
750 => unreachable,
751 .Fn,
752 .Frame,
753 .AnyFrame,
754 .Vector,
755 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
756 @tagName(tag),
757 }),
605 }758 }
759 unreachable;
606 }760 }
607 switch (ty.zigTypeTag()) {761 switch (ty.zigTypeTag()) {
608 .Int => switch (val.tag()) {762 .Int => switch (val.tag()) {
609 .int_big_positive => try dg.renderBigIntConst(writer, val.castTag(.int_big_positive).?.asBigInt(), ty.isSignedInt()),
610 .int_big_negative => try dg.renderBigIntConst(writer, val.castTag(.int_big_negative).?.asBigInt(), true),
611 .field_ptr,763 .field_ptr,
612 .elem_ptr,764 .elem_ptr,
613 .opt_payload_ptr,765 .opt_payload_ptr,
...@@ -615,48 +767,86 @@ pub const DeclGen = struct {...@@ -615,48 +767,86 @@ pub const DeclGen = struct {
615 .decl_ref_mut,767 .decl_ref_mut,
616 .decl_ref,768 .decl_ref,
617 => try dg.renderParentPtr(writer, val, ty),769 => try dg.renderParentPtr(writer, val, ty),
618 else => {770 else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val)}),
619 if (ty.isSignedInt())
620 return writer.print("{d}", .{val.toSignedInt()});
621 return writer.print("{d}u", .{val.toUnsignedInt(target)});
622 },
623 },771 },
624 .Float => {772 .Float => {
625 if (ty.floatBits(dg.module.getTarget()) <= 64) {773 try writer.writeByte('(');
626 if (std.math.isNan(val.toFloat(f64)) or std.math.isInf(val.toFloat(f64))) {774 try dg.renderTypecast(writer, ty);
627 // just generate a bit cast (exactly like we do in airBitcast)775 try writer.writeByte(')');
628 switch (ty.tag()) {776 const f128_val = val.toFloat(f128);
629 .f32 => return writer.print("zig_bitcast_f32_u32(0x{x})", .{@bitCast(u32, val.toFloat(f32))}),777 if (std.math.signbit(f128_val)) try writer.writeByte('-');
630 .f64 => return writer.print("zig_bitcast_f64_u64(0x{x})", .{@bitCast(u64, val.toFloat(f64))}),778 if (std.math.isFinite(f128_val)) {
631 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),779 try writer.writeAll("zig_suffix_");
632 }780 try dg.renderTypeForBuiltinFnName(writer, ty);
633 } else {781 try writer.writeByte('(');
634 return writer.print("{x}", .{val.toFloat(f64)});782 switch (ty.floatBits(target)) {
783 16 => try writer.print("{x}", .{@fabs(val.toFloat(f16))}),
784 32 => try writer.print("{x}", .{@fabs(val.toFloat(f32))}),
785 64 => try writer.print("{x}", .{@fabs(val.toFloat(f64))}),
786 80 => try writer.print("{x}", .{@fabs(val.toFloat(f80))}),
787 128 => try writer.print("{x}", .{@fabs(f128_val)}),
788 else => unreachable,
635 }789 }
790 } else {
791 const operation = if (std.math.isSignalNan(f128_val))
792 "nans"
793 else if (std.math.isNan(f128_val))
794 "nan"
795 else if (std.math.isInf(f128_val))
796 "inf"
797 else
798 unreachable;
799 try writer.writeAll("zig_builtin_constant_");
800 try dg.renderTypeForBuiltinFnName(writer, ty);
801 try writer.writeByte('(');
802 try writer.writeAll(operation);
803 try writer.writeAll(")(");
804 if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) {
805 // We only actually need to pass the significand, but it will get
806 // properly masked anyway, so just pass the whole value.
807 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, @fabs(val.toFloat(f16)))}),
808 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, @fabs(val.toFloat(f32)))}),
809 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, @fabs(val.toFloat(f64)))}),
810 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, @fabs(val.toFloat(f80)))}),
811 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, @fabs(f128_val))}),
812 else => unreachable,
813 };
636 }814 }
637 return dg.fail("TODO: C backend: implement lowering large float values", .{});815 return writer.writeByte(')');
638 },816 },
639 .Pointer => switch (val.tag()) {817 .Pointer => switch (val.tag()) {
640 .null_value => try writer.writeAll("NULL"),818 .null_value, .zero => if (ty.isSlice()) {
641 // Technically this should produce NULL but the integer literal 0 will always coerce819 var slice_pl = Value.Payload.Slice{
642 // to the assigned pointer type. Note this is just a hack to fix warnings from ordered comparisons (<, >, etc)820 .base = .{ .tag = .slice },
643 // between pointers and 0, which is an extension to begin with.821 .data = .{ .ptr = val, .len = Value.undef },
644 .zero => try writer.writeByte('0'),822 };
823 const slice_val = Value.initPayload(&slice_pl.base);
824
825 return dg.renderValue(writer, ty, slice_val, location);
826 } else {
827 try writer.writeAll("((");
828 try dg.renderTypecast(writer, ty);
829 try writer.writeAll(")NULL)");
830 },
645 .variable => {831 .variable => {
646 const decl = val.castTag(.variable).?.data.owner_decl;832 const decl = val.castTag(.variable).?.data.owner_decl;
647 return dg.renderDeclValue(writer, ty, val, decl);833 return dg.renderDeclValue(writer, ty, val, decl);
648 },834 },
649 .slice => {835 .slice => {
836 if (location != .Initializer) {
837 try writer.writeByte('(');
838 try dg.renderTypecast(writer, ty);
839 try writer.writeByte(')');
840 }
841
650 const slice = val.castTag(.slice).?.data;842 const slice = val.castTag(.slice).?.data;
651 var buf: Type.SlicePtrFieldTypeBuffer = undefined;843 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
652844
653 try writer.writeByte('(');845 try writer.writeByte('{');
654 try dg.renderTypecast(writer, ty);846 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, .Initializer);
655 try writer.writeAll("){");
656 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location);
657 try writer.writeAll(", ");847 try writer.writeAll(", ");
658 try dg.renderValue(writer, Type.usize, slice.len, location);848 try dg.renderValue(writer, Type.usize, slice.len, .Initializer);
659 try writer.writeAll("}");849 try writer.writeByte('}');
660 },850 },
661 .function => {851 .function => {
662 const func = val.castTag(.function).?.data;852 const func = val.castTag(.function).?.data;
...@@ -669,7 +859,7 @@ pub const DeclGen = struct {...@@ -669,7 +859,7 @@ pub const DeclGen = struct {
669 .int_u64, .one => {859 .int_u64, .one => {
670 try writer.writeAll("((");860 try writer.writeAll("((");
671 try dg.renderTypecast(writer, ty);861 try dg.renderTypecast(writer, ty);
672 try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)});862 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
673 },863 },
674 .field_ptr,864 .field_ptr,
675 .elem_ptr,865 .elem_ptr,
...@@ -681,111 +871,106 @@ pub const DeclGen = struct {...@@ -681,111 +871,106 @@ pub const DeclGen = struct {
681 else => unreachable,871 else => unreachable,
682 },872 },
683 .Array => {873 .Array => {
874 if (location == .FunctionArgument) {
875 try writer.writeByte('(');
876 try dg.renderTypecast(writer, ty);
877 try writer.writeByte(')');
878 }
879
684 // First try specific tag representations for more efficiency.880 // First try specific tag representations for more efficiency.
685 switch (val.tag()) {881 switch (val.tag()) {
686 .undef, .empty_struct_value, .empty_array => {882 .undef, .empty_struct_value, .empty_array => {
687 try writer.writeByte('{');883 try writer.writeByte('{');
688 const ai = ty.arrayInfo();884 const ai = ty.arrayInfo();
689 if (ai.sentinel) |s| {885 if (ai.sentinel) |s| {
690 try dg.renderValue(writer, ai.elem_type, s, location);886 try dg.renderValue(writer, ai.elem_type, s, .Initializer);
887 } else {
888 try writer.writeByte('0');
691 }889 }
692 try writer.writeByte('}');890 try writer.writeByte('}');
693 },891 },
694 else => {892 else => {
695 // Fall back to generic implementation.893 // Fall back to generic implementation.
696 var arena = std.heap.ArenaAllocator.init(dg.module.gpa);894 var arena = std.heap.ArenaAllocator.init(dg.gpa);
697 defer arena.deinit();895 defer arena.deinit();
698 const arena_allocator = arena.allocator();896 const arena_allocator = arena.allocator();
699897
700 if (location == .FunctionArgument) {
701 try writer.writeByte('(');
702 try dg.renderTypecast(writer, ty);
703 try writer.writeByte(')');
704 }
705
706 try writer.writeByte('{');898 try writer.writeByte('{');
707 const ai = ty.arrayInfo();899 const ai = ty.arrayInfo();
708 var index: usize = 0;900 var index: usize = 0;
709 while (index < ai.len) : (index += 1) {901 while (index < ai.len) : (index += 1) {
710 if (index != 0) try writer.writeAll(",");902 if (index != 0) try writer.writeByte(',');
711 const elem_val = try val.elemValue(dg.module, arena_allocator, index);903 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
712 try dg.renderValue(writer, ai.elem_type, elem_val, .Other);904 try dg.renderValue(writer, ai.elem_type, elem_val, .Initializer);
713 }905 }
714 if (ai.sentinel) |s| {906 if (ai.sentinel) |s| {
715 if (index != 0) try writer.writeAll(",");907 if (index != 0) try writer.writeByte(',');
716 try dg.renderValue(writer, ai.elem_type, s, .Other);908 try dg.renderValue(writer, ai.elem_type, s, .Initializer);
717 }909 }
718 try writer.writeByte('}');910 try writer.writeByte('}');
719 },911 },
720 }912 }
721 },913 },
722 .Bool => return writer.print("{}", .{val.toBool()}),914 .Bool => return writer.print("zig_{}", .{val.toBool()}),
723 .Optional => {915 .Optional => {
724 var opt_buf: Type.Payload.ElemType = undefined;916 var opt_buf: Type.Payload.ElemType = undefined;
725 const payload_ty = ty.optionalChild(&opt_buf);917 const payload_ty = ty.optionalChild(&opt_buf);
726918
727 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {919 const is_null_val = Value.makeBool(val.tag() == .null_value);
728 const is_null = val.castTag(.opt_payload) == null;920 if (!payload_ty.hasRuntimeBitsIgnoreComptime())
729 return writer.print("{}", .{is_null});921 return dg.renderValue(writer, Type.bool, is_null_val, location);
730 }
731922
732 if (ty.optionalReprIsPayload()) {923 if (ty.optionalReprIsPayload()) {
733 if (val.castTag(.opt_payload)) |payload| {924 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val;
734 return dg.renderValue(writer, payload_ty, payload.data, location);925 return dg.renderValue(writer, payload_ty, payload_val, location);
735 } else {
736 return dg.renderValue(writer, payload_ty, val, location);
737 }
738 }926 }
739927
740 try writer.writeByte('(');928 if (location != .Initializer) {
741 try dg.renderTypecast(writer, ty);929 try writer.writeByte('(');
742 try writer.writeAll("){");930 try dg.renderTypecast(writer, ty);
743 if (val.castTag(.opt_payload)) |pl| {931 try writer.writeByte(')');
744 const payload_val = pl.data;
745 try writer.writeAll(" .is_null = false, .payload = ");
746 try dg.renderValue(writer, payload_ty, payload_val, location);
747 try writer.writeAll(" }");
748 } else {
749 try writer.writeAll(" .is_null = true }");
750 }932 }
933
934 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else Value.undef;
935
936 try writer.writeAll("{ .payload = ");
937 try dg.renderValue(writer, payload_ty, payload_val, .Initializer);
938 try writer.writeAll(", .is_null = ");
939 try dg.renderValue(writer, Type.bool, is_null_val, .Initializer);
940 try writer.writeAll(" }");
751 },941 },
752 .ErrorSet => {942 .ErrorSet => {
753 switch (val.tag()) {943 const error_name = if (val.castTag(.@"error")) |error_pl|
754 .@"error" => {944 error_pl.data.name
755 const payload = val.castTag(.@"error").?;945 else
756 // error values will be #defined at the top of the file946 dg.module.error_name_list.items[0];
757 return writer.print("zig_error_{s}", .{payload.data.name});947 // Error values are already defined by genErrDecls.
758 },948 try writer.print("zig_error_{}", .{fmtIdent(error_name)});
759 else => {
760 // In this case we are rendering an error union which has a
761 // 0 bits payload.
762 return writer.writeAll("0");
763 },
764 }
765 },949 },
766 .ErrorUnion => {950 .ErrorUnion => {
767 const error_type = ty.errorUnionSet();951 const error_ty = ty.errorUnionSet();
768 const payload_type = ty.errorUnionPayload();952 const payload_ty = ty.errorUnionPayload();
769953
770 if (!payload_type.hasRuntimeBits()) {954 if (!payload_ty.hasRuntimeBits()) {
771 // We use the error type directly as the type.955 // We use the error type directly as the type.
772 const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val;956 const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val;
773 return dg.renderValue(writer, error_type, err_val, location);957 return dg.renderValue(writer, error_ty, err_val, location);
774 }958 }
775959
776 try writer.writeByte('(');960 if (location != .Initializer) {
777 try dg.renderTypecast(writer, ty);961 try writer.writeByte('(');
778 try writer.writeAll("){");962 try dg.renderTypecast(writer, ty);
779 if (val.castTag(.eu_payload)) |pl| {963 try writer.writeByte(')');
780 const payload_val = pl.data;
781 try writer.writeAll(" .payload = ");
782 try dg.renderValue(writer, payload_type, payload_val, location);
783 try writer.writeAll(", .error = 0 }");
784 } else {
785 try writer.writeAll(" .error = ");
786 try dg.renderValue(writer, error_type, val, location);
787 try writer.writeAll(" }");
788 }964 }
965
966 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef;
967 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
968
969 try writer.writeAll("{ .payload = ");
970 try dg.renderValue(writer, payload_ty, payload_val, .Initializer);
971 try writer.writeAll(", .error = ");
972 try dg.renderValue(writer, error_ty, error_val, .Initializer);
973 try writer.writeAll(" }");
789 },974 },
790 .Enum => {975 .Enum => {
791 switch (val.tag()) {976 switch (val.tag()) {
...@@ -832,37 +1017,79 @@ pub const DeclGen = struct {...@@ -832,37 +1017,79 @@ pub const DeclGen = struct {
832 },1017 },
833 else => unreachable,1018 else => unreachable,
834 },1019 },
835 .Struct => {1020 .Struct => switch (ty.containerLayout()) {
836 const field_vals = val.castTag(.aggregate).?.data;1021 .Auto, .Extern => {
1022 const field_vals = val.castTag(.aggregate).?.data;
1023
1024 if (location != .Initializer) {
1025 try writer.writeByte('(');
1026 try dg.renderTypecast(writer, ty);
1027 try writer.writeByte(')');
1028 }
8371029
838 try writer.writeAll("(");1030 try writer.writeByte('{');
839 try dg.renderTypecast(writer, ty);1031 var empty = true;
840 try writer.writeAll("){");1032 for (field_vals) |field_val, field_index| {
1033 const field_ty = ty.structFieldType(field_index);
1034 if (!field_ty.hasRuntimeBits()) continue;
8411035
842 var i: usize = 0;1036 if (!empty) try writer.writeByte(',');
843 for (field_vals) |field_val, field_index| {1037 try dg.renderValue(writer, field_ty, field_val, .Initializer);
844 const field_ty = ty.structFieldType(field_index);
845 if (!field_ty.hasRuntimeBits()) continue;
8461038
847 if (i != 0) try writer.writeAll(",");1039 empty = false;
848 try dg.renderValue(writer, field_ty, field_val, location);1040 }
849 i += 1;1041 if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)});
850 }1042 try writer.writeByte('}');
1043 },
1044 .Packed => {
1045 const field_vals = val.castTag(.aggregate).?.data;
1046 const int_info = ty.intInfo(target);
1047
1048 var bit_offset_ty_pl = Type.Payload.Bits{
1049 .base = .{ .tag = .int_unsigned },
1050 .data = Type.smallestUnsignedBits(int_info.bits - 1),
1051 };
1052 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
8511053
852 try writer.writeAll("}");1054 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
1055 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
1056
1057 try writer.writeByte('(');
1058 var empty = true;
1059 for (field_vals) |field_val, index| {
1060 const field_ty = ty.structFieldType(index);
1061 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1062
1063 if (!empty) try writer.writeAll(" | ");
1064 try writer.writeByte('(');
1065 try dg.renderTypecast(writer, ty);
1066 try writer.writeByte(')');
1067 try dg.renderValue(writer, field_ty, field_val, .Other);
1068 try writer.writeAll(" << ");
1069 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1070
1071 bit_offset_val_pl.data += field_ty.bitSize(target);
1072 empty = false;
1073 }
1074 if (empty) try dg.renderValue(writer, ty, Value.undef, .Initializer);
1075 try writer.writeByte(')');
1076 },
853 },1077 },
854 .Union => {1078 .Union => {
855 const union_obj = val.castTag(.@"union").?.data;1079 const union_obj = val.castTag(.@"union").?.data;
856 const layout = ty.unionGetLayout(target);1080 const layout = ty.unionGetLayout(target);
8571081
858 try writer.writeAll("(");1082 if (location != .Initializer) {
859 try dg.renderTypecast(writer, ty);1083 try writer.writeByte('(');
860 try writer.writeAll("){");1084 try dg.renderTypecast(writer, ty);
1085 try writer.writeByte(')');
1086 }
8611087
1088 try writer.writeByte('{');
862 if (ty.unionTagTypeSafety()) |tag_ty| {1089 if (ty.unionTagTypeSafety()) |tag_ty| {
863 if (layout.tag_size != 0) {1090 if (layout.tag_size != 0) {
864 try writer.writeAll(".tag = ");1091 try writer.writeAll(".tag = ");
865 try dg.renderValue(writer, tag_ty, union_obj.tag, location);1092 try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer);
866 try writer.writeAll(", ");1093 try writer.writeAll(", ");
867 }1094 }
868 try writer.writeAll(".payload = {");1095 try writer.writeAll(".payload = {");
...@@ -873,12 +1100,10 @@ pub const DeclGen = struct {...@@ -873,12 +1100,10 @@ pub const DeclGen = struct {
873 const field_name = ty.unionFields().keys()[index];1100 const field_name = ty.unionFields().keys()[index];
874 if (field_ty.hasRuntimeBits()) {1101 if (field_ty.hasRuntimeBits()) {
875 try writer.print(".{ } = ", .{fmtIdent(field_name)});1102 try writer.print(".{ } = ", .{fmtIdent(field_name)});
876 try dg.renderValue(writer, field_ty, union_obj.val, location);1103 try dg.renderValue(writer, field_ty, union_obj.val, .Initializer);
877 }1104 } else try writer.writeByte('0');
878 if (ty.unionTagTypeSafety()) |_| {1105 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
879 try writer.writeAll("}");1106 try writer.writeByte('}');
880 }
881 try writer.writeAll("}");
882 },1107 },
8831108
884 .ComptimeInt => unreachable,1109 .ComptimeInt => unreachable,
...@@ -901,75 +1126,69 @@ pub const DeclGen = struct {...@@ -901,75 +1126,69 @@ pub const DeclGen = struct {
901 }1126 }
902 }1127 }
9031128
904 fn renderFunctionSignature(dg: *DeclGen, w: anytype, is_global: bool) !void {1129 fn renderFunctionSignature(dg: *DeclGen, w: anytype, kind: TypedefKind) !void {
905 if (!is_global) {
906 try w.writeAll("static ");
907 }
908 if (dg.decl.val.castTag(.function)) |func_payload| {
909 const func: *Module.Fn = func_payload.data;
910 if (func.is_cold) {
911 try w.writeAll("ZIG_COLD ");
912 }
913 }
914 const fn_info = dg.decl.ty.fnInfo();1130 const fn_info = dg.decl.ty.fnInfo();
915 if (fn_info.return_type.hasRuntimeBits()) {1131 if (fn_info.cc == .Naked) try w.writeAll("zig_naked ");
916 try dg.renderType(w, fn_info.return_type);1132 if (dg.decl.val.castTag(.function)) |func_payload|
917 } else if (fn_info.return_type.isError()) {1133 if (func_payload.data.is_cold) try w.writeAll("zig_cold ");
918 try dg.renderType(w, Type.anyerror);1134
919 } else if (fn_info.return_type.zigTypeTag() == .NoReturn) {1135 const target = dg.module.getTarget();
920 try w.writeAll("zig_noreturn void");1136 var ret_buf: LowerFnRetTyBuffer = undefined;
921 } else {1137 const ret_ty = lowerFnRetTy(fn_info.return_type, &ret_buf, target);
922 try w.writeAll("void");1138
923 }1139 try dg.renderType(w, ret_ty, kind);
924 try w.writeAll(" ");1140 try w.writeByte(' ');
925 try dg.renderDeclName(w, dg.decl_index);1141 try dg.renderDeclName(w, dg.decl_index);
926 try w.writeAll("(");1142 try w.writeByte('(');
9271143
928 var params_written: usize = 0;1144 var index: usize = 0;
929 for (fn_info.param_types) |param_type, index| {1145 for (fn_info.param_types) |param_type| {
930 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;1146 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
931 if (params_written > 0) {1147 if (index > 0) try w.writeAll(", ");
932 try w.writeAll(", ");
933 }
934 const name = CValue{ .arg = index };1148 const name = CValue{ .arg = index };
935 try dg.renderTypeAndName(w, param_type, name, .Mut, 0);1149 try dg.renderTypeAndName(w, param_type, name, .ConstArgument, 0, kind);
936 params_written += 1;1150 index += 1;
937 }1151 }
9381152
939 if (fn_info.is_var_args) {1153 if (fn_info.is_var_args) {
940 if (params_written != 0) try w.writeAll(", ");1154 if (index > 0) try w.writeAll(", ");
941 try w.writeAll("...");1155 try w.writeAll("...");
942 } else if (params_written == 0) {1156 } else if (index == 0) {
943 try w.writeAll("void");1157 try dg.renderType(w, Type.void, kind);
944 }1158 }
945 try w.writeByte(')');1159 try w.writeByte(')');
946 }1160 }
9471161
948 fn renderPtrToFnTypedef(dg: *DeclGen, t: Type, fn_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1162 fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
949 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1163 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
950 defer buffer.deinit();1164 defer buffer.deinit();
951 const bw = buffer.writer();1165 const bw = buffer.writer();
9521166
953 const fn_info = fn_ty.fnInfo();1167 const fn_info = t.fnInfo();
1168
1169 const target = dg.module.getTarget();
1170 var ret_buf: LowerFnRetTyBuffer = undefined;
1171 const ret_ty = lowerFnRetTy(fn_info.return_type, &ret_buf, target);
9541172
955 try bw.writeAll("typedef ");1173 try bw.writeAll("typedef ");
956 try dg.renderType(bw, fn_info.return_type);1174 try dg.renderType(bw, ret_ty, .Forward);
957 try bw.writeAll(" (*");1175 try bw.writeAll(" (*");
9581176 const name_begin = buffer.items.len;
959 const name_start = buffer.items.len;1177 try bw.print("zig_F_{}", .{typeToCIdentifier(t, dg.module)});
960 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, dg.module)});1178 const name_end = buffer.items.len;
961 const name_end = buffer.items.len - 2;1179 try bw.writeAll(")(");
9621180
963 const param_len = fn_info.param_types.len;1181 const param_len = fn_info.param_types.len;
9641182
965 var params_written: usize = 0;1183 var params_written: usize = 0;
966 var index: usize = 0;1184 var index: usize = 0;
967 while (index < param_len) : (index += 1) {1185 while (index < param_len) : (index += 1) {
968 if (!fn_info.param_types[index].hasRuntimeBitsIgnoreComptime()) continue;1186 const param_ty = fn_info.param_types[index];
1187 if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;
969 if (params_written > 0) {1188 if (params_written > 0) {
970 try bw.writeAll(", ");1189 try bw.writeAll(", ");
971 }1190 }
972 try dg.renderTypecast(bw, fn_info.param_types[index]);1191 try dg.renderTypeAndName(bw, param_ty, .{ .bytes = "" }, .Mut, 0, .Forward);
973 params_written += 1;1192 params_written += 1;
974 }1193 }
9751194
...@@ -977,13 +1196,13 @@ pub const DeclGen = struct {...@@ -977,13 +1196,13 @@ pub const DeclGen = struct {
977 if (params_written != 0) try bw.writeAll(", ");1196 if (params_written != 0) try bw.writeAll(", ");
978 try bw.writeAll("...");1197 try bw.writeAll("...");
979 } else if (params_written == 0) {1198 } else if (params_written == 0) {
980 try bw.writeAll("void");1199 try dg.renderType(bw, Type.void, .Forward);
981 }1200 }
982 try bw.writeAll(");\n");1201 try bw.writeAll(");\n");
9831202
984 const rendered = buffer.toOwnedSlice();1203 const rendered = buffer.toOwnedSlice();
985 errdefer dg.typedefs.allocator.free(rendered);1204 errdefer dg.typedefs.allocator.free(rendered);
986 const name = rendered[name_start..name_end];1205 const name = rendered[name_begin..name_end];
9871206
988 try dg.typedefs.ensureUnusedCapacity(1);1207 try dg.typedefs.ensureUnusedCapacity(1);
989 dg.typedefs.putAssumeCapacityNoClobber(1208 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -995,36 +1214,35 @@ pub const DeclGen = struct {...@@ -995,36 +1214,35 @@ pub const DeclGen = struct {
995 }1214 }
9961215
997 fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1216 fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1217 std.debug.assert(t.sentinel() == null); // expected canonical type
1218
998 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1219 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
999 defer buffer.deinit();1220 defer buffer.deinit();
1000 const bw = buffer.writer();1221 const bw = buffer.writer();
10011222
1002 try bw.writeAll("typedef struct { ");1223 var ptr_ty_buf: Type.SlicePtrFieldTypeBuffer = undefined;
10031224 const ptr_ty = t.slicePtrFieldType(&ptr_ty_buf);
1004 var ptr_type_buf: Type.SlicePtrFieldTypeBuffer = undefined;1225 const ptr_name = CValue{ .identifier = "ptr" };
1005 const ptr_type = t.slicePtrFieldType(&ptr_type_buf);1226 const len_ty = Type.usize;
1006 const ptr_name = CValue{ .bytes = "ptr" };1227 const len_name = CValue{ .identifier = "len" };
1007 try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, 0);1228
10081229 try bw.writeAll("typedef struct {\n ");
1009 const ptr_sentinel = ptr_type.ptrInfo().data.sentinel;1230 try dg.renderTypeAndName(bw, ptr_ty, ptr_name, .Mut, 0, .Complete);
1010 const child_type = t.childType();1231 try bw.writeAll(";\n ");
10111232 try dg.renderTypeAndName(bw, len_ty, len_name, .Mut, 0, .Complete);
1012 try bw.writeAll("; size_t len; } ");1233
1013 const name_index = buffer.items.len;1234 try bw.writeAll(";\n} ");
1014 if (t.isConstPtr()) {1235 const name_begin = buffer.items.len;
1015 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, dg.module)});1236 try bw.print("zig_{c}_{}", .{
1016 } else {1237 @as(u8, if (t.isConstPtr()) 'L' else 'M'),
1017 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, dg.module)});1238 typeToCIdentifier(t.childType(), dg.module),
1018 }1239 });
1019 if (ptr_sentinel) |s| {1240 const name_end = buffer.items.len;
1020 try bw.writeAll("_s_");
1021 try dg.renderValue(bw, child_type, s, .Other);
1022 }
1023 try bw.writeAll(";\n");1241 try bw.writeAll(";\n");
10241242
1025 const rendered = buffer.toOwnedSlice();1243 const rendered = buffer.toOwnedSlice();
1026 errdefer dg.typedefs.allocator.free(rendered);1244 errdefer dg.typedefs.allocator.free(rendered);
1027 const name = rendered[name_index .. rendered.len - 2];1245 const name = rendered[name_begin..name_end];
10281246
1029 try dg.typedefs.ensureUnusedCapacity(1);1247 try dg.typedefs.ensureUnusedCapacity(1);
1030 dg.typedefs.putAssumeCapacityNoClobber(1248 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1035,36 +1253,34 @@ pub const DeclGen = struct {...@@ -1035,36 +1253,34 @@ pub const DeclGen = struct {
1035 return name;1253 return name;
1036 }1254 }
10371255
1038 fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1256 fn renderFwdTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1039 const struct_obj = t.castTag(.@"struct").?.data; // Handle 0 bit types elsewhere.1257 // The forward declaration for T is stored with a key of *const T.
1040 const fqn = try struct_obj.getFullyQualifiedName(dg.module);1258 const child_ty = t.childType();
1041 defer dg.typedefs.allocator.free(fqn);
10421259
1043 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1260 var fqn_buf = std.ArrayList(u8).init(dg.typedefs.allocator);
1044 defer buffer.deinit();1261 defer fqn_buf.deinit();
10451262
1046 try buffer.appendSlice("typedef struct {\n");1263 const owner_decl = dg.module.declPtr(child_ty.getOwnerDecl());
1047 {1264 try owner_decl.renderFullyQualifiedName(dg.module, fqn_buf.writer());
1048 var it = struct_obj.fields.iterator();
1049 while (it.next()) |entry| {
1050 const field_ty = entry.value_ptr.ty;
1051 if (!field_ty.hasRuntimeBits()) continue;
10521265
1053 const alignment = entry.value_ptr.abi_align;1266 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1054 const name: CValue = .{ .identifier = entry.key_ptr.* };1267 defer buffer.deinit();
1055 try buffer.append(' ');
1056 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);
1057 try buffer.appendSlice(";\n");
1058 }
1059 }
1060 try buffer.appendSlice("} ");
10611268
1062 const name_start = buffer.items.len;1269 const tag = switch (child_ty.zigTypeTag()) {
1063 try buffer.writer().print("zig_S_{};\n", .{fmtIdent(fqn)});1270 .Struct => "struct ",
1271 .Union => if (child_ty.unionTagTypeSafety()) |_| "struct " else "union ",
1272 else => unreachable,
1273 };
1274 const name_begin = buffer.items.len + "typedef ".len + tag.len;
1275 try buffer.writer().print("typedef {s}zig_S_{} ", .{ tag, fmtIdent(fqn_buf.items) });
1276 const name_end = buffer.items.len - " ".len;
1277 try buffer.ensureUnusedCapacity((name_end - name_begin) + ";\n".len);
1278 buffer.appendSliceAssumeCapacity(buffer.items[name_begin..name_end]);
1279 buffer.appendSliceAssumeCapacity(";\n");
10641280
1065 const rendered = buffer.toOwnedSlice();1281 const rendered = buffer.toOwnedSlice();
1066 errdefer dg.typedefs.allocator.free(rendered);1282 errdefer dg.typedefs.allocator.free(rendered);
1067 const name = rendered[name_start .. rendered.len - 2];1283 const name = rendered[name_begin..name_end];
10681284
1069 try dg.typedefs.ensureUnusedCapacity(1);1285 try dg.typedefs.ensureUnusedCapacity(1);
1070 dg.typedefs.putAssumeCapacityNoClobber(1286 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1075,36 +1291,84 @@ pub const DeclGen = struct {...@@ -1075,36 +1291,84 @@ pub const DeclGen = struct {
1075 return name;1291 return name;
1076 }1292 }
10771293
1078 fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1294 fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1079 const tuple = t.tupleFields();1295 var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t };
1296 const ptr_ty = Type.initPayload(&ptr_pl.base);
1297 const name = dg.getTypedefName(ptr_ty) orelse
1298 try dg.renderFwdTypedef(ptr_ty);
10801299
1081 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1300 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1082 defer buffer.deinit();1301 defer buffer.deinit();
1083 const writer = buffer.writer();
10841302
1085 try buffer.appendSlice("typedef struct {\n");1303 try buffer.appendSlice("struct ");
1304 try buffer.appendSlice(name);
1305 try buffer.appendSlice(" {\n");
1086 {1306 {
1087 for (tuple.types) |field_ty, i| {1307 var it = t.structFields().iterator();
1088 const val = tuple.values[i];1308 var empty = true;
1089 if (val.tag() != .unreachable_value) continue;1309 while (it.next()) |field| {
10901310 const field_ty = field.value_ptr.ty;
1091 var name = std.ArrayList(u8).init(dg.gpa);1311 if (!field_ty.hasRuntimeBits()) continue;
1092 defer name.deinit();
1093 try name.writer().print("field_{d}", .{i});
10941312
1313 const alignment = field.value_ptr.abi_align;
1314 const field_name = CValue{ .identifier = field.key_ptr.* };
1095 try buffer.append(' ');1315 try buffer.append(' ');
1096 try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0);1316 try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete);
1097 try buffer.appendSlice(";\n");1317 try buffer.appendSlice(";\n");
1318
1319 empty = false;
1098 }1320 }
1321 if (empty) try buffer.appendSlice(" char empty_struct;\n");
1099 }1322 }
1100 try buffer.appendSlice("} ");1323 try buffer.appendSlice("};\n");
1324
1325 const rendered = buffer.toOwnedSlice();
1326 errdefer dg.typedefs.allocator.free(rendered);
1327
1328 try dg.typedefs.ensureUnusedCapacity(1);
1329 dg.typedefs.putAssumeCapacityNoClobber(
1330 try t.copy(dg.typedefs_arena),
1331 .{ .name = name, .rendered = rendered },
1332 );
1333
1334 return name;
1335 }
1336
1337 fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1338 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1339 defer buffer.deinit();
1340
1341 try buffer.appendSlice("typedef struct {\n");
1342 {
1343 const fields = t.tupleFields();
1344 var empty = true;
1345 for (fields.types) |field_ty, i| {
1346 if (!field_ty.hasRuntimeBits()) continue;
1347 const val = fields.values[i];
1348 if (val.tag() != .unreachable_value) continue;
1349
1350 var field_name_buf: []const u8 = &.{};
1351 defer dg.typedefs.allocator.free(field_name_buf);
1352 const field_name = if (t.isTuple()) field_name: {
1353 field_name_buf = try std.fmt.allocPrint(dg.typedefs.allocator, "field_{d}", .{i});
1354 break :field_name field_name_buf;
1355 } else t.structFieldName(i);
11011356
1102 const name_start = buffer.items.len;1357 try buffer.append(' ');
1103 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});1358 try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .identifier = field_name }, .Mut, 0, .Complete);
1359 try buffer.appendSlice(";\n");
1360
1361 empty = false;
1362 }
1363 if (empty) try buffer.appendSlice(" char empty_tuple;\n");
1364 }
1365 const name_begin = buffer.items.len + "} ".len;
1366 try buffer.writer().print("}} zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});
1367 const name_end = buffer.items.len - ";\n".len;
11041368
1105 const rendered = buffer.toOwnedSlice();1369 const rendered = buffer.toOwnedSlice();
1106 errdefer dg.typedefs.allocator.free(rendered);1370 errdefer dg.typedefs.allocator.free(rendered);
1107 const name = rendered[name_start .. rendered.len - 2];1371 const name = rendered[name_begin..name_end];
11081372
1109 try dg.typedefs.ensureUnusedCapacity(1);1373 try dg.typedefs.ensureUnusedCapacity(1);
1110 dg.typedefs.putAssumeCapacityNoClobber(1374 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1116,51 +1380,56 @@ pub const DeclGen = struct {...@@ -1116,51 +1380,56 @@ pub const DeclGen = struct {
1116 }1380 }
11171381
1118 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1382 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1119 const union_ty = t.cast(Type.Payload.Union).?.data;1383 var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t };
1120 const fqn = try union_ty.getFullyQualifiedName(dg.module);1384 const ptr_ty = Type.initPayload(&ptr_pl.base);
1121 defer dg.typedefs.allocator.free(fqn);1385 const name = dg.getTypedefName(ptr_ty) orelse
11221386 try dg.renderFwdTypedef(ptr_ty);
1123 const target = dg.module.getTarget();
1124 const layout = t.unionGetLayout(target);
11251387
1126 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1388 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1127 defer buffer.deinit();1389 defer buffer.deinit();
11281390
1129 try buffer.appendSlice("typedef ");1391 try buffer.appendSlice(if (t.unionTagTypeSafety()) |_| "struct " else "union ");
1130 if (t.unionTagTypeSafety()) |tag_ty| {1392 try buffer.appendSlice(name);
1131 const name: CValue = .{ .bytes = "tag" };1393 try buffer.appendSlice(" {\n");
1132 try buffer.appendSlice("struct {\n ");1394
1395 const indent = if (t.unionTagTypeSafety()) |tag_ty| indent: {
1396 const target = dg.module.getTarget();
1397 const layout = t.unionGetLayout(target);
1133 if (layout.tag_size != 0) {1398 if (layout.tag_size != 0) {
1134 try dg.renderTypeAndName(buffer.writer(), tag_ty, name, .Mut, 0);1399 try buffer.append(' ');
1400 try dg.renderTypeAndName(buffer.writer(), tag_ty, .{ .identifier = "tag" }, .Mut, 0, .Complete);
1135 try buffer.appendSlice(";\n");1401 try buffer.appendSlice(";\n");
1136 }1402 }
1137 }1403 try buffer.appendSlice(" union {\n");
1404 break :indent " ";
1405 } else " ";
11381406
1139 try buffer.appendSlice("union {\n");
1140 {1407 {
1141 var it = t.unionFields().iterator();1408 var it = t.unionFields().iterator();
1142 while (it.next()) |entry| {1409 var empty = true;
1143 const field_ty = entry.value_ptr.ty;1410 while (it.next()) |field| {
1411 const field_ty = field.value_ptr.ty;
1144 if (!field_ty.hasRuntimeBits()) continue;1412 if (!field_ty.hasRuntimeBits()) continue;
1145 const alignment = entry.value_ptr.abi_align;1413
1146 const name: CValue = .{ .identifier = entry.key_ptr.* };1414 const alignment = field.value_ptr.abi_align;
1147 try buffer.append(' ');1415 const field_name = CValue{ .identifier = field.key_ptr.* };
1148 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);1416 try buffer.appendSlice(indent);
1417 try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete);
1149 try buffer.appendSlice(";\n");1418 try buffer.appendSlice(";\n");
1150 }
1151 }
1152 try buffer.appendSlice("} ");
11531419
1154 if (t.unionTagTypeSafety()) |_| {1420 empty = false;
1155 try buffer.appendSlice("payload;\n} ");1421 }
1422 if (empty) {
1423 try buffer.appendSlice(indent);
1424 try buffer.appendSlice("char empty_union;\n");
1425 }
1156 }1426 }
11571427
1158 const name_start = buffer.items.len;1428 if (t.unionTagTypeSafety()) |_| try buffer.appendSlice(" } payload;\n");
1159 try buffer.writer().print("zig_U_{};\n", .{fmtIdent(fqn)});1429 try buffer.appendSlice("};\n");
11601430
1161 const rendered = buffer.toOwnedSlice();1431 const rendered = buffer.toOwnedSlice();
1162 errdefer dg.typedefs.allocator.free(rendered);1432 errdefer dg.typedefs.allocator.free(rendered);
1163 const name = rendered[name_start .. rendered.len - 2];
11641433
1165 try dg.typedefs.ensureUnusedCapacity(1);1434 try dg.typedefs.ensureUnusedCapacity(1);
1166 dg.typedefs.putAssumeCapacityNoClobber(1435 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1172,42 +1441,39 @@ pub const DeclGen = struct {...@@ -1172,42 +1441,39 @@ pub const DeclGen = struct {
1172 }1441 }
11731442
1174 fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1443 fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1175 const payload_ty = t.errorUnionPayload();1444 assert(t.errorUnionSet().tag() == .anyerror);
1176 const error_ty = t.errorUnionSet();
11771445
1178 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1446 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1179 defer buffer.deinit();1447 defer buffer.deinit();
1180 const bw = buffer.writer();1448 const bw = buffer.writer();
11811449
1182 const payload_name = CValue{ .bytes = "payload" };1450 const payload_ty = t.errorUnionPayload();
1451 const payload_name = CValue{ .identifier = "payload" };
1452 const error_ty = t.errorUnionSet();
1453 const error_name = CValue{ .identifier = "error" };
1454
1183 const target = dg.module.getTarget();1455 const target = dg.module.getTarget();
1184 const payload_align = payload_ty.abiAlignment(target);1456 const payload_align = payload_ty.abiAlignment(target);
1185 const error_align = Type.anyerror.abiAlignment(target);1457 const error_align = error_ty.abiAlignment(target);
1458 try bw.writeAll("typedef struct {\n ");
1186 if (error_align > payload_align) {1459 if (error_align > payload_align) {
1187 try bw.writeAll("typedef struct { ");1460 try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete);
1188 try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0);1461 try bw.writeAll(";\n ");
1189 try bw.writeAll("; uint16_t error; } ");1462 try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete);
1190 } else {
1191 try bw.writeAll("typedef struct { uint16_t error; ");
1192 try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0);
1193 try bw.writeAll("; } ");
1194 }
1195
1196 const name_index = buffer.items.len;
1197 if (error_ty.castTag(.error_set_inferred)) |inf_err_set_payload| {
1198 const func = inf_err_set_payload.data.func;
1199 try bw.writeAll("zig_E_");
1200 try dg.renderDeclName(bw, func.owner_decl);
1201 try bw.writeAll(";\n");
1202 } else {1463 } else {
1203 try bw.print("zig_E_{s}_{s};\n", .{1464 try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete);
1204 typeToCIdentifier(error_ty, dg.module), typeToCIdentifier(payload_ty, dg.module),1465 try bw.writeAll(";\n ");
1205 });1466 try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete);
1206 }1467 }
1468 try bw.writeAll(";\n} ");
1469 const name_begin = buffer.items.len;
1470 try bw.print("zig_E_{}", .{typeToCIdentifier(payload_ty, dg.module)});
1471 const name_end = buffer.items.len;
1472 try bw.writeAll(";\n");
12071473
1208 const rendered = buffer.toOwnedSlice();1474 const rendered = buffer.toOwnedSlice();
1209 errdefer dg.typedefs.allocator.free(rendered);1475 errdefer dg.typedefs.allocator.free(rendered);
1210 const name = rendered[name_index .. rendered.len - 2];1476 const name = rendered[name_begin..name_end];
12111477
1212 try dg.typedefs.ensureUnusedCapacity(1);1478 try dg.typedefs.ensureUnusedCapacity(1);
1213 dg.typedefs.putAssumeCapacityNoClobber(1479 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1219,26 +1485,28 @@ pub const DeclGen = struct {...@@ -1219,26 +1485,28 @@ pub const DeclGen = struct {
1219 }1485 }
12201486
1221 fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1487 fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1488 const info = t.arrayInfo();
1489 std.debug.assert(info.sentinel == null); // expected canonical type
1490
1222 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1491 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1223 defer buffer.deinit();1492 defer buffer.deinit();
1224 const bw = buffer.writer();1493 const bw = buffer.writer();
12251494
1226 const elem_type = t.elemType();
1227 const sentinel_bit = @boolToInt(t.sentinel() != null);
1228 const c_len = t.arrayLen() + sentinel_bit;
1229
1230 try bw.writeAll("typedef ");1495 try bw.writeAll("typedef ");
1231 try dg.renderType(bw, elem_type);1496 try dg.renderType(bw, info.elem_type, .Complete);
12321497
1233 const name_start = buffer.items.len + 1;1498 const name_begin = buffer.items.len + " ".len;
1234 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, dg.module), c_len });1499 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(info.elem_type, dg.module), info.len });
1235 const name_end = buffer.items.len;1500 const name_end = buffer.items.len;
12361501
1237 try bw.print("[{d}];\n", .{c_len});1502 const c_len = if (info.len > 0) info.len else 1;
1503 var c_len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = c_len };
1504 const c_len_val = Value.initPayload(&c_len_pl.base);
1505 try bw.print("[{}];\n", .{try dg.fmtIntLiteral(Type.usize, c_len_val)});
12381506
1239 const rendered = buffer.toOwnedSlice();1507 const rendered = buffer.toOwnedSlice();
1240 errdefer dg.typedefs.allocator.free(rendered);1508 errdefer dg.typedefs.allocator.free(rendered);
1241 const name = rendered[name_start..name_end];1509 const name = rendered[name_begin..name_end];
12421510
1243 try dg.typedefs.ensureUnusedCapacity(1);1511 try dg.typedefs.ensureUnusedCapacity(1);
1244 dg.typedefs.putAssumeCapacityNoClobber(1512 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1254,16 +1522,48 @@ pub const DeclGen = struct {...@@ -1254,16 +1522,48 @@ pub const DeclGen = struct {
1254 defer buffer.deinit();1522 defer buffer.deinit();
1255 const bw = buffer.writer();1523 const bw = buffer.writer();
12561524
1257 try bw.writeAll("typedef struct { ");1525 try bw.writeAll("typedef struct {\n ");
1258 const payload_name = CValue{ .bytes = "payload" };1526 try dg.renderTypeAndName(bw, child_type, .{ .identifier = "payload" }, .Mut, 0, .Complete);
1259 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1527 try bw.writeAll(";\n ");
1260 try bw.writeAll("; bool is_null; } ");1528 try dg.renderTypeAndName(bw, Type.bool, .{ .identifier = "is_null" }, .Mut, 0, .Complete);
1261 const name_index = buffer.items.len;1529 try bw.writeAll(";\n} ");
1262 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, dg.module)});1530 const name_begin = buffer.items.len;
1531 try bw.print("zig_Q_{}", .{typeToCIdentifier(child_type, dg.module)});
1532 const name_end = buffer.items.len;
1533 try bw.writeAll(";\n");
1534
1535 const rendered = buffer.toOwnedSlice();
1536 errdefer dg.typedefs.allocator.free(rendered);
1537 const name = rendered[name_begin..name_end];
1538
1539 try dg.typedefs.ensureUnusedCapacity(1);
1540 dg.typedefs.putAssumeCapacityNoClobber(
1541 try t.copy(dg.typedefs_arena),
1542 .{ .name = name, .rendered = rendered },
1543 );
1544
1545 return name;
1546 }
1547
1548 fn renderOpaqueTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1549 const opaque_ty = t.cast(Type.Payload.Opaque).?.data;
1550 const unqualified_name = dg.module.declPtr(opaque_ty.owner_decl).name;
1551 const fqn = try opaque_ty.getFullyQualifiedName(dg.module);
1552 defer dg.typedefs.allocator.free(fqn);
1553
1554 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1555 defer buffer.deinit();
1556
1557 try buffer.writer().print("typedef struct { } ", .{fmtIdent(std.mem.span(unqualified_name))});
1558
1559 const name_begin = buffer.items.len;
1560 try buffer.writer().print("zig_O_{}", .{fmtIdent(fqn)});
1561 const name_end = buffer.items.len;
1562 try buffer.appendSlice(";\n");
12631563
1264 const rendered = buffer.toOwnedSlice();1564 const rendered = buffer.toOwnedSlice();
1265 errdefer dg.typedefs.allocator.free(rendered);1565 errdefer dg.typedefs.allocator.free(rendered);
1266 const name = rendered[name_index .. rendered.len - 2];1566 const name = rendered[name_begin..name_end];
12671567
1268 try dg.typedefs.ensureUnusedCapacity(1);1568 try dg.typedefs.ensureUnusedCapacity(1);
1269 dg.typedefs.putAssumeCapacityNoClobber(1569 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1286,84 +1586,98 @@ pub const DeclGen = struct {...@@ -1286,84 +1586,98 @@ pub const DeclGen = struct {
1286 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |1586 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
1287 /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" |1587 /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" |
1288 ///1588 ///
1289 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void {1589 fn renderType(
1590 dg: *DeclGen,
1591 w: anytype,
1592 t: Type,
1593 kind: TypedefKind,
1594 ) error{ OutOfMemory, AnalysisFail }!void {
1290 const target = dg.module.getTarget();1595 const target = dg.module.getTarget();
12911596
1292 switch (t.zigTypeTag()) {1597 switch (t.zigTypeTag()) {
1293 .NoReturn, .Void => try w.writeAll("void"),1598 .NoReturn, .Void, .Bool, .Int, .Float, .ErrorSet => |tag| {
1294 .Bool => try w.writeAll("bool"),1599 const is_named = switch (tag) {
1295 .Int => {1600 .Int => t.isNamedInt(),
1296 switch (t.tag()) {1601 .ErrorSet => false,
1297 .u1, .u8 => try w.writeAll("uint8_t"),1602 else => true,
1298 .i8 => try w.writeAll("int8_t"),1603 };
1299 .u16 => try w.writeAll("uint16_t"),1604 if (is_named) {
1300 .i16 => try w.writeAll("int16_t"),1605 try w.writeAll("zig_");
1301 .u32 => try w.writeAll("uint32_t"),1606 try t.print(w, dg.module);
1302 .i32 => try w.writeAll("int32_t"),1607 } else {
1303 .u64 => try w.writeAll("uint64_t"),1608 const int_info = t.intInfo(target);
1304 .i64 => try w.writeAll("int64_t"),1609 if (toCIntBits(int_info.bits)) |c_bits|
1305 .u128 => try w.writeAll("uint128_t"),1610 return w.print("zig_{c}{d}", .{ signAbbrev(int_info.signedness), c_bits })
1306 .i128 => try w.writeAll("int128_t"),1611 else if (loweredArrayInfo(t, target)) |array_info| {
1307 .usize => try w.writeAll("uintptr_t"),1612 assert(array_info.sentinel == null);
1308 .isize => try w.writeAll("intptr_t"),1613 var array_pl = Type.Payload.Array{
1309 .c_short => try w.writeAll("short"),1614 .base = .{ .tag = .array },
1310 .c_ushort => try w.writeAll("unsigned short"),1615 .data = .{ .len = array_info.len, .elem_type = array_info.elem_type },
1311 .c_int => try w.writeAll("int"),
1312 .c_uint => try w.writeAll("unsigned int"),
1313 .c_long => try w.writeAll("long"),
1314 .c_ulong => try w.writeAll("unsigned long"),
1315 .c_longlong => try w.writeAll("long long"),
1316 .c_ulonglong => try w.writeAll("unsigned long long"),
1317 .int_signed, .int_unsigned => {
1318 const info = t.intInfo(target);
1319 const sign_prefix = switch (info.signedness) {
1320 .signed => "",
1321 .unsigned => "u",
1322 };1616 };
1323 const c_bits = toCIntBits(info.bits) orelse1617 const array_ty = Type.initPayload(&array_pl.base);
1324 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});1618
1325 try w.print("{s}int{d}_t", .{ sign_prefix, c_bits });1619 return dg.renderType(w, array_ty, kind);
1326 },1620 } else return dg.fail("C backend: Unable to lower unnamed integer type {}", .{
1327 else => unreachable,1621 t.fmt(dg.module),
1328 }1622 });
1329 },
1330 .Float => {
1331 switch (t.tag()) {
1332 .f32 => try w.writeAll("float"),
1333 .f64 => try w.writeAll("double"),
1334 .c_longdouble => try w.writeAll("long double"),
1335 .f16 => return dg.fail("TODO: C backend: implement float type f16", .{}),
1336 .f128 => return dg.fail("TODO: C backend: implement float type f128", .{}),
1337 else => unreachable,
1338 }1623 }
1339 },1624 },
1340 .Pointer => {1625 .Pointer => {
1341 if (t.isSlice()) {1626 const ptr_info = t.ptrInfo().data;
1342 const name = dg.getTypedefName(t) orelse1627 if (ptr_info.size == .Slice) {
1343 try dg.renderSliceTypedef(t);1628 var slice_pl = Type.Payload.ElemType{
1629 .base = .{ .tag = if (t.ptrIsMutable()) .mut_slice else .const_slice },
1630 .data = ptr_info.pointee_type,
1631 };
1632 const slice_ty = Type.initPayload(&slice_pl.base);
1633
1634 const name = dg.getTypedefName(slice_ty) orelse
1635 try dg.renderSliceTypedef(slice_ty);
13441636
1345 return w.writeAll(name);1637 return w.writeAll(name);
1346 }1638 }
13471639
1348 if (t.castPtrToFn()) |fn_ty| {1640 if (ptr_info.pointee_type.zigTypeTag() == .Fn) {
1349 const name = dg.getTypedefName(t) orelse1641 const name = dg.getTypedefName(ptr_info.pointee_type) orelse
1350 try dg.renderPtrToFnTypedef(t, fn_ty);1642 try dg.renderPtrToFnTypedef(ptr_info.pointee_type);
13511643
1352 return w.writeAll(name);1644 return w.writeAll(name);
1353 }1645 }
13541646
1355 try dg.renderType(w, t.elemType());1647 if (ptr_info.host_size != 0) {
1356 if (t.isConstPtr()) {1648 var host_pl = Type.Payload.Bits{
1357 try w.writeAll(" const");1649 .base = .{ .tag = .int_unsigned },
1358 }1650 .data = ptr_info.host_size * 8,
1359 if (t.isVolatilePtr()) {1651 };
1360 try w.writeAll(" volatile");1652 const host_ty = Type.initPayload(&host_pl.base);
1361 }1653
1654 try dg.renderType(w, host_ty, .Forward);
1655 } else if (t.isCPtr() and ptr_info.pointee_type.eql(Type.u8, dg.module) and
1656 (dg.decl.val.tag() == .extern_fn or
1657 std.mem.eql(u8, std.mem.span(dg.decl.name), "main")))
1658 {
1659 // This is a hack, since the c compiler expects a lot of external
1660 // library functions to have char pointers in their signatures, but
1661 // u8 and i8 produce unsigned char and signed char respectively,
1662 // which in C are (not very usefully) different than char.
1663 try w.writeAll("char");
1664 } else try dg.renderType(w, switch (ptr_info.pointee_type.tag()) {
1665 .anyopaque => Type.void,
1666 else => ptr_info.pointee_type,
1667 }, .Forward);
1668 if (t.isConstPtr()) try w.writeAll(" const");
1669 if (t.isVolatilePtr()) try w.writeAll(" volatile");
1362 return w.writeAll(" *");1670 return w.writeAll(" *");
1363 },1671 },
1364 .Array => {1672 .Array => {
1365 const name = dg.getTypedefName(t) orelse1673 var array_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{
1366 try dg.renderArrayTypedef(t);1674 .len = t.arrayLenIncludingSentinel(),
1675 .elem_type = t.childType(),
1676 } };
1677 const array_ty = Type.initPayload(&array_pl.base);
1678
1679 const name = dg.getTypedefName(array_ty) orelse
1680 try dg.renderArrayTypedef(array_ty);
13671681
1368 return w.writeAll(name);1682 return w.writeAll(name);
1369 },1683 },
...@@ -1371,57 +1685,74 @@ pub const DeclGen = struct {...@@ -1371,57 +1685,74 @@ pub const DeclGen = struct {
1371 var opt_buf: Type.Payload.ElemType = undefined;1685 var opt_buf: Type.Payload.ElemType = undefined;
1372 const child_type = t.optionalChild(&opt_buf);1686 const child_type = t.optionalChild(&opt_buf);
13731687
1374 if (!child_type.hasRuntimeBitsIgnoreComptime()) {1688 if (!child_type.hasRuntimeBitsIgnoreComptime())
1375 return w.writeAll("bool");1689 return dg.renderType(w, Type.bool, kind);
1376 }
13771690
1378 if (t.optionalReprIsPayload()) {1691 if (t.optionalReprIsPayload())
1379 return dg.renderType(w, child_type);1692 return dg.renderType(w, child_type, kind);
1380 }
13811693
1382 const name = dg.getTypedefName(t) orelse1694 const name = dg.getTypedefName(t) orelse
1383 try dg.renderOptionalTypedef(t, child_type);1695 try dg.renderOptionalTypedef(t, child_type);
13841696
1385 return w.writeAll(name);1697 return w.writeAll(name);
1386 },1698 },
1387 .ErrorSet => {
1388 comptime assert(Type.anyerror.abiSize(builtin.target) == 2);
1389 return w.writeAll("uint16_t");
1390 },
1391 .ErrorUnion => {1699 .ErrorUnion => {
1392 const payload_ty = t.errorUnionPayload();1700 const payload_ty = t.errorUnionPayload();
13931701
1394 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1702 if (!payload_ty.hasRuntimeBitsIgnoreComptime())
1395 return dg.renderType(w, Type.anyerror);1703 return dg.renderType(w, Type.anyerror, kind);
1396 }
13971704
1398 const name = dg.getTypedefName(t) orelse1705 var error_union_pl = Type.Payload.ErrorUnion{
1399 try dg.renderErrorUnionTypedef(t);1706 .data = .{ .error_set = Type.anyerror, .payload = payload_ty },
1707 };
1708 const error_union_ty = Type.initPayload(&error_union_pl.base);
14001709
1401 return w.writeAll(name);1710 const name = dg.getTypedefName(error_union_ty) orelse
1402 },1711 try dg.renderErrorUnionTypedef(error_union_ty);
1403 .Struct => {
1404 const name = dg.getTypedefName(t) orelse if (t.isTuple() or t.tag() == .anon_struct)
1405 try dg.renderTupleTypedef(t)
1406 else
1407 try dg.renderStructTypedef(t);
14081712
1409 return w.writeAll(name);1713 return w.writeAll(name);
1410 },1714 },
1411 .Union => {1715 .Struct, .Union => |tag| if (tag == .Struct and t.containerLayout() == .Packed)
1412 const name = dg.getTypedefName(t) orelse1716 try dg.renderType(w, t.castTag(.@"struct").?.data.backing_int_ty, kind)
1413 try dg.renderUnionTypedef(t);1717 else if (kind == .Complete or t.isTupleOrAnonStruct()) {
1718 const name = dg.getTypedefName(t) orelse switch (tag) {
1719 .Struct => if (t.isTupleOrAnonStruct())
1720 try dg.renderTupleTypedef(t)
1721 else
1722 try dg.renderStructTypedef(t),
1723 .Union => try dg.renderUnionTypedef(t),
1724 else => unreachable,
1725 };
14141726
1415 return w.writeAll(name);1727 try w.writeAll(name);
1728 } else {
1729 var ptr_pl = Type.Payload.ElemType{
1730 .base = .{ .tag = .single_const_pointer },
1731 .data = t,
1732 };
1733 const ptr_ty = Type.initPayload(&ptr_pl.base);
1734
1735 const name = dg.getTypedefName(ptr_ty) orelse
1736 try dg.renderFwdTypedef(ptr_ty);
1737
1738 try w.writeAll(name);
1416 },1739 },
1417 .Enum => {1740 .Enum => {
1418 // For enums, we simply use the integer tag type.1741 // For enums, we simply use the integer tag type.
1419 var int_tag_ty_buffer: Type.Payload.Bits = undefined;1742 var int_tag_buf: Type.Payload.Bits = undefined;
1420 const int_tag_ty = t.intTagType(&int_tag_ty_buffer);1743 const int_tag_ty = t.intTagType(&int_tag_buf);
1744
1745 try dg.renderType(w, int_tag_ty, kind);
1746 },
1747 .Opaque => switch (t.tag()) {
1748 .@"opaque" => {
1749 const name = dg.getTypedefName(t) orelse
1750 try dg.renderOpaqueTypedef(t);
14211751
1422 try dg.renderType(w, int_tag_ty);1752 try w.writeAll(name);
1753 },
1754 else => unreachable,
1423 },1755 },
1424 .Opaque => return w.writeAll("void"),
14251756
1426 .Frame,1757 .Frame,
1427 .AnyFrame,1758 .AnyFrame,
...@@ -1456,13 +1787,8 @@ pub const DeclGen = struct {...@@ -1456,13 +1787,8 @@ pub const DeclGen = struct {
1456 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |1787 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
1457 /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" |1788 /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" |
1458 ///1789 ///
1459 fn renderTypecast(1790 fn renderTypecast(dg: *DeclGen, w: anytype, ty: Type) error{ OutOfMemory, AnalysisFail }!void {
1460 dg: *DeclGen,1791 return renderTypeAndName(dg, w, ty, .{ .bytes = "" }, .Mut, 0, .Complete);
1461 w: anytype,
1462 ty: Type,
1463 ) error{ OutOfMemory, AnalysisFail }!void {
1464 const name = CValue{ .bytes = "" };
1465 return renderTypeAndName(dg, w, ty, name, .Mut, 0);
1466 }1792 }
14671793
1468 /// Renders a type and name in field declaration/definition format.1794 /// Renders a type and name in field declaration/definition format.
...@@ -1481,26 +1807,36 @@ pub const DeclGen = struct {...@@ -1481,26 +1807,36 @@ pub const DeclGen = struct {
1481 name: CValue,1807 name: CValue,
1482 mutability: Mutability,1808 mutability: Mutability,
1483 alignment: u32,1809 alignment: u32,
1810 kind: TypedefKind,
1484 ) error{ OutOfMemory, AnalysisFail }!void {1811 ) error{ OutOfMemory, AnalysisFail }!void {
1485 var suffix = std.ArrayList(u8).init(dg.gpa);1812 var suffix = std.ArrayList(u8).init(dg.gpa);
1486 defer suffix.deinit();1813 defer suffix.deinit();
1814 const suffix_writer = suffix.writer();
14871815
1488 // Any top-level array types are rendered here as a suffix, which1816 // Any top-level array types are rendered here as a suffix, which
1489 // avoids creating typedefs for every array type1817 // avoids creating typedefs for every array type
1818 const target = dg.module.getTarget();
1490 var render_ty = ty;1819 var render_ty = ty;
1491 while (render_ty.zigTypeTag() == .Array) {1820 var depth: u32 = 0;
1492 const sentinel_bit = @boolToInt(render_ty.sentinel() != null);1821 while (loweredArrayInfo(render_ty, target)) |array_info| {
1493 const c_len = render_ty.arrayLen() + sentinel_bit;1822 const c_len = array_info.len + @boolToInt(array_info.sentinel != null);
1494 try suffix.writer().print("[{d}]", .{c_len});1823 var c_len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = c_len };
1495 render_ty = render_ty.elemType();1824 const c_len_val = Value.initPayload(&c_len_pl.base);
1825
1826 try suffix_writer.writeByte('[');
1827 if (mutability == .ConstArgument and depth == 0) try suffix_writer.writeAll("static const ");
1828 try suffix.writer().print("{}]", .{try dg.fmtIntLiteral(Type.usize, c_len_val)});
1829 render_ty = array_info.elem_type;
1830 depth += 1;
1496 }1831 }
14971832
1498 if (alignment != 0)1833 if (alignment != 0 and alignment > ty.abiAlignment(target)) {
1499 try w.print("ZIG_ALIGN({}) ", .{alignment});1834 try w.print("zig_align({}) ", .{alignment});
1500 try dg.renderType(w, render_ty);1835 }
1836 try dg.renderType(w, render_ty, kind);
15011837
1502 const const_prefix = switch (mutability) {1838 const const_prefix = switch (mutability) {
1503 .Const => "const ",1839 .Const, .ConstArgument => "const ",
1504 .Mut => "",1840 .Mut => "",
1505 };1841 };
1506 try w.print(" {s}", .{const_prefix});1842 try w.print(" {s}", .{const_prefix});
...@@ -1508,6 +1844,79 @@ pub const DeclGen = struct {...@@ -1508,6 +1844,79 @@ pub const DeclGen = struct {
1508 try w.writeAll(suffix.items);1844 try w.writeAll(suffix.items);
1509 }1845 }
15101846
1847 fn renderTagNameFn(dg: *DeclGen, enum_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1848 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1849 defer buffer.deinit();
1850 const bw = buffer.writer();
1851
1852 const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
1853
1854 try buffer.appendSlice("static ");
1855 try dg.renderType(bw, name_slice_ty, .Complete);
1856 const name_begin = buffer.items.len + " ".len;
1857 try bw.print(" zig_tagName_{}(", .{typeToCIdentifier(enum_ty, dg.module)});
1858 const name_end = buffer.items.len - "(".len;
1859 try dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, .Const, 0, .Complete);
1860 try buffer.appendSlice(") {\n switch (tag) {\n");
1861 for (enum_ty.enumFields().keys()) |name, index| {
1862 const name_z = try dg.typedefs.allocator.dupeZ(u8, name);
1863 defer dg.typedefs.allocator.free(name_z);
1864 const name_bytes = name_z[0 .. name_z.len + 1];
1865
1866 var tag_pl: Value.Payload.U32 = .{
1867 .base = .{ .tag = .enum_field_index },
1868 .data = @intCast(u32, index),
1869 };
1870 const tag_val = Value.initPayload(&tag_pl.base);
1871
1872 var int_pl: Value.Payload.U64 = undefined;
1873 const int_val = tag_val.enumToInt(enum_ty, &int_pl);
1874
1875 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
1876 const name_ty = Type.initPayload(&name_ty_pl.base);
1877
1878 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes };
1879 const name_val = Value.initPayload(&name_pl.base);
1880
1881 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
1882 const len_val = Value.initPayload(&len_pl.base);
1883
1884 try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)});
1885 try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0, .Complete);
1886 try buffer.appendSlice(" = ");
1887 try dg.renderValue(bw, name_ty, name_val, .Initializer);
1888 try buffer.appendSlice(";\n return (");
1889 try dg.renderTypecast(bw, name_slice_ty);
1890 try bw.print("){{{}, {}}};\n", .{
1891 fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val),
1892 });
1893
1894 try buffer.appendSlice(" }\n");
1895 }
1896 try buffer.appendSlice(" }\n while (");
1897 try dg.renderValue(bw, Type.bool, Value.@"true", .Other);
1898 try buffer.appendSlice(") ");
1899 _ = try airBreakpoint(bw);
1900 try buffer.appendSlice("}\n");
1901
1902 const rendered = buffer.toOwnedSlice();
1903 errdefer dg.typedefs.allocator.free(rendered);
1904 const name = rendered[name_begin..name_end];
1905
1906 try dg.typedefs.ensureUnusedCapacity(1);
1907 dg.typedefs.putAssumeCapacityNoClobber(
1908 try enum_ty.copy(dg.typedefs_arena),
1909 .{ .name = name, .rendered = rendered },
1910 );
1911
1912 return name;
1913 }
1914
1915 fn getTagNameFn(dg: *DeclGen, enum_ty: Type) ![]const u8 {
1916 return dg.getTypedefName(enum_ty) orelse
1917 try dg.renderTagNameFn(enum_ty);
1918 }
1919
1511 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {1920 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
1512 switch (tv.val.tag()) {1921 switch (tv.val.tag()) {
1513 .extern_fn => return true,1922 .extern_fn => return true,
...@@ -1523,7 +1932,7 @@ pub const DeclGen = struct {...@@ -1523,7 +1932,7 @@ pub const DeclGen = struct {
1523 }1932 }
1524 }1933 }
15251934
1526 fn writeCValue(dg: DeclGen, w: anytype, c_value: CValue) !void {1935 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
1527 switch (c_value) {1936 switch (c_value) {
1528 .none => unreachable,1937 .none => unreachable,
1529 .local => |i| return w.print("t{d}", .{i}),1938 .local => |i| return w.print("t{d}", .{i}),
...@@ -1535,20 +1944,13 @@ pub const DeclGen = struct {...@@ -1535,20 +1944,13 @@ pub const DeclGen = struct {
1535 try w.writeByte('&');1944 try w.writeByte('&');
1536 return dg.renderDeclName(w, decl);1945 return dg.renderDeclName(w, decl);
1537 },1946 },
1538 .undefined_ptr => {1947 .undef => |ty| return dg.renderValue(w, ty, Value.undef, .Other),
1539 const target = dg.module.getTarget();
1540 switch (target.cpu.arch.ptrBitWidth()) {
1541 32 => try w.writeAll("(void *)0xaaaaaaaa"),
1542 64 => try w.writeAll("(void *)0xaaaaaaaaaaaaaaaa"),
1543 else => unreachable,
1544 }
1545 },
1546 .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),1948 .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
1547 .bytes => |bytes| return w.writeAll(bytes),1949 .bytes => |bytes| return w.writeAll(bytes),
1548 }1950 }
1549 }1951 }
15501952
1551 fn writeCValueDeref(dg: DeclGen, w: anytype, c_value: CValue) !void {1953 fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {
1552 switch (c_value) {1954 switch (c_value) {
1553 .none => unreachable,1955 .none => unreachable,
1554 .local => |i| return w.print("(*t{d})", .{i}),1956 .local => |i| return w.print("(*t{d})", .{i}),
...@@ -1561,7 +1963,7 @@ pub const DeclGen = struct {...@@ -1561,7 +1963,7 @@ pub const DeclGen = struct {
1561 return w.writeByte(')');1963 return w.writeByte(')');
1562 },1964 },
1563 .decl_ref => |decl| return dg.renderDeclName(w, decl),1965 .decl_ref => |decl| return dg.renderDeclName(w, decl),
1564 .undefined_ptr => unreachable,1966 .undef => unreachable,
1565 .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}),1967 .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}),
1566 .bytes => |bytes| {1968 .bytes => |bytes| {
1567 try w.writeAll("(*");1969 try w.writeAll("(*");
...@@ -1571,23 +1973,175 @@ pub const DeclGen = struct {...@@ -1571,23 +1973,175 @@ pub const DeclGen = struct {
1571 }1973 }
1572 }1974 }
15731975
1574 fn renderDeclName(dg: DeclGen, writer: anytype, decl_index: Decl.Index) !void {1976 fn writeCValueMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
1977 try dg.writeCValue(writer, c_value);
1978 try writer.writeByte('.');
1979 try dg.writeCValue(writer, member);
1980 }
1981
1982 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
1983 switch (c_value) {
1984 .none, .constant, .undef => unreachable,
1985 .local, .arg, .decl, .identifier, .bytes => {
1986 try dg.writeCValue(writer, c_value);
1987 try writer.writeAll("->");
1988 },
1989 .local_ref, .decl_ref => {
1990 try dg.writeCValueDeref(writer, c_value);
1991 try writer.writeByte('.');
1992 },
1993 }
1994 try dg.writeCValue(writer, member);
1995 }
1996
1997 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index) !void {
1575 const decl = dg.module.declPtr(decl_index);1998 const decl = dg.module.declPtr(decl_index);
1576 dg.module.markDeclAlive(decl);1999 dg.module.markDeclAlive(decl);
15772000
1578 if (dg.module.decl_exports.get(decl_index)) |exports| {2001 if (dg.module.decl_exports.get(decl_index)) |exports| {
1579 return writer.writeAll(exports[0].options.name);2002 return writer.writeAll(exports[0].options.name);
1580 } else if (decl.val.tag() == .extern_fn) {2003 } else if (decl.isExtern()) {
1581 return writer.writeAll(mem.sliceTo(decl.name, 0));2004 return writer.writeAll(mem.sliceTo(decl.name, 0));
1582 } else {2005 } else {
1583 const gpa = dg.module.gpa;2006 const gpa = dg.gpa;
1584 const name = try decl.getFullyQualifiedName(dg.module);2007 const name = try decl.getFullyQualifiedName(dg.module);
1585 defer gpa.free(name);2008 defer gpa.free(name);
1586 return writer.print("{ }", .{fmtIdent(name)});2009 return writer.print("{ }", .{fmtIdent(name)});
1587 }2010 }
1588 }2011 }
2012
2013 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
2014 const target = dg.module.getTarget();
2015 if (ty.isAbiInt()) {
2016 const int_info = ty.intInfo(target);
2017 const c_bits = toCIntBits(int_info.bits) orelse
2018 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
2019 try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits });
2020 } else if (ty.isRuntimeFloat()) {
2021 try ty.print(writer, dg.module);
2022 } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
2023 ty.fmt(dg.module),
2024 });
2025 }
2026
2027 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {
2028 const target = dg.module.getTarget();
2029 switch (info) {
2030 .None => {},
2031 .Range => {
2032 var arena = std.heap.ArenaAllocator.init(dg.gpa);
2033 defer arena.deinit();
2034
2035 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
2036 var stack align(@alignOf(ExpectedContents)) =
2037 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
2038
2039 const int_info = ty.intInfo(target);
2040 if (int_info.signedness == .signed) {
2041 const min_val = try ty.minInt(stack.get(), target);
2042 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val)});
2043 }
2044
2045 const max_val = try ty.maxInt(stack.get(), target);
2046 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val)});
2047 },
2048 .Bits => {
2049 var bits_pl = Value.Payload.U64{
2050 .base = .{ .tag = .int_u64 },
2051 .data = ty.bitSize(target),
2052 };
2053 const bits_val = Value.initPayload(&bits_pl.base);
2054 try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val)});
2055 },
2056 }
2057 }
2058
2059 fn fmtIntLiteral(
2060 dg: *DeclGen,
2061 ty: Type,
2062 val: Value,
2063 ) !std.fmt.Formatter(formatIntLiteral) {
2064 const int_info = ty.intInfo(dg.module.getTarget());
2065 const c_bits = toCIntBits(int_info.bits);
2066 if (c_bits == null or c_bits.? > 128)
2067 return dg.fail("TODO implement integer constants larger than 128 bits", .{});
2068 return std.fmt.Formatter(formatIntLiteral){ .data = .{
2069 .ty = ty,
2070 .val = val,
2071 .mod = dg.module,
2072 } };
2073 }
1589};2074};
15902075
2076pub fn genGlobalAsm(mod: *Module, code: *std.ArrayList(u8)) !void {
2077 var it = mod.global_assembly.valueIterator();
2078 while (it.next()) |asm_source| {
2079 try code.writer().print("__asm({s});\n", .{fmtStringLiteral(asm_source.*)});
2080 }
2081}
2082
2083pub fn genErrDecls(o: *Object) !void {
2084 const writer = o.writer();
2085
2086 try writer.writeAll("enum {\n");
2087 o.indent_writer.pushIndent();
2088 var max_name_len: usize = 0;
2089 for (o.dg.module.error_name_list.items) |name, value| {
2090 max_name_len = std.math.max(name.len, max_name_len);
2091 var err_pl = Value.Payload.Error{ .data = .{ .name = name } };
2092 try o.dg.renderValue(writer, Type.anyerror, Value.initPayload(&err_pl.base), .Other);
2093 try writer.print(" = {d}u,\n", .{value});
2094 }
2095 o.indent_writer.popIndent();
2096 try writer.writeAll("};\n");
2097
2098 const name_prefix = "zig_errorName";
2099 const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1);
2100 defer o.dg.gpa.free(name_buf);
2101
2102 std.mem.copy(u8, name_buf, name_prefix ++ "_");
2103 for (o.dg.module.error_name_list.items) |name| {
2104 std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name);
2105 name_buf[name_prefix.len + "_".len + name.len] = 0;
2106
2107 const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0];
2108 const name_z = identifier[name_prefix.len + "_".len ..];
2109
2110 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
2111 const name_ty = Type.initPayload(&name_ty_pl.base);
2112
2113 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z };
2114 const name_val = Value.initPayload(&name_pl.base);
2115
2116 try writer.writeAll("static ");
2117 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .Const, 0, .Complete);
2118 try writer.writeAll(" = ");
2119 try o.dg.renderValue(writer, name_ty, name_val, .Initializer);
2120 try writer.writeAll(";\n");
2121 }
2122
2123 var name_array_ty_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{
2124 .len = o.dg.module.error_name_list.items.len,
2125 .elem_type = Type.initTag(.const_slice_u8_sentinel_0),
2126 } };
2127 const name_array_ty = Type.initPayload(&name_array_ty_pl.base);
2128
2129 try writer.writeAll("static ");
2130 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, .Const, 0, .Complete);
2131 try writer.writeAll(" = {");
2132 for (o.dg.module.error_name_list.items) |name, value| {
2133 if (value != 0) try writer.writeByte(',');
2134
2135 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
2136 const len_val = Value.initPayload(&len_pl.base);
2137
2138 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{
2139 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val),
2140 });
2141 }
2142 try writer.writeAll("};\n");
2143}
2144
1591pub fn genFunc(f: *Function) !void {2145pub fn genFunc(f: *Function) !void {
1592 const tracy = trace(@src());2146 const tracy = trace(@src());
1593 defer tracy.end();2147 defer tracy.end();
...@@ -1599,14 +2153,13 @@ pub fn genFunc(f: *Function) !void {...@@ -1599,14 +2153,13 @@ pub fn genFunc(f: *Function) !void {
15992153
1600 const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl);2154 const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl);
1601 const fwd_decl_writer = o.dg.fwd_decl.writer();2155 const fwd_decl_writer = o.dg.fwd_decl.writer();
1602 if (is_global) {2156 try fwd_decl_writer.writeAll(if (is_global) "zig_extern_c " else "static ");
1603 try fwd_decl_writer.writeAll("ZIG_EXTERN_C ");2157 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
1604 }
1605 try o.dg.renderFunctionSignature(fwd_decl_writer, is_global);
1606 try fwd_decl_writer.writeAll(";\n");2158 try fwd_decl_writer.writeAll(";\n");
16072159
1608 try o.indent_writer.insertNewline();2160 try o.indent_writer.insertNewline();
1609 try o.dg.renderFunctionSignature(o.writer(), is_global);2161 if (!is_global) try o.writer().writeAll("static ");
2162 try o.dg.renderFunctionSignature(o.writer(), .Complete);
1610 try o.writer().writeByte(' ');2163 try o.writer().writeByte(' ');
16112164
1612 // In case we need to use the header, populate it with a copy of the function2165 // In case we need to use the header, populate it with a copy of the function
...@@ -1638,16 +2191,16 @@ pub fn genDecl(o: *Object) !void {...@@ -1638,16 +2191,16 @@ pub fn genDecl(o: *Object) !void {
1638 .val = o.dg.decl.val,2191 .val = o.dg.decl.val,
1639 };2192 };
1640 if (tv.val.tag() == .extern_fn) {2193 if (tv.val.tag() == .extern_fn) {
1641 const writer = o.writer();2194 const fwd_decl_writer = o.dg.fwd_decl.writer();
1642 try writer.writeAll("ZIG_EXTERN_C ");2195 try fwd_decl_writer.writeAll("zig_extern_c ");
1643 try o.dg.renderFunctionSignature(writer, true);2196 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
1644 try writer.writeAll(";\n");2197 try fwd_decl_writer.writeAll(";\n");
1645 } else if (tv.val.castTag(.variable)) |var_payload| {2198 } else if (tv.val.castTag(.variable)) |var_payload| {
1646 const variable: *Module.Var = var_payload.data;2199 const variable: *Module.Var = var_payload.data;
1647 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;2200 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;
1648 const fwd_decl_writer = o.dg.fwd_decl.writer();2201 const fwd_decl_writer = o.dg.fwd_decl.writer();
1649 if (is_global) {2202 if (is_global) {
1650 try fwd_decl_writer.writeAll("ZIG_EXTERN_C ");2203 try fwd_decl_writer.writeAll("zig_extern_c ");
1651 }2204 }
1652 if (variable.is_threadlocal) {2205 if (variable.is_threadlocal) {
1653 try fwd_decl_writer.writeAll("zig_threadlocal ");2206 try fwd_decl_writer.writeAll("zig_threadlocal ");
...@@ -1659,34 +2212,36 @@ pub fn genDecl(o: *Object) !void {...@@ -1659,34 +2212,36 @@ pub fn genDecl(o: *Object) !void {
1659 .decl = o.dg.decl_index,2212 .decl = o.dg.decl_index,
1660 };2213 };
16612214
1662 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");2215 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
1663 try fwd_decl_writer.writeAll(";\n");2216 try fwd_decl_writer.writeAll(";\n");
16642217
1665 if (variable.init.isUndefDeep()) {2218 if (variable.is_extern or variable.init.isUndefDeep()) {
1666 return;2219 return;
1667 }2220 }
16682221
1669 try o.indent_writer.insertNewline();
1670 const w = o.writer();2222 const w = o.writer();
1671 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");2223 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
1672 try w.writeAll(" = ");2224 try w.writeAll(" = ");
1673 if (variable.init.tag() != .unreachable_value) {2225 if (variable.init.tag() != .unreachable_value) {
1674 try o.dg.renderValue(w, tv.ty, variable.init, .Other);2226 try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
1675 }2227 }
1676 try w.writeAll(";");2228 try w.writeByte(';');
1677 try o.indent_writer.insertNewline();2229 try o.indent_writer.insertNewline();
1678 } else {2230 } else {
2231 const decl_c_value: CValue = .{ .decl = o.dg.decl_index };
2232
2233 const fwd_decl_writer = o.dg.fwd_decl.writer();
2234 try fwd_decl_writer.writeAll("static ");
2235 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
2236 try fwd_decl_writer.writeAll(";\n");
2237
1679 const writer = o.writer();2238 const writer = o.writer();
1680 try writer.writeAll("static ");2239 try writer.writeAll("static ");
1681
1682 // TODO ask the Decl if it is const2240 // TODO ask the Decl if it is const
1683 // https://github.com/ziglang/zig/issues/75822241 // https://github.com/ziglang/zig/issues/7582
16842242 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
1685 const decl_c_value: CValue = .{ .decl = o.dg.decl_index };
1686 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align");
1687
1688 try writer.writeAll(" = ");2243 try writer.writeAll(" = ");
1689 try o.dg.renderValue(writer, tv.ty, tv.val, .Other);2244 try o.dg.renderValue(writer, tv.ty, tv.val, .Initializer);
1690 try writer.writeAll(";\n");2245 try writer.writeAll(";\n");
1691 }2246 }
1692}2247}
...@@ -1705,8 +2260,8 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -1705,8 +2260,8 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
1705 .Fn => {2260 .Fn => {
1706 const is_global = dg.declIsGlobal(tv);2261 const is_global = dg.declIsGlobal(tv);
1707 if (is_global) {2262 if (is_global) {
1708 try writer.writeAll("ZIG_EXTERN_C ");2263 try writer.writeAll("zig_extern_c ");
1709 try dg.renderFunctionSignature(writer, is_global);2264 try dg.renderFunctionSignature(writer, .Complete);
1710 try dg.fwd_decl.appendSlice(";\n");2265 try dg.fwd_decl.appendSlice(";\n");
1711 }2266 }
1712 },2267 },
...@@ -1733,44 +2288,53 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1733,44 +2288,53 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1733 .const_ty => unreachable, // excluded from function bodies2288 .const_ty => unreachable, // excluded from function bodies
1734 .arg => airArg(f),2289 .arg => airArg(f),
17352290
1736 .breakpoint => try airBreakpoint(f),2291 .breakpoint => try airBreakpoint(f.object.writer()),
1737 .ret_addr => try airRetAddr(f, inst),2292 .ret_addr => try airRetAddr(f, inst),
1738 .frame_addr => try airFrameAddress(f, inst),2293 .frame_addr => try airFrameAddress(f, inst),
1739 .unreach => try airUnreach(f),2294 .unreach => try airUnreach(f),
1740 .fence => try airFence(f, inst),2295 .fence => try airFence(f, inst),
17412296
1742 .ptr_add => try airPtrAddSub(f, inst, " + "),2297 .ptr_add => try airPtrAddSub(f, inst, '+'),
1743 .ptr_sub => try airPtrAddSub(f, inst, " - "),2298 .ptr_sub => try airPtrAddSub(f, inst, '-'),
17442299
1745 // TODO use a different strategy for add, sub, mul, div2300 // TODO use a different strategy for add, sub, mul, div
1746 // that communicates to the optimizer that wrapping is UB.2301 // that communicates to the optimizer that wrapping is UB.
1747 .add => try airBinOp (f, inst, " + "),2302 .add => try airBinOp(f, inst, "+", "add", .None),
1748 .sub => try airBinOp (f, inst, " - "),2303 .sub => try airBinOp(f, inst, "-", "sub", .None),
1749 .mul => try airBinOp (f, inst, " * "),2304 .mul => try airBinOp(f, inst, "*", "mul", .None),
1750 .div_float, .div_exact => try airBinOp( f, inst, " / "),2305 .div_float, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None),
1751 .rem => try airBinOp( f, inst, " % "),
17522306
2307 .rem => blk: {
2308 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2309 const lhs_ty = f.air.typeOf(bin_op.lhs);
2310 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2311 // so we only check one.
2312 break :blk if (lhs_ty.isInt())
2313 try airBinOp(f, inst, "%", "rem", .None)
2314 else
2315 try airBinFloatOp(f, inst, "fmod");
2316 },
1753 .div_trunc => blk: {2317 .div_trunc => blk: {
1754 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2318 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
1755 const lhs_ty = f.air.typeOf(bin_op.lhs);2319 const lhs_ty = f.air.typeOf(bin_op.lhs);
1756 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2320 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
1757 // so we only check one.2321 // so we only check one.
1758 break :blk if (lhs_ty.isInt())2322 break :blk if (lhs_ty.isInt())
1759 try airBinOp(f, inst, " / ")2323 try airBinOp(f, inst, "/", "div_trunc", .None)
1760 else2324 else
1761 try airBinOpBuiltinCall(f, inst, "div_trunc");2325 try airBinBuiltinCall(f, inst, "div_trunc", .None);
1762 },2326 },
1763 .div_floor => try airBinOpBuiltinCall(f, inst, "div_floor"),2327 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None),
1764 .mod => try airBinOpBuiltinCall(f, inst, "mod"),2328 .mod => try airBinBuiltinCall(f, inst, "mod", .None),
17652329
1766 .addwrap => try airWrapOp(f, inst, " + ", "addw_"),2330 .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits),
1767 .subwrap => try airWrapOp(f, inst, " - ", "subw_"),2331 .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits),
1768 .mulwrap => try airWrapOp(f, inst, " * ", "mulw_"),2332 .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits),
17692333
1770 .add_sat => try airSatOp(f, inst, "adds_"),2334 .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits),
1771 .sub_sat => try airSatOp(f, inst, "subs_"),2335 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits),
1772 .mul_sat => try airSatOp(f, inst, "muls_"),2336 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits),
1773 .shl_sat => try airSatOp(f, inst, "shls_"),2337 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits),
17742338
1775 .neg => try airNeg(f, inst),2339 .neg => try airNeg(f, inst),
17762340
...@@ -1787,41 +2351,40 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1787,41 +2351,40 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1787 .floor,2351 .floor,
1788 .ceil,2352 .ceil,
1789 .round,2353 .round,
1790 .trunc_float,2354 => |tag| try airUnFloatOp(f, inst, @tagName(tag)),
1791 => |tag| return f.fail("TODO: C backend: implement unary op for tag '{s}'", .{@tagName(tag)}),2355 .trunc_float => try airUnFloatOp(f, inst, "trunc"),
17922356
1793 .mul_add => try airMulAdd(f, inst),2357 .mul_add => try airMulAdd(f, inst),
17942358
1795 .add_with_overflow => try airOverflow(f, inst, "addo_"),2359 .add_with_overflow => try airOverflow(f, inst, "add", .Bits),
1796 .sub_with_overflow => try airOverflow(f, inst, "subo_"),2360 .sub_with_overflow => try airOverflow(f, inst, "sub", .Bits),
1797 .mul_with_overflow => try airOverflow(f, inst, "mulo_"),2361 .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits),
1798 .shl_with_overflow => try airOverflow(f, inst, "shlo_"),2362 .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits),
17992363
1800 .min => try airMinMax(f, inst, "<"),2364 .min => try airMinMax(f, inst, '<'),
1801 .max => try airMinMax(f, inst, ">"),2365 .max => try airMinMax(f, inst, '>'),
18022366
1803 .slice => try airSlice(f, inst),2367 .slice => try airSlice(f, inst),
18042368
1805 .cmp_gt => try airBinOp(f, inst, " > "),2369 .cmp_gt => try airCmpOp(f, inst, ">"),
1806 .cmp_gte => try airBinOp(f, inst, " >= "),2370 .cmp_gte => try airCmpOp(f, inst, ">="),
1807 .cmp_lt => try airBinOp(f, inst, " < "),2371 .cmp_lt => try airCmpOp(f, inst, "<"),
1808 .cmp_lte => try airBinOp(f, inst, " <= "),2372 .cmp_lte => try airCmpOp(f, inst, "<="),
18092373
1810 .cmp_eq => try airEquality(f, inst, "((", "=="),2374 .cmp_eq => try airEquality(f, inst, "((", "=="),
1811 .cmp_neq => try airEquality(f, inst, "!((", "!="),2375 .cmp_neq => try airEquality(f, inst, "!((", "!="),
18122376
1813 .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}),2377 .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}),
1814 .cmp_lt_errors_len => return f.fail("TODO: C backend: implement cmp_lt_errors_len", .{}),2378 .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst),
18152379
1816 // bool_and and bool_or are non-short-circuit operations2380 // bool_and and bool_or are non-short-circuit operations
1817 .bool_and => try airBinOp(f, inst, " & "),2381 .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None),
1818 .bool_or => try airBinOp(f, inst, " | "),2382 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),
1819 .bit_and => try airBinOp(f, inst, " & "),2383 .xor => try airBinOp(f, inst, "^", "xor", .None),
1820 .bit_or => try airBinOp(f, inst, " | "),2384 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),
1821 .xor => try airBinOp(f, inst, " ^ "),2385 .shl, => try airBinBuiltinCall(f, inst, "shl", .None),
1822 .shr, .shr_exact => try airBinOp(f, inst, " >> "),2386 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),
1823 .shl, .shl_exact => try airBinOp(f, inst, " << "),2387 .not => try airNot (f, inst),
1824 .not => try airNot (f, inst),
18252388
1826 .optional_payload => try airOptionalPayload(f, inst),2389 .optional_payload => try airOptionalPayload(f, inst),
1827 .optional_payload_ptr => try airOptionalPayloadPtr(f, inst),2390 .optional_payload_ptr => try airOptionalPayloadPtr(f, inst),
...@@ -1833,10 +2396,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1833,10 +2396,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1833 .is_err_ptr => try airIsErr(f, inst, true, "!="),2396 .is_err_ptr => try airIsErr(f, inst, true, "!="),
1834 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),2397 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),
18352398
1836 .is_null => try airIsNull(f, inst, "==", ""),2399 .is_null => try airIsNull(f, inst, "==", false),
1837 .is_non_null => try airIsNull(f, inst, "!=", ""),2400 .is_non_null => try airIsNull(f, inst, "!=", false),
1838 .is_null_ptr => try airIsNull(f, inst, "==", "[0]"),2401 .is_null_ptr => try airIsNull(f, inst, "==", true),
1839 .is_non_null_ptr => try airIsNull(f, inst, "!=", "[0]"),2402 .is_non_null_ptr => try airIsNull(f, inst, "!=", true),
18402403
1841 .alloc => try airAlloc(f, inst),2404 .alloc => try airAlloc(f, inst),
1842 .ret_ptr => try airRetPtr(f, inst),2405 .ret_ptr => try airRetPtr(f, inst),
...@@ -1848,8 +2411,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1848,8 +2411,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1848 .trunc => try airTrunc(f, inst),2411 .trunc => try airTrunc(f, inst),
1849 .bool_to_int => try airBoolToInt(f, inst),2412 .bool_to_int => try airBoolToInt(f, inst),
1850 .load => try airLoad(f, inst),2413 .load => try airLoad(f, inst),
1851 .ret => try airRet(f, inst),2414 .ret => try airRet(f, inst, false),
1852 .ret_load => try airRetLoad(f, inst),2415 .ret_load => try airRet(f, inst, true),
1853 .store => try airStore(f, inst),2416 .store => try airStore(f, inst),
1854 .loop => try airLoop(f, inst),2417 .loop => try airLoop(f, inst),
1855 .cond_br => try airCondBr(f, inst),2418 .cond_br => try airCondBr(f, inst),
...@@ -1865,11 +2428,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1865,11 +2428,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1865 .memcpy => try airMemcpy(f, inst),2428 .memcpy => try airMemcpy(f, inst),
1866 .set_union_tag => try airSetUnionTag(f, inst),2429 .set_union_tag => try airSetUnionTag(f, inst),
1867 .get_union_tag => try airGetUnionTag(f, inst),2430 .get_union_tag => try airGetUnionTag(f, inst),
1868 .clz => try airBuiltinCall(f, inst, "clz"),2431 .clz => try airUnBuiltinCall(f, inst, "clz", .Bits),
1869 .ctz => try airBuiltinCall(f, inst, "ctz"),2432 .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits),
1870 .popcount => try airBuiltinCall(f, inst, "popcount"),2433 .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits),
1871 .byte_swap => try airBuiltinCall(f, inst, "byte_swap"),2434 .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits),
1872 .bit_reverse => try airBuiltinCall(f, inst, "bit_reverse"),2435 .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits),
1873 .tag_name => try airTagName(f, inst),2436 .tag_name => try airTagName(f, inst),
1874 .error_name => try airErrorName(f, inst),2437 .error_name => try airErrorName(f, inst),
1875 .splat => try airSplat(f, inst),2438 .splat => try airSplat(f, inst),
...@@ -1922,11 +2485,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1922,11 +2485,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1922 .field_parent_ptr => try airFieldParentPtr(f, inst),2485 .field_parent_ptr => try airFieldParentPtr(f, inst),
19232486
1924 .struct_field_val => try airStructFieldVal(f, inst),2487 .struct_field_val => try airStructFieldVal(f, inst),
1925 .slice_ptr => try airSliceField(f, inst, ".ptr;\n"),2488 .slice_ptr => try airSliceField(f, inst, false, "ptr"),
1926 .slice_len => try airSliceField(f, inst, ".len;\n"),2489 .slice_len => try airSliceField(f, inst, false, "len"),
19272490
1928 .ptr_slice_len_ptr => try airPtrSliceFieldPtr(f, inst, ".len;\n"),2491 .ptr_slice_len_ptr => try airSliceField(f, inst, true, "len"),
1929 .ptr_slice_ptr_ptr => try airPtrSliceFieldPtr(f, inst, ".ptr;\n"),2492 .ptr_slice_ptr_ptr => try airSliceField(f, inst, true, "ptr"),
19302493
1931 .ptr_elem_val => try airPtrElemVal(f, inst),2494 .ptr_elem_val => try airPtrElemVal(f, inst),
1932 .ptr_elem_ptr => try airPtrElemPtr(f, inst),2495 .ptr_elem_ptr => try airPtrElemPtr(f, inst),
...@@ -1934,8 +2497,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1934,8 +2497,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1934 .slice_elem_ptr => try airSliceElemPtr(f, inst),2497 .slice_elem_ptr => try airSliceElemPtr(f, inst),
1935 .array_elem_val => try airArrayElemVal(f, inst),2498 .array_elem_val => try airArrayElemVal(f, inst),
19362499
1937 .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""),2500 .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, false),
1938 .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"),2501 .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, true),
1939 .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst),2502 .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst),
1940 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),2503 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
1941 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),2504 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
...@@ -1983,10 +2546,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1983,10 +2546,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1983 }2546 }
19842547
1985 f.object.indent_writer.popIndent();2548 f.object.indent_writer.popIndent();
1986 try writer.writeAll("}");2549 try writer.writeByte('}');
1987}2550}
19882551
1989fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {2552fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {
1990 if (f.liveness.isUnused(inst)) return CValue.none;2553 if (f.liveness.isUnused(inst)) return CValue.none;
19912554
1992 const inst_ty = f.air.typeOfIndex(inst);2555 const inst_ty = f.air.typeOfIndex(inst);
...@@ -1995,26 +2558,14 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue...@@ -1995,26 +2558,14 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue
1995 const writer = f.object.writer();2558 const writer = f.object.writer();
1996 const local = try f.allocLocal(inst_ty, .Const);2559 const local = try f.allocLocal(inst_ty, .Const);
1997 try writer.writeAll(" = ");2560 try writer.writeAll(" = ");
1998 try f.writeCValue(writer, operand);2561 if (is_ptr) {
1999 try writer.writeAll(suffix);2562 try writer.writeByte('&');
2563 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });
2564 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });
2565 try writer.writeAll(";\n");
2000 return local;2566 return local;
2001}2567}
20022568
2003fn airPtrSliceFieldPtr(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
2004 if (f.liveness.isUnused(inst))
2005 return CValue.none;
2006
2007 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
2008 const operand = try f.resolveInst(ty_op.operand);
2009 const writer = f.object.writer();
2010
2011 _ = writer;
2012 _ = operand;
2013 _ = suffix;
2014
2015 return f.fail("TODO: C backend: airPtrSliceFieldPtr", .{});
2016}
2017
2018fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {2569fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2019 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2570 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2020 const ptr_ty = f.air.typeOf(bin_op.lhs);2571 const ptr_ty = f.air.typeOf(bin_op.lhs);
...@@ -2025,9 +2576,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2025,9 +2576,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2025 const writer = f.object.writer();2576 const writer = f.object.writer();
2026 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2577 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2027 try writer.writeAll(" = ");2578 try writer.writeAll(" = ");
2028 try f.writeCValue(writer, ptr);2579 try f.writeCValue(writer, ptr, .Other);
2029 try writer.writeByte('[');2580 try writer.writeByte('[');
2030 try f.writeCValue(writer, index);2581 try f.writeCValue(writer, index, .Other);
2031 try writer.writeAll("];\n");2582 try writer.writeAll("];\n");
2032 return local;2583 return local;
2033}2584}
...@@ -2049,10 +2600,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2049,10 +2600,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
2049 // It's a pointer to an array, so we need to de-reference.2600 // It's a pointer to an array, so we need to de-reference.
2050 try f.writeCValueDeref(writer, ptr);2601 try f.writeCValueDeref(writer, ptr);
2051 } else {2602 } else {
2052 try f.writeCValue(writer, ptr);2603 try f.writeCValue(writer, ptr, .Other);
2053 }2604 }
2054 try writer.writeAll(")[");2605 try writer.writeAll(")[");
2055 try f.writeCValue(writer, index);2606 try f.writeCValue(writer, index, .Other);
2056 try writer.writeAll("];\n");2607 try writer.writeAll("];\n");
2057 return local;2608 return local;
2058}2609}
...@@ -2067,9 +2618,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2067,9 +2618,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2067 const writer = f.object.writer();2618 const writer = f.object.writer();
2068 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2619 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2069 try writer.writeAll(" = ");2620 try writer.writeAll(" = ");
2070 try f.writeCValue(writer, slice);2621 try f.writeCValue(writer, slice, .Other);
2071 try writer.writeAll(".ptr[");2622 try writer.writeAll(".ptr[");
2072 try f.writeCValue(writer, index);2623 try f.writeCValue(writer, index, .Other);
2073 try writer.writeAll("];\n");2624 try writer.writeAll("];\n");
2074 return local;2625 return local;
2075}2626}
...@@ -2085,9 +2636,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2085,9 +2636,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
2085 const writer = f.object.writer();2636 const writer = f.object.writer();
2086 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2637 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2087 try writer.writeAll(" = &");2638 try writer.writeAll(" = &");
2088 try f.writeCValue(writer, slice);2639 try f.writeCValue(writer, slice, .Other);
2089 try writer.writeAll(".ptr[");2640 try writer.writeAll(".ptr[");
2090 try f.writeCValue(writer, index);2641 try f.writeCValue(writer, index, .Other);
2091 try writer.writeAll("];\n");2642 try writer.writeAll("];\n");
2092 return local;2643 return local;
2093}2644}
...@@ -2101,9 +2652,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2101,9 +2652,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2101 const writer = f.object.writer();2652 const writer = f.object.writer();
2102 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2653 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2103 try writer.writeAll(" = ");2654 try writer.writeAll(" = ");
2104 try f.writeCValue(writer, array);2655 try f.writeCValue(writer, array, .Other);
2105 try writer.writeAll("[");2656 try writer.writeByte('[');
2106 try f.writeCValue(writer, index);2657 try f.writeCValue(writer, index, .Other);
2107 try writer.writeAll("];\n");2658 try writer.writeAll("];\n");
2108 return local;2659 return local;
2109}2660}
...@@ -2115,7 +2666,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2115,7 +2666,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
2115 const elem_type = inst_ty.elemType();2666 const elem_type = inst_ty.elemType();
2116 const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut;2667 const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut;
2117 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime()) {2668 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime()) {
2118 return CValue.undefined_ptr;2669 return CValue{ .undef = inst_ty };
2119 }2670 }
21202671
2121 const target = f.object.dg.module.getTarget();2672 const target = f.object.dg.module.getTarget();
...@@ -2130,9 +2681,13 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2130,9 +2681,13 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
2130 const writer = f.object.writer();2681 const writer = f.object.writer();
2131 const inst_ty = f.air.typeOfIndex(inst);2682 const inst_ty = f.air.typeOfIndex(inst);
21322683
2684 const elem_ty = inst_ty.elemType();
2685 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) {
2686 return CValue{ .undef = inst_ty };
2687 }
2688
2133 // First line: the variable used as data storage.2689 // First line: the variable used as data storage.
2134 const elem_type = inst_ty.elemType();2690 const local = try f.allocLocal(elem_ty, .Mut);
2135 const local = try f.allocLocal(elem_type, .Mut);
2136 try writer.writeAll(";\n");2691 try writer.writeAll(";\n");
21372692
2138 return CValue{ .local_ref = local.local };2693 return CValue{ .local_ref = local.local };
...@@ -2146,13 +2701,15 @@ fn airArg(f: *Function) CValue {...@@ -2146,13 +2701,15 @@ fn airArg(f: *Function) CValue {
21462701
2147fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {2702fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2148 const ty_op = f.air.instructions.items(.data)[inst].ty_op;2703 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
2149 const is_volatile = f.air.typeOf(ty_op.operand).isVolatilePtr();2704 const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data;
21502705
2151 if (!is_volatile and f.liveness.isUnused(inst))2706 const inst_ty = f.air.typeOfIndex(inst);
2707 if (!inst_ty.hasRuntimeBitsIgnoreComptime() or
2708 !ptr_info.@"volatile" and f.liveness.isUnused(inst))
2152 return CValue.none;2709 return CValue.none;
21532710
2154 const inst_ty = f.air.typeOfIndex(inst);2711 const target = f.object.dg.module.getTarget();
2155 const is_array = inst_ty.zigTypeTag() == .Array;2712 const is_array = lowersToArray(inst_ty, target);
2156 const operand = try f.resolveInst(ty_op.operand);2713 const operand = try f.resolveInst(ty_op.operand);
2157 const writer = f.object.writer();2714 const writer = f.object.writer();
21582715
...@@ -2162,53 +2719,97 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2162,53 +2719,97 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2162 if (is_array) {2719 if (is_array) {
2163 // Insert a memcpy to initialize this array. The source operand is always a pointer2720 // Insert a memcpy to initialize this array. The source operand is always a pointer
2164 // and thus we only need to know size/type information from the local type/dest.2721 // and thus we only need to know size/type information from the local type/dest.
2165 try writer.writeAll(";");2722 try writer.writeAll(";\n");
2166 try f.object.indent_writer.insertNewline();
2167 try writer.writeAll("memcpy(");2723 try writer.writeAll("memcpy(");
2168 try f.writeCValue(writer, local);2724 try f.writeCValue(writer, local, .FunctionArgument);
2169 try writer.writeAll(", ");2725 try writer.writeAll(", ");
2170 try f.writeCValue(writer, operand);2726 try f.writeCValue(writer, operand, .FunctionArgument);
2171 try writer.writeAll(", sizeof(");2727 try writer.writeAll(", sizeof(");
2172 try f.writeCValue(writer, local);2728 try f.renderTypecast(writer, inst_ty);
2173 try writer.writeAll("));\n");2729 try writer.writeAll("))");
2174 } else {2730 } else if (ptr_info.host_size != 0) {
2175 try writer.writeAll(" = ");2731 var host_pl = Type.Payload.Bits{
2176 try f.writeCValueDeref(writer, operand);2732 .base = .{ .tag = .int_unsigned },
2177 try writer.writeAll(";\n");2733 .data = ptr_info.host_size * 8,
2178 }2734 };
2179 return local;2735 const host_ty = Type.initPayload(&host_pl.base);
2180}
21812736
2182fn airRet(f: *Function, inst: Air.Inst.Index) !CValue {2737 var bit_offset_ty_pl = Type.Payload.Bits{
2183 const un_op = f.air.instructions.items(.data)[inst].un_op;2738 .base = .{ .tag = .int_unsigned },
2184 const writer = f.object.writer();2739 .data = Type.smallestUnsignedBits(host_pl.data - 1),
2185 const ret_ty = f.air.typeOf(un_op);2740 };
2186 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {2741 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
2187 const operand = try f.resolveInst(un_op);2742
2188 try writer.writeAll("return ");2743 var bit_offset_val_pl: Value.Payload.U64 = .{
2189 try f.writeCValue(writer, operand);2744 .base = .{ .tag = .int_u64 },
2190 try writer.writeAll(";\n");2745 .data = ptr_info.bit_offset,
2191 } else if (ret_ty.isError()) {2746 };
2192 try writer.writeAll("return 0;");2747 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
2748
2749 var field_pl = Type.Payload.Bits{
2750 .base = .{ .tag = .int_unsigned },
2751 .data = @intCast(u16, inst_ty.bitSize(target)),
2752 };
2753 const field_ty = Type.initPayload(&field_pl.base);
2754
2755 try writer.writeAll(" = (");
2756 try f.renderTypecast(writer, inst_ty);
2757 try writer.writeAll(")zig_wrap_");
2758 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);
2759 try writer.writeAll("((");
2760 try f.renderTypecast(writer, field_ty);
2761 try writer.writeAll(")zig_shr_");
2762 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
2763 try writer.writeByte('(');
2764 try f.writeCValueDeref(writer, operand);
2765 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
2766 try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits);
2767 try writer.writeByte(')');
2193 } else {2768 } else {
2194 try writer.writeAll("return;\n");2769 try writer.writeAll(" = ");
2770 try f.writeCValueDeref(writer, operand);
2195 }2771 }
2196 return CValue.none;2772 try writer.writeAll(";\n");
2773 return local;
2197}2774}
21982775
2199fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue {2776fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
2200 const un_op = f.air.instructions.items(.data)[inst].un_op;2777 const un_op = f.air.instructions.items(.data)[inst].un_op;
2201 const writer = f.object.writer();2778 const writer = f.object.writer();
2202 const ptr_ty = f.air.typeOf(un_op);2779 const target = f.object.dg.module.getTarget();
2203 const ret_ty = ptr_ty.childType();2780 const op_ty = f.air.typeOf(un_op);
2204 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {2781 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
2205 const ptr = try f.resolveInst(un_op);2782 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
2206 try writer.writeAll("return *");2783 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target);
2207 try f.writeCValue(writer, ptr);2784
2785 if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {
2786 var deref = is_ptr;
2787 const operand = try f.resolveInst(un_op);
2788 const ret_val = if (lowersToArray(ret_ty, target)) ret_val: {
2789 const array_local = try f.allocLocal(lowered_ret_ty, .Mut);
2790 try writer.writeAll(";\n");
2791 try writer.writeAll("memcpy(");
2792 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
2793 try writer.writeAll(", ");
2794 if (deref)
2795 try f.writeCValueDeref(writer, operand)
2796 else
2797 try f.writeCValue(writer, operand, .FunctionArgument);
2798 deref = false;
2799 try writer.writeAll(", sizeof(");
2800 try f.renderTypecast(writer, ret_ty);
2801 try writer.writeAll("));\n");
2802 break :ret_val array_local;
2803 } else operand;
2804
2805 try writer.writeAll("return ");
2806 if (deref)
2807 try f.writeCValueDeref(writer, ret_val)
2808 else
2809 try f.writeCValue(writer, ret_val, .Other);
2208 try writer.writeAll(";\n");2810 try writer.writeAll(";\n");
2209 } else if (ret_ty.isError()) {2811 } else if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) {
2210 try writer.writeAll("return 0;\n");2812 // Not even allowed to return void in a naked function.
2211 } else {
2212 try writer.writeAll("return;\n");2813 try writer.writeAll("return;\n");
2213 }2814 }
2214 return CValue.none;2815 return CValue.none;
...@@ -2226,8 +2827,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2226,8 +2827,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
2226 const local = try f.allocLocal(inst_ty, .Const);2827 const local = try f.allocLocal(inst_ty, .Const);
2227 try writer.writeAll(" = (");2828 try writer.writeAll(" = (");
2228 try f.renderTypecast(writer, inst_ty);2829 try f.renderTypecast(writer, inst_ty);
2229 try writer.writeAll(")");2830 try writer.writeByte(')');
2230 try f.writeCValue(writer, operand);2831 try f.writeCValue(writer, operand, .Other);
2231 try writer.writeAll(";\n");2832 try writer.writeAll(";\n");
2232 return local;2833 return local;
2233}2834}
...@@ -2244,32 +2845,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2244,32 +2845,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
2244 const dest_int_info = inst_ty.intInfo(target);2845 const dest_int_info = inst_ty.intInfo(target);
2245 const dest_bits = dest_int_info.bits;2846 const dest_bits = dest_int_info.bits;
22462847
2247 try writer.writeAll(" = ");2848 try writer.writeAll(" = (");
2849 try f.renderTypecast(writer, inst_ty);
2850 try writer.writeByte(')');
22482851
2249 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {2852 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
2250 try f.writeCValue(writer, operand);2853 try f.writeCValue(writer, operand, .Other);
2251 try writer.writeAll(";\n");2854 try writer.writeAll(";\n");
2252 return local;2855 } else switch (dest_int_info.signedness) {
2253 }
2254
2255 switch (dest_int_info.signedness) {
2256 .unsigned => {2856 .unsigned => {
2257 try f.writeCValue(writer, operand);2857 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
2258 const mask = (@as(u65, 1) << @intCast(u7, dest_bits)) - 1;2858 defer arena.deinit();
2259 try writer.print(" & {d}ULL;\n", .{mask});2859
2260 return local;2860 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
2861 var stack align(@alignOf(ExpectedContents)) =
2862 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
2863
2864 const mask_val = try inst_ty.maxInt(stack.get(), target);
2865
2866 try writer.writeByte('(');
2867 try f.writeCValue(writer, operand, .Other);
2868 try writer.print(" & {x});\n", .{try f.fmtIntLiteral(inst_ty, mask_val)});
2261 },2869 },
2262 .signed => {2870 .signed => {
2263 const operand_ty = f.air.typeOf(ty_op.operand);2871 const operand_ty = f.air.typeOf(ty_op.operand);
2264 const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse2872 const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse
2265 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});2873 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
2266 const shift_rhs = c_bits - dest_bits;2874 var shift_pl = Value.Payload.U64{
2267 try writer.print("(int{d}_t)((uint{d}_t)", .{ c_bits, c_bits });2875 .base = .{ .tag = .int_u64 },
2268 try f.writeCValue(writer, operand);2876 .data = c_bits - dest_bits,
2269 try writer.print(" << {d}) >> {d};\n", .{ shift_rhs, shift_rhs });2877 };
2270 return local;2878 const shift_val = Value.initPayload(&shift_pl.base);
2879
2880 try writer.print("((int{d}_t)((uint{0d}_t)", .{c_bits});
2881 try f.writeCValue(writer, operand, .Other);
2882 try writer.print(" << {}) >> {0});\n", .{try f.fmtIntLiteral(Type.u8, shift_val)});
2271 },2883 },
2272 }2884 }
2885 return local;
2273}2886}
22742887
2275fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {2888fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -2281,256 +2894,127 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2281,256 +2894,127 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
2281 const operand = try f.resolveInst(un_op);2894 const operand = try f.resolveInst(un_op);
2282 const local = try f.allocLocal(inst_ty, .Const);2895 const local = try f.allocLocal(inst_ty, .Const);
2283 try writer.writeAll(" = ");2896 try writer.writeAll(" = ");
2284 try f.writeCValue(writer, operand);2897 try f.writeCValue(writer, operand, .Other);
2285 try writer.writeAll(";\n");2898 try writer.writeAll(";\n");
2286 return local;2899 return local;
2287}2900}
22882901
2289fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue {2902fn airStoreUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue {
2290 const is_debug_build = f.object.dg.module.optimizeMode() == .Debug;2903 if (f.wantSafety()) {
2291 if (!is_debug_build)2904 const writer = f.object.writer();
2292 return CValue.none;2905 try writer.writeAll("memset(");
22932906 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
2294 const writer = f.object.writer();2907 try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)});
2295 try writer.writeAll("memset(");2908 try f.renderTypecast(writer, lhs_child_ty);
2296 try f.writeCValue(writer, dest_ptr);2909 try writer.writeAll("));\n");
2297 try writer.writeAll(", 0xaa, sizeof(");2910 }
2298 try f.writeCValueDeref(writer, dest_ptr);
2299 try writer.writeAll("));\n");
2300 return CValue.none;2911 return CValue.none;
2301}2912}
23022913
2303fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {2914fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2304 // *a = b;2915 // *a = b;
2305 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2916 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2306 const dest_ptr = try f.resolveInst(bin_op.lhs);2917 const ptr_info = f.air.typeOf(bin_op.lhs).ptrInfo().data;
2918 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) return CValue.none;
2919
2920 const ptr_val = try f.resolveInst(bin_op.lhs);
2921 const src_ty = f.air.typeOf(bin_op.rhs);
2307 const src_val = try f.resolveInst(bin_op.rhs);2922 const src_val = try f.resolveInst(bin_op.rhs);
2308 const lhs_child_type = f.air.typeOf(bin_op.lhs).childType();
23092923
2310 // TODO Sema should emit a different instruction when the store should2924 // TODO Sema should emit a different instruction when the store should
2311 // possibly do the safety 0xaa bytes for undefined.2925 // possibly do the safety 0xaa bytes for undefined.
2312 const src_val_is_undefined =2926 const src_val_is_undefined =
2313 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;2927 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
2314 if (src_val_is_undefined)2928 if (src_val_is_undefined)
2315 return try airStoreUndefined(f, dest_ptr);2929 return try airStoreUndefined(f, ptr_info.pointee_type, ptr_val);
23162930
2931 const target = f.object.dg.module.getTarget();
2317 const writer = f.object.writer();2932 const writer = f.object.writer();
2318 if (lhs_child_type.zigTypeTag() == .Array) {2933 if (lowersToArray(ptr_info.pointee_type, target)) {
2319 // For this memcpy to safely work we need the rhs to have the same2934 // For this memcpy to safely work we need the rhs to have the same
2320 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).2935 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
2321 const rhs_type = f.air.typeOf(bin_op.rhs);2936 assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module));
2322 assert(rhs_type.eql(lhs_child_type, f.object.dg.module));
23232937
2324 // If the source is a constant, writeCValue will emit a brace initialization2938 // If the source is a constant, writeCValue will emit a brace initialization
2325 // so work around this by initializing into new local.2939 // so work around this by initializing into new local.
2326 // TODO this should be done by manually initializing elements of the dest array2940 // TODO this should be done by manually initializing elements of the dest array
2327 const array_src = if (src_val == .constant) blk: {2941 const array_src = if (src_val == .constant) blk: {
2328 const new_local = try f.allocLocal(rhs_type, .Const);2942 const new_local = try f.allocLocal(src_ty, .Const);
2329 try writer.writeAll(" = ");2943 try writer.writeAll(" = ");
2330 try f.writeCValue(writer, src_val);2944 try f.writeCValue(writer, src_val, .Initializer);
2331 try writer.writeAll(";");2945 try writer.writeAll(";\n");
2332 try f.object.indent_writer.insertNewline();
23332946
2334 break :blk new_local;2947 break :blk new_local;
2335 } else src_val;2948 } else src_val;
23362949
2337 try writer.writeAll("memcpy(");2950 try writer.writeAll("memcpy(");
2338 try f.writeCValue(writer, dest_ptr);2951 try f.writeCValue(writer, ptr_val, .FunctionArgument);
2339 try writer.writeAll(", ");2952 try writer.writeAll(", ");
2340 try f.writeCValue(writer, array_src);2953 try f.writeCValue(writer, array_src, .FunctionArgument);
2341 try writer.writeAll(", sizeof(");2954 try writer.writeAll(", sizeof(");
2342 try f.writeCValue(writer, array_src);2955 try f.renderTypecast(writer, src_ty);
2343 try writer.writeAll("));\n");2956 try writer.writeAll("))");
2344 } else {2957 } else if (ptr_info.host_size != 0) {
2345 try f.writeCValueDeref(writer, dest_ptr);2958 const host_bits = ptr_info.host_size * 8;
2346 try writer.writeAll(" = ");2959 var host_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = host_bits };
2347 try f.writeCValue(writer, src_val);2960 const host_ty = Type.initPayload(&host_pl.base);
2348 try writer.writeAll(";\n");2961
2349 }2962 var bit_offset_ty_pl = Type.Payload.Bits{
2350 return CValue.none;2963 .base = .{ .tag = .int_unsigned },
2351}2964 .data = Type.smallestUnsignedBits(host_bits - 1),
2352
2353fn airWrapOp(
2354 f: *Function,
2355 inst: Air.Inst.Index,
2356 str_op: [*:0]const u8,
2357 fn_op: [*:0]const u8,
2358) !CValue {
2359 if (f.liveness.isUnused(inst))
2360 return CValue.none;
2361
2362 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2363 const inst_ty = f.air.typeOfIndex(inst);
2364 const target = f.object.dg.module.getTarget();
2365 const int_info = inst_ty.intInfo(target);
2366 const bits = int_info.bits;
2367
2368 // if it's an unsigned int with non-arbitrary bit size then we can just add
2369 if (int_info.signedness == .unsigned) {
2370 const ok_bits = switch (bits) {
2371 8, 16, 32, 64, 128 => true,
2372 else => false,
2373 };2965 };
2374 if (ok_bits or inst_ty.tag() != .int_unsigned) {2966 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
2375 return try airBinOp(f, inst, str_op);
2376 }
2377 }
2378
2379 if (bits > 64) {
2380 return f.fail("TODO: C backend: airWrapOp for large integers", .{});
2381 }
2382
2383 var max_buf: [80]u8 = undefined;
2384 const max = intMax(inst_ty, target, &max_buf);
2385
2386 const lhs = try f.resolveInst(bin_op.lhs);
2387 const rhs = try f.resolveInst(bin_op.rhs);
2388 const w = f.object.writer();
2389
2390 const ret = try f.allocLocal(inst_ty, .Mut);
2391 try w.print(" = zig_{s}", .{fn_op});
2392
2393 switch (inst_ty.tag()) {
2394 .isize => try w.writeAll("isize"),
2395 .c_short => try w.writeAll("short"),
2396 .c_int => try w.writeAll("int"),
2397 .c_long => try w.writeAll("long"),
2398 .c_longlong => try w.writeAll("longlong"),
2399 else => {
2400 const prefix_byte: u8 = signAbbrev(int_info.signedness);
2401 for ([_]u8{ 8, 16, 32, 64 }) |nbits| {
2402 if (bits <= nbits) {
2403 try w.print("{c}{d}", .{ prefix_byte, nbits });
2404 break;
2405 }
2406 } else {
2407 unreachable;
2408 }
2409 },
2410 }
2411
2412 try w.writeByte('(');
2413 try f.writeCValue(w, lhs);
2414 try w.writeAll(", ");
2415 try f.writeCValue(w, rhs);
2416
2417 if (int_info.signedness == .signed) {
2418 var min_buf: [80]u8 = undefined;
2419 const min = intMin(inst_ty, target, &min_buf);
2420
2421 try w.print(", {s}", .{min});
2422 }
2423
2424 try w.print(", {s});", .{max});
2425 try f.object.indent_writer.insertNewline();
2426
2427 return ret;
2428}
2429
2430fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2431 if (f.liveness.isUnused(inst))
2432 return CValue.none;
2433
2434 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2435 const inst_ty = f.air.typeOfIndex(inst);
2436 const int_info = inst_ty.intInfo(f.object.dg.module.getTarget());
2437 const bits = int_info.bits;
2438
2439 switch (bits) {
2440 8, 16, 32, 64, 128 => {},
2441 else => return f.object.dg.fail("TODO: C backend: airSatOp for non power of 2 integers", .{}),
2442 }
2443
2444 // if it's an unsigned int with non-arbitrary bit size then we can just add
2445 if (bits > 64) {
2446 return f.object.dg.fail("TODO: C backend: airSatOp for large integers", .{});
2447 }
24482967
2449 var min_buf: [80]u8 = undefined;2968 var bit_offset_val_pl: Value.Payload.U64 = .{
2450 const min = switch (int_info.signedness) {2969 .base = .{ .tag = .int_u64 },
2451 .unsigned => "0",2970 .data = ptr_info.bit_offset,
2452 else => switch (inst_ty.tag()) {2971 };
2453 .c_short => "SHRT_MIN",2972 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
2454 .c_int => "INT_MIN",
2455 .c_long => "LONG_MIN",
2456 .c_longlong => "LLONG_MIN",
2457 .isize => "INTPTR_MIN",
2458 else => blk: {
2459 // compute the type minimum based on the bitcount (bits)
2460 const val = -1 * std.math.pow(i65, 2, @intCast(i65, bits - 1));
2461 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {
2462 error.NoSpaceLeft => unreachable,
2463 };
2464 },
2465 },
2466 };
24672973
2468 var max_buf: [80]u8 = undefined;2974 const src_bits = src_ty.bitSize(target);
2469 const max = switch (inst_ty.tag()) {
2470 .c_short => "SHRT_MAX",
2471 .c_ushort => "USHRT_MAX",
2472 .c_int => "INT_MAX",
2473 .c_uint => "UINT_MAX",
2474 .c_long => "LONG_MAX",
2475 .c_ulong => "ULONG_MAX",
2476 .c_longlong => "LLONG_MAX",
2477 .c_ulonglong => "ULLONG_MAX",
2478 .isize => "INTPTR_MAX",
2479 .usize => "UINTPTR_MAX",
2480 else => blk: {
2481 const pow_bits = switch (int_info.signedness) {
2482 .signed => bits - 1,
2483 .unsigned => bits,
2484 };
2485 const val = std.math.pow(u65, 2, pow_bits) - 1;
2486 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {
2487 error.NoSpaceLeft => unreachable,
2488 };
2489 },
2490 };
24912975
2492 const lhs = try f.resolveInst(bin_op.lhs);2976 const Limb = std.math.big.Limb;
2493 const rhs = try f.resolveInst(bin_op.rhs);2977 const ExpectedContents = [BigInt.Managed.default_capacity]Limb;
2494 const w = f.object.writer();2978 var stack align(@alignOf(ExpectedContents)) =
2979 std.heap.stackFallback(@sizeOf(ExpectedContents), f.object.dg.gpa);
24952980
2496 const ret = try f.allocLocal(inst_ty, .Mut);2981 var mask = try BigInt.Managed.initCapacity(stack.get(), BigInt.calcTwosCompLimbCount(host_bits));
2497 try w.print(" = zig_{s}", .{fn_op});2982 defer mask.deinit();
24982983
2499 switch (inst_ty.tag()) {2984 try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits));
2500 .isize => try w.writeAll("isize"),2985 try mask.shiftLeft(&mask, ptr_info.bit_offset);
2501 .c_short => try w.writeAll("short"),2986 try mask.bitNotWrap(&mask, .unsigned, host_bits);
2502 .c_int => try w.writeAll("int"),
2503 .c_long => try w.writeAll("long"),
2504 .c_longlong => try w.writeAll("longlong"),
2505 else => {
2506 const prefix_byte: u8 = signAbbrev(int_info.signedness);
2507 for ([_]u8{ 8, 16, 32, 64 }) |nbits| {
2508 if (bits <= nbits) {
2509 try w.print("{c}{d}", .{ prefix_byte, nbits });
2510 break;
2511 }
2512 } else {
2513 unreachable;
2514 }
2515 },
2516 }
25172987
2518 try w.writeByte('(');2988 var mask_pl = Value.Payload.BigInt{
2519 try f.writeCValue(w, lhs);2989 .base = .{ .tag = .int_big_positive },
2520 try w.writeAll(", ");2990 .data = mask.limbs[0..mask.len()],
2521 try f.writeCValue(w, rhs);2991 };
2992 const mask_val = Value.initPayload(&mask_pl.base);
25222993
2523 if (int_info.signedness == .signed) {2994 try f.writeCValueDeref(writer, ptr_val);
2524 try w.print(", {s}", .{min});2995 try writer.writeAll(" = zig_or_");
2996 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
2997 try writer.writeAll("(zig_and_");
2998 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
2999 try writer.writeByte('(');
3000 try f.writeCValueDeref(writer, ptr_val);
3001 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
3002 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3003 try writer.writeAll("((");
3004 try f.renderTypecast(writer, host_ty);
3005 try writer.writeByte(')');
3006 try f.writeCValue(writer, src_val, .Other);
3007 try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
3008 } else {
3009 try f.writeCValueDeref(writer, ptr_val);
3010 try writer.writeAll(" = ");
3011 try f.writeCValue(writer, src_val, .Other);
2525 }3012 }
25263013 try writer.writeAll(";\n");
2527 try w.print(", {s});", .{max});3014 return CValue.none;
2528 try f.object.indent_writer.insertNewline();
2529
2530 return ret;
2531}3015}
25323016
2533fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CValue {3017fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
2534 if (f.liveness.isUnused(inst))3018 if (f.liveness.isUnused(inst))
2535 return CValue.none;3019 return CValue.none;
25363020
...@@ -2542,56 +3026,29 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV...@@ -2542,56 +3026,29 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV
25423026
2543 const inst_ty = f.air.typeOfIndex(inst);3027 const inst_ty = f.air.typeOfIndex(inst);
2544 const scalar_ty = f.air.typeOf(bin_op.lhs).scalarType();3028 const scalar_ty = f.air.typeOf(bin_op.lhs).scalarType();
2545 const target = f.object.dg.module.getTarget();
2546 const int_info = scalar_ty.intInfo(target);
2547 const w = f.object.writer();3029 const w = f.object.writer();
2548 const c_bits = toCIntBits(int_info.bits) orelse
2549 return f.fail("TODO: C backend: implement integer arithmetic larger than 128 bits", .{});
2550
2551 var max_buf: [80]u8 = undefined;
2552 const max = intMax(scalar_ty, target, &max_buf);
2553
2554 const ret = try f.allocLocal(inst_ty, .Mut);
2555 try w.writeAll(";");
2556 try f.object.indent_writer.insertNewline();
2557 try f.writeCValue(w, ret);
2558
2559 switch (int_info.signedness) {
2560 .unsigned => {
2561 try w.print(".field_1 = zig_{s}u{d}(", .{
2562 op_abbrev, c_bits,
2563 });
2564 try f.writeCValue(w, lhs);
2565 try w.writeAll(", ");
2566 try f.writeCValue(w, rhs);
2567 try w.writeAll(", &");
2568 try f.writeCValue(w, ret);
2569 try w.print(".field_0, {s}", .{max});
2570 },
2571 .signed => {
2572 var min_buf: [80]u8 = undefined;
2573 const min = intMin(scalar_ty, target, &min_buf);
2574
2575 try w.print(".field_1 = zig_{s}i{d}(", .{
2576 op_abbrev, c_bits,
2577 });
2578 try f.writeCValue(w, lhs);
2579 try w.writeAll(", ");
2580 try f.writeCValue(w, rhs);
2581 try w.writeAll(", &");
2582 try f.writeCValue(w, ret);
2583 try w.print(".field_0, {s}, {s}", .{ min, max });
2584 },
2585 }
25863030
2587 try w.writeAll(");");3031 const local = try f.allocLocal(inst_ty, .Mut);
2588 try f.object.indent_writer.insertNewline();3032 try w.writeAll(";\n");
2589 return ret;3033
3034 try f.writeCValue(w, local, .Other);
3035 try w.writeAll(".field_1 = zig_");
3036 try w.writeAll(operation);
3037 try w.writeAll("o_");
3038 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3039 try w.writeAll("(&");
3040 try f.writeCValueMember(w, local, .{ .identifier = "field_0" });
3041 try w.writeAll(", ");
3042 try f.writeCValue(w, lhs, .FunctionArgument);
3043 try w.writeAll(", ");
3044 try f.writeCValue(w, rhs, .FunctionArgument);
3045 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
3046 try w.writeAll(");\n");
3047 return local;
2590}3048}
25913049
2592fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3050fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
2593 if (f.liveness.isUnused(inst))3051 if (f.liveness.isUnused(inst)) return CValue.none;
2594 return CValue.none;
25953052
2596 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3053 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
2597 const op = try f.resolveInst(ty_op.operand);3054 const op = try f.resolveInst(ty_op.operand);
...@@ -2600,33 +3057,74 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2600,33 +3057,74 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
2600 const inst_ty = f.air.typeOfIndex(inst);3057 const inst_ty = f.air.typeOfIndex(inst);
2601 const local = try f.allocLocal(inst_ty, .Const);3058 const local = try f.allocLocal(inst_ty, .Const);
26023059
3060 const target = f.object.dg.module.getTarget();
3061 if (inst_ty.bitSize(target) > 64) {}
3062
2603 try writer.writeAll(" = ");3063 try writer.writeAll(" = ");
2604 if (inst_ty.zigTypeTag() == .Bool)3064 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
2605 try writer.writeAll("!")3065 try f.writeCValue(writer, op, .Other);
2606 else
2607 try writer.writeAll("~");
2608 try f.writeCValue(writer, op);
2609 try writer.writeAll(";\n");3066 try writer.writeAll(";\n");
26103067
2611 return local;3068 return local;
2612}3069}
26133070
2614fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {3071fn airBinOp(
2615 if (f.liveness.isUnused(inst))3072 f: *Function,
2616 return CValue.none;3073 inst: Air.Inst.Index,
3074 operator: []const u8,
3075 operation: []const u8,
3076 info: BuiltinInfo,
3077) !CValue {
3078 if (f.liveness.isUnused(inst)) return CValue.none;
26173079
2618 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3080 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3081
3082 const operand_ty = f.air.typeOf(bin_op.lhs);
3083 const target = f.object.dg.module.getTarget();
3084 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)
3085 return try airBinBuiltinCall(f, inst, operation, info);
3086
3087 const inst_ty = f.air.typeOfIndex(inst);
2619 const lhs = try f.resolveInst(bin_op.lhs);3088 const lhs = try f.resolveInst(bin_op.lhs);
2620 const rhs = try f.resolveInst(bin_op.rhs);3089 const rhs = try f.resolveInst(bin_op.rhs);
26213090
2622 const writer = f.object.writer();3091 const writer = f.object.writer();
3092 const local = try f.allocLocal(inst_ty, .Const);
3093
3094 try writer.writeAll(" = ");
3095 try f.writeCValue(writer, lhs, .Other);
3096 try writer.writeByte(' ');
3097 try writer.writeAll(operator);
3098 try writer.writeByte(' ');
3099 try f.writeCValue(writer, rhs, .Other);
3100 try writer.writeAll(";\n");
3101
3102 return local;
3103}
3104
3105fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue {
3106 if (f.liveness.isUnused(inst)) return CValue.none;
3107
3108 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3109
3110 const operand_ty = f.air.typeOf(bin_op.lhs);
3111 const target = f.object.dg.module.getTarget();
3112 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)
3113 return try airCmpBuiltinCall(f, inst, operator);
3114
2623 const inst_ty = f.air.typeOfIndex(inst);3115 const inst_ty = f.air.typeOfIndex(inst);
3116 const lhs = try f.resolveInst(bin_op.lhs);
3117 const rhs = try f.resolveInst(bin_op.rhs);
3118
3119 const writer = f.object.writer();
2624 const local = try f.allocLocal(inst_ty, .Const);3120 const local = try f.allocLocal(inst_ty, .Const);
26253121
2626 try writer.writeAll(" = ");3122 try writer.writeAll(" = ");
2627 try f.writeCValue(writer, lhs);3123 try f.writeCValue(writer, lhs, .Other);
2628 try writer.print("{s}", .{operator});3124 try writer.writeByte(' ');
2629 try f.writeCValue(writer, rhs);3125 try writer.writeAll(operator);
3126 try writer.writeByte(' ');
3127 try f.writeCValue(writer, rhs, .Other);
2630 try writer.writeAll(";\n");3128 try writer.writeAll(";\n");
26313129
2632 return local;3130 return local;
...@@ -2656,31 +3154,48 @@ fn airEquality(...@@ -2656,31 +3154,48 @@ fn airEquality(
2656 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload3154 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
26573155
2658 try writer.writeAll(negate_prefix);3156 try writer.writeAll(negate_prefix);
2659 try f.writeCValue(writer, lhs);3157 try f.writeCValue(writer, lhs, .Other);
2660 try writer.writeAll(".is_null && ");3158 try writer.writeAll(".is_null && ");
2661 try f.writeCValue(writer, rhs);3159 try f.writeCValue(writer, rhs, .Other);
2662 try writer.writeAll(".is_null) || (");3160 try writer.writeAll(".is_null) || (");
2663 try f.writeCValue(writer, lhs);3161 try f.writeCValue(writer, lhs, .Other);
2664 try writer.writeAll(".payload == ");3162 try writer.writeAll(".payload == ");
2665 try f.writeCValue(writer, rhs);3163 try f.writeCValue(writer, rhs, .Other);
2666 try writer.writeAll(".payload && ");3164 try writer.writeAll(".payload && ");
2667 try f.writeCValue(writer, lhs);3165 try f.writeCValue(writer, lhs, .Other);
2668 try writer.writeAll(".is_null == ");3166 try writer.writeAll(".is_null == ");
2669 try f.writeCValue(writer, rhs);3167 try f.writeCValue(writer, rhs, .Other);
2670 try writer.writeAll(".is_null));\n");3168 try writer.writeAll(".is_null));\n");
26713169
2672 return local;3170 return local;
2673 }3171 }
26743172
2675 try f.writeCValue(writer, lhs);3173 try f.writeCValue(writer, lhs, .Other);
3174 try writer.writeByte(' ');
2676 try writer.writeAll(eq_op_str);3175 try writer.writeAll(eq_op_str);
2677 try f.writeCValue(writer, rhs);3176 try writer.writeByte(' ');
3177 try f.writeCValue(writer, rhs, .Other);
2678 try writer.writeAll(";\n");3178 try writer.writeAll(";\n");
26793179
2680 return local;3180 return local;
2681}3181}
26823182
2683fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {3183fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
3184 if (f.liveness.isUnused(inst)) return CValue.none;
3185
3186 const un_op = f.air.instructions.items(.data)[inst].un_op;
3187 const inst_ty = f.air.typeOfIndex(inst);
3188 const operand = try f.resolveInst(un_op);
3189
3190 const writer = f.object.writer();
3191 const local = try f.allocLocal(inst_ty, .Const);
3192 try writer.writeAll(" = ");
3193 try f.writeCValue(writer, operand, .Other);
3194 try writer.print(" < sizeof({ }) / sizeof(*{0 });\n", .{fmtIdent("zig_errorName")});
3195 return local;
3196}
3197
3198fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
2684 if (f.liveness.isUnused(inst)) return CValue.none;3199 if (f.liveness.isUnused(inst)) return CValue.none;
26853200
2686 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3201 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
...@@ -2704,17 +3219,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV...@@ -2704,17 +3219,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV
2704 try writer.writeAll(" = (");3219 try writer.writeAll(" = (");
2705 try f.renderTypecast(writer, inst_ty);3220 try f.renderTypecast(writer, inst_ty);
2706 try writer.writeAll(")(((uintptr_t)");3221 try writer.writeAll(")(((uintptr_t)");
2707 try f.writeCValue(writer, lhs);3222 try f.writeCValue(writer, lhs, .Other);
2708 try writer.print("){s}(", .{operator});3223 try writer.writeAll(") ");
2709 try f.writeCValue(writer, rhs);3224 try writer.writeByte(operator);
3225 try writer.writeAll(" (");
3226 try f.writeCValue(writer, rhs, .Other);
2710 try writer.writeAll("*sizeof(");3227 try writer.writeAll("*sizeof(");
2711 try f.renderTypecast(writer, elem_ty);3228 try f.renderTypecast(writer, elem_ty);
2712 try writer.print(")));\n", .{});3229 try writer.writeAll(")));\n");
27133230
2714 return local;3231 return local;
2715}3232}
27163233
2717fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {3234fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
2718 if (f.liveness.isUnused(inst)) return CValue.none;3235 if (f.liveness.isUnused(inst)) return CValue.none;
27193236
2720 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3237 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
...@@ -2727,13 +3244,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu...@@ -2727,13 +3244,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu
27273244
2728 // (lhs <> rhs) ? lhs : rhs3245 // (lhs <> rhs) ? lhs : rhs
2729 try writer.writeAll(" = (");3246 try writer.writeAll(" = (");
2730 try f.writeCValue(writer, lhs);3247 try f.writeCValue(writer, lhs, .Other);
2731 try writer.print("{s}", .{operator});3248 try writer.writeByte(' ');
2732 try f.writeCValue(writer, rhs);3249 try writer.writeByte(operator);
3250 try writer.writeByte(' ');
3251 try f.writeCValue(writer, rhs, .Other);
2733 try writer.writeAll(") ? ");3252 try writer.writeAll(") ? ");
2734 try f.writeCValue(writer, lhs);3253 try f.writeCValue(writer, lhs, .Other);
2735 try writer.writeAll(" : ");3254 try writer.writeAll(" : ");
2736 try f.writeCValue(writer, rhs);3255 try f.writeCValue(writer, rhs, .Other);
2737 try writer.writeAll(";\n");3256 try writer.writeAll(";\n");
27383257
2739 return local;3258 return local;
...@@ -2751,10 +3270,13 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2751,10 +3270,13 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
2751 const inst_ty = f.air.typeOfIndex(inst);3270 const inst_ty = f.air.typeOfIndex(inst);
2752 const local = try f.allocLocal(inst_ty, .Const);3271 const local = try f.allocLocal(inst_ty, .Const);
27533272
2754 try writer.writeAll(" = {");3273 try writer.writeAll(" = {(");
2755 try f.writeCValue(writer, ptr);3274 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3275 try f.renderTypecast(writer, inst_ty.slicePtrFieldType(&buf));
3276 try writer.writeByte(')');
3277 try f.writeCValue(writer, ptr, .Other);
2756 try writer.writeAll(", ");3278 try writer.writeAll(", ");
2757 try f.writeCValue(writer, len);3279 try f.writeCValue(writer, len, .Initializer);
2758 try writer.writeAll("};\n");3280 try writer.writeAll("};\n");
27593281
2760 return local;3282 return local;
...@@ -2765,6 +3287,9 @@ fn airCall(...@@ -2765,6 +3287,9 @@ fn airCall(
2765 inst: Air.Inst.Index,3287 inst: Air.Inst.Index,
2766 modifier: std.builtin.CallOptions.Modifier,3288 modifier: std.builtin.CallOptions.Modifier,
2767) !CValue {3289) !CValue {
3290 // Not even allowed to call panic in a naked function.
3291 if (f.object.dg.decl.ty.fnCallingConvention() == .Naked) return .none;
3292
2768 switch (modifier) {3293 switch (modifier) {
2769 .auto => {},3294 .auto => {},
2770 .always_tail => return f.fail("TODO: C backend: call with always_tail attribute", .{}),3295 .always_tail => return f.fail("TODO: C backend: call with always_tail attribute", .{}),
...@@ -2783,39 +3308,50 @@ fn airCall(...@@ -2783,39 +3308,50 @@ fn airCall(
2783 };3308 };
2784 const writer = f.object.writer();3309 const writer = f.object.writer();
27853310
2786 const result_local: CValue = r: {3311 const target = f.object.dg.module.getTarget();
2787 if (f.liveness.isUnused(inst)) {3312 const ret_ty = fn_ty.fnReturnType();
2788 if (loweredFnRetTyHasBits(fn_ty)) {3313 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
2789 try writer.print("(void)", .{});3314 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target);
2790 }3315
2791 break :r .none;3316 const result_local: CValue = if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime())
2792 } else {3317 .none
2793 const local = try f.allocLocal(fn_ty.fnReturnType(), .Const);3318 else if (f.liveness.isUnused(inst)) r: {
2794 try writer.writeAll(" = ");3319 try writer.writeByte('(');
2795 break :r local;3320 try f.renderTypecast(writer, Type.void);
2796 }3321 try writer.writeByte(')');
3322 break :r .none;
3323 } else r: {
3324 const local = try f.allocLocal(lowered_ret_ty, .Const);
3325 try writer.writeAll(" = ");
3326 break :r local;
2797 };3327 };
27983328
3329 var is_extern = false;
3330 var name: [*:0]const u8 = "";
2799 callee: {3331 callee: {
2800 known: {3332 known: {
2801 const fn_decl = fn_decl: {3333 const fn_decl = fn_decl: {
2802 const callee_val = f.air.value(pl_op.operand) orelse break :known;3334 const callee_val = f.air.value(pl_op.operand) orelse break :known;
2803 break :fn_decl switch (callee_val.tag()) {3335 break :fn_decl switch (callee_val.tag()) {
2804 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,3336 .extern_fn => blk: {
3337 is_extern = true;
3338 break :blk callee_val.castTag(.extern_fn).?.data.owner_decl;
3339 },
2805 .function => callee_val.castTag(.function).?.data.owner_decl,3340 .function => callee_val.castTag(.function).?.data.owner_decl,
2806 .decl_ref => callee_val.castTag(.decl_ref).?.data,3341 .decl_ref => callee_val.castTag(.decl_ref).?.data,
2807 else => break :known,3342 else => break :known,
2808 };3343 };
2809 };3344 };
3345 name = f.object.dg.module.declPtr(fn_decl).name;
2810 try f.object.dg.renderDeclName(writer, fn_decl);3346 try f.object.dg.renderDeclName(writer, fn_decl);
2811 break :callee;3347 break :callee;
2812 }3348 }
2813 // Fall back to function pointer call.3349 // Fall back to function pointer call.
2814 const callee = try f.resolveInst(pl_op.operand);3350 const callee = try f.resolveInst(pl_op.operand);
2815 try f.writeCValue(writer, callee);3351 try f.writeCValue(writer, callee, .Other);
2816 }3352 }
28173353
2818 try writer.writeAll("(");3354 try writer.writeByte('(');
2819 var args_written: usize = 0;3355 var args_written: usize = 0;
2820 for (args) |arg| {3356 for (args) |arg| {
2821 const ty = f.air.typeOf(arg);3357 const ty = f.air.typeOf(arg);
...@@ -2823,16 +3359,32 @@ fn airCall(...@@ -2823,16 +3359,32 @@ fn airCall(
2823 if (args_written != 0) {3359 if (args_written != 0) {
2824 try writer.writeAll(", ");3360 try writer.writeAll(", ");
2825 }3361 }
2826 if (f.air.value(arg)) |val| {3362 if ((is_extern or std.mem.eql(u8, std.mem.span(name), "main")) and
2827 try f.object.dg.renderValue(writer, f.air.typeOf(arg), val, .FunctionArgument);3363 ty.isCPtr() and ty.childType().tag() == .u8)
2828 } else {3364 {
2829 const val = try f.resolveInst(arg);3365 // Corresponds with hack in renderType .Pointer case.
2830 try f.writeCValue(writer, val);3366 try writer.writeAll("(char");
3367 if (ty.isConstPtr()) try writer.writeAll(" const");
3368 if (ty.isVolatilePtr()) try writer.writeAll(" volatile");
3369 try writer.writeAll(" *)");
2831 }3370 }
3371 try f.writeCValue(writer, try f.resolveInst(arg), .FunctionArgument);
2832 args_written += 1;3372 args_written += 1;
2833 }3373 }
2834 try writer.writeAll(");\n");3374 try writer.writeAll(");\n");
2835 return result_local;3375
3376 if (result_local == .none or !lowersToArray(ret_ty, target)) return result_local;
3377
3378 const array_local = try f.allocLocal(ret_ty, .Mut);
3379 try writer.writeAll(";\n");
3380 try writer.writeAll("memcpy(");
3381 try f.writeCValue(writer, array_local, .FunctionArgument);
3382 try writer.writeAll(", ");
3383 try f.writeCValueMember(writer, result_local, .{ .identifier = "array" });
3384 try writer.writeAll(", sizeof(");
3385 try f.renderTypecast(writer, ret_ty);
3386 try writer.writeAll("));\n");
3387 return array_local;
2836}3388}
28373389
2838fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {3390fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -2931,27 +3483,19 @@ fn lowerTry(...@@ -2931,27 +3483,19 @@ fn lowerTry(
2931 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();3483 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
29323484
2933 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {3485 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
2934 err: {3486 try writer.writeAll("if (");
2935 if (!payload_has_bits) {3487 if (!payload_has_bits) {
2936 if (operand_is_ptr) {3488 if (operand_is_ptr)
2937 try writer.writeAll("if(*");3489 try f.writeCValueDeref(writer, err_union)
2938 } else {3490 else
2939 try writer.writeAll("if(");3491 try f.writeCValue(writer, err_union, .Other);
2940 }3492 } else {
2941 try f.writeCValue(writer, err_union);3493 if (operand_is_ptr or isByRef(err_union_ty))
2942 try writer.writeAll(")");3494 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })
2943 break :err;3495 else
2944 }3496 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });
2945 if (operand_is_ptr or isByRef(err_union_ty)) {
2946 try writer.writeAll("if(");
2947 try f.writeCValue(writer, err_union);
2948 try writer.writeAll("->error)");
2949 break :err;
2950 }
2951 try writer.writeAll("if(");
2952 try f.writeCValue(writer, err_union);
2953 try writer.writeAll(".error)");
2954 }3497 }
3498 try writer.writeByte(')');
29553499
2956 try genBody(f, body);3500 try genBody(f, body);
2957 try f.object.indent_writer.insertNewline();3501 try f.object.indent_writer.insertNewline();
...@@ -2965,15 +3509,25 @@ fn lowerTry(...@@ -2965,15 +3509,25 @@ fn lowerTry(
2965 }3509 }
2966 }3510 }
29673511
2968 const local = try f.allocLocal(result_ty, .Const);3512 const target = f.object.dg.module.getTarget();
2969 if (operand_is_ptr or isByRef(payload_ty)) {3513 const is_array = lowersToArray(payload_ty, target);
2970 try writer.writeAll(" = &");3514 const local = try f.allocLocal(result_ty, if (is_array) .Mut else .Const);
2971 try f.writeCValue(writer, err_union);3515 if (is_array) {
2972 try writer.writeAll("->payload;\n");3516 try writer.writeAll(";\n");
3517 try writer.writeAll("memcpy(");
3518 try f.writeCValue(writer, local, .FunctionArgument);
3519 try writer.writeAll(", ");
3520 try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
3521 try writer.writeAll(", sizeof(");
3522 try f.renderTypecast(writer, payload_ty);
3523 try writer.writeAll("));\n");
2973 } else {3524 } else {
2974 try writer.writeAll(" = ");3525 try writer.writeAll(" = ");
2975 try f.writeCValue(writer, err_union);3526 if (operand_is_ptr or isByRef(payload_ty)) {
2976 try writer.writeAll(".payload;\n");3527 try writer.writeByte('&');
3528 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
3529 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
3530 try writer.writeAll(";\n");
2977 }3531 }
2978 return local;3532 return local;
2979}3533}
...@@ -2987,9 +3541,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2987,9 +3541,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
2987 // If result is .none then the value of the block is unused.3541 // If result is .none then the value of the block is unused.
2988 if (result != .none) {3542 if (result != .none) {
2989 const operand = try f.resolveInst(branch.operand);3543 const operand = try f.resolveInst(branch.operand);
2990 try f.writeCValue(writer, result);3544 try f.writeCValue(writer, result, .Other);
2991 try writer.writeAll(" = ");3545 try writer.writeAll(" = ");
2992 try f.writeCValue(writer, operand);3546 try f.writeCValue(writer, operand, .Other);
2993 try writer.writeAll(";\n");3547 try writer.writeAll(";\n");
2994 }3548 }
29953549
...@@ -3013,8 +3567,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3013,8 +3567,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3013 try writer.writeAll(" = (");3567 try writer.writeAll(" = (");
3014 try f.renderTypecast(writer, inst_ty);3568 try f.renderTypecast(writer, inst_ty);
30153569
3016 try writer.writeAll(")");3570 try writer.writeByte(')');
3017 try f.writeCValue(writer, operand);3571 try f.writeCValue(writer, operand, .Other);
3018 try writer.writeAll(";\n");3572 try writer.writeAll(";\n");
3019 return local;3573 return local;
3020 }3574 }
...@@ -3023,32 +3577,38 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3023,32 +3577,38 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3023 try writer.writeAll(";\n");3577 try writer.writeAll(";\n");
30243578
3025 try writer.writeAll("memcpy(&");3579 try writer.writeAll("memcpy(&");
3026 try f.writeCValue(writer, local);3580 try f.writeCValue(writer, local, .Other);
3027 try writer.writeAll(", &");3581 try writer.writeAll(", &");
3028 try f.writeCValue(writer, operand);3582 try f.writeCValue(writer, operand, .Other);
3029 try writer.writeAll(", sizeof(");3583 try writer.writeAll(", sizeof(");
3030 try f.writeCValue(writer, local);3584 try f.renderTypecast(writer, inst_ty);
3031 try writer.writeAll("));\n");3585 try writer.writeAll("));\n");
30323586
3033 return local;3587 return local;
3034}3588}
30353589
3036fn airBreakpoint(f: *Function) !CValue {3590fn airBreakpoint(writer: anytype) !CValue {
3037 try f.object.writer().writeAll("zig_breakpoint();\n");3591 try writer.writeAll("zig_breakpoint();\n");
3038 return CValue.none;3592 return CValue.none;
3039}3593}
30403594
3041fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {3595fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
3042 if (f.liveness.isUnused(inst)) return CValue.none;3596 if (f.liveness.isUnused(inst)) return CValue.none;
3597 const writer = f.object.writer();
3043 const local = try f.allocLocal(Type.usize, .Const);3598 const local = try f.allocLocal(Type.usize, .Const);
3044 try f.object.writer().writeAll(" = zig_return_address();\n");3599 try writer.writeAll(" = (");
3600 try f.renderTypecast(writer, Type.usize);
3601 try writer.writeAll(")zig_return_address();\n");
3045 return local;3602 return local;
3046}3603}
30473604
3048fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {3605fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
3049 if (f.liveness.isUnused(inst)) return CValue.none;3606 if (f.liveness.isUnused(inst)) return CValue.none;
3607 const writer = f.object.writer();
3050 const local = try f.allocLocal(Type.usize, .Const);3608 const local = try f.allocLocal(Type.usize, .Const);
3051 try f.object.writer().writeAll(" = zig_frame_address();\n");3609 try writer.writeAll(" = (");
3610 try f.renderTypecast(writer, Type.usize);
3611 try writer.writeAll(")zig_frame_address();\n");
3052 return local;3612 return local;
3053}3613}
30543614
...@@ -3064,6 +3624,9 @@ fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3064,6 +3624,9 @@ fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
3064}3624}
30653625
3066fn airUnreach(f: *Function) !CValue {3626fn airUnreach(f: *Function) !CValue {
3627 // Not even allowed to call unreachable in a naked function.
3628 if (f.object.dg.decl.ty.fnCallingConvention() == .Naked) return .none;
3629
3067 try f.object.writer().writeAll("zig_unreachable();\n");3630 try f.object.writer().writeAll("zig_unreachable();\n");
3068 return CValue.none;3631 return CValue.none;
3069}3632}
...@@ -3072,9 +3635,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3072,9 +3635,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
3072 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3635 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3073 const loop = f.air.extraData(Air.Block, ty_pl.payload);3636 const loop = f.air.extraData(Air.Block, ty_pl.payload);
3074 const body = f.air.extra[loop.end..][0..loop.data.body_len];3637 const body = f.air.extra[loop.end..][0..loop.data.body_len];
3075 try f.object.writer().writeAll("while (true) ");3638 const writer = f.object.writer();
3639 try writer.writeAll("while (");
3640 try f.object.dg.renderValue(writer, Type.bool, Value.@"true", .Other);
3641 try writer.writeAll(") ");
3076 try genBody(f, body);3642 try genBody(f, body);
3077 try f.object.indent_writer.insertNewline();3643 try writer.writeByte('\n');
3078 return CValue.none;3644 return CValue.none;
3079}3645}
30803646
...@@ -3087,7 +3653,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3087,7 +3653,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
3087 const writer = f.object.writer();3653 const writer = f.object.writer();
30883654
3089 try writer.writeAll("if (");3655 try writer.writeAll("if (");
3090 try f.writeCValue(writer, cond);3656 try f.writeCValue(writer, cond, .Other);
3091 try writer.writeAll(") ");3657 try writer.writeAll(") ");
3092 try genBody(f, then_body);3658 try genBody(f, then_body);
3093 try writer.writeAll(" else ");3659 try writer.writeAll(" else ");
...@@ -3105,7 +3671,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3105,7 +3671,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
3105 const writer = f.object.writer();3671 const writer = f.object.writer();
31063672
3107 try writer.writeAll("switch (");3673 try writer.writeAll("switch (");
3108 try f.writeCValue(writer, condition);3674 if (condition_ty.tag() == .bool) {
3675 try writer.writeByte('(');
3676 try f.renderTypecast(writer, Type.u1);
3677 try writer.writeByte(')');
3678 }
3679 try f.writeCValue(writer, condition, .Other);
3109 try writer.writeAll(") {");3680 try writer.writeAll(") {");
3110 f.object.indent_writer.pushIndent();3681 f.object.indent_writer.pushIndent();
31113682
...@@ -3138,6 +3709,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3138,6 +3709,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
3138 return CValue.none;3709 return CValue.none;
3139}3710}
31403711
3712fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool {
3713 return switch (constraint[0]) {
3714 '{' => true,
3715 'i', 'r' => false,
3716 else => value == .constant,
3717 };
3718}
3719
3141fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {3720fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3142 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3721 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3143 const extra = f.air.extraData(Air.Asm, ty_pl.payload);3722 const extra = f.air.extraData(Air.Asm, ty_pl.payload);
...@@ -3151,54 +3730,79 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3151,54 +3730,79 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
31513730
3152 if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none;3731 if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none;
31533732
3154 if (outputs.len > 1) {3733 const writer = f.object.writer();
3155 return f.fail("TODO implement codegen for asm with more than 1 output", .{});3734 const inst_ty = f.air.typeOfIndex(inst);
3156 }3735 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime()) local: {
31573736 const local = try f.allocLocal(inst_ty, .Mut);
3158 const output_constraint: ?[]const u8 = for (outputs) |output| {3737 if (f.wantSafety()) {
3159 if (output != .none) {3738 try writer.writeAll(" = ");
3160 return f.fail("TODO implement codegen for non-expr asm", .{});3739 try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);
3161 }3740 }
3741 try writer.writeAll(";\n");
3742 break :local local;
3743 } else .none;
3744
3745 const locals_begin = f.next_local_index;
3746 const constraints_extra_begin = extra_i;
3747 for (outputs) |output| {
3162 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);3748 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3163 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);3749 const constraint = std.mem.sliceTo(extra_bytes, 0);
3164 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);3750 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3165 // This equation accounts for the fact that even if we have exactly 4 bytes3751 // This equation accounts for the fact that even if we have exactly 4 bytes
3166 // for the string, we still use the next u32 for the null terminator.3752 // for the string, we still use the next u32 for the null terminator.
3167 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3753 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
31683754
3169 break constraint;3755 if (constraint.len < 2 or constraint[0] != '=' or
3170 } else null;3756 (constraint[1] == '{' and constraint[constraint.len - 1] != '}'))
31713757 {
3172 const writer = f.object.writer();3758 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
3173 try writer.writeAll("{\n");3759 }
31743760
3175 const inputs_extra_begin = extra_i;3761 const is_reg = constraint[1] == '{';
3176 for (inputs) |input, i| {3762 if (is_reg) {
3177 const input_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);3763 const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
3178 const constraint = std.mem.sliceTo(input_bytes, 0);3764 try writer.writeAll("register ");
3179 const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);3765 _ = try f.allocLocal(output_ty, .Mut);
3766 try writer.writeAll(" __asm(\"");
3767 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
3768 try writer.writeAll("\")");
3769 if (f.wantSafety()) {
3770 try writer.writeAll(" = ");
3771 try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer);
3772 }
3773 try writer.writeAll(";\n");
3774 }
3775 }
3776 for (inputs) |input| {
3777 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3778 const constraint = std.mem.sliceTo(extra_bytes, 0);
3779 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3180 // This equation accounts for the fact that even if we have exactly 4 bytes3780 // This equation accounts for the fact that even if we have exactly 4 bytes
3181 // for the string, we still use the next u32 for the null terminator.3781 // for the string, we still use the next u32 for the null terminator.
3182 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3782 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
31833783
3184 if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') {3784 if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null or
3185 const reg = constraint[1 .. constraint.len - 1];3785 (constraint[0] == '{' and constraint[constraint.len - 1] != '}'))
3186 const arg_c_value = try f.resolveInst(input);3786 {
3187 try writer.writeAll("register ");3787 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
3188 try f.renderType(writer, f.air.typeOf(input));3788 }
31893789
3190 try writer.print(" {s}_constant __asm__(\"{s}\") = ", .{ reg, reg });3790 const is_reg = constraint[0] == '{';
3191 try f.writeCValue(writer, arg_c_value);3791 const input_val = try f.resolveInst(input);
3192 try writer.writeAll(";\n");3792 if (asmInputNeedsLocal(constraint, input_val)) {
3193 } else {3793 const input_ty = f.air.typeOf(input);
3194 try writer.writeAll("register ");3794 if (is_reg) try writer.writeAll("register ");
3195 try f.renderType(writer, f.air.typeOf(input));3795 _ = try f.allocLocal(input_ty, .Const);
3196 try writer.print(" input_{d} = ", .{i});3796 if (is_reg) {
3197 try f.writeCValue(writer, try f.resolveInst(input));3797 try writer.writeAll(" __asm(\"");
3798 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
3799 try writer.writeAll("\")");
3800 }
3801 try writer.writeAll(" = ");
3802 try f.writeCValue(writer, input_val, .Initializer);
3198 try writer.writeAll(";\n");3803 try writer.writeAll(";\n");
3199 }3804 }
3200 }3805 }
3201
3202 {3806 {
3203 var clobber_i: u32 = 0;3807 var clobber_i: u32 = 0;
3204 while (clobber_i < clobbers_len) : (clobber_i += 1) {3808 while (clobber_i < clobbers_len) : (clobber_i += 1) {
...@@ -3206,58 +3810,109 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3206,58 +3810,109 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3206 // This equation accounts for the fact that even if we have exactly 4 bytes3810 // This equation accounts for the fact that even if we have exactly 4 bytes
3207 // for the string, we still use the next u32 for the null terminator.3811 // for the string, we still use the next u32 for the null terminator.
3208 extra_i += clobber.len / 4 + 1;3812 extra_i += clobber.len / 4 + 1;
3209
3210 // TODO honor these
3211 }3813 }
3212 }3814 }
3213
3214 const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len];3815 const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len];
32153816
3216 const volatile_string: []const u8 = if (is_volatile) "volatile " else "";3817 try writer.writeAll("__asm");
3217 try writer.print("__asm {s}(\"{s}\"", .{ volatile_string, asm_source });3818 if (is_volatile) try writer.writeAll(" volatile");
3218 if (output_constraint) |_| {3819 try writer.print("({s}", .{fmtStringLiteral(asm_source)});
3219 return f.fail("TODO: CBE inline asm output", .{});3820
3220 }3821 extra_i = constraints_extra_begin;
3221 if (inputs.len > 0) {3822 var locals_index = locals_begin;
3222 if (output_constraint == null) {3823 try writer.writeByte(':');
3223 try writer.writeAll(" :");3824 for (outputs) |output, index| {
3825 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3826 const constraint = std.mem.sliceTo(extra_bytes, 0);
3827 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3828 // This equation accounts for the fact that even if we have exactly 4 bytes
3829 // for the string, we still use the next u32 for the null terminator.
3830 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
3831
3832 if (index > 0) try writer.writeByte(',');
3833 try writer.writeByte(' ');
3834 if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});
3835 const is_reg = constraint[1] == '{';
3836 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint)});
3837 if (is_reg) {
3838 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
3839 locals_index += 1;
3840 } else {
3841 try f.writeCValueDeref(writer, try f.resolveInst(output));
3224 }3842 }
3225 try writer.writeAll(": ");3843 try writer.writeByte(')');
3226 extra_i = inputs_extra_begin;3844 }
3227 for (inputs) |_, index| {3845 try writer.writeByte(':');
3228 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);3846 for (inputs) |input, index| {
3847 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3848 const constraint = std.mem.sliceTo(extra_bytes, 0);
3849 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3850 // This equation accounts for the fact that even if we have exactly 4 bytes
3851 // for the string, we still use the next u32 for the null terminator.
3852 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
3853
3854 if (index > 0) try writer.writeByte(',');
3855 try writer.writeByte(' ');
3856 if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});
3857
3858 const is_reg = constraint[0] == '{';
3859 const input_val = try f.resolveInst(input);
3860 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint)});
3861 try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: {
3862 const input_local = CValue{ .local = locals_index };
3863 locals_index += 1;
3864 break :local input_local;
3865 } else input_val, .Other);
3866 try writer.writeByte(')');
3867 }
3868 try writer.writeByte(':');
3869 {
3870 var clobber_i: u32 = 0;
3871 while (clobber_i < clobbers_len) : (clobber_i += 1) {
3872 const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
3229 // This equation accounts for the fact that even if we have exactly 4 bytes3873 // This equation accounts for the fact that even if we have exactly 4 bytes
3230 // for the string, we still use the next u32 for the null terminator.3874 // for the string, we still use the next u32 for the null terminator.
3231 extra_i += constraint.len / 4 + 1;3875 extra_i += clobber.len / 4 + 1;
32323876
3233 if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') {3877 if (clobber.len == 0) continue;
3234 const reg = constraint[1 .. constraint.len - 1];3878
3235 if (index > 0) {3879 if (clobber_i > 0) try writer.writeByte(',');
3236 try writer.writeAll(", ");3880 try writer.print(" {s}", .{fmtStringLiteral(clobber)});
3237 }
3238 try writer.print("\"r\"({s}_constant)", .{reg});
3239 } else {
3240 if (index > 0) {
3241 try writer.writeAll(", ");
3242 }
3243 try writer.print("\"r\"(input_{d})", .{index});
3244 }
3245 }3881 }
3246 }3882 }
3247 try writer.writeAll(");\n");3883 try writer.writeAll(");\n");
3248 try writer.writeAll("}\n");
32493884
3250 if (f.liveness.isUnused(inst))3885 extra_i = constraints_extra_begin;
3251 return CValue.none;3886 locals_index = locals_begin;
3887 for (outputs) |output| {
3888 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3889 const constraint = std.mem.sliceTo(extra_bytes, 0);
3890 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
3891 // This equation accounts for the fact that even if we have exactly 4 bytes
3892 // for the string, we still use the next u32 for the null terminator.
3893 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
32523894
3253 return f.fail("TODO: C backend: inline asm expression result used", .{});3895 const is_reg = constraint[1] == '{';
3896 if (is_reg) {
3897 try f.writeCValueDeref(writer, if (output == .none)
3898 CValue{ .local_ref = local.local }
3899 else
3900 try f.resolveInst(output));
3901 try writer.writeAll(" = ");
3902 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
3903 locals_index += 1;
3904 try writer.writeAll(";\n");
3905 }
3906 }
3907
3908 return local;
3254}3909}
32553910
3256fn airIsNull(3911fn airIsNull(
3257 f: *Function,3912 f: *Function,
3258 inst: Air.Inst.Index,3913 inst: Air.Inst.Index,
3259 operator: [*:0]const u8,3914 operator: []const u8,
3260 deref_suffix: [*:0]const u8,3915 is_ptr: bool,
3261) !CValue {3916) !CValue {
3262 if (f.liveness.isUnused(inst))3917 if (f.liveness.isUnused(inst))
3263 return CValue.none;3918 return CValue.none;
...@@ -3267,26 +3922,35 @@ fn airIsNull(...@@ -3267,26 +3922,35 @@ fn airIsNull(
3267 const operand = try f.resolveInst(un_op);3922 const operand = try f.resolveInst(un_op);
32683923
3269 const local = try f.allocLocal(Type.initTag(.bool), .Const);3924 const local = try f.allocLocal(Type.initTag(.bool), .Const);
3270 try writer.writeAll(" = (");3925 try writer.writeAll(" = ");
3271 try f.writeCValue(writer, operand);3926 try if (is_ptr) f.writeCValueDeref(writer, operand) else f.writeCValue(writer, operand, .Other);
3272
3273 const ty = f.air.typeOf(un_op);
3274 const opt_ty = if (deref_suffix[0] != 0) ty.childType() else ty;
3275 var opt_buf: Type.Payload.ElemType = undefined;
3276 const payload_ty = opt_ty.optionalChild(&opt_buf);
32773927
3278 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3928 const operand_ty = f.air.typeOf(un_op);
3279 try writer.print("){s} {s} true;\n", .{ deref_suffix, operator });3929 const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty;
3280 } else if (ty.isPtrLikeOptional()) {3930 var payload_buf: Type.Payload.ElemType = undefined;
3931 const payload_ty = optional_ty.optionalChild(&payload_buf);
3932 var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
3933
3934 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime())
3935 TypedValue{ .ty = Type.bool, .val = Value.@"true" }
3936 else if (operand_ty.isPtrLikeOptional())
3281 // operand is a regular pointer, test `operand !=/== NULL`3937 // operand is a regular pointer, test `operand !=/== NULL`
3282 try writer.print("){s} {s} NULL;\n", .{ deref_suffix, operator });3938 TypedValue{ .ty = operand_ty, .val = Value.@"null" }
3283 } else if (payload_ty.zigTypeTag() == .ErrorSet) {3939 else if (payload_ty.zigTypeTag() == .ErrorSet)
3284 try writer.print("){s} {s} 0;\n", .{ deref_suffix, operator });3940 TypedValue{ .ty = payload_ty, .val = Value.zero }
3285 } else if (payload_ty.isSlice() and opt_ty.optionalReprIsPayload()) {3941 else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload()) rhs: {
3286 try writer.print("){s}.ptr {s} NULL;\n", .{ deref_suffix, operator });3942 try writer.writeAll(".ptr");
3287 } else {3943 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
3288 try writer.print("){s}.is_null {s} true;\n", .{ deref_suffix, operator });3944 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.@"null" };
3289 }3945 } else rhs: {
3946 try writer.writeAll(".is_null");
3947 break :rhs TypedValue{ .ty = Type.bool, .val = Value.@"true" };
3948 };
3949 try writer.writeByte(' ');
3950 try writer.writeAll(operator);
3951 try writer.writeByte(' ');
3952 try f.object.dg.renderValue(writer, rhs.ty, rhs.val, .Other);
3953 try writer.writeAll(";\n");
3290 return local;3954 return local;
3291}3955}
32923956
...@@ -3312,7 +3976,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3312,7 +3976,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
3312 const inst_ty = f.air.typeOfIndex(inst);3976 const inst_ty = f.air.typeOfIndex(inst);
3313 const local = try f.allocLocal(inst_ty, .Const);3977 const local = try f.allocLocal(inst_ty, .Const);
3314 try writer.writeAll(" = (");3978 try writer.writeAll(" = (");
3315 try f.writeCValue(writer, operand);3979 try f.writeCValue(writer, operand, .Other);
3316 try writer.writeAll(").payload;\n");3980 try writer.writeAll(").payload;\n");
3317 return local;3981 return local;
3318}3982}
...@@ -3325,11 +3989,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3325,11 +3989,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3325 const operand = try f.resolveInst(ty_op.operand);3989 const operand = try f.resolveInst(ty_op.operand);
3326 const ptr_ty = f.air.typeOf(ty_op.operand);3990 const ptr_ty = f.air.typeOf(ty_op.operand);
3327 const opt_ty = ptr_ty.childType();3991 const opt_ty = ptr_ty.childType();
3328 var buf: Type.Payload.ElemType = undefined;3992 const inst_ty = f.air.typeOfIndex(inst);
3329 const payload_ty = opt_ty.optionalChild(&buf);
33303993
3331 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3994 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime()) {
3332 return operand;3995 return CValue{ .undef = inst_ty };
3333 }3996 }
33343997
3335 if (opt_ty.optionalReprIsPayload()) {3998 if (opt_ty.optionalReprIsPayload()) {
...@@ -3338,11 +4001,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3338,11 +4001,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3338 return operand;4001 return operand;
3339 }4002 }
33404003
3341 const inst_ty = f.air.typeOfIndex(inst);
3342 const local = try f.allocLocal(inst_ty, .Const);4004 const local = try f.allocLocal(inst_ty, .Const);
3343 try writer.writeAll(" = &(");4005 try writer.writeAll(" = &");
3344 try f.writeCValue(writer, operand);4006 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
3345 try writer.writeAll(")->payload;\n");4007 try writer.writeAll(";\n");
3346 return local;4008 return local;
3347}4009}
33484010
...@@ -3361,7 +4023,9 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3361,7 +4023,9 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
3361 }4023 }
33624024
3363 try f.writeCValueDeref(writer, operand);4025 try f.writeCValueDeref(writer, operand);
3364 try writer.writeAll(".is_null = false;\n");4026 try writer.writeAll(".is_null = ");
4027 try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer);
4028 try writer.writeAll(";\n");
33654029
3366 const inst_ty = f.air.typeOfIndex(inst);4030 const inst_ty = f.air.typeOfIndex(inst);
3367 const local = try f.allocLocal(inst_ty, .Const);4031 const local = try f.allocLocal(inst_ty, .Const);
...@@ -3396,55 +4060,111 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -3396,55 +4060,111 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
3396}4060}
33974061
3398fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {4062fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3399 _ = inst;4063 if (f.liveness.isUnused(inst)) return CValue.none;
3400 return f.fail("TODO: C backend: implement airFieldParentPtr", .{});4064
4065 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4066 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
4067
4068 const struct_ptr_ty = f.air.typeOfIndex(inst);
4069 const field_ptr_ty = f.air.typeOf(extra.field_ptr);
4070 const field_ptr_val = try f.resolveInst(extra.field_ptr);
4071
4072 const target = f.object.dg.module.getTarget();
4073 const struct_ty = struct_ptr_ty.childType();
4074 const field_offset = struct_ty.structFieldOffset(extra.field_index, target);
4075
4076 var field_offset_pl = Value.Payload.I64{
4077 .base = .{ .tag = .int_i64 },
4078 .data = -@intCast(i64, field_offset),
4079 };
4080 const field_offset_val = Value.initPayload(&field_offset_pl.base);
4081
4082 var u8_ptr_pl = field_ptr_ty.ptrInfo();
4083 u8_ptr_pl.data.pointee_type = Type.u8;
4084 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
4085
4086 const writer = f.object.writer();
4087 const local = try f.allocLocal(struct_ptr_ty, .Const);
4088 try writer.writeAll(" = (");
4089 try f.renderTypecast(writer, struct_ptr_ty);
4090 try writer.writeAll(")&((");
4091 try f.renderTypecast(writer, u8_ptr_ty);
4092 try writer.writeByte(')');
4093 try f.writeCValue(writer, field_ptr_val, .Other);
4094 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)});
4095 return local;
3401}4096}
34024097
3403fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {4098fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {
3404 const writer = f.object.writer();4099 const writer = f.object.writer();
4100 const field_ptr_ty = f.air.typeOfIndex(inst);
4101 const field_ptr_info = field_ptr_ty.ptrInfo();
3405 const struct_ty = struct_ptr_ty.elemType();4102 const struct_ty = struct_ptr_ty.elemType();
3406 var field_name: []const u8 = undefined;4103 const field_ty = struct_ty.structFieldType(index);
3407 var field_val_ty: Type = undefined;4104
34084105 // Ensure complete type definition is visible before accessing fields.
3409 var buf = std.ArrayList(u8).init(f.object.dg.gpa);4106 try f.renderType(std.io.null_writer, struct_ty);
3410 defer buf.deinit();4107
3411 switch (struct_ty.tag()) {4108 const local = try f.allocLocal(field_ptr_ty, .Const);
3412 .@"struct" => {4109 try writer.writeAll(" = (");
3413 const fields = struct_ty.structFields();4110 try f.renderTypecast(writer, field_ptr_ty);
3414 field_name = fields.keys()[index];4111 try writer.writeByte(')');
3415 field_val_ty = fields.values()[index].ty;4112
3416 },4113 const extra_name: ?[]const u8 = switch (struct_ty.tag()) {
3417 .@"union", .union_safety_tagged, .union_tagged => {4114 .union_tagged, .union_safety_tagged => "payload",
3418 const fields = struct_ty.unionFields();4115 else => null,
3419 field_name = fields.keys()[index];4116 };
3420 field_val_ty = fields.values()[index].ty;4117
4118 var field_name_buf: []const u8 = &.{};
4119 defer f.object.dg.gpa.free(field_name_buf);
4120 const field_name: ?[]const u8 = switch (struct_ty.tag()) {
4121 .@"struct" => switch (struct_ty.containerLayout()) {
4122 .Auto, .Extern => struct_ty.structFieldName(index),
4123 .Packed => if (field_ptr_info.data.host_size == 0) {
4124 const target = f.object.dg.module.getTarget();
4125
4126 const byte_offset = struct_ty.packedStructFieldByteOffset(index, target);
4127 var byte_offset_pl = Value.Payload.U64{
4128 .base = .{ .tag = .int_u64 },
4129 .data = byte_offset,
4130 };
4131 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
4132
4133 var u8_ptr_pl = field_ptr_info;
4134 u8_ptr_pl.data.pointee_type = Type.u8;
4135 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
4136
4137 try writer.writeAll("&((");
4138 try f.renderTypecast(writer, u8_ptr_ty);
4139 try writer.writeByte(')');
4140 try f.writeCValue(writer, struct_ptr, .Other);
4141 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
4142 return local;
4143 } else null,
3421 },4144 },
3422 .tuple, .anon_struct => {4145 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[index],
4146 .tuple, .anon_struct => |tag| field_name: {
3423 const tuple = struct_ty.tupleFields();4147 const tuple = struct_ty.tupleFields();
3424 if (tuple.values[index].tag() != .unreachable_value) return CValue.none;4148 if (tuple.values[index].tag() != .unreachable_value) return CValue.none;
34254149
3426 try buf.writer().print("field_{d}", .{index});4150 if (tag == .anon_struct) break :field_name struct_ty.structFieldName(index);
3427 field_name = buf.items;4151
3428 field_val_ty = tuple.types[index];4152 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index});
4153 break :field_name field_name_buf;
3429 },4154 },
3430 else => unreachable,4155 else => unreachable,
3431 }4156 };
3432 const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else "";
3433
3434 const inst_ty = f.air.typeOfIndex(inst);
3435 const local = try f.allocLocal(inst_ty, .Const);
34364157
3437 if (field_val_ty.hasRuntimeBitsIgnoreComptime()) {4158 if (field_ty.hasRuntimeBitsIgnoreComptime()) {
3438 try writer.writeAll(" = &");4159 try writer.writeByte('&');
3439 try f.writeCValueDeref(writer, struct_ptr);4160 if (extra_name orelse field_name) |name|
3440 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });4161 try f.writeCValueDerefMember(writer, struct_ptr, .{ .identifier = name })
3441 } else {4162 else
3442 try writer.writeAll(" = (");4163 try f.writeCValueDeref(writer, struct_ptr);
3443 try f.renderTypecast(writer, inst_ty);4164 if (extra_name) |_| if (field_name) |name|
3444 try writer.writeByte(')');4165 try writer.print(".{ }", .{fmtIdent(name)});
3445 try f.writeCValue(writer, struct_ptr);4166 } else try f.writeCValue(writer, struct_ptr, .Other);
3446 try writer.writeAll(";\n");4167 try writer.writeAll(";\n");
3447 }
3448 return local;4168 return local;
3449}4169}
34504170
...@@ -3454,100 +4174,162 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3454,100 +4174,162 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
34544174
3455 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4175 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3456 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;4176 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
3457 const writer = f.object.writer();4177 const inst_ty = f.air.typeOfIndex(inst);
4178 const target = f.object.dg.module.getTarget();
3458 const struct_byval = try f.resolveInst(extra.struct_operand);4179 const struct_byval = try f.resolveInst(extra.struct_operand);
3459 const struct_ty = f.air.typeOf(extra.struct_operand);4180 const struct_ty = f.air.typeOf(extra.struct_operand);
3460 var buf = std.ArrayList(u8).init(f.object.dg.gpa);4181 const writer = f.object.writer();
3461 defer buf.deinit();4182
4183 // Ensure complete type definition is visible before accessing fields.
4184 try f.renderType(std.io.null_writer, struct_ty);
4185
4186 var field_name_buf: []const u8 = "";
4187 defer f.object.dg.gpa.free(field_name_buf);
3462 const field_name = switch (struct_ty.tag()) {4188 const field_name = switch (struct_ty.tag()) {
3463 .@"struct" => struct_ty.structFields().keys()[extra.field_index],4189 .@"struct" => switch (struct_ty.containerLayout()) {
4190 .Auto, .Extern => struct_ty.structFieldName(extra.field_index),
4191 .Packed => {
4192 const struct_obj = struct_ty.castTag(.@"struct").?.data;
4193 const int_info = struct_ty.intInfo(target);
4194
4195 var bit_offset_ty_pl = Type.Payload.Bits{
4196 .base = .{ .tag = .int_unsigned },
4197 .data = Type.smallestUnsignedBits(int_info.bits - 1),
4198 };
4199 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
4200
4201 var bit_offset_val_pl: Value.Payload.U64 = .{
4202 .base = .{ .tag = .int_u64 },
4203 .data = struct_obj.packedFieldBitOffset(target, extra.field_index),
4204 };
4205 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
4206
4207 const field_int_signedness = if (inst_ty.isAbiInt())
4208 inst_ty.intInfo(target).signedness
4209 else
4210 .unsigned;
4211 var field_int_pl = Type.Payload.Bits{
4212 .base = .{ .tag = switch (field_int_signedness) {
4213 .unsigned => .int_unsigned,
4214 .signed => .int_signed,
4215 } },
4216 .data = @intCast(u16, inst_ty.bitSize(target)),
4217 };
4218 const field_int_ty = Type.initPayload(&field_int_pl.base);
4219
4220 const temp_local = try f.allocLocal(field_int_ty, .Const);
4221 try writer.writeAll(" = zig_wrap_");
4222 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
4223 try writer.writeAll("((");
4224 try f.renderTypecast(writer, field_int_ty);
4225 try writer.writeAll(")zig_shr_");
4226 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
4227 try writer.writeByte('(');
4228 try f.writeCValue(writer, struct_byval, .Other);
4229 try writer.writeAll(", ");
4230 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
4231 try writer.writeByte(')');
4232 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits);
4233 try writer.writeAll(");\n");
4234 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
4235
4236 const local = try f.allocLocal(inst_ty, .Mut);
4237 try writer.writeAll(";\n");
4238 try writer.writeAll("memcpy(");
4239 try f.writeCValue(writer, .{ .local_ref = local.local }, .FunctionArgument);
4240 try writer.writeAll(", ");
4241 try f.writeCValue(writer, .{ .local_ref = temp_local.local }, .FunctionArgument);
4242 try writer.writeAll(", sizeof(");
4243 try f.renderTypecast(writer, inst_ty);
4244 try writer.writeAll("));\n");
4245 return local;
4246 },
4247 },
3464 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index],4248 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index],
3465 .tuple, .anon_struct => blk: {4249 .tuple, .anon_struct => |tag| blk: {
3466 const tuple = struct_ty.tupleFields();4250 const tuple = struct_ty.tupleFields();
3467 if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;4251 if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;
34684252
3469 try buf.writer().print("field_{d}", .{extra.field_index});4253 if (tag == .anon_struct) break :blk struct_ty.structFieldName(extra.field_index);
3470 break :blk buf.items;4254
4255 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{extra.field_index});
4256 break :blk field_name_buf;
3471 },4257 },
3472 else => unreachable,4258 else => unreachable,
3473 };4259 };
3474 const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else "";4260 const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else "";
34754261
3476 const inst_ty = f.air.typeOfIndex(inst);4262 const is_array = lowersToArray(inst_ty, target);
3477 const local = try f.allocLocal(inst_ty, .Const);4263 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
3478 try writer.writeAll(" = ");4264 if (is_array) {
3479 try f.writeCValue(writer, struct_byval);4265 try writer.writeAll(";\n");
3480 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });4266 try writer.writeAll("memcpy(");
4267 try f.writeCValue(writer, local, .FunctionArgument);
4268 try writer.writeAll(", ");
4269 try f.writeCValue(writer, struct_byval, .Other);
4270 try writer.print(".{s}{ }, sizeof(", .{ payload, fmtIdent(field_name) });
4271 try f.renderTypecast(writer, inst_ty);
4272 try writer.writeAll("));\n");
4273 } else {
4274 try writer.writeAll(" = ");
4275 try f.writeCValue(writer, struct_byval, .Other);
4276 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });
4277 }
3481 return local;4278 return local;
3482}4279}
34834280
3484/// *(E!T) -> E4281/// *(E!T) -> E
3485/// Note that the result is never a pointer.4282/// Note that the result is never a pointer.
3486fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {4283fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3487 if (f.liveness.isUnused(inst))4284 if (f.liveness.isUnused(inst)) return CValue.none;
3488 return CValue.none;
34894285
3490 const ty_op = f.air.instructions.items(.data)[inst].ty_op;4286 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3491 const inst_ty = f.air.typeOfIndex(inst);4287 const inst_ty = f.air.typeOfIndex(inst);
3492 const writer = f.object.writer();
3493 const operand = try f.resolveInst(ty_op.operand);4288 const operand = try f.resolveInst(ty_op.operand);
3494 const operand_ty = f.air.typeOf(ty_op.operand);4289 const operand_ty = f.air.typeOf(ty_op.operand);
34954290
3496 if (operand_ty.zigTypeTag() == .Pointer) {4291 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
3497 const err_union_ty = operand_ty.childType();4292 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
3498 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {4293 const error_ty = error_union_ty.errorUnionSet();
3499 return CValue{ .bytes = "0" };4294 const payload_ty = error_union_ty.errorUnionPayload();
3500 }4295 if (!payload_ty.hasRuntimeBits()) return operand;
3501 if (!err_union_ty.errorUnionPayload().hasRuntimeBits()) {
3502 return operand;
3503 }
3504 const local = try f.allocLocal(inst_ty, .Const);
3505 try writer.writeAll(" = *");
3506 try f.writeCValue(writer, operand);
3507 try writer.writeAll(";\n");
3508 return local;
3509 }
3510 if (operand_ty.errorUnionSet().errorSetIsEmpty()) {
3511 return CValue{ .bytes = "0" };
3512 }
3513 if (!operand_ty.errorUnionPayload().hasRuntimeBits()) {
3514 return operand;
3515 }
35164296
4297 const writer = f.object.writer();
3517 const local = try f.allocLocal(inst_ty, .Const);4298 const local = try f.allocLocal(inst_ty, .Const);
3518 try writer.writeAll(" = ");4299 try writer.writeAll(" = ");
3519 if (operand_ty.zigTypeTag() == .Pointer) {4300 if (!error_ty.errorSetIsEmpty())
3520 try f.writeCValueDeref(writer, operand);4301 if (operand_is_ptr)
3521 } else {4302 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
3522 try f.writeCValue(writer, operand);4303 else
3523 }4304 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
3524 try writer.writeAll(".error;\n");4305 else
4306 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
4307 try writer.writeAll(";\n");
3525 return local;4308 return local;
3526}4309}
35274310
3528fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]const u8) !CValue {4311fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3529 if (f.liveness.isUnused(inst))4312 if (f.liveness.isUnused(inst))
3530 return CValue.none;4313 return CValue.none;
35314314
3532 const ty_op = f.air.instructions.items(.data)[inst].ty_op;4315 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3533 const writer = f.object.writer();4316 const inst_ty = f.air.typeOfIndex(inst);
3534 const operand = try f.resolveInst(ty_op.operand);4317 const operand = try f.resolveInst(ty_op.operand);
3535 const operand_ty = f.air.typeOf(ty_op.operand);4318 const operand_ty = f.air.typeOf(ty_op.operand);
3536 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;4319 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
3537 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;4320 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
35384321
3539 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {4322 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) return CValue.none;
3540 return CValue.none;
3541 }
3542
3543 const inst_ty = f.air.typeOfIndex(inst);
3544 const maybe_deref = if (operand_is_ptr) "->" else ".";
35454323
4324 const writer = f.object.writer();
3546 const local = try f.allocLocal(inst_ty, .Const);4325 const local = try f.allocLocal(inst_ty, .Const);
3547 try writer.print(" = {s}(", .{maybe_addrof});4326 try writer.writeAll(" = ");
3548 try f.writeCValue(writer, operand);4327 if (is_ptr) try writer.writeByte('&');
35494328 if (operand_is_ptr)
3550 try writer.print("){s}payload;\n", .{maybe_deref});4329 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" })
4330 else
4331 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
4332 try writer.writeAll(";\n");
3551 return local;4333 return local;
3552}4334}
35534335
...@@ -3566,9 +4348,11 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3566,9 +4348,11 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
35664348
3567 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.4349 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.
3568 const local = try f.allocLocal(inst_ty, .Const);4350 const local = try f.allocLocal(inst_ty, .Const);
3569 try writer.writeAll(" = { .is_null = false, .payload =");4351 try writer.writeAll(" = { .payload = ");
3570 try f.writeCValue(writer, operand);4352 try f.writeCValue(writer, operand, .Initializer);
3571 try writer.writeAll("};\n");4353 try writer.writeAll(", .is_null = ");
4354 try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer);
4355 try writer.writeAll(" };\n");
3572 return local;4356 return local;
3573}4357}
35744358
...@@ -3578,15 +4362,15 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3578,15 +4362,15 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3578 const writer = f.object.writer();4362 const writer = f.object.writer();
3579 const ty_op = f.air.instructions.items(.data)[inst].ty_op;4363 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3580 const operand = try f.resolveInst(ty_op.operand);4364 const operand = try f.resolveInst(ty_op.operand);
3581 const err_un_ty = f.air.typeOfIndex(inst);4365 const error_union_ty = f.air.typeOfIndex(inst);
3582 const payload_ty = err_un_ty.errorUnionPayload();4366 const payload_ty = error_union_ty.errorUnionPayload();
3583 if (!payload_ty.hasRuntimeBits()) {4367 if (!payload_ty.hasRuntimeBits()) return operand;
3584 return operand;
3585 }
35864368
3587 const local = try f.allocLocal(err_un_ty, .Const);4369 const local = try f.allocLocal(error_union_ty, .Const);
3588 try writer.writeAll(" = { .error = ");4370 try writer.writeAll(" = { .payload = ");
3589 try f.writeCValue(writer, operand);4371 try f.writeCValue(writer, .{ .undef = payload_ty }, .Initializer);
4372 try writer.writeAll(", .error = ");
4373 try f.writeCValue(writer, operand, .Initializer);
3590 try writer.writeAll(" };\n");4374 try writer.writeAll(" };\n");
3591 return local;4375 return local;
3592}4376}
...@@ -3648,19 +4432,31 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3648,19 +4432,31 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
3648 const operand = try f.resolveInst(ty_op.operand);4432 const operand = try f.resolveInst(ty_op.operand);
36494433
3650 const inst_ty = f.air.typeOfIndex(inst);4434 const inst_ty = f.air.typeOfIndex(inst);
3651 const local = try f.allocLocal(inst_ty, .Const);4435 const payload_ty = inst_ty.errorUnionPayload();
3652 try writer.writeAll(" = { .error = 0, .payload = ");4436 const error_ty = inst_ty.errorUnionSet();
3653 try f.writeCValue(writer, operand);4437 const target = f.object.dg.module.getTarget();
4438 const is_array = lowersToArray(payload_ty, target);
4439 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4440 try writer.writeAll(" = { .payload = ");
4441 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer);
4442 try writer.writeAll(", .error = ");
4443 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
3654 try writer.writeAll(" };\n");4444 try writer.writeAll(" };\n");
4445
4446 if (is_array) {
4447 try writer.writeAll("memcpy(");
4448 try f.writeCValue(writer, local, .Other);
4449 try writer.writeAll(".payload, ");
4450 try f.writeCValue(writer, operand, .FunctionArgument);
4451 try writer.writeAll(", sizeof(");
4452 try f.renderTypecast(writer, payload_ty);
4453 try writer.writeAll("));\n");
4454 }
4455
3655 return local;4456 return local;
3656}4457}
36574458
3658fn airIsErr(4459fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
3659 f: *Function,
3660 inst: Air.Inst.Index,
3661 is_ptr: bool,
3662 op_str: [*:0]const u8,
3663) !CValue {
3664 if (f.liveness.isUnused(inst))4460 if (f.liveness.isUnused(inst))
3665 return CValue.none;4461 return CValue.none;
36664462
...@@ -3675,19 +4471,21 @@ fn airIsErr(...@@ -3675,19 +4471,21 @@ fn airIsErr(
36754471
3676 try writer.writeAll(" = ");4472 try writer.writeAll(" = ");
36774473
3678 if (error_ty.errorSetIsEmpty()) {4474 if (!error_ty.errorSetIsEmpty())
3679 try writer.print("0 {s} 0;\n", .{op_str});4475 if (payload_ty.hasRuntimeBits())
3680 } else {4476 if (is_ptr)
3681 if (is_ptr) {4477 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
3682 try f.writeCValueDeref(writer, operand);4478 else
3683 } else {4479 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
3684 try f.writeCValue(writer, operand);4480 else
3685 }4481 try f.writeCValue(writer, operand, .Other)
3686 if (payload_ty.hasRuntimeBits()) {4482 else
3687 try writer.writeAll(".error");4483 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);
3688 }4484 try writer.writeByte(' ');
3689 try writer.print(" {s} 0;\n", .{op_str});4485 try writer.writeAll(operator);
3690 }4486 try writer.writeByte(' ');
4487 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);
4488 try writer.writeAll(";\n");
3691 return local;4489 return local;
3692}4490}
36934491
...@@ -3703,16 +4501,20 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3703,16 +4501,20 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
3703 const array_len = f.air.typeOf(ty_op.operand).elemType().arrayLen();4501 const array_len = f.air.typeOf(ty_op.operand).elemType().arrayLen();
37044502
3705 try writer.writeAll(" = { .ptr = ");4503 try writer.writeAll(" = { .ptr = ");
3706 if (operand == .undefined_ptr) {4504 if (operand == .undef) {
3707 // Unfortunately, C does not support any equivalent to4505 // Unfortunately, C does not support any equivalent to
3708 // &(*(void *)p)[0], although LLVM does via GetElementPtr4506 // &(*(void *)p)[0], although LLVM does via GetElementPtr
3709 try f.writeCValue(writer, CValue.undefined_ptr);4507 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4508 try f.writeCValue(writer, CValue{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
3710 } else {4509 } else {
3711 try writer.writeAll("&(");4510 try writer.writeAll("&(");
3712 try f.writeCValueDeref(writer, operand);4511 try f.writeCValueDeref(writer, operand);
3713 try writer.writeAll(")[0]");4512 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)});
3714 }4513 }
3715 try writer.print(", .len = {d} }};\n", .{array_len});4514
4515 var len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = array_len };
4516 const len_val = Value.initPayload(&len_pl.base);
4517 try writer.print(", .len = {} }};\n", .{try f.fmtIntLiteral(Type.usize, len_val)});
3716 return local;4518 return local;
3717}4519}
37184520
...@@ -3728,7 +4530,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3728,7 +4530,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
3728 const operand = try f.resolveInst(ty_op.operand);4530 const operand = try f.resolveInst(ty_op.operand);
37294531
3730 try writer.writeAll(" = ");4532 try writer.writeAll(" = ");
3731 try f.writeCValue(writer, operand);4533 try f.writeCValue(writer, operand, .Other);
3732 try writer.writeAll(";\n");4534 try writer.writeAll(";\n");
3733 return local;4535 return local;
3734}4536}
...@@ -3744,61 +4546,80 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3744,61 +4546,80 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
37444546
3745 try writer.writeAll(" = (");4547 try writer.writeAll(" = (");
3746 try f.renderTypecast(writer, inst_ty);4548 try f.renderTypecast(writer, inst_ty);
3747 try writer.writeAll(")");4549 try writer.writeByte(')');
3748 try f.writeCValue(writer, operand);4550 try f.writeCValue(writer, operand, .Other);
3749 try writer.writeAll(";\n");4551 try writer.writeAll(";\n");
3750 return local;4552 return local;
3751}4553}
37524554
3753fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {4555fn airUnBuiltinCall(
4556 f: *Function,
4557 inst: Air.Inst.Index,
4558 operation: []const u8,
4559 info: BuiltinInfo,
4560) !CValue {
3754 if (f.liveness.isUnused(inst)) return CValue.none;4561 if (f.liveness.isUnused(inst)) return CValue.none;
37554562
3756 const inst_ty = f.air.typeOfIndex(inst);4563 const inst_ty = f.air.typeOfIndex(inst);
3757 const local = try f.allocLocal(inst_ty, .Const);
3758 const operand = f.air.instructions.items(.data)[inst].ty_op.operand;4564 const operand = f.air.instructions.items(.data)[inst].ty_op.operand;
3759 const operand_ty = f.air.typeOf(operand);4565 const operand_ty = f.air.typeOf(operand);
3760 const target = f.object.dg.module.getTarget();
3761 const writer = f.object.writer();
3762
3763 const int_info = operand_ty.intInfo(target);
3764 const c_bits = toCIntBits(int_info.bits) orelse
3765 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
37664566
3767 try writer.print(" = zig_{s}_", .{fn_name});4567 const local = try f.allocLocal(inst_ty, .Const);
3768 try writer.print("{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits });4568 const writer = f.object.writer();
3769 try f.writeCValue(writer, try f.resolveInst(operand));4569 try writer.writeAll(" = zig_");
3770 try writer.print(", {d});\n", .{int_info.bits});4570 try writer.writeAll(operation);
4571 try writer.writeByte('_');
4572 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
4573 try writer.writeByte('(');
4574 try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument);
4575 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
4576 try writer.writeAll(");\n");
3771 return local;4577 return local;
3772}4578}
37734579
3774fn airBinOpBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {4580fn airBinBuiltinCall(
4581 f: *Function,
4582 inst: Air.Inst.Index,
4583 operation: []const u8,
4584 info: BuiltinInfo,
4585) !CValue {
3775 if (f.liveness.isUnused(inst)) return CValue.none;4586 if (f.liveness.isUnused(inst)) return CValue.none;
37764587
3777 const inst_ty = f.air.typeOfIndex(inst);4588 const inst_ty = f.air.typeOfIndex(inst);
3778 const local = try f.allocLocal(inst_ty, .Const);
3779 const bin_op = f.air.instructions.items(.data)[inst].bin_op;4589 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3780 const lhs_ty = f.air.typeOf(bin_op.lhs);4590 const operand_ty = f.air.typeOf(bin_op.lhs);
3781 const target = f.object.dg.module.getTarget();4591
4592 const local = try f.allocLocal(inst_ty, .Const);
3782 const writer = f.object.writer();4593 const writer = f.object.writer();
4594 try writer.writeAll(" = zig_");
4595 try writer.writeAll(operation);
4596 try writer.writeByte('_');
4597 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
4598 try writer.writeByte('(');
4599 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
4600 try writer.writeAll(", ");
4601 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
4602 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
4603 try writer.writeAll(");\n");
4604 return local;
4605}
37834606
3784 // For binary operations @TypeOf(lhs)==@TypeOf(rhs), so we only check one.4607fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue {
3785 if (lhs_ty.isInt()) {4608 if (f.liveness.isUnused(inst)) return CValue.none;
3786 const int_info = lhs_ty.intInfo(target);
3787 const c_bits = toCIntBits(int_info.bits) orelse
3788 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3789 try writer.print(" = zig_{s}_{c}{d}", .{ fn_name, signAbbrev(int_info.signedness), c_bits });
3790 } else if (lhs_ty.isRuntimeFloat()) {
3791 const c_bits = lhs_ty.floatBits(target);
3792 try writer.print(" = zig_{s}_f{d}", .{ fn_name, c_bits });
3793 } else {
3794 return f.fail("TODO: C backend: implement airBinOpBuiltinCall for type {s}", .{@tagName(lhs_ty.tag())});
3795 }
37964609
4610 const inst_ty = f.air.typeOfIndex(inst);
4611 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
4612 const operand_ty = f.air.typeOf(bin_op.lhs);
4613
4614 const local = try f.allocLocal(inst_ty, .Const);
4615 const writer = f.object.writer();
4616 try writer.writeAll(" = zig_cmp_");
4617 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
3797 try writer.writeByte('(');4618 try writer.writeByte('(');
3798 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs));4619 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
3799 try writer.writeAll(", ");4620 try writer.writeAll(", ");
3800 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs));4621 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
3801 try writer.writeAll(");\n");4622 try writer.print(") {s} {};\n", .{ operator, try f.fmtIntLiteral(Type.initTag(.i8), Value.zero) });
3802 return local;4623 return local;
3803}4624}
38044625
...@@ -3806,23 +4627,58 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -3806,23 +4627,58 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
3806 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4627 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3807 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;4628 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
3808 const inst_ty = f.air.typeOfIndex(inst);4629 const inst_ty = f.air.typeOfIndex(inst);
4630 const is_struct = !inst_ty.isPtrLikeOptional();
4631 const ptr_ty = f.air.typeOf(extra.ptr);
3809 const ptr = try f.resolveInst(extra.ptr);4632 const ptr = try f.resolveInst(extra.ptr);
3810 const expected_value = try f.resolveInst(extra.expected_value);4633 const expected_value = try f.resolveInst(extra.expected_value);
3811 const new_value = try f.resolveInst(extra.new_value);4634 const new_value = try f.resolveInst(extra.new_value);
3812 const local = try f.allocLocal(inst_ty, .Const);
3813 const writer = f.object.writer();4635 const writer = f.object.writer();
38144636
3815 try writer.print(" = zig_cmpxchg_{s}(", .{flavor});4637 const local = try f.allocLocal(inst_ty, .Mut);
3816 try f.writeCValue(writer, ptr);4638 try writer.writeAll(" = ");
4639 if (is_struct) try writer.writeAll("{ .payload = ");
4640 try f.writeCValue(writer, expected_value, .Initializer);
4641 if (is_struct) {
4642 try writer.writeAll(", .is_null = ");
4643 try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer);
4644 try writer.writeAll(" }");
4645 }
4646 try writer.writeAll(";\n");
4647
4648 if (is_struct) {
4649 try f.writeCValue(writer, local, .Other);
4650 try writer.writeAll(".is_null = ");
4651 } else {
4652 try writer.writeAll("if (");
4653 }
4654 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
4655 try f.renderTypecast(writer, ptr_ty.elemType());
4656 try writer.writeByte(')');
4657 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4658 try writer.writeAll(" *)");
4659 try f.writeCValue(writer, ptr, .Other);
3817 try writer.writeAll(", ");4660 try writer.writeAll(", ");
3818 try f.writeCValue(writer, expected_value);4661 if (is_struct)
4662 try f.writeCValueMember(writer, local, .{ .identifier = "payload" })
4663 else
4664 try f.writeCValue(writer, local, .FunctionArgument);
3819 try writer.writeAll(", ");4665 try writer.writeAll(", ");
3820 try f.writeCValue(writer, new_value);4666 try f.writeCValue(writer, new_value, .FunctionArgument);
3821 try writer.writeAll(", ");4667 try writer.writeAll(", ");
3822 try writeMemoryOrder(writer, extra.successOrder());4668 try writeMemoryOrder(writer, extra.successOrder());
3823 try writer.writeAll(", ");4669 try writer.writeAll(", ");
3824 try writeMemoryOrder(writer, extra.failureOrder());4670 try writeMemoryOrder(writer, extra.failureOrder());
3825 try writer.writeAll(");\n");4671 try writer.writeByte(')');
4672 if (is_struct) {
4673 try writer.writeAll(";\n");
4674 } else {
4675 try writer.writeAll(") {\n");
4676 f.object.indent_writer.pushIndent();
4677 try f.writeCValue(writer, local, .Other);
4678 try writer.writeAll(" = NULL;\n");
4679 f.object.indent_writer.popIndent();
4680 try writer.writeAll("}\n");
4681 }
38264682
3827 return local;4683 return local;
3828}4684}
...@@ -3831,15 +4687,29 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3831,15 +4687,29 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
3831 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4687 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
3832 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;4688 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
3833 const inst_ty = f.air.typeOfIndex(inst);4689 const inst_ty = f.air.typeOfIndex(inst);
4690 const ptr_ty = f.air.typeOf(pl_op.operand);
3834 const ptr = try f.resolveInst(pl_op.operand);4691 const ptr = try f.resolveInst(pl_op.operand);
3835 const operand = try f.resolveInst(extra.operand);4692 const operand = try f.resolveInst(extra.operand);
3836 const local = try f.allocLocal(inst_ty, .Const);4693 const local = try f.allocLocal(inst_ty, .Const);
3837 const writer = f.object.writer();4694 const writer = f.object.writer();
38384695
3839 try writer.print(" = zig_atomicrmw_{s}(", .{toAtomicRmwSuffix(extra.op())});4696 try writer.print(" = zig_atomicrmw_{s}((", .{toAtomicRmwSuffix(extra.op())});
3840 try f.writeCValue(writer, ptr);4697 switch (extra.op()) {
4698 else => {
4699 try writer.writeAll("zig_atomic(");
4700 try f.renderTypecast(writer, ptr_ty.elemType());
4701 try writer.writeByte(')');
4702 },
4703 .Nand, .Min, .Max => {
4704 // These are missing from stdatomic.h, so no atomic types for now.
4705 try f.renderTypecast(writer, ptr_ty.elemType());
4706 },
4707 }
4708 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4709 try writer.writeAll(" *)");
4710 try f.writeCValue(writer, ptr, .Other);
3841 try writer.writeAll(", ");4711 try writer.writeAll(", ");
3842 try f.writeCValue(writer, operand);4712 try f.writeCValue(writer, operand, .FunctionArgument);
3843 try writer.writeAll(", ");4713 try writer.writeAll(", ");
3844 try writeMemoryOrder(writer, extra.ordering());4714 try writeMemoryOrder(writer, extra.ordering());
3845 try writer.writeAll(");\n");4715 try writer.writeAll(");\n");
...@@ -3858,8 +4728,12 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3858,8 +4728,12 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3858 const local = try f.allocLocal(inst_ty, .Const);4728 const local = try f.allocLocal(inst_ty, .Const);
3859 const writer = f.object.writer();4729 const writer = f.object.writer();
38604730
3861 try writer.writeAll(" = zig_atomic_load(");4731 try writer.writeAll(" = zig_atomic_load((zig_atomic(");
3862 try f.writeCValue(writer, ptr);4732 try f.renderTypecast(writer, ptr_ty.elemType());
4733 try writer.writeByte(')');
4734 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4735 try writer.writeAll(" *)");
4736 try f.writeCValue(writer, ptr, .Other);
3863 try writer.writeAll(", ");4737 try writer.writeAll(", ");
3864 try writeMemoryOrder(writer, atomic_load.order);4738 try writeMemoryOrder(writer, atomic_load.order);
3865 try writer.writeAll(");\n");4739 try writer.writeAll(");\n");
...@@ -3869,19 +4743,22 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3869,19 +4743,22 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
38694743
3870fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {4744fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
3871 const bin_op = f.air.instructions.items(.data)[inst].bin_op;4745 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
4746 const ptr_ty = f.air.typeOf(bin_op.lhs);
3872 const ptr = try f.resolveInst(bin_op.lhs);4747 const ptr = try f.resolveInst(bin_op.lhs);
3873 const element = try f.resolveInst(bin_op.rhs);4748 const element = try f.resolveInst(bin_op.rhs);
3874 const inst_ty = f.air.typeOfIndex(inst);
3875 const local = try f.allocLocal(inst_ty, .Const);
3876 const writer = f.object.writer();4749 const writer = f.object.writer();
38774750
3878 try writer.writeAll(" = zig_atomic_store(");4751 try writer.writeAll("zig_atomic_store((zig_atomic(");
3879 try f.writeCValue(writer, ptr);4752 try f.renderTypecast(writer, ptr_ty.elemType());
4753 try writer.writeByte(')');
4754 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4755 try writer.writeAll(" *)");
4756 try f.writeCValue(writer, ptr, .Other);
3880 try writer.writeAll(", ");4757 try writer.writeAll(", ");
3881 try f.writeCValue(writer, element);4758 try f.writeCValue(writer, element, .FunctionArgument);
3882 try writer.print(", {s});\n", .{order});4759 try writer.print(", {s});\n", .{order});
38834760
3884 return local;4761 return CValue.none;
3885}4762}
38864763
3887fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {4764fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -3893,11 +4770,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3893,11 +4770,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {
3893 const writer = f.object.writer();4770 const writer = f.object.writer();
38944771
3895 try writer.writeAll("memset(");4772 try writer.writeAll("memset(");
3896 try f.writeCValue(writer, dest_ptr);4773 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
3897 try writer.writeAll(", ");4774 try writer.writeAll(", ");
3898 try f.writeCValue(writer, value);4775 try f.writeCValue(writer, value, .FunctionArgument);
3899 try writer.writeAll(", ");4776 try writer.writeAll(", ");
3900 try f.writeCValue(writer, len);4777 try f.writeCValue(writer, len, .FunctionArgument);
3901 try writer.writeAll(");\n");4778 try writer.writeAll(");\n");
39024779
3903 return CValue.none;4780 return CValue.none;
...@@ -3912,11 +4789,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3912,11 +4789,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
3912 const writer = f.object.writer();4789 const writer = f.object.writer();
39134790
3914 try writer.writeAll("memcpy(");4791 try writer.writeAll("memcpy(");
3915 try f.writeCValue(writer, dest_ptr);4792 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
3916 try writer.writeAll(", ");4793 try writer.writeAll(", ");
3917 try f.writeCValue(writer, src_ptr);4794 try f.writeCValue(writer, src_ptr, .FunctionArgument);
3918 try writer.writeAll(", ");4795 try writer.writeAll(", ");
3919 try f.writeCValue(writer, len);4796 try f.writeCValue(writer, len, .FunctionArgument);
3920 try writer.writeAll(");\n");4797 try writer.writeAll(");\n");
39214798
3922 return CValue.none;4799 return CValue.none;
...@@ -3933,9 +4810,10 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3933,9 +4810,10 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
3933 const layout = union_ty.unionGetLayout(target);4810 const layout = union_ty.unionGetLayout(target);
3934 if (layout.tag_size == 0) return CValue.none;4811 if (layout.tag_size == 0) return CValue.none;
39354812
3936 try f.writeCValue(writer, union_ptr);4813 try writer.writeByte('(');
3937 try writer.writeAll("->tag = ");4814 try f.writeCValue(writer, union_ptr, .Other);
3938 try f.writeCValue(writer, new_tag);4815 try writer.writeAll(")->tag = ");
4816 try f.writeCValue(writer, new_tag, .Other);
3939 try writer.writeAll(";\n");4817 try writer.writeAll(";\n");
39404818
3941 return CValue.none;4819 return CValue.none;
...@@ -3957,7 +4835,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3957,7 +4835,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
3957 if (layout.tag_size == 0) return CValue.none;4835 if (layout.tag_size == 0) return CValue.none;
39584836
3959 try writer.writeAll(" = ");4837 try writer.writeAll(" = ");
3960 try f.writeCValue(writer, operand);4838 try f.writeCValue(writer, operand, .Other);
3961 try writer.writeAll(".tag;\n");4839 try writer.writeAll(".tag;\n");
3962 return local;4840 return local;
3963}4841}
...@@ -3966,18 +4844,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3966,18 +4844,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
3966 if (f.liveness.isUnused(inst)) return CValue.none;4844 if (f.liveness.isUnused(inst)) return CValue.none;
39674845
3968 const un_op = f.air.instructions.items(.data)[inst].un_op;4846 const un_op = f.air.instructions.items(.data)[inst].un_op;
3969 const writer = f.object.writer();
3970 const inst_ty = f.air.typeOfIndex(inst);4847 const inst_ty = f.air.typeOfIndex(inst);
4848 const enum_ty = f.air.typeOf(un_op);
3971 const operand = try f.resolveInst(un_op);4849 const operand = try f.resolveInst(un_op);
3972 const local = try f.allocLocal(inst_ty, .Const);
39734850
3974 try writer.writeAll(" = ");4851 const writer = f.object.writer();
4852 const local = try f.allocLocal(inst_ty, .Const);
4853 try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)});
4854 try f.writeCValue(writer, operand, .Other);
4855 try writer.writeAll(");\n");
39754856
3976 _ = operand;4857 return local;
3977 _ = local;
3978 return f.fail("TODO: C backend: implement airTagName", .{});
3979 //try writer.writeAll(";\n");
3980 //return local;
3981}4858}
39824859
3983fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {4860fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -3989,11 +4866,10 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3989,11 +4866,10 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
3989 const operand = try f.resolveInst(un_op);4866 const operand = try f.resolveInst(un_op);
3990 const local = try f.allocLocal(inst_ty, .Const);4867 const local = try f.allocLocal(inst_ty, .Const);
39914868
3992 try writer.writeAll(" = ");4869 try writer.writeAll(" = zig_errorName[");
39934870 try f.writeCValue(writer, operand, .Other);
3994 _ = operand;4871 try writer.writeAll("];\n");
3995 _ = local;4872 return local;
3996 return f.fail("TODO: C backend: implement airErrorName", .{});
3997}4873}
39984874
3999fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {4875fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -4061,29 +4937,131 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4061,29 +4937,131 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
40614937
4062 const inst_ty = f.air.typeOfIndex(inst);4938 const inst_ty = f.air.typeOfIndex(inst);
4063 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4939 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4064 const vector_ty = f.air.getRefType(ty_pl.ty);4940 const len = @intCast(usize, inst_ty.arrayLen());
4065 const len = vector_ty.vectorLen();
4066 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);4941 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
4942 const target = f.object.dg.module.getTarget();
4943 const mutability: Mutability = for (elements) |element| {
4944 if (lowersToArray(f.air.typeOf(element), target)) break .Mut;
4945 } else .Const;
40674946
4068 const writer = f.object.writer();4947 const writer = f.object.writer();
4069 const local = try f.allocLocal(inst_ty, .Const);4948 const local = try f.allocLocal(inst_ty, mutability);
4070 try writer.writeAll(" = {");4949 try writer.writeAll(" = ");
4071 switch (vector_ty.zigTypeTag()) {4950 switch (inst_ty.zigTypeTag()) {
4072 .Struct => {4951 .Array => {
4073 const tuple = vector_ty.tupleFields();4952 const elem_ty = inst_ty.childType();
4074 var i: usize = 0;4953 try writer.writeByte('{');
4075 for (elements) |elem, elem_index| {4954 var empty = true;
4076 if (tuple.values[elem_index].tag() != .unreachable_value) continue;4955 for (elements) |element| {
40774956 if (!empty) try writer.writeAll(", ");
4078 const value = try f.resolveInst(elem);4957 try f.writeCValue(writer, try f.resolveInst(element), .Initializer);
4079 if (i != 0) try writer.writeAll(", ");4958 empty = false;
4080 try f.writeCValue(writer, value);4959 }
4081 i += 1;4960 if (inst_ty.sentinel()) |sentinel| {
4961 if (!empty) try writer.writeAll(", ");
4962 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer);
4963 empty = false;
4082 }4964 }
4965 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
4966 try writer.writeAll("};\n");
4967 },
4968 .Struct => switch (inst_ty.containerLayout()) {
4969 .Auto, .Extern => {
4970 try writer.writeByte('{');
4971 var empty = true;
4972 for (elements) |element, index| {
4973 if (inst_ty.structFieldValueComptime(index)) |_| continue;
4974
4975 if (!empty) try writer.writeAll(", ");
4976 if (!inst_ty.isTupleOrAnonStruct()) {
4977 try writer.print(".{ } = ", .{fmtIdent(inst_ty.structFieldName(index))});
4978 }
4979
4980 const element_ty = f.air.typeOf(element);
4981 try f.writeCValue(writer, switch (element_ty.zigTypeTag()) {
4982 .Array => CValue{ .undef = element_ty },
4983 else => try f.resolveInst(element),
4984 }, .Initializer);
4985 empty = false;
4986 }
4987 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
4988 try writer.writeAll("};\n");
4989
4990 for (elements) |element, index| {
4991 if (inst_ty.structFieldValueComptime(index)) |_| continue;
4992
4993 const element_ty = f.air.typeOf(element);
4994 if (element_ty.zigTypeTag() != .Array) continue;
4995
4996 var field_name_buf: []u8 = &.{};
4997 defer f.object.dg.gpa.free(field_name_buf);
4998 const field_name = if (inst_ty.isTuple()) field_name: {
4999 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index});
5000 break :field_name field_name_buf;
5001 } else inst_ty.structFieldName(index);
5002
5003 try writer.writeAll(";\n");
5004 try writer.writeAll("memcpy(");
5005 try f.writeCValue(writer, local, .Other);
5006 try writer.print(".{ }, ", .{fmtIdent(field_name)});
5007 try f.writeCValue(writer, try f.resolveInst(element), .FunctionArgument);
5008 try writer.writeAll(", sizeof(");
5009 try f.renderTypecast(writer, element_ty);
5010 try writer.writeAll("));\n");
5011 }
5012 },
5013 .Packed => {
5014 const int_info = inst_ty.intInfo(target);
5015
5016 var bit_offset_ty_pl = Type.Payload.Bits{
5017 .base = .{ .tag = .int_unsigned },
5018 .data = Type.smallestUnsignedBits(int_info.bits - 1),
5019 };
5020 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
5021
5022 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
5023 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
5024
5025 var empty = true;
5026 for (elements) |_, index| {
5027 const field_ty = inst_ty.structFieldType(index);
5028 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5029
5030 if (!empty) {
5031 try writer.writeAll("zig_or_");
5032 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5033 try writer.writeByte('(');
5034 }
5035 empty = false;
5036 }
5037 empty = true;
5038 for (elements) |element, index| {
5039 const field_ty = inst_ty.structFieldType(index);
5040 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5041
5042 if (!empty) try writer.writeAll(", ");
5043 try writer.writeAll("zig_shlw_");
5044 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5045 try writer.writeAll("((");
5046 try f.renderTypecast(writer, inst_ty);
5047 try writer.writeByte(')');
5048 try f.writeCValue(writer, try f.resolveInst(element), .Other);
5049 try writer.writeAll(", ");
5050 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5051 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);
5052 try writer.writeByte(')');
5053 if (!empty) try writer.writeByte(')');
5054
5055 bit_offset_val_pl.data += field_ty.bitSize(target);
5056 empty = false;
5057 }
5058 if (empty) try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);
5059 try writer.writeAll(";\n");
5060 },
4083 },5061 },
4084 else => |tag| return f.fail("TODO: C backend: implement airAggregateInit for type {s}", .{@tagName(tag)}),5062 .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),
5063 else => unreachable,
4085 }5064 }
4086 try writer.writeAll("};\n");
40875065
4088 return local;5066 return local;
4089}5067}
...@@ -4091,16 +5069,43 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4091,16 +5069,43 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
4091fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {5069fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
4092 if (f.liveness.isUnused(inst)) return CValue.none;5070 if (f.liveness.isUnused(inst)) return CValue.none;
40935071
4094 const inst_ty = f.air.typeOfIndex(inst);
4095 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5072 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5073 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
5074 const union_ty = f.air.typeOfIndex(inst);
5075 const target = f.object.dg.module.getTarget();
5076 const layout = union_ty.unionGetLayout(target);
5077 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
5078 const field_name = union_obj.fields.keys()[extra.field_index];
5079 const payload = try f.resolveInst(extra.init);
40965080
4097 const writer = f.object.writer();5081 const writer = f.object.writer();
4098 const local = try f.allocLocal(inst_ty, .Const);5082 const local = try f.allocLocal(union_ty, .Const);
4099 try writer.writeAll(" = ");5083 try writer.writeAll(" = {");
5084 if (union_ty.unionTagTypeSafety()) |tag_ty| {
5085 if (layout.tag_size != 0) {
5086 const field_index = tag_ty.enumFieldIndex(field_name).?;
41005087
4101 _ = local;5088 var tag_pl: Value.Payload.U32 = .{
4102 _ = ty_pl;5089 .base = .{ .tag = .enum_field_index },
4103 return f.fail("TODO: C backend: implement airUnionInit", .{});5090 .data = @intCast(u32, field_index),
5091 };
5092 const tag_val = Value.initPayload(&tag_pl.base);
5093
5094 var int_pl: Value.Payload.U64 = undefined;
5095 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
5096
5097 try writer.print(".tag = {}, ", .{try f.fmtIntLiteral(tag_ty, int_val)});
5098 }
5099 try writer.writeAll(".payload = {");
5100 }
5101
5102 try writer.print(".{ } = ", .{fmtIdent(field_name)});
5103 try f.writeCValue(writer, payload, .Initializer);
5104
5105 if (union_ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
5106 try writer.writeAll("};\n");
5107
5108 return local;
4104}5109}
41055110
4106fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {5111fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -4115,7 +5120,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4115,7 +5120,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
4115 const ptr = try f.resolveInst(prefetch.ptr);5120 const ptr = try f.resolveInst(prefetch.ptr);
4116 const writer = f.object.writer();5121 const writer = f.object.writer();
4117 try writer.writeAll("zig_prefetch(");5122 try writer.writeAll("zig_prefetch(");
4118 try f.writeCValue(writer, ptr);5123 try f.writeCValue(writer, ptr, .FunctionArgument);
4119 try writer.print(", {d}, {d});\n", .{5124 try writer.print(", {d}, {d});\n", .{
4120 @enumToInt(prefetch.rw), prefetch.locality,5125 @enumToInt(prefetch.rw), prefetch.locality,
4121 });5126 });
...@@ -4147,7 +5152,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4147,7 +5152,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
41475152
4148 try writer.writeAll(" = ");5153 try writer.writeAll(" = ");
4149 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});5154 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
4150 try f.writeCValue(writer, operand);5155 try f.writeCValue(writer, operand, .FunctionArgument);
4151 try writer.writeAll(");\n");5156 try writer.writeAll(");\n");
4152 return local;5157 return local;
4153}5158}
...@@ -4160,12 +5165,49 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4160,12 +5165,49 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {
4160 const inst_ty = f.air.typeOfIndex(inst);5165 const inst_ty = f.air.typeOfIndex(inst);
4161 const operand = try f.resolveInst(un_op);5166 const operand = try f.resolveInst(un_op);
4162 const local = try f.allocLocal(inst_ty, .Const);5167 const local = try f.allocLocal(inst_ty, .Const);
4163 try writer.writeAll("-");5168 try writer.writeAll(" = -");
4164 try f.writeCValue(writer, operand);5169 try f.writeCValue(writer, operand, .Other);
4165 try writer.writeAll(";\n");5170 try writer.writeAll(";\n");
4166 return local;5171 return local;
4167}5172}
41685173
5174fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
5175 if (f.liveness.isUnused(inst)) return CValue.none;
5176 const un_op = f.air.instructions.items(.data)[inst].un_op;
5177 const writer = f.object.writer();
5178 const inst_ty = f.air.typeOfIndex(inst);
5179 const operand = try f.resolveInst(un_op);
5180 const local = try f.allocLocal(inst_ty, .Const);
5181 try writer.writeAll(" = zig_builtin_");
5182 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5183 try writer.writeByte('(');
5184 try writer.writeAll(operation);
5185 try writer.writeAll(")(");
5186 try f.writeCValue(writer, operand, .FunctionArgument);
5187 try writer.writeAll(");\n");
5188 return local;
5189}
5190
5191fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
5192 if (f.liveness.isUnused(inst)) return CValue.none;
5193 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
5194 const writer = f.object.writer();
5195 const inst_ty = f.air.typeOfIndex(inst);
5196 const lhs = try f.resolveInst(bin_op.lhs);
5197 const rhs = try f.resolveInst(bin_op.rhs);
5198 const local = try f.allocLocal(inst_ty, .Const);
5199 try writer.writeAll(" = zig_builtin_");
5200 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
5201 try writer.writeByte('(');
5202 try writer.writeAll(operation);
5203 try writer.writeAll(")(");
5204 try f.writeCValue(writer, lhs, .FunctionArgument);
5205 try writer.writeAll(", ");
5206 try f.writeCValue(writer, rhs, .FunctionArgument);
5207 try writer.writeAll(");\n");
5208 return local;
5209}
5210
4169fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {5211fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
4170 if (f.liveness.isUnused(inst)) return CValue.none;5212 if (f.liveness.isUnused(inst)) return CValue.none;
4171 const pl_op = f.air.instructions.items(.data)[inst].pl_op;5213 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
...@@ -4175,30 +5217,23 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4175,30 +5217,23 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
4175 const mulend2 = try f.resolveInst(extra.rhs);5217 const mulend2 = try f.resolveInst(extra.rhs);
4176 const addend = try f.resolveInst(pl_op.operand);5218 const addend = try f.resolveInst(pl_op.operand);
4177 const writer = f.object.writer();5219 const writer = f.object.writer();
4178 const target = f.object.dg.module.getTarget();
4179 const fn_name = switch (inst_ty.floatBits(target)) {
4180 16, 32 => "fmaf",
4181 64 => "fma",
4182 80 => if (CType.longdouble.sizeInBits(target) == 80) "fmal" else "__fmax",
4183 128 => if (CType.longdouble.sizeInBits(target) == 128) "fmal" else "fmaq",
4184 else => unreachable,
4185 };
4186 const local = try f.allocLocal(inst_ty, .Const);5220 const local = try f.allocLocal(inst_ty, .Const);
4187 try writer.writeAll(" = ");5221 try writer.writeAll(" = zig_builtin_");
4188 try writer.print("{s}(", .{fn_name});5222 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
4189 try f.writeCValue(writer, mulend1);5223 try writer.writeAll("(fma)(");
5224 try f.writeCValue(writer, mulend1, .FunctionArgument);
4190 try writer.writeAll(", ");5225 try writer.writeAll(", ");
4191 try f.writeCValue(writer, mulend2);5226 try f.writeCValue(writer, mulend2, .FunctionArgument);
4192 try writer.writeAll(", ");5227 try writer.writeAll(", ");
4193 try f.writeCValue(writer, addend);5228 try f.writeCValue(writer, addend, .FunctionArgument);
4194 try writer.writeAll(");\n");5229 try writer.writeAll(");\n");
4195 return local;5230 return local;
4196}5231}
41975232
4198fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {5233fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
4199 return switch (order) {5234 return switch (order) {
4200 .Unordered => "memory_order_relaxed",5235 // Note: unordered is actually even less atomic than relaxed
4201 .Monotonic => "memory_order_consume",5236 .Unordered, .Monotonic => "memory_order_relaxed",
4202 .Acquire => "memory_order_acquire",5237 .Acquire => "memory_order_acquire",
4203 .Release => "memory_order_release",5238 .Release => "memory_order_release",
4204 .AcqRel => "memory_order_acq_rel",5239 .AcqRel => "memory_order_acq_rel",
...@@ -4293,61 +5328,250 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {...@@ -4293,61 +5328,250 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {
4293 };5328 };
4294}5329}
42955330
4296fn intMax(ty: Type, target: std.Target, buf: []u8) []const u8 {5331fn formatStringLiteral(
4297 switch (ty.tag()) {5332 str: []const u8,
4298 .c_short => return "SHRT_MAX",5333 comptime fmt: []const u8,
4299 .c_ushort => return "USHRT_MAX",5334 _: std.fmt.FormatOptions,
4300 .c_int => return "INT_MAX",5335 writer: anytype,
4301 .c_uint => return "UINT_MAX",5336) @TypeOf(writer).Error!void {
4302 .c_long => return "LONG_MAX",5337 if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt);
4303 .c_ulong => return "ULONG_MAX",5338 try writer.writeByte('\"');
4304 .c_longlong => return "LLONG_MAX",5339 for (str) |c| switch (c) {
4305 .c_ulonglong => return "ULLONG_MAX",5340 7 => try writer.writeAll("\\a"),
4306 else => {5341 8 => try writer.writeAll("\\b"),
4307 const int_info = ty.intInfo(target);5342 '\t' => try writer.writeAll("\\t"),
4308 const rhs = @intCast(u7, int_info.bits - @boolToInt(int_info.signedness == .signed));5343 '\n' => try writer.writeAll("\\n"),
4309 const val = (@as(u128, 1) << rhs) - 1;5344 11 => try writer.writeAll("\\v"),
4310 // TODO make this integer literal have a suffix if necessary (such as "ull")5345 12 => try writer.writeAll("\\f"),
4311 return std.fmt.bufPrint(buf, "{}", .{val}) catch |err| switch (err) {5346 '\r' => try writer.writeAll("\\r"),
4312 error.NoSpaceLeft => unreachable,5347 '"', '\'', '?', '\\' => try writer.print("\\{c}", .{c}),
4313 };5348 else => switch (c) {
5349 ' '...'~' => try writer.writeByte(c),
5350 else => try writer.print("\\{o:0>3}", .{c}),
4314 },5351 },
4315 }5352 };
5353 try writer.writeByte('\"');
5354}
5355fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) {
5356 return .{ .data = str };
4316}5357}
43175358
4318fn intMin(ty: Type, target: std.Target, buf: []u8) []const u8 {5359fn undefPattern(comptime T: type) T {
4319 switch (ty.tag()) {5360 return (1 << (@bitSizeOf(T) | 1)) / 3;
4320 .c_short => return "SHRT_MIN",
4321 .c_int => return "INT_MIN",
4322 .c_long => return "LONG_MIN",
4323 .c_longlong => return "LLONG_MIN",
4324 else => {
4325 const int_info = ty.intInfo(target);
4326 assert(int_info.signedness == .signed);
4327 const val = v: {
4328 if (int_info.bits == 0) break :v 0;
4329 const rhs = @intCast(u7, (int_info.bits - 1));
4330 break :v -(@as(i128, 1) << rhs);
4331 };
4332 return std.fmt.bufPrint(buf, "{d}", .{val}) catch |err| switch (err) {
4333 error.NoSpaceLeft => unreachable,
4334 };
4335 },
4336 }
4337}5361}
43385362
4339fn loweredFnRetTyHasBits(fn_ty: Type) bool {5363const FormatIntLiteralContext = struct {
4340 const ret_ty = fn_ty.fnReturnType();5364 ty: Type,
4341 if (ret_ty.hasRuntimeBitsIgnoreComptime()) {5365 val: Value,
4342 return true;5366 mod: *Module,
5367};
5368fn formatIntLiteral(
5369 data: FormatIntLiteralContext,
5370 comptime fmt: []const u8,
5371 options: std.fmt.FormatOptions,
5372 writer: anytype,
5373) @TypeOf(writer).Error!void {
5374 const target = data.mod.getTarget();
5375 const int_info = data.ty.intInfo(target);
5376
5377 const Limb = std.math.big.Limb;
5378 const ExpectedContents = struct {
5379 const base = 10;
5380 const limbs_count_128 = BigInt.calcTwosCompLimbCount(128);
5381 const expected_needed_limbs_count = BigInt.calcToStringLimbsBufferLen(limbs_count_128, base);
5382 const worst_case_int = BigInt.Const{
5383 .limbs = &([1]Limb{std.math.maxInt(Limb)} ** expected_needed_limbs_count),
5384 .positive = false,
5385 };
5386
5387 undef_limbs: [limbs_count_128]Limb,
5388 wrap_limbs: [limbs_count_128]Limb,
5389 };
5390 var stack align(@alignOf(ExpectedContents)) =
5391 std.heap.stackFallback(@sizeOf(ExpectedContents), data.mod.gpa);
5392 const allocator = stack.get();
5393
5394 var undef_limbs: []Limb = &.{};
5395 defer allocator.free(undef_limbs);
5396
5397 var int_buf: Value.BigIntSpace = undefined;
5398 const int = if (data.val.isUndefDeep()) blk: {
5399 undef_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(int_info.bits));
5400 std.mem.set(Limb, undef_limbs, undefPattern(Limb));
5401
5402 var undef_int = BigInt.Mutable{
5403 .limbs = undef_limbs,
5404 .len = undef_limbs.len,
5405 .positive = true,
5406 };
5407 undef_int.truncate(undef_int.toConst(), int_info.signedness, int_info.bits);
5408 break :blk undef_int.toConst();
5409 } else data.val.toBigInt(&int_buf, target);
5410 assert(int.fitsInTwosComp(int_info.signedness, int_info.bits));
5411
5412 const c_bits = toCIntBits(int_info.bits) orelse unreachable;
5413 var one_limbs: [BigInt.calcLimbLen(1)]Limb = undefined;
5414 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();
5415
5416 const wrap_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(c_bits));
5417 defer allocator.free(wrap_limbs);
5418 var wrap = BigInt.Mutable{ .limbs = wrap_limbs, .len = undefined, .positive = undefined };
5419 if (wrap.addWrap(int, one, int_info.signedness, c_bits) or
5420 int_info.signedness == .signed and wrap.subWrap(int, one, int_info.signedness, c_bits))
5421 {
5422 const abbrev = switch (data.ty.tag()) {
5423 .c_short, .c_ushort => "SHRT",
5424 .c_int, .c_uint => "INT",
5425 .c_long, .c_ulong => "LONG",
5426 .c_longlong, .c_ulonglong => "LLONG",
5427 .isize, .usize => "INTPTR",
5428 else => return writer.print("zig_{s}Int_{c}{d}", .{
5429 if (int.positive) "max" else "min", signAbbrev(int_info.signedness), c_bits,
5430 }),
5431 };
5432 if (int_info.signedness == .unsigned) try writer.writeByte('U');
5433 return writer.print("{s}_{s}", .{ abbrev, if (int.positive) "MAX" else "MIN" });
4343 }5434 }
4344 if (ret_ty.isError()) {5435
4345 return true;5436 if (!int.positive) try writer.writeByte('-');
5437 switch (data.ty.tag()) {
5438 .c_short, .c_ushort, .c_int, .c_uint, .c_long, .c_ulong, .c_longlong, .c_ulonglong => {},
5439 else => try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }),
5440 }
5441
5442 const limbs_count_64 = @divExact(64, @bitSizeOf(Limb));
5443 if (c_bits <= 64) {
5444 var base: u8 = undefined;
5445 var case: std.fmt.Case = undefined;
5446 switch (fmt.len) {
5447 0 => base = 10,
5448 1 => switch (fmt[0]) {
5449 'b' => {
5450 base = 2;
5451 try writer.writeAll("0b");
5452 },
5453 'o' => {
5454 base = 8;
5455 try writer.writeByte('0');
5456 },
5457 'd' => base = 10,
5458 'x' => {
5459 base = 16;
5460 case = .lower;
5461 try writer.writeAll("0x");
5462 },
5463 'X' => {
5464 base = 16;
5465 case = .upper;
5466 try writer.writeAll("0x");
5467 },
5468 else => @compileError("Invalid fmt: " ++ fmt),
5469 },
5470 else => @compileError("Invalid fmt: " ++ fmt),
5471 }
5472
5473 var str: [64]u8 = undefined;
5474 var limbs_buf: [BigInt.calcToStringLimbsBufferLen(limbs_count_64, 10)]Limb = undefined;
5475 try writer.writeAll(str[0..int.abs().toString(&str, base, case, &limbs_buf)]);
5476 } else {
5477 assert(c_bits == 128);
5478 const split = std.math.min(int.limbs.len, limbs_count_64);
5479
5480 var upper_pl = Value.Payload.BigInt{
5481 .base = .{ .tag = .int_big_positive },
5482 .data = int.limbs[split..],
5483 };
5484 const upper_val = Value.initPayload(&upper_pl.base);
5485 try formatIntLiteral(.{
5486 .ty = switch (int_info.signedness) {
5487 .unsigned => Type.u64,
5488 .signed => Type.i64,
5489 },
5490 .val = upper_val,
5491 .mod = data.mod,
5492 }, fmt, options, writer);
5493
5494 try writer.writeAll(", ");
5495
5496 var lower_pl = Value.Payload.BigInt{
5497 .base = .{ .tag = .int_big_positive },
5498 .data = int.limbs[0..split],
5499 };
5500 const lower_val = Value.initPayload(&lower_pl.base);
5501 try formatIntLiteral(.{
5502 .ty = Type.u64,
5503 .val = lower_val,
5504 .mod = data.mod,
5505 }, fmt, options, writer);
5506
5507 return writer.writeByte(')');
5508 }
5509
5510 switch (data.ty.tag()) {
5511 .c_short, .c_ushort, .c_int => {},
5512 .c_uint => try writer.writeAll("u"),
5513 .c_long => try writer.writeAll("l"),
5514 .c_ulong => try writer.writeAll("ul"),
5515 .c_longlong => try writer.writeAll("ll"),
5516 .c_ulonglong => try writer.writeAll("ull"),
5517 else => try writer.writeByte(')'),
4346 }5518 }
4347 return false;
4348}5519}
43495520
4350fn isByRef(ty: Type) bool {5521fn isByRef(ty: Type) bool {
4351 _ = ty;5522 _ = ty;
4352 return false;5523 return false;
4353}5524}
5525
5526const LowerFnRetTyBuffer = struct {
5527 const names = [1][]const u8{"array"};
5528 types: [1]Type,
5529 values: [1]Value,
5530 payload: Type.Payload.AnonStruct,
5531};
5532fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) Type {
5533 if (ret_ty.zigTypeTag() == .NoReturn) return Type.initTag(.noreturn);
5534
5535 if (lowersToArray(ret_ty, target)) {
5536 buffer.types = [1]Type{ret_ty};
5537 buffer.values = [1]Value{Value.initTag(.unreachable_value)};
5538 buffer.payload = .{ .data = .{
5539 .names = &LowerFnRetTyBuffer.names,
5540 .types = &buffer.types,
5541 .values = &buffer.values,
5542 } };
5543 return Type.initPayload(&buffer.payload.base);
5544 }
5545
5546 return if (ret_ty.hasRuntimeBitsIgnoreComptime()) ret_ty else Type.void;
5547}
5548
5549fn lowersToArray(ty: Type, target: std.Target) bool {
5550 return switch (ty.zigTypeTag()) {
5551 .Array => return true,
5552 else => return ty.isAbiInt() and toCIntBits(@intCast(u32, ty.bitSize(target))) == null,
5553 };
5554}
5555
5556fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo {
5557 if (!lowersToArray(ty, target)) return null;
5558
5559 switch (ty.zigTypeTag()) {
5560 .Array => return ty.arrayInfo(),
5561 else => {
5562 const abi_size = ty.abiSize(target);
5563 const abi_align = ty.abiAlignment(target);
5564 return Type.ArrayInfo{
5565 .elem_type = switch (abi_align) {
5566 1 => Type.u8,
5567 2 => Type.u16,
5568 4 => Type.u32,
5569 8 => Type.u64,
5570 16 => Type.initTag(.u128),
5571 else => unreachable,
5572 },
5573 .len = @divExact(abi_size, abi_align),
5574 };
5575 },
5576 }
5577}
src/link/C.zig+114-101
...@@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
108 const typedefs = &gop.value_ptr.typedefs;108 const typedefs = &gop.value_ptr.typedefs;
109 const code = &gop.value_ptr.code;109 const code = &gop.value_ptr.code;
110 fwd_decl.shrinkRetainingCapacity(0);110 fwd_decl.shrinkRetainingCapacity(0);
111 {111 for (typedefs.values()) |typedef| {
112 for (typedefs.values()) |value| {112 module.gpa.free(typedef.rendered);
113 module.gpa.free(value.rendered);
114 }
115 }113 }
116 typedefs.clearRetainingCapacity();114 typedefs.clearRetainingCapacity();
117 code.shrinkRetainingCapacity(0);115 code.shrinkRetainingCapacity(0);
...@@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
139137
140 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };138 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
141 defer {139 defer {
142 function.value_map.deinit();
143 function.blocks.deinit(module.gpa);140 function.blocks.deinit(module.gpa);
141 function.value_map.deinit();
144 function.object.code.deinit();142 function.object.code.deinit();
145 function.object.dg.fwd_decl.deinit();143 for (function.object.dg.typedefs.values()) |typedef| {
146 for (function.object.dg.typedefs.values()) |value| {144 module.gpa.free(typedef.rendered);
147 module.gpa.free(value.rendered);
148 }145 }
149 function.object.dg.typedefs.deinit();146 function.object.dg.typedefs.deinit();
147 function.object.dg.fwd_decl.deinit();
150 }148 }
151149
152 codegen.genFunc(&function) catch |err| switch (err) {150 codegen.genFunc(&function) catch |err| switch (err) {
...@@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
179 const typedefs = &gop.value_ptr.typedefs;177 const typedefs = &gop.value_ptr.typedefs;
180 const code = &gop.value_ptr.code;178 const code = &gop.value_ptr.code;
181 fwd_decl.shrinkRetainingCapacity(0);179 fwd_decl.shrinkRetainingCapacity(0);
182 {180 for (typedefs.values()) |value| {
183 for (typedefs.values()) |value| {181 module.gpa.free(value.rendered);
184 module.gpa.free(value.rendered);
185 }
186 }182 }
187 typedefs.clearRetainingCapacity();183 typedefs.clearRetainingCapacity();
188 code.shrinkRetainingCapacity(0);184 code.shrinkRetainingCapacity(0);
...@@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
206 object.indent_writer = .{ .underlying_writer = object.code.writer() };202 object.indent_writer = .{ .underlying_writer = object.code.writer() };
207 defer {203 defer {
208 object.code.deinit();204 object.code.deinit();
209 object.dg.fwd_decl.deinit();205 for (object.dg.typedefs.values()) |typedef| {
210 for (object.dg.typedefs.values()) |value| {206 module.gpa.free(typedef.rendered);
211 module.gpa.free(value.rendered);
212 }207 }
213 object.dg.typedefs.deinit();208 object.dg.typedefs.deinit();
209 object.dg.fwd_decl.deinit();
214 }210 }
215211
216 codegen.genDecl(&object) catch |err| switch (err) {212 codegen.genDecl(&object) catch |err| switch (err) {
...@@ -260,30 +256,26 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -260,30 +256,26 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
260 var f: Flush = .{};256 var f: Flush = .{};
261 defer f.deinit(gpa);257 defer f.deinit(gpa);
262258
263 // Covers zig.h and err_typedef_item.259 // Covers zig.h, typedef, and asm.
264 try f.all_buffers.ensureUnusedCapacity(gpa, 2);260 try f.all_buffers.ensureUnusedCapacity(gpa, 2);
265261
266 if (zig_h.len != 0) {262 f.appendBufAssumeCapacity(zig_h);
267 f.all_buffers.appendAssumeCapacity(.{
268 .iov_base = zig_h,
269 .iov_len = zig_h.len,
270 });
271 f.file_size += zig_h.len;
272 }
273263
274 const err_typedef_writer = f.err_typedef_buf.writer(gpa);264 const typedef_index = f.all_buffers.items.len;
275 const err_typedef_index = f.all_buffers.items.len;
276 f.all_buffers.items.len += 1;265 f.all_buffers.items.len += 1;
277266
278 render_errors: {267 {
279 if (module.global_error_set.size == 0) break :render_errors;268 var asm_buf = f.asm_buf.toManaged(module.gpa);
280 var it = module.global_error_set.iterator();269 defer asm_buf.deinit();
281 while (it.next()) |entry| {270
282 try err_typedef_writer.print("#define zig_error_{s} {d}\n", .{ entry.key_ptr.*, entry.value_ptr.* });271 try codegen.genGlobalAsm(module, &asm_buf);
283 }272
284 try err_typedef_writer.writeByte('\n');273 f.asm_buf = asm_buf.moveToUnmanaged();
274 f.appendBufAssumeCapacity(f.asm_buf.items);
285 }275 }
286276
277 try self.flushErrDecls(&f);
278
287 // Typedefs, forward decls, and non-functions first.279 // Typedefs, forward decls, and non-functions first.
288 // Unlike other backends, the .c code we are emitting is order-dependent. Therefore280 // Unlike other backends, the .c code we are emitting is order-dependent. Therefore
289 // we must traverse the set of Decls that we are emitting according to their dependencies.281 // we must traverse the set of Decls that we are emitting according to their dependencies.
...@@ -300,38 +292,19 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -300,38 +292,19 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
300292
301 while (f.remaining_decls.popOrNull()) |kv| {293 while (f.remaining_decls.popOrNull()) |kv| {
302 const decl_index = kv.key;294 const decl_index = kv.key;
303 try flushDecl(self, &f, decl_index);295 try self.flushDecl(&f, decl_index);
304 }296 }
305297
306 if (f.err_typedef_buf.items.len == 0) {298 f.all_buffers.items[typedef_index] = .{
307 f.all_buffers.items[err_typedef_index] = .{299 .iov_base = if (f.typedef_buf.items.len > 0) f.typedef_buf.items.ptr else "",
308 .iov_base = "",300 .iov_len = f.typedef_buf.items.len,
309 .iov_len = 0,301 };
310 };302 f.file_size += f.typedef_buf.items.len;
311 } else {
312 f.all_buffers.items[err_typedef_index] = .{
313 .iov_base = f.err_typedef_buf.items.ptr,
314 .iov_len = f.err_typedef_buf.items.len,
315 };
316 f.file_size += f.err_typedef_buf.items.len;
317 }
318303
319 // Now the function bodies.304 // Now the code.
320 try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count);305 try f.all_buffers.ensureUnusedCapacity(gpa, decl_values.len);
321 for (decl_keys) |decl_index, i| {306 for (decl_values) |decl|
322 const decl = module.declPtr(decl_index);307 f.appendBufAssumeCapacity(decl.code.items);
323 if (decl.getFunction() != null) {
324 const decl_block = &decl_values[i];
325 const buf = decl_block.code.items;
326 if (buf.len != 0) {
327 f.all_buffers.appendAssumeCapacity(.{
328 .iov_base = buf.ptr,
329 .iov_len = buf.len,
330 });
331 f.file_size += buf.len;
332 }
333 }
334 }
335308
336 const file = self.base.file.?;309 const file = self.base.file.?;
337 try file.setEndPos(f.file_size);310 try file.setEndPos(f.file_size);
...@@ -339,14 +312,15 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -339,14 +312,15 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
339}312}
340313
341const Flush = struct {314const Flush = struct {
315 err_decls: DeclBlock = .{},
342 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},316 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
343 typedefs: Typedefs = .{},317 typedefs: Typedefs = .{},
344 err_typedef_buf: std.ArrayListUnmanaged(u8) = .{},318 typedef_buf: std.ArrayListUnmanaged(u8) = .{},
319 asm_buf: std.ArrayListUnmanaged(u8) = .{},
345 /// We collect a list of buffers to write, and write them all at once with pwritev 😎320 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
346 all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},321 all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},
347 /// Keeps track of the total bytes of `all_buffers`.322 /// Keeps track of the total bytes of `all_buffers`.
348 file_size: u64 = 0,323 file_size: u64 = 0,
349 fn_count: usize = 0,
350324
351 const Typedefs = std.HashMapUnmanaged(325 const Typedefs = std.HashMapUnmanaged(
352 Type,326 Type,
...@@ -355,11 +329,18 @@ const Flush = struct {...@@ -355,11 +329,18 @@ const Flush = struct {
355 std.hash_map.default_max_load_percentage,329 std.hash_map.default_max_load_percentage,
356 );330 );
357331
332 fn appendBufAssumeCapacity(f: *Flush, buf: []const u8) void {
333 if (buf.len == 0) return;
334 f.all_buffers.appendAssumeCapacity(.{ .iov_base = buf.ptr, .iov_len = buf.len });
335 f.file_size += buf.len;
336 }
337
358 fn deinit(f: *Flush, gpa: Allocator) void {338 fn deinit(f: *Flush, gpa: Allocator) void {
359 f.all_buffers.deinit(gpa);339 f.all_buffers.deinit(gpa);
360 f.err_typedef_buf.deinit(gpa);340 f.typedef_buf.deinit(gpa);
361 f.typedefs.deinit(gpa);341 f.typedefs.deinit(gpa);
362 f.remaining_decls.deinit(gpa);342 f.remaining_decls.deinit(gpa);
343 f.err_decls.deinit(gpa);
363 }344 }
364};345};
365346
...@@ -367,6 +348,72 @@ const FlushDeclError = error{...@@ -367,6 +348,72 @@ const FlushDeclError = error{
367 OutOfMemory,348 OutOfMemory,
368};349};
369350
351fn flushTypedefs(self: *C, f: *Flush, typedefs: codegen.TypedefMap.Unmanaged) FlushDeclError!void {
352 if (typedefs.count() == 0) return;
353 const gpa = self.base.allocator;
354 const module = self.base.options.module.?;
355
356 try f.typedefs.ensureUnusedCapacityContext(gpa, @intCast(u32, typedefs.count()), .{
357 .mod = module,
358 });
359 var it = typedefs.iterator();
360 while (it.next()) |new| {
361 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{
362 .mod = module,
363 });
364 if (!gop.found_existing) {
365 try f.typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
366 }
367 }
368}
369
370fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
371 const module = self.base.options.module.?;
372
373 const fwd_decl = &f.err_decls.fwd_decl;
374 const typedefs = &f.err_decls.typedefs;
375 const code = &f.err_decls.code;
376
377 var object = codegen.Object{
378 .dg = .{
379 .gpa = module.gpa,
380 .module = module,
381 .error_msg = null,
382 .decl_index = undefined,
383 .decl = undefined,
384 .fwd_decl = fwd_decl.toManaged(module.gpa),
385 .typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
386 .typedefs_arena = self.arena.allocator(),
387 },
388 .code = code.toManaged(module.gpa),
389 .indent_writer = undefined, // set later so we can get a pointer to object.code
390 };
391 object.indent_writer = .{ .underlying_writer = object.code.writer() };
392 defer {
393 object.code.deinit();
394 for (object.dg.typedefs.values()) |typedef| {
395 module.gpa.free(typedef.rendered);
396 }
397 object.dg.typedefs.deinit();
398 object.dg.fwd_decl.deinit();
399 }
400
401 codegen.genErrDecls(&object) catch |err| switch (err) {
402 error.AnalysisFail => unreachable,
403 else => |e| return e,
404 };
405
406 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
407 typedefs.* = object.dg.typedefs.unmanaged;
408 object.dg.typedefs.unmanaged = .{};
409 code.* = object.code.moveToUnmanaged();
410
411 try self.flushTypedefs(f, typedefs.*);
412 try f.all_buffers.ensureUnusedCapacity(self.base.allocator, 1);
413 f.appendBufAssumeCapacity(fwd_decl.items);
414 f.appendBufAssumeCapacity(code.items);
415}
416
370/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.417/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.
371fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void {418fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void {
372 const module = self.base.options.module.?;419 const module = self.base.options.module.?;
...@@ -383,43 +430,9 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!...@@ -383,43 +430,9 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!
383 const decl_block = self.decl_table.getPtr(decl_index).?;430 const decl_block = self.decl_table.getPtr(decl_index).?;
384 const gpa = self.base.allocator;431 const gpa = self.base.allocator;
385432
386 if (decl_block.typedefs.count() != 0) {433 try self.flushTypedefs(f, decl_block.typedefs);
387 try f.typedefs.ensureUnusedCapacityContext(gpa, @intCast(u32, decl_block.typedefs.count()), .{434 try f.all_buffers.ensureUnusedCapacity(gpa, 2);
388 .mod = module,435 f.appendBufAssumeCapacity(decl_block.fwd_decl.items);
389 });
390 var it = decl_block.typedefs.iterator();
391 while (it.next()) |new| {
392 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{
393 .mod = module,
394 });
395 if (!gop.found_existing) {
396 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
397 }
398 }
399 }
400
401 if (decl_block.fwd_decl.items.len != 0) {
402 const buf = decl_block.fwd_decl.items;
403 if (buf.len != 0) {
404 try f.all_buffers.append(gpa, .{
405 .iov_base = buf.ptr,
406 .iov_len = buf.len,
407 });
408 f.file_size += buf.len;
409 }
410 }
411 if (decl.getFunction() != null) {
412 f.fn_count += 1;
413 } else if (decl_block.code.items.len != 0) {
414 const buf = decl_block.code.items;
415 if (buf.len != 0) {
416 try f.all_buffers.append(gpa, .{
417 .iov_base = buf.ptr,
418 .iov_len = buf.len,
419 });
420 f.file_size += buf.len;
421 }
422 }
423}436}
424437
425pub fn flushEmitH(module: *Module) !void {438pub fn flushEmitH(module: *Module) !void {
src/main.zig+4-1
...@@ -3018,7 +3018,10 @@ fn buildOutputType(...@@ -3018,7 +3018,10 @@ fn buildOutputType(
3018 const c_code_path = try fs.path.join(arena, &[_][]const u8{3018 const c_code_path = try fs.path.join(arena, &[_][]const u8{
3019 c_code_directory.path orelse ".", c_code_loc.basename,3019 c_code_directory.path orelse ".", c_code_loc.basename,
3020 });3020 });
3021 try test_exec_args.appendSlice(&.{ self_exe_path, "run", "-lc", c_code_path });3021 try test_exec_args.append(self_exe_path);
3022 try test_exec_args.append("run");
3023 if (link_libc) try test_exec_args.append("-lc");
3024 try test_exec_args.append(c_code_path);
3022 }3025 }
30233026
3024 const run_or_test = switch (arg_mode) {3027 const run_or_test = switch (arg_mode) {
src/test.zig+1
...@@ -791,6 +791,7 @@ pub const TestContext = struct {...@@ -791,6 +791,7 @@ pub const TestContext = struct {
791 .updates = std.ArrayList(Update).init(ctx.cases.allocator),791 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
792 .output_mode = .Exe,792 .output_mode = .Exe,
793 .files = std.ArrayList(File).init(ctx.arena),793 .files = std.ArrayList(File).init(ctx.arena),
794 .link_libc = true,
794 }) catch @panic("out of memory");795 }) catch @panic("out of memory");
795 return &ctx.cases.items[ctx.cases.items.len - 1];796 return &ctx.cases.items[ctx.cases.items.len - 1];
796 }797 }
src/type.zig+20-6
...@@ -5282,7 +5282,7 @@ pub const Type = extern union {...@@ -5282,7 +5282,7 @@ pub const Type = extern union {
5282 // Works for vectors and vectors of integers.5282 // Works for vectors and vectors of integers.
5283 pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {5283 pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {
5284 const scalar = try minIntScalar(ty.scalarType(), arena, target);5284 const scalar = try minIntScalar(ty.scalarType(), arena, target);
5285 if (ty.zigTypeTag() == .Vector) {5285 if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) {
5286 return Value.Tag.repeated.create(arena, scalar);5286 return Value.Tag.repeated.create(arena, scalar);
5287 } else {5287 } else {
5288 return scalar;5288 return scalar;
...@@ -5294,12 +5294,16 @@ pub const Type = extern union {...@@ -5294,12 +5294,16 @@ pub const Type = extern union {
5294 assert(ty.zigTypeTag() == .Int);5294 assert(ty.zigTypeTag() == .Int);
5295 const info = ty.intInfo(target);5295 const info = ty.intInfo(target);
52965296
5297 if (info.bits == 0) {
5298 return Value.initTag(.the_only_possible_value);
5299 }
5300
5297 if (info.signedness == .unsigned) {5301 if (info.signedness == .unsigned) {
5298 return Value.zero;5302 return Value.zero;
5299 }5303 }
53005304
5301 if (info.bits <= 6) {5305 if (std.math.cast(u6, info.bits - 1)) |shift| {
5302 const n: i64 = -(@as(i64, 1) << @truncate(u6, info.bits - 1));5306 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
5303 return Value.Tag.int_i64.create(arena, n);5307 return Value.Tag.int_i64.create(arena, n);
5304 }5308 }
53055309
...@@ -5319,13 +5323,23 @@ pub const Type = extern union {...@@ -5319,13 +5323,23 @@ pub const Type = extern union {
5319 assert(self.zigTypeTag() == .Int);5323 assert(self.zigTypeTag() == .Int);
5320 const info = self.intInfo(target);5324 const info = self.intInfo(target);
53215325
5322 if (info.bits <= 6) switch (info.signedness) {5326 if (info.bits == 0) {
5327 return Value.initTag(.the_only_possible_value);
5328 }
5329
5330 switch (info.bits - @boolToInt(info.signedness == .signed)) {
5331 0 => return Value.zero,
5332 1 => return Value.one,
5333 else => {},
5334 }
5335
5336 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {
5323 .signed => {5337 .signed => {
5324 const n: i64 = (@as(i64, 1) << @truncate(u6, info.bits - 1)) - 1;5338 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);
5325 return Value.Tag.int_i64.create(arena, n);5339 return Value.Tag.int_i64.create(arena, n);
5326 },5340 },
5327 .unsigned => {5341 .unsigned => {
5328 const n: u64 = (@as(u64, 1) << @truncate(u6, info.bits)) - 1;5342 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);
5329 return Value.Tag.int_u64.create(arena, n);5343 return Value.Tag.int_u64.create(arena, n);
5330 },5344 },
5331 };5345 };
test/behavior.zig+1-7
...@@ -213,13 +213,7 @@ test {...@@ -213,13 +213,7 @@ test {
213 _ = @import("behavior/export.zig");213 _ = @import("behavior/export.zig");
214 }214 }
215215
216 if (builtin.zig_backend != .stage2_arm and216 if (builtin.zig_backend != .stage2_wasm) {
217 builtin.zig_backend != .stage2_x86_64 and
218 builtin.zig_backend != .stage2_aarch64 and
219 builtin.zig_backend != .stage2_wasm and
220 builtin.zig_backend != .stage2_c and
221 builtin.zig_backend != .stage1)
222 {
223 _ = @import("behavior/export_self_referential_type_info.zig");217 _ = @import("behavior/export_self_referential_type_info.zig");
224 }218 }
225}219}
test/behavior/align.zig-12
...@@ -7,8 +7,6 @@ const assert = std.debug.assert;...@@ -7,8 +7,6 @@ const assert = std.debug.assert;
7var foo: u8 align(4) = 100;7var foo: u8 align(4) = 100;
88
9test "global variable alignment" {9test "global variable alignment" {
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11
12 comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4);10 comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4);
13 comptime try expect(@TypeOf(&foo) == *align(4) u8);11 comptime try expect(@TypeOf(&foo) == *align(4) u8);
14 {12 {
...@@ -223,7 +221,6 @@ fn fnWithAlignedStack() i32 {...@@ -223,7 +221,6 @@ fn fnWithAlignedStack() i32 {
223}221}
224222
225test "implicitly decreasing slice alignment" {223test "implicitly decreasing slice alignment" {
226 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
228225
229 const a: u32 align(4) = 3;226 const a: u32 align(4) = 3;
...@@ -235,7 +232,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {...@@ -235,7 +232,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
235}232}
236233
237test "specifying alignment allows pointer cast" {234test "specifying alignment allows pointer cast" {
238 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
239 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
240236
241 try testBytesAlign(0x33);237 try testBytesAlign(0x33);
...@@ -247,7 +243,6 @@ fn testBytesAlign(b: u8) !void {...@@ -247,7 +243,6 @@ fn testBytesAlign(b: u8) !void {
247}243}
248244
249test "@alignCast slices" {245test "@alignCast slices" {
250 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
251 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
253248
...@@ -301,7 +296,6 @@ fn noop4() align(4) void {}...@@ -301,7 +296,6 @@ fn noop4() align(4) void {}
301296
302test "function alignment" {297test "function alignment" {
303 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
304 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
306300
307 // function alignment is a compile error on wasm32/wasm64301 // function alignment is a compile error on wasm32/wasm64
...@@ -316,7 +310,6 @@ test "function alignment" {...@@ -316,7 +310,6 @@ test "function alignment" {
316310
317test "implicitly decreasing fn alignment" {311test "implicitly decreasing fn alignment" {
318 if (builtin.zig_backend == .stage1) return error.SkipZigTest;312 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
319 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
321 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;314 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
322315
...@@ -341,7 +334,6 @@ fn alignedBig() align(16) i32 {...@@ -341,7 +334,6 @@ fn alignedBig() align(16) i32 {
341test "@alignCast functions" {334test "@alignCast functions" {
342 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;335 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
343 if (builtin.zig_backend == .stage1) return error.SkipZigTest;336 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
344 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
345 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
346338
347 // function alignment is a compile error on wasm32/wasm64339 // function alignment is a compile error on wasm32/wasm64
...@@ -401,8 +393,6 @@ test "function callconv expression depends on generic parameter" {...@@ -401,8 +393,6 @@ test "function callconv expression depends on generic parameter" {
401}393}
402394
403test "runtime-known array index has best alignment possible" {395test "runtime-known array index has best alignment possible" {
404 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
405
406 // take full advantage of over-alignment396 // take full advantage of over-alignment
407 var array align(4) = [_]u8{ 1, 2, 3, 4 };397 var array align(4) = [_]u8{ 1, 2, 3, 4 };
408 comptime assert(@TypeOf(&array[0]) == *align(4) u8);398 comptime assert(@TypeOf(&array[0]) == *align(4) u8);
...@@ -482,7 +472,6 @@ test "read 128-bit field from default aligned struct in global memory" {...@@ -482,7 +472,6 @@ test "read 128-bit field from default aligned struct in global memory" {
482}472}
483473
484test "struct field explicit alignment" {474test "struct field explicit alignment" {
485 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
486 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;475 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
487 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
488 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;477 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -546,7 +535,6 @@ test "comptime alloc alignment" {...@@ -546,7 +535,6 @@ test "comptime alloc alignment" {
546 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO535 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO536 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO537 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
549 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
550 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO538 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
551539
552 comptime var bytes1 = [_]u8{0};540 comptime var bytes1 = [_]u8{0};
test/behavior/alignof.zig-2
...@@ -12,7 +12,6 @@ const Foo = struct {...@@ -12,7 +12,6 @@ const Foo = struct {
1212
13test "@alignOf(T) before referencing T" {13test "@alignOf(T) before referencing T" {
14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16 comptime try expect(@alignOf(Foo) != maxInt(usize));15 comptime try expect(@alignOf(Foo) != maxInt(usize));
17 if (native_arch == .x86_64) {16 if (native_arch == .x86_64) {
18 comptime try expect(@alignOf(Foo) == 4);17 comptime try expect(@alignOf(Foo) == 4);
...@@ -20,7 +19,6 @@ test "@alignOf(T) before referencing T" {...@@ -20,7 +19,6 @@ test "@alignOf(T) before referencing T" {
20}19}
2120
22test "comparison of @alignOf(T) against zero" {21test "comparison of @alignOf(T) against zero" {
23 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
24 {22 {
25 const T = struct { x: u32 };23 const T = struct { x: u32 };
26 try expect(!(@alignOf(T) == 0));24 try expect(!(@alignOf(T) == 0));
test/behavior/array.zig-6
...@@ -6,8 +6,6 @@ const expect = testing.expect;...@@ -6,8 +6,6 @@ const expect = testing.expect;
6const expectEqual = testing.expectEqual;6const expectEqual = testing.expectEqual;
77
8test "array to slice" {8test "array to slice" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10
11 const a: u32 align(4) = 3;9 const a: u32 align(4) = 3;
12 const b: u32 align(8) = 4;10 const b: u32 align(8) = 4;
13 const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..];11 const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..];
...@@ -160,7 +158,6 @@ test "nested arrays of strings" {...@@ -160,7 +158,6 @@ test "nested arrays of strings" {
160158
161test "nested arrays of integers" {159test "nested arrays of integers" {
162 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
164161
165 const array_of_numbers = [_][2]u8{162 const array_of_numbers = [_][2]u8{
166 [2]u8{ 1, 2 },163 [2]u8{ 1, 2 },
...@@ -479,7 +476,6 @@ test "sentinel element count towards the ABI size calculation" {...@@ -479,7 +476,6 @@ test "sentinel element count towards the ABI size calculation" {
479476
480test "zero-sized array with recursive type definition" {477test "zero-sized array with recursive type definition" {
481 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO478 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
482 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
483479
484 const U = struct {480 const U = struct {
485 fn foo(comptime T: type, comptime n: usize) type {481 fn foo(comptime T: type, comptime n: usize) type {
...@@ -501,7 +497,6 @@ test "zero-sized array with recursive type definition" {...@@ -501,7 +497,6 @@ test "zero-sized array with recursive type definition" {
501test "type coercion of anon struct literal to array" {497test "type coercion of anon struct literal to array" {
502 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
503 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO499 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
504 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
505 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO500 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
506501
507 const S = struct {502 const S = struct {
...@@ -532,7 +527,6 @@ test "type coercion of anon struct literal to array" {...@@ -532,7 +527,6 @@ test "type coercion of anon struct literal to array" {
532}527}
533528
534test "type coercion of pointer to anon struct literal to pointer to array" {529test "type coercion of pointer to anon struct literal to pointer to array" {
535 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO530 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO531 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
538 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO532 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/asm.zig-4
...@@ -18,7 +18,6 @@ comptime {...@@ -18,7 +18,6 @@ comptime {
18}18}
1919
20test "module level assembly" {20test "module level assembly" {
21 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO21 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO22 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -30,7 +29,6 @@ test "module level assembly" {...@@ -30,7 +29,6 @@ test "module level assembly" {
30}29}
3130
32test "output constraint modifiers" {31test "output constraint modifiers" {
33 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
34 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO33 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO34 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -51,7 +49,6 @@ test "output constraint modifiers" {...@@ -51,7 +49,6 @@ test "output constraint modifiers" {
51}49}
5250
53test "alternative constraints" {51test "alternative constraints" {
54 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
55 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO52 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO53 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -115,7 +112,6 @@ test "sized integer/float in asm input" {...@@ -115,7 +112,6 @@ test "sized integer/float in asm input" {
115}112}
116113
117test "struct/array/union types as input values" {114test "struct/array/union types as input values" {
118 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
119 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
121 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/atomics.zig-14
...@@ -4,7 +4,6 @@ const expect = std.testing.expect;...@@ -4,7 +4,6 @@ const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
55
6test "cmpxchg" {6test "cmpxchg" {
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -33,7 +32,6 @@ fn testCmpxchg() !void {...@@ -33,7 +32,6 @@ fn testCmpxchg() !void {
33}32}
3433
35test "fence" {34test "fence" {
36 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO35 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
38 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO36 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
39 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO37 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -45,7 +43,6 @@ test "fence" {...@@ -45,7 +43,6 @@ test "fence" {
45}43}
4644
47test "atomicrmw and atomicload" {45test "atomicrmw and atomicload" {
48 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO46 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -75,7 +72,6 @@ fn testAtomicLoad(ptr: *u8) !void {...@@ -75,7 +72,6 @@ fn testAtomicLoad(ptr: *u8) !void {
75}72}
7673
77test "cmpxchg with ptr" {74test "cmpxchg with ptr" {
78 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO75 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO76 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -102,7 +98,6 @@ test "cmpxchg with ptr" {...@@ -102,7 +98,6 @@ test "cmpxchg with ptr" {
102}98}
10399
104test "cmpxchg with ignored result" {100test "cmpxchg with ignored result" {
105 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
106 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO101 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
107 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO102 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
108 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -117,7 +112,6 @@ test "cmpxchg with ignored result" {...@@ -117,7 +112,6 @@ test "cmpxchg with ignored result" {
117}112}
118113
119test "128-bit cmpxchg" {114test "128-bit cmpxchg" {
120 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
121 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
122 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO117 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -151,7 +145,6 @@ fn test_u128_cmpxchg() !void {...@@ -151,7 +145,6 @@ fn test_u128_cmpxchg() !void {
151var a_global_variable = @as(u32, 1234);145var a_global_variable = @as(u32, 1234);
152146
153test "cmpxchg on a global variable" {147test "cmpxchg on a global variable" {
154 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO148 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO149 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
157 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO150 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -170,7 +163,6 @@ test "cmpxchg on a global variable" {...@@ -170,7 +163,6 @@ test "cmpxchg on a global variable" {
170}163}
171164
172test "atomic load and rmw with enum" {165test "atomic load and rmw with enum" {
173 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
174 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO166 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
175 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO167 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
176 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -189,7 +181,6 @@ test "atomic load and rmw with enum" {...@@ -189,7 +181,6 @@ test "atomic load and rmw with enum" {
189}181}
190182
191test "atomic store" {183test "atomic store" {
192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
193 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO184 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO185 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
195 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO186 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -204,7 +195,6 @@ test "atomic store" {...@@ -204,7 +195,6 @@ test "atomic store" {
204}195}
205196
206test "atomic store comptime" {197test "atomic store comptime" {
207 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
208 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO198 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO199 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO200 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -224,7 +214,6 @@ fn testAtomicStore() !void {...@@ -224,7 +214,6 @@ fn testAtomicStore() !void {
224}214}
225215
226test "atomicrmw with floats" {216test "atomicrmw with floats" {
227 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
228 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO217 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
229 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO218 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
230 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO219 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -253,7 +242,6 @@ fn testAtomicRmwFloat() !void {...@@ -253,7 +242,6 @@ fn testAtomicRmwFloat() !void {
253}242}
254243
255test "atomicrmw with ints" {244test "atomicrmw with ints" {
256 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
257 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO245 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
258 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO246 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
259 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -288,7 +276,6 @@ fn testAtomicRmwInt() !void {...@@ -288,7 +276,6 @@ fn testAtomicRmwInt() !void {
288}276}
289277
290test "atomics with different types" {278test "atomics with different types" {
291 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO279 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
293 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO280 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO281 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -319,7 +306,6 @@ fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {...@@ -319,7 +306,6 @@ fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
319}306}
320307
321test "return @atomicStore, using it as a void value" {308test "return @atomicStore, using it as a void value" {
322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO309 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
324 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
325 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO311 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/basic.zig-7
...@@ -333,7 +333,6 @@ test "call result of if else expression" {...@@ -333,7 +333,6 @@ test "call result of if else expression" {
333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
334 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;334 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
335 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;335 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
336 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
337336
338 try expect(mem.eql(u8, f2(true), "a"));337 try expect(mem.eql(u8, f2(true), "a"));
339 try expect(mem.eql(u8, f2(false), "b"));338 try expect(mem.eql(u8, f2(false), "b"));
...@@ -364,8 +363,6 @@ fn testMemcpyMemset() !void {...@@ -364,8 +363,6 @@ fn testMemcpyMemset() !void {
364}363}
365364
366test "variable is allowed to be a pointer to an opaque type" {365test "variable is allowed to be a pointer to an opaque type" {
367 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
368
369 var x: i32 = 1234;366 var x: i32 = 1234;
370 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));367 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
371}368}
...@@ -386,8 +383,6 @@ fn testTakeAddressOfParameter(f: f32) !void {...@@ -386,8 +383,6 @@ fn testTakeAddressOfParameter(f: f32) !void {
386}383}
387384
388test "pointer to void return type" {385test "pointer to void return type" {
389 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
390
391 try testPointerToVoidReturnType();386 try testPointerToVoidReturnType();
392}387}
393fn testPointerToVoidReturnType() anyerror!void {388fn testPointerToVoidReturnType() anyerror!void {
...@@ -593,7 +588,6 @@ test "equality compare fn ptrs" {...@@ -593,7 +588,6 @@ test "equality compare fn ptrs" {
593588
594test "self reference through fn ptr field" {589test "self reference through fn ptr field" {
595 if (builtin.zig_backend == .stage1) return error.SkipZigTest;590 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
596 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
597591
598 const S = struct {592 const S = struct {
599 const A = struct {593 const A = struct {
...@@ -881,7 +875,6 @@ test "labeled block implicitly ends in a break" {...@@ -881,7 +875,6 @@ test "labeled block implicitly ends in a break" {
881}875}
882876
883test "catch in block has correct result location" {877test "catch in block has correct result location" {
884 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
885 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
886879
887 const S = struct {880 const S = struct {
test/behavior/bitcast.zig-8
...@@ -161,7 +161,6 @@ test "@bitCast packed structs at runtime and comptime" {...@@ -161,7 +161,6 @@ test "@bitCast packed structs at runtime and comptime" {
161 return error.SkipZigTest;161 return error.SkipZigTest;
162 }162 }
163 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;163 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
164 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
165 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;164 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
166 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;165 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;166 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -189,7 +188,6 @@ test "@bitCast packed structs at runtime and comptime" {...@@ -189,7 +188,6 @@ test "@bitCast packed structs at runtime and comptime" {
189188
190test "@bitCast extern structs at runtime and comptime" {189test "@bitCast extern structs at runtime and comptime" {
191 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;190 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
194192
195 const Full = extern struct {193 const Full = extern struct {
...@@ -221,7 +219,6 @@ test "@bitCast extern structs at runtime and comptime" {...@@ -221,7 +219,6 @@ test "@bitCast extern structs at runtime and comptime" {
221219
222test "bitcast packed struct to integer and back" {220test "bitcast packed struct to integer and back" {
223 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;221 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
225 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;222 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
226 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
227 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -261,7 +258,6 @@ test "implicit cast to error union by returning" {...@@ -261,7 +258,6 @@ test "implicit cast to error union by returning" {
261258
262test "bitcast packed struct literal to byte" {259test "bitcast packed struct literal to byte" {
263 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;260 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
264 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
265261
266 const Foo = packed struct {262 const Foo = packed struct {
267 value: u8,263 value: u8,
...@@ -271,8 +267,6 @@ test "bitcast packed struct literal to byte" {...@@ -271,8 +267,6 @@ test "bitcast packed struct literal to byte" {
271}267}
272268
273test "comptime bitcast used in expression has the correct type" {269test "comptime bitcast used in expression has the correct type" {
274 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
275
276 const Foo = packed struct {270 const Foo = packed struct {
277 value: u8,271 value: u8,
278 };272 };
...@@ -290,8 +284,6 @@ test "bitcast passed as tuple element" {...@@ -290,8 +284,6 @@ test "bitcast passed as tuple element" {
290}284}
291285
292test "triple level result location with bitcast sandwich passed as tuple element" {286test "triple level result location with bitcast sandwich passed as tuple element" {
293 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
294
295 const S = struct {287 const S = struct {
296 fn foo(args: anytype) !void {288 fn foo(args: anytype) !void {
297 comptime try expect(@TypeOf(args[0]) == f64);289 comptime try expect(@TypeOf(args[0]) == f64);
test/behavior/bugs/10970.zig-1
...@@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" {...@@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" {
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1110
12 var cond = true;11 var cond = true;
13 const opt = while (cond) {12 const opt = while (cond) {
test/behavior/bugs/11159.zig-1
...@@ -9,7 +9,6 @@ test {...@@ -9,7 +9,6 @@ test {
99
10test {10test {
11 if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1312
14 const S = struct {13 const S = struct {
15 comptime x: i32 = 0,14 comptime x: i32 = 0,
test/behavior/bugs/11181.zig-4
...@@ -1,8 +1,6 @@...@@ -1,8 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3test "const inferred array of slices" {3test "const inferred array of slices" {
4 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5
6 const T = struct { v: bool };4 const T = struct { v: bool };
75
8 const decls = [_][]const T{6 const decls = [_][]const T{
...@@ -14,8 +12,6 @@ test "const inferred array of slices" {...@@ -14,8 +12,6 @@ test "const inferred array of slices" {
14}12}
1513
16test "var inferred array of slices" {14test "var inferred array of slices" {
17 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
18
19 const T = struct { v: bool };15 const T = struct { v: bool };
2016
21 var decls = [_][]const T{17 var decls = [_][]const T{
test/behavior/bugs/11213.zig-2
...@@ -3,8 +3,6 @@ const builtin = @import("builtin");...@@ -3,8 +3,6 @@ const builtin = @import("builtin");
3const testing = std.testing;3const testing = std.testing;
44
5test {5test {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
7
8 const g: error{Test}!void = error.Test;6 const g: error{Test}!void = error.Test;
97
10 var v: u32 = 0;8 var v: u32 = 0;
test/behavior/bugs/12776.zig-1
...@@ -31,7 +31,6 @@ const CPU = packed struct {...@@ -31,7 +31,6 @@ const CPU = packed struct {
31test {31test {
32 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;32 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
33 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;33 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
34 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;34 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
36 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;35 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
3736
test/behavior/bugs/12891.zig-1
...@@ -8,7 +8,6 @@ test "issue12891" {...@@ -8,7 +8,6 @@ test "issue12891" {
8}8}
9test "nan" {9test "nan" {
10 if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1211
13 const f = comptime std.math.nan(f64);12 const f = comptime std.math.nan(f64);
14 var i: usize = 0;13 var i: usize = 0;
test/behavior/bugs/12972.zig-1
...@@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {}...@@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {}
5test {5test {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
98
10 const c: u8 = 42;9 const c: u8 = 42;
11 f(&[_:null]?u8{c});10 f(&[_:null]?u8{c});
test/behavior/bugs/12984.zig-1
...@@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void);...@@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void);
14test "simple test" {14test "simple test" {
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1918
20 var c: CustomDraw = undefined;19 var c: CustomDraw = undefined;
test/behavior/bugs/13068.zig-1
...@@ -7,7 +7,6 @@ var list = std.ArrayList(u32).init(allocator);...@@ -7,7 +7,6 @@ var list = std.ArrayList(u32).init(allocator);
7test {7test {
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1312
test/behavior/bugs/1310.zig-1
...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {
2424
25test "fixed" {25test "fixed" {
26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
28 try expect(agent_callback(undefined, undefined) == 11);27 try expect(agent_callback(undefined, undefined) == 11);
29}28}
test/behavior/bugs/13128.zig-1
...@@ -12,7 +12,6 @@ fn foo(val: U) !void {...@@ -12,7 +12,6 @@ fn foo(val: U) !void {
12}12}
1313
14test "runtime union init, most-aligned field != largest" {14test "runtime union init, most-aligned field != largest" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/bugs/1421.zig-1
...@@ -10,7 +10,6 @@ const S = struct {...@@ -10,7 +10,6 @@ const S = struct {
1010
11test "functions with return type required to be comptime are generic" {11test "functions with return type required to be comptime are generic" {
12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14 const ti = S.method();13 const ti = S.method();
15 try expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct);14 try expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct);
16}15}
test/behavior/bugs/1442.zig-1
...@@ -10,7 +10,6 @@ test "const error union field alignment" {...@@ -10,7 +10,6 @@ test "const error union field alignment" {
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14 var union_or_err: anyerror!Union = Union{ .Color = 1234 };13 var union_or_err: anyerror!Union = Union{ .Color = 1234 };
15 try std.testing.expect((union_or_err catch unreachable).Color == 1234);14 try std.testing.expect((union_or_err catch unreachable).Color == 1234);
16}15}
test/behavior/bugs/1500.zig-1
...@@ -6,7 +6,6 @@ const A = struct {...@@ -6,7 +6,6 @@ const A = struct {
6const B = *const fn (A) void;6const B = *const fn (A) void;
77
8test "allow these dependencies" {8test "allow these dependencies" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10 var a: A = undefined;9 var a: A = undefined;
11 var b: B = undefined;10 var b: B = undefined;
12 if (false) {11 if (false) {
test/behavior/bugs/1607.zig-1
...@@ -14,7 +14,6 @@ test "slices pointing at the same address as global array." {...@@ -14,7 +14,6 @@ test "slices pointing at the same address as global array." {
14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18 try checkAddress(&a);17 try checkAddress(&a);
19 comptime try checkAddress(&a);18 comptime try checkAddress(&a);
20}19}
test/behavior/bugs/1735.zig-1
...@@ -43,7 +43,6 @@ const a = struct {...@@ -43,7 +43,6 @@ const a = struct {
4343
44test "initialization" {44test "initialization" {
45 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;45 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
46 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
47 var t = a.init();46 var t = a.init();
48 try std.testing.expect(t.foo.len == 0);47 try std.testing.expect(t.foo.len == 0);
49}48}
test/behavior/bugs/1914.zig-2
...@@ -12,7 +12,6 @@ const b_list: []B = &[_]B{};...@@ -12,7 +12,6 @@ const b_list: []B = &[_]B{};
12const a = A{ .b_list_pointer = &b_list };12const a = A{ .b_list_pointer = &b_list };
1313
14test "segfault bug" {14test "segfault bug" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 const assert = std.debug.assert;15 const assert = std.debug.assert;
17 const obj = B{ .a_pointer = &a };16 const obj = B{ .a_pointer = &a };
18 assert(obj.a_pointer == &a); // this makes zig crash17 assert(obj.a_pointer == &a); // this makes zig crash
...@@ -29,6 +28,5 @@ pub const B2 = struct {...@@ -29,6 +28,5 @@ pub const B2 = struct {
29var b_value = B2{ .pointer_array = &[_]*A2{} };28var b_value = B2{ .pointer_array = &[_]*A2{} };
3029
31test "basic stuff" {30test "basic stuff" {
32 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
33 std.debug.assert(&b_value == &b_value);31 std.debug.assert(&b_value == &b_value);
34}32}
test/behavior/bugs/2006.zig-1
...@@ -6,7 +6,6 @@ const S = struct {...@@ -6,7 +6,6 @@ const S = struct {
6 p: *S,6 p: *S,
7};7};
8test "bug 2006" {8test "bug 2006" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10 var a: S = undefined;9 var a: S = undefined;
11 a = S{ .p = undefined };10 a = S{ .p = undefined };
12 try expect(@sizeOf(S) != 0);11 try expect(@sizeOf(S) != 0);
test/behavior/bugs/2114.zig-1
...@@ -12,7 +12,6 @@ test "fixed" {...@@ -12,7 +12,6 @@ test "fixed" {
12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1615
17 try testCtz();16 try testCtz();
18 comptime try testCtz();17 comptime try testCtz();
test/behavior/bugs/2578.zig-1
...@@ -15,7 +15,6 @@ test "fixed" {...@@ -15,7 +15,6 @@ test "fixed" {
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1918
20 bar(t);19 bar(t);
21}20}
test/behavior/bugs/2692.zig-1
...@@ -5,7 +5,6 @@ fn foo(a: []u8) void {...@@ -5,7 +5,6 @@ fn foo(a: []u8) void {
5}5}
66
7test "address of 0 length array" {7test "address of 0 length array" {
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
109
11 var pt: [0]u8 = undefined;10 var pt: [0]u8 = undefined;
test/behavior/bugs/3007.zig-1
...@@ -22,7 +22,6 @@ test "fixed" {...@@ -22,7 +22,6 @@ test "fixed" {
22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2625
27 default_foo = get_foo() catch null; // This Line26 default_foo = get_foo() catch null; // This Line
28 try std.testing.expect(!default_foo.?.free);27 try std.testing.expect(!default_foo.?.free);
test/behavior/bugs/3046.zig-1
...@@ -15,7 +15,6 @@ var some_struct: SomeStruct = undefined;...@@ -15,7 +15,6 @@ var some_struct: SomeStruct = undefined;
15test "fixed" {15test "fixed" {
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1918
20 some_struct = SomeStruct{19 some_struct = SomeStruct{
21 .field = couldFail() catch @as(i32, 0),20 .field = couldFail() catch @as(i32, 0),
test/behavior/bugs/3367.zig-1
...@@ -10,7 +10,6 @@ const Mixin = struct {...@@ -10,7 +10,6 @@ const Mixin = struct {
10};10};
1111
12test "container member access usingnamespace decls" {12test "container member access usingnamespace decls" {
13 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14 var foo = Foo{};13 var foo = Foo{};
15 foo.two();14 foo.two();
16}15}
test/behavior/bugs/3742.zig-1
...@@ -38,6 +38,5 @@ test "fixed" {...@@ -38,6 +38,5 @@ test "fixed" {
38 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;38 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
39 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;39 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
40 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;40 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
41 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
42 ArgSerializer.serializeCommand(GET.init("banana"));41 ArgSerializer.serializeCommand(GET.init("banana"));
43}42}
test/behavior/bugs/4328.zig+8-8
...@@ -5,10 +5,10 @@ const FILE = extern struct {...@@ -5,10 +5,10 @@ const FILE = extern struct {
5 dummy_field: u8,5 dummy_field: u8,
6};6};
77
8extern fn printf([*c]const u8, ...) c_int;8extern fn c_printf([*c]const u8, ...) c_int;
9extern fn fputs([*c]const u8, noalias [*c]FILE) c_int;9extern fn c_fputs([*c]const u8, noalias [*c]FILE) c_int;
10extern fn ftell([*c]FILE) c_long;10extern fn c_ftell([*c]FILE) c_long;
11extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE;11extern fn c_fopen([*c]const u8, [*c]const u8) [*c]FILE;
1212
13const S = extern struct {13const S = extern struct {
14 state: c_short,14 state: c_short,
...@@ -18,7 +18,7 @@ const S = extern struct {...@@ -18,7 +18,7 @@ const S = extern struct {
1818
19test "Extern function calls in @TypeOf" {19test "Extern function calls in @TypeOf" {
20 const Test = struct {20 const Test = struct {
21 fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) {21 fn test_fn_1(a: anytype, b: anytype) @TypeOf(c_printf("%d %s\n", a, b)) {
22 return 0;22 return 0;
23 }23 }
2424
...@@ -38,7 +38,7 @@ test "Extern function calls in @TypeOf" {...@@ -38,7 +38,7 @@ test "Extern function calls in @TypeOf" {
3838
39test "Peer resolution of extern function calls in @TypeOf" {39test "Peer resolution of extern function calls in @TypeOf" {
40 const Test = struct {40 const Test = struct {
41 fn test_fn() @TypeOf(ftell(null), fputs(null, null)) {41 fn test_fn() @TypeOf(c_ftell(null), c_fputs(null, null)) {
42 return 0;42 return 0;
43 }43 }
4444
...@@ -55,12 +55,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" {...@@ -55,12 +55,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" {
55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
5656
57 const Test = struct {57 const Test = struct {
58 fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) {58 fn test_fn_1(a: c_long) @TypeOf(c_fopen("test", "r").*) {
59 _ = a;59 _ = a;
60 return .{ .dummy_field = 0 };60 return .{ .dummy_field = 0 };
61 }61 }
6262
63 fn test_fn_2(a: anytype) @TypeOf(fopen("test", "r").*.dummy_field) {63 fn test_fn_2(a: anytype) @TypeOf(c_fopen("test", "r").*.dummy_field) {
64 _ = a;64 _ = a;
65 return 255;65 return 255;
66 }66 }
test/behavior/bugs/4954.zig-1
...@@ -5,7 +5,6 @@ fn f(buf: []u8) void {...@@ -5,7 +5,6 @@ fn f(buf: []u8) void {
5}5}
66
7test "crash" {7test "crash" {
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1110
test/behavior/bugs/5398.zig-1
...@@ -22,7 +22,6 @@ test "assignment of field with padding" {...@@ -22,7 +22,6 @@ test "assignment of field with padding" {
22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
25 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2625
27 renderable = Renderable{26 renderable = Renderable{
28 .mesh = Mesh{ .id = 0 },27 .mesh = Mesh{ .id = 0 },
test/behavior/bugs/5487.zig-1
...@@ -13,6 +13,5 @@ test "crash" {...@@ -13,6 +13,5 @@ test "crash" {
13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
17 _ = io.multiWriter(.{writer()});16 _ = io.multiWriter(.{writer()});
18}17}
test/behavior/bugs/726.zig-2
...@@ -5,7 +5,6 @@ test "@ptrCast from const to nullable" {...@@ -5,7 +5,6 @@ test "@ptrCast from const to nullable" {
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
98
10 const c: u8 = 4;9 const c: u8 = 4;
11 var x: ?*const u8 = @ptrCast(?*const u8, &c);10 var x: ?*const u8 = @ptrCast(?*const u8, &c);
...@@ -16,7 +15,6 @@ test "@ptrCast from var in empty struct to nullable" {...@@ -16,7 +15,6 @@ test "@ptrCast from var in empty struct to nullable" {
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2018
21 const container = struct {19 const container = struct {
22 var c: u8 = 4;20 var c: u8 = 4;
test/behavior/bugs/920.zig-1
...@@ -67,7 +67,6 @@ const NormalDist = blk: {...@@ -67,7 +67,6 @@ const NormalDist = blk: {
6767
68test "bug 920 fixed" {68test "bug 920 fixed" {
69 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO70 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO71 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO72 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/bugs/9584.zig-1
...@@ -49,7 +49,6 @@ test {...@@ -49,7 +49,6 @@ test {
49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO51 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
52 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5352
54 var flags = A{53 var flags = A{
55 .a = false,54 .a = false,
test/behavior/call.zig-2
...@@ -58,7 +58,6 @@ test "basic invocations" {...@@ -58,7 +58,6 @@ test "basic invocations" {
58test "tuple parameters" {58test "tuple parameters" {
59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
62 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO61 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
6362
64 const add = struct {63 const add = struct {
...@@ -87,7 +86,6 @@ test "tuple parameters" {...@@ -87,7 +86,6 @@ test "tuple parameters" {
87}86}
8887
89test "result location of function call argument through runtime condition and struct init" {88test "result location of function call argument through runtime condition and struct init" {
90 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO89 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO90 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9391
test/behavior/cast.zig-39
...@@ -119,7 +119,6 @@ test "@intToFloat(f80)" {...@@ -119,7 +119,6 @@ test "@intToFloat(f80)" {
119 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO119 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO120 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
121 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO121 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
122 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
123122
124 const S = struct {123 const S = struct {
125 fn doTheTest(comptime Int: type) !void {124 fn doTheTest(comptime Int: type) !void {
...@@ -395,7 +394,6 @@ test "expected [*c]const u8, found [*:0]const u8" {...@@ -395,7 +394,6 @@ test "expected [*c]const u8, found [*:0]const u8" {
395test "explicit cast from integer to error type" {394test "explicit cast from integer to error type" {
396 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;395 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
397 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO396 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;397 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO398 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
401399
...@@ -410,7 +408,6 @@ fn testCastIntToErr(err: anyerror) !void {...@@ -410,7 +408,6 @@ fn testCastIntToErr(err: anyerror) !void {
410408
411test "peer resolve array and const slice" {409test "peer resolve array and const slice" {
412 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;410 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
413 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
414 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO411 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
415 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO412 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
416413
...@@ -451,7 +448,6 @@ fn castToOptionalTypeError(z: i32) !void {...@@ -451,7 +448,6 @@ fn castToOptionalTypeError(z: i32) !void {
451448
452test "implicitly cast from [0]T to anyerror![]T" {449test "implicitly cast from [0]T to anyerror![]T" {
453 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;450 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
454 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
455451
456 try testCastZeroArrayToErrSliceMut();452 try testCastZeroArrayToErrSliceMut();
457 comptime try testCastZeroArrayToErrSliceMut();453 comptime try testCastZeroArrayToErrSliceMut();
...@@ -467,7 +463,6 @@ fn gimmeErrOrSlice() anyerror![]u8 {...@@ -467,7 +463,6 @@ fn gimmeErrOrSlice() anyerror![]u8 {
467463
468test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {464test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
469 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;465 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
470 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
471 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
472467
473 const S = struct {468 const S = struct {
...@@ -546,7 +541,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {...@@ -546,7 +541,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
546541
547test "single-item pointer of array to slice to unknown length pointer" {542test "single-item pointer of array to slice to unknown length pointer" {
548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
549 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
550544
551 try testCastPtrOfArrayToSliceAndPtr();545 try testCastPtrOfArrayToSliceAndPtr();
552 comptime try testCastPtrOfArrayToSliceAndPtr();546 comptime try testCastPtrOfArrayToSliceAndPtr();
...@@ -575,7 +569,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {...@@ -575,7 +569,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {
575569
576test "cast *[1][*]const u8 to [*]const ?[*]const u8" {570test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
577 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;571 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
578 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
579 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO572 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
580573
581 const window_name = [1][*]const u8{"window name"};574 const window_name = [1][*]const u8{"window name"};
...@@ -813,7 +806,6 @@ test "peer type resolution: error union after non-error" {...@@ -813,7 +806,6 @@ test "peer type resolution: error union after non-error" {
813test "peer cast *[0]T to E![]const T" {806test "peer cast *[0]T to E![]const T" {
814 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;807 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
815 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
816 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
817 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO809 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
818810
819 var buffer: [5]u8 = "abcde".*;811 var buffer: [5]u8 = "abcde".*;
...@@ -828,7 +820,6 @@ test "peer cast *[0]T to E![]const T" {...@@ -828,7 +820,6 @@ test "peer cast *[0]T to E![]const T" {
828test "peer cast *[0]T to []const T" {820test "peer cast *[0]T to []const T" {
829 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;821 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
830 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;822 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
831 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
832 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO823 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
833824
834 var buffer: [5]u8 = "abcde".*;825 var buffer: [5]u8 = "abcde".*;
...@@ -839,8 +830,6 @@ test "peer cast *[0]T to []const T" {...@@ -839,8 +830,6 @@ test "peer cast *[0]T to []const T" {
839}830}
840831
841test "peer cast *[N]T to [*]T" {832test "peer cast *[N]T to [*]T" {
842 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
843
844 var array = [4:99]i32{ 1, 2, 3, 4 };833 var array = [4:99]i32{ 1, 2, 3, 4 };
845 var dest: [*]i32 = undefined;834 var dest: [*]i32 = undefined;
846 try expect(@TypeOf(&array, dest) == [*]i32);835 try expect(@TypeOf(&array, dest) == [*]i32);
...@@ -849,7 +838,6 @@ test "peer cast *[N]T to [*]T" {...@@ -849,7 +838,6 @@ test "peer cast *[N]T to [*]T" {
849838
850test "peer resolution of string literals" {839test "peer resolution of string literals" {
851 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;840 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
852 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
853 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO841 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
854 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO842 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
855843
...@@ -872,7 +860,6 @@ test "peer resolution of string literals" {...@@ -872,7 +860,6 @@ test "peer resolution of string literals" {
872860
873test "peer cast [:x]T to []T" {861test "peer cast [:x]T to []T" {
874 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;862 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
875 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
876863
877 const S = struct {864 const S = struct {
878 fn doTheTest() !void {865 fn doTheTest() !void {
...@@ -888,7 +875,6 @@ test "peer cast [:x]T to []T" {...@@ -888,7 +875,6 @@ test "peer cast [:x]T to []T" {
888875
889test "peer cast [N:x]T to [N]T" {876test "peer cast [N:x]T to [N]T" {
890 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;877 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
891 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
892878
893 const S = struct {879 const S = struct {
894 fn doTheTest() !void {880 fn doTheTest() !void {
...@@ -903,7 +889,6 @@ test "peer cast [N:x]T to [N]T" {...@@ -903,7 +889,6 @@ test "peer cast [N:x]T to [N]T" {
903889
904test "peer cast *[N:x]T to *[N]T" {890test "peer cast *[N:x]T to *[N]T" {
905 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO891 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
906 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
907892
908 const S = struct {893 const S = struct {
909 fn doTheTest() !void {894 fn doTheTest() !void {
...@@ -937,7 +922,6 @@ test "peer cast [*:x]T to [*]T" {...@@ -937,7 +922,6 @@ test "peer cast [*:x]T to [*]T" {
937922
938test "peer cast [:x]T to [*:x]T" {923test "peer cast [:x]T to [*:x]T" {
939 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;924 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
940 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
941 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO925 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
942 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO926 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
943927
...@@ -1018,7 +1002,6 @@ test "cast between C pointer with different but compatible types" {...@@ -1018,7 +1002,6 @@ test "cast between C pointer with different but compatible types" {
10181002
1019test "peer type resolve string lit with sentinel-terminated mutable slice" {1003test "peer type resolve string lit with sentinel-terminated mutable slice" {
1020 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1004 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10221005
1023 var array: [4:0]u8 = undefined;1006 var array: [4:0]u8 = undefined;
1024 array[4] = 0; // TODO remove this when #4372 is solved1007 array[4] = 0; // TODO remove this when #4372 is solved
...@@ -1035,8 +1018,6 @@ test "peer type resolve array pointers, one of them const" {...@@ -1035,8 +1018,6 @@ test "peer type resolve array pointers, one of them const" {
1035}1018}
10361019
1037test "peer type resolve array pointer and unknown pointer" {1020test "peer type resolve array pointer and unknown pointer" {
1038 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1039
1040 const const_array: [4]u8 = undefined;1021 const const_array: [4]u8 = undefined;
1041 var array: [4]u8 = undefined;1022 var array: [4]u8 = undefined;
1042 var const_ptr: [*]const u8 = undefined;1023 var const_ptr: [*]const u8 = undefined;
...@@ -1069,7 +1050,6 @@ test "comptime float casts" {...@@ -1069,7 +1050,6 @@ test "comptime float casts" {
10691050
1070test "pointer reinterpret const float to int" {1051test "pointer reinterpret const float to int" {
1071 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1052 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1072 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10731053
1074 // The hex representation is 0x3fe3333333333303.1054 // The hex representation is 0x3fe3333333333303.
1075 const float: f64 = 5.99999999999994648725e-01;1055 const float: f64 = 5.99999999999994648725e-01;
...@@ -1084,7 +1064,6 @@ test "pointer reinterpret const float to int" {...@@ -1084,7 +1064,6 @@ test "pointer reinterpret const float to int" {
10841064
1085test "implicit cast from [*]T to ?*anyopaque" {1065test "implicit cast from [*]T to ?*anyopaque" {
1086 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1066 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1087 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1088 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1067 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10891068
1090 var a = [_]u8{ 3, 2, 1 };1069 var a = [_]u8{ 3, 2, 1 };
...@@ -1102,8 +1081,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {...@@ -1102,8 +1081,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
11021081
1103test "compile time int to ptr of function" {1082test "compile time int to ptr of function" {
1104 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1083 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1105
1106 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1107 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1084 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11081085
1109 try foobar(FUNCTION_CONSTANT);1086 try foobar(FUNCTION_CONSTANT);
...@@ -1120,7 +1097,6 @@ fn foobar(func: PFN_void) !void {...@@ -1120,7 +1097,6 @@ fn foobar(func: PFN_void) !void {
11201097
1121test "implicit ptr to *anyopaque" {1098test "implicit ptr to *anyopaque" {
1122 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1099 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1123 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11251101
1126 var a: u32 = 1;1102 var a: u32 = 1;
...@@ -1149,7 +1125,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {...@@ -1149,7 +1125,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
11491125
1150test "peer type resolution: [0]u8 and []const u8" {1126test "peer type resolution: [0]u8 and []const u8" {
1151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1152 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11531128
1154 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);1129 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
1155 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);1130 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
...@@ -1168,7 +1143,6 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {...@@ -1168,7 +1143,6 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
11681143
1169test "implicitly cast from [N]T to ?[]const T" {1144test "implicitly cast from [N]T to ?[]const T" {
1170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1145 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1171 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1172 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1146 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1173 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1147 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
11741148
...@@ -1182,7 +1156,6 @@ fn castToOptionalSlice() ?[]const u8 {...@@ -1182,7 +1156,6 @@ fn castToOptionalSlice() ?[]const u8 {
11821156
1183test "cast u128 to f128 and back" {1157test "cast u128 to f128 and back" {
1184 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1158 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1185 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1186 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1159 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1160 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1188 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1161 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
...@@ -1221,7 +1194,6 @@ test "implicit cast from *[N]T to ?[*]T" {...@@ -1221,7 +1194,6 @@ test "implicit cast from *[N]T to ?[*]T" {
12211194
1222test "implicit cast from *T to ?*anyopaque" {1195test "implicit cast from *T to ?*anyopaque" {
1223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1224 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1225 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12261198
1227 var a: u8 = 1;1199 var a: u8 = 1;
...@@ -1235,7 +1207,6 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void {...@@ -1235,7 +1207,6 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void {
12351207
1236test "implicit cast *[0]T to E![]const u8" {1208test "implicit cast *[0]T to E![]const u8" {
1237 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1209 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1238 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12391210
1240 var x = @as(anyerror![]const u8, &[0]u8{});1211 var x = @as(anyerror![]const u8, &[0]u8{});
1241 try expect((x catch unreachable).len == 0);1212 try expect((x catch unreachable).len == 0);
...@@ -1247,15 +1218,12 @@ test "cast from array reference to fn: comptime fn ptr" {...@@ -1247,15 +1218,12 @@ test "cast from array reference to fn: comptime fn ptr" {
1247 try expect(@ptrToInt(f) == @ptrToInt(&global_array));1218 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
1248}1219}
1249test "cast from array reference to fn: runtime fn ptr" {1220test "cast from array reference to fn: runtime fn ptr" {
1250 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1251
1252 var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);1221 var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);
1253 try expect(@ptrToInt(f) == @ptrToInt(&global_array));1222 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
1254}1223}
12551224
1256test "*const [N]null u8 to ?[]const u8" {1225test "*const [N]null u8 to ?[]const u8" {
1257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1226 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1258 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1227 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1260 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1228 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
12611229
...@@ -1291,7 +1259,6 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {...@@ -1291,7 +1259,6 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {
1291var global_struct: struct { f0: usize } = undefined;1259var global_struct: struct { f0: usize } = undefined;
1292test "assignment to optional pointer result loc" {1260test "assignment to optional pointer result loc" {
1293 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1261 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1294 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1295 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1262 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12961263
1297 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };1264 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
...@@ -1318,7 +1285,6 @@ fn boolToStr(b: bool) []const u8 {...@@ -1318,7 +1285,6 @@ fn boolToStr(b: bool) []const u8 {
13181285
1319test "cast f16 to wider types" {1286test "cast f16 to wider types" {
1320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1287 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1321 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1322 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1288 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1323 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1289 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1324 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1290 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
...@@ -1337,7 +1303,6 @@ test "cast f16 to wider types" {...@@ -1337,7 +1303,6 @@ test "cast f16 to wider types" {
13371303
1338test "cast f128 to narrower types" {1304test "cast f128 to narrower types" {
1339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1340 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1306 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1342 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1307 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1343 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1308 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
...@@ -1356,7 +1321,6 @@ test "cast f128 to narrower types" {...@@ -1356,7 +1321,6 @@ test "cast f128 to narrower types" {
13561321
1357test "peer type resolution: unreachable, null, slice" {1322test "peer type resolution: unreachable, null, slice" {
1358 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1323 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1359 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1360 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1324 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1361 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1325 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13621326
...@@ -1396,7 +1360,6 @@ test "cast i8 fn call peers to i32 result" {...@@ -1396,7 +1360,6 @@ test "cast i8 fn call peers to i32 result" {
1396test "cast compatible optional types" {1360test "cast compatible optional types" {
1397 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1361 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1398 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1362 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1399 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1400 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1363 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
14011364
1402 var a: ?[:0]const u8 = null;1365 var a: ?[:0]const u8 = null;
...@@ -1414,13 +1377,11 @@ test "coerce undefined single-item pointer of array to error union of slice" {...@@ -1414,13 +1377,11 @@ test "coerce undefined single-item pointer of array to error union of slice" {
1414}1377}
14151378
1416test "pointer to empty struct literal to mutable slice" {1379test "pointer to empty struct literal to mutable slice" {
1417 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1418 var x: []i32 = &.{};1380 var x: []i32 = &.{};
1419 try expect(x.len == 0);1381 try expect(x.len == 0);
1420}1382}
14211383
1422test "coerce between pointers of compatible differently-named floats" {1384test "coerce between pointers of compatible differently-named floats" {
1423 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1424 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1426 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1387 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/cast_int.zig-1
...@@ -8,7 +8,6 @@ test "@intCast i32 to u7" {...@@ -8,7 +8,6 @@ test "@intCast i32 to u7" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1211
13 var x: u128 = maxInt(u128);12 var x: u128 = maxInt(u128);
14 var y: i32 = 120;13 var y: i32 = 120;
test/behavior/defer.zig-1
...@@ -108,7 +108,6 @@ test "mixing normal and error defers" {...@@ -108,7 +108,6 @@ test "mixing normal and error defers" {
108}108}
109109
110test "errdefer with payload" {110test "errdefer with payload" {
111 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO111 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO112 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO113 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/empty_union.zig-4
...@@ -3,7 +3,6 @@ const std = @import("std");...@@ -3,7 +3,6 @@ const std = @import("std");
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5test "switch on empty enum" {5test "switch on empty enum" {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
87
9 const E = enum {};8 const E = enum {};
...@@ -12,7 +11,6 @@ test "switch on empty enum" {...@@ -12,7 +11,6 @@ test "switch on empty enum" {
12}11}
1312
14test "switch on empty enum with a specified tag type" {13test "switch on empty enum with a specified tag type" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1715
18 const E = enum(u8) {};16 const E = enum(u8) {};
...@@ -21,7 +19,6 @@ test "switch on empty enum with a specified tag type" {...@@ -21,7 +19,6 @@ test "switch on empty enum with a specified tag type" {
21}19}
2220
23test "switch on empty auto numbered tagged union" {21test "switch on empty auto numbered tagged union" {
24 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2724
...@@ -31,7 +28,6 @@ test "switch on empty auto numbered tagged union" {...@@ -31,7 +28,6 @@ test "switch on empty auto numbered tagged union" {
31}28}
3229
33test "switch on empty tagged union" {30test "switch on empty tagged union" {
34 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
3733
test/behavior/enum.zig-4
...@@ -972,7 +972,6 @@ fn test3_2(f: Test3Foo) !void {...@@ -972,7 +972,6 @@ fn test3_2(f: Test3Foo) !void {
972}972}
973973
974test "@tagName" {974test "@tagName" {
975 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
976 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO975 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
977 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;976 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
978 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;977 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -989,7 +988,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 {...@@ -989,7 +988,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 {
989const BareNumber = enum { One, Two, Three };988const BareNumber = enum { One, Two, Three };
990989
991test "@tagName non-exhaustive enum" {990test "@tagName non-exhaustive enum" {
992 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
993 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO991 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
994 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;992 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
995 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;993 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -1001,7 +999,6 @@ test "@tagName non-exhaustive enum" {...@@ -1001,7 +999,6 @@ test "@tagName non-exhaustive enum" {
1001const NonExhaustive = enum(u8) { A, B, _ };999const NonExhaustive = enum(u8) { A, B, _ };
10021000
1003test "@tagName is null-terminated" {1001test "@tagName is null-terminated" {
1004 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1005 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1002 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1006 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;1003 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1007 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1004 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -1017,7 +1014,6 @@ test "@tagName is null-terminated" {...@@ -1017,7 +1014,6 @@ test "@tagName is null-terminated" {
1017}1014}
10181015
1019test "tag name with assigned enum values" {1016test "tag name with assigned enum values" {
1020 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1017 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1022 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;1018 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1023 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1019 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
test/behavior/error.zig+16-4
...@@ -258,7 +258,6 @@ fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {...@@ -258,7 +258,6 @@ fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
258}258}
259259
260test "comptime err to int of error set with only 1 possible value" {260test "comptime err to int of error set with only 1 possible value" {
261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO261 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO262 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
264263
...@@ -471,7 +470,6 @@ test "function pointer with return type that is error union with payload which i...@@ -471,7 +470,6 @@ test "function pointer with return type that is error union with payload which i
471 return error.SkipZigTest;470 return error.SkipZigTest;
472 }471 }
473472
474 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
475 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO473 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
476 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO474 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
477475
...@@ -556,7 +554,6 @@ test "error union comptime caching" {...@@ -556,7 +554,6 @@ test "error union comptime caching" {
556}554}
557555
558test "@errorName" {556test "@errorName" {
559 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
560 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;557 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
561 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;558 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
562 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;559 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -570,7 +567,6 @@ fn gimmeItBroke() anyerror {...@@ -570,7 +567,6 @@ fn gimmeItBroke() anyerror {
570}567}
571568
572test "@errorName sentinel length matches slice length" {569test "@errorName sentinel length matches slice length" {
573 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
574 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;570 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;571 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
576 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -843,3 +839,19 @@ fn non_errorable() void {...@@ -843,3 +839,19 @@ fn non_errorable() void {
843test "catch within a function that calls no errorable functions" {839test "catch within a function that calls no errorable functions" {
844 non_errorable();840 non_errorable();
845}841}
842
843test "error from comptime string" {
844 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
845 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
846 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
847
848 const name = "Weird error name!";
849 const S = struct {
850 fn foo() !void {
851 return @field(anyerror, name);
852 }
853 };
854 if (S.foo()) unreachable else |err| {
855 try expect(mem.eql(u8, name, @errorName(err)));
856 }
857}
test/behavior/eval.zig-9
...@@ -531,7 +531,6 @@ test "@tagName of @typeInfo" {...@@ -531,7 +531,6 @@ test "@tagName of @typeInfo" {
531}531}
532532
533test "static eval list init" {533test "static eval list init" {
534 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
535 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO534 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO535 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO536 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -719,7 +718,6 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" {...@@ -719,7 +718,6 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" {
719}718}
720719
721test "array concatenation of function calls" {720test "array concatenation of function calls" {
722 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
723 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;721 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
724 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;722 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
725723
...@@ -728,7 +726,6 @@ test "array concatenation of function calls" {...@@ -728,7 +726,6 @@ test "array concatenation of function calls" {
728}726}
729727
730test "array multiplication of function calls" {728test "array multiplication of function calls" {
731 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
732 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;729 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
733 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;730 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
734731
...@@ -746,7 +743,6 @@ fn scalar(x: u32) u32 {...@@ -746,7 +743,6 @@ fn scalar(x: u32) u32 {
746743
747test "array concatenation peer resolves element types - value" {744test "array concatenation peer resolves element types - value" {
748 if (builtin.zig_backend == .stage1) return error.SkipZigTest;745 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
749 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
750 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;746 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
751 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;747 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
752748
...@@ -763,7 +759,6 @@ test "array concatenation peer resolves element types - value" {...@@ -763,7 +759,6 @@ test "array concatenation peer resolves element types - value" {
763759
764test "array concatenation peer resolves element types - pointer" {760test "array concatenation peer resolves element types - pointer" {
765 if (builtin.zig_backend == .stage1) return error.SkipZigTest;761 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
766 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
767 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;762 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
768 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;763 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
769764
...@@ -782,7 +777,6 @@ test "array concatenation sets the sentinel - value" {...@@ -782,7 +777,6 @@ test "array concatenation sets the sentinel - value" {
782 if (builtin.zig_backend == .stage1) return error.SkipZigTest;777 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
783 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;778 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
784 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;779 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
785 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
786 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;780 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
787 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;781 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
788782
...@@ -801,7 +795,6 @@ test "array concatenation sets the sentinel - value" {...@@ -801,7 +795,6 @@ test "array concatenation sets the sentinel - value" {
801795
802test "array concatenation sets the sentinel - pointer" {796test "array concatenation sets the sentinel - pointer" {
803 if (builtin.zig_backend == .stage1) return error.SkipZigTest;797 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
804 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
805 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;798 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
806799
807 var a = [2]u3{ 1, 7 };800 var a = [2]u3{ 1, 7 };
...@@ -821,7 +814,6 @@ test "array multiplication sets the sentinel - value" {...@@ -821,7 +814,6 @@ test "array multiplication sets the sentinel - value" {
821 if (builtin.zig_backend == .stage1) return error.SkipZigTest;814 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
822 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;815 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
823 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;816 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
824 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;817 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
826 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;818 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
827819
...@@ -838,7 +830,6 @@ test "array multiplication sets the sentinel - value" {...@@ -838,7 +830,6 @@ test "array multiplication sets the sentinel - value" {
838830
839test "array multiplication sets the sentinel - pointer" {831test "array multiplication sets the sentinel - pointer" {
840 if (builtin.zig_backend == .stage1) return error.SkipZigTest;832 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
841 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
842 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;833 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
843 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;834 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
844835
test/behavior/export_self_referential_type_info.zig+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1export const foo: c_int = @boolToInt(@typeInfo(@This()).Struct.is_tuple);1export const self_referential_type_info: c_int = @boolToInt(@typeInfo(@This()).Struct.is_tuple);
test/behavior/field_parent_ptr.zig-2
...@@ -4,7 +4,6 @@ const builtin = @import("builtin");...@@ -4,7 +4,6 @@ const builtin = @import("builtin");
4test "@fieldParentPtr non-first field" {4test "@fieldParentPtr non-first field" {
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
8 try testParentFieldPtr(&foo.c);7 try testParentFieldPtr(&foo.c);
9 comptime try testParentFieldPtr(&foo.c);8 comptime try testParentFieldPtr(&foo.c);
10}9}
...@@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" {...@@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" {
12test "@fieldParentPtr first field" {11test "@fieldParentPtr first field" {
13 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;13 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16 try testParentFieldPtrFirst(&foo.a);14 try testParentFieldPtrFirst(&foo.a);
17 comptime try testParentFieldPtrFirst(&foo.a);15 comptime try testParentFieldPtrFirst(&foo.a);
18}16}
test/behavior/floatop.zig-15
...@@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T {...@@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T {
2121
22test "floating point comparisons" {22test "floating point comparisons" {
23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2625
27 try testFloatComparisons();26 try testFloatComparisons();
...@@ -55,7 +54,6 @@ fn testFloatComparisons() !void {...@@ -55,7 +54,6 @@ fn testFloatComparisons() !void {
5554
56test "different sized float comparisons" {55test "different sized float comparisons" {
57 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO57 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -91,7 +89,6 @@ fn testDifferentSizedFloatComparisons() !void {...@@ -91,7 +89,6 @@ fn testDifferentSizedFloatComparisons() !void {
9189
92test "negative f128 floatToInt at compile-time" {90test "negative f128 floatToInt at compile-time" {
93 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO91 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
94 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
95 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO92 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
96 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO93 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9794
...@@ -150,7 +147,6 @@ fn testSqrt() !void {...@@ -150,7 +147,6 @@ fn testSqrt() !void {
150147
151test "more @sqrt f16 tests" {148test "more @sqrt f16 tests" {
152 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO149 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
153 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO150 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO151 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -305,7 +301,6 @@ test "@log" {...@@ -305,7 +301,6 @@ test "@log" {
305 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO301 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO302 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
308 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
309304
310 comptime try testLog();305 comptime try testLog();
311 try testLog();306 try testLog();
...@@ -545,7 +540,6 @@ fn testTrunc() !void {...@@ -545,7 +540,6 @@ fn testTrunc() !void {
545540
546test "negation f16" {541test "negation f16" {
547 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO542 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
548 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
549 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO543 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
550 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO544 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
551 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -573,7 +567,6 @@ test "negation f32" {...@@ -573,7 +567,6 @@ test "negation f32" {
573 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO567 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
574 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
575 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
576 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
577 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO570 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
578571
579 const S = struct {572 const S = struct {
...@@ -595,7 +588,6 @@ test "negation f64" {...@@ -595,7 +588,6 @@ test "negation f64" {
595 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO588 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
596 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO589 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
597 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO590 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
598 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
599591
600 const S = struct {592 const S = struct {
601 fn doTheTest() !void {593 fn doTheTest() !void {
...@@ -615,7 +607,6 @@ test "negation f80" {...@@ -615,7 +607,6 @@ test "negation f80" {
615 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO607 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
616 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO608 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
617 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO609 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
618 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
619 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO610 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
620611
621 const S = struct {612 const S = struct {
...@@ -636,7 +627,6 @@ test "negation f128" {...@@ -636,7 +627,6 @@ test "negation f128" {
636 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO627 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO628 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
638 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO629 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
639 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
640 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO630 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
641631
642 const S = struct {632 const S = struct {
...@@ -680,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {...@@ -680,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
680 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO670 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
681 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO671 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
682 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO672 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
683 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
684673
685 inline for (.{ f16, f32, f64, f80, f128 }) |F| {674 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
686 try expect(math.isNan(@as(F, 0) / @as(F, 0)));675 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
...@@ -716,7 +705,6 @@ test "nan negation f16" {...@@ -716,7 +705,6 @@ test "nan negation f16" {
716 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO705 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
717 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
718 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO707 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
719 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
720708
721 const nan_comptime = comptime math.nan(f16);709 const nan_comptime = comptime math.nan(f16);
722 const neg_nan_comptime = -nan_comptime;710 const neg_nan_comptime = -nan_comptime;
...@@ -736,7 +724,6 @@ test "nan negation f32" {...@@ -736,7 +724,6 @@ test "nan negation f32" {
736 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO724 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
737 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO725 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO726 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
739 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
740727
741 const nan_comptime = comptime math.nan(f32);728 const nan_comptime = comptime math.nan(f32);
742 const neg_nan_comptime = -nan_comptime;729 const neg_nan_comptime = -nan_comptime;
...@@ -756,7 +743,6 @@ test "nan negation f64" {...@@ -756,7 +743,6 @@ test "nan negation f64" {
756 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO743 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
757 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO744 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
758 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO745 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
759 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
760746
761 const nan_comptime = comptime math.nan(f64);747 const nan_comptime = comptime math.nan(f64);
762 const neg_nan_comptime = -nan_comptime;748 const neg_nan_comptime = -nan_comptime;
...@@ -776,7 +762,6 @@ test "nan negation f128" {...@@ -776,7 +762,6 @@ test "nan negation f128" {
776 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO762 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
777 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO763 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
778 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO764 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
779 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
780765
781 const nan_comptime = comptime math.nan(f128);766 const nan_comptime = comptime math.nan(f128);
782 const neg_nan_comptime = -nan_comptime;767 const neg_nan_comptime = -nan_comptime;
test/behavior/fn.zig-8
...@@ -97,7 +97,6 @@ test "discard the result of a function that returns a struct" {...@@ -97,7 +97,6 @@ test "discard the result of a function that returns a struct" {
97}97}
9898
99test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {99test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {
100 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
101 if (builtin.zig_backend == .stage1) return error.SkipZigTest;100 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
102 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;101 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
103 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -146,7 +145,6 @@ fn fnWithUnreachable() noreturn {...@@ -146,7 +145,6 @@ fn fnWithUnreachable() noreturn {
146}145}
147146
148test "extern struct with stdcallcc fn pointer" {147test "extern struct with stdcallcc fn pointer" {
149 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
150 if (builtin.zig_backend == .stage1) return error.SkipZigTest;148 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
151 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;150 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -274,7 +272,6 @@ test "void parameters" {...@@ -274,7 +272,6 @@ test "void parameters" {
274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;272 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
276274
277 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
278 try voidFun(1, void{}, 2, {});275 try voidFun(1, void{}, 2, {});
279}276}
280fn voidFun(a: i32, b: void, c: i32, d: void) !void {277fn voidFun(a: i32, b: void, c: i32, d: void) !void {
...@@ -286,7 +283,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void {...@@ -286,7 +283,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void {
286}283}
287284
288test "call function with empty string" {285test "call function with empty string" {
289 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
290 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
291287
292 acceptsString("");288 acceptsString("");
...@@ -305,7 +301,6 @@ test "function pointers" {...@@ -305,7 +301,6 @@ test "function pointers" {
305 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO301 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO302 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
308 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
309304
310 const fns = [_]*const @TypeOf(fn1){305 const fns = [_]*const @TypeOf(fn1){
311 &fn1,306 &fn1,
...@@ -399,8 +394,6 @@ test "ability to give comptime types and non comptime types to same parameter" {...@@ -399,8 +394,6 @@ test "ability to give comptime types and non comptime types to same parameter" {
399}394}
400395
401test "function with inferred error set but returning no error" {396test "function with inferred error set but returning no error" {
402 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
403
404 const S = struct {397 const S = struct {
405 fn foo() !void {}398 fn foo() !void {}
406 };399 };
...@@ -410,7 +403,6 @@ test "function with inferred error set but returning no error" {...@@ -410,7 +403,6 @@ test "function with inferred error set but returning no error" {
410}403}
411404
412test "import passed byref to function in return type" {405test "import passed byref to function in return type" {
413 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO406 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
415407
416 const S = struct {408 const S = struct {
test/behavior/for.zig-1
...@@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" {...@@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" {
195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
198 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
199198
200 const S = struct {199 const S = struct {
201 fn doTheTest(slice: []const u8) !void {200 fn doTheTest(slice: []const u8) !void {
test/behavior/generics.zig+5-5
...@@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool {...@@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool {
204}204}
205205
206test "generic struct" {206test "generic struct" {
207 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
208 var a1 = GenNode(i32){207 var a1 = GenNode(i32){
209 .value = 13,208 .value = 13,
210 .next = null,209 .next = null,
...@@ -361,13 +360,14 @@ test "nested generic function" {...@@ -361,13 +360,14 @@ test "nested generic function" {
361360
362test "extern function used as generic parameter" {361test "extern function used as generic parameter" {
363 const S = struct {362 const S = struct {
364 extern fn foo() void;363 extern fn usedAsGenericParameterFoo() void;
365 extern fn bar() void;364 extern fn usedAsGenericParameterBar() void;
366 inline fn baz(comptime _: anytype) type {365 inline fn usedAsGenericParameterBaz(comptime _: anytype) type {
367 return struct {};366 return struct {};
368 }367 }
369 };368 };
370 try expect(S.baz(S.foo) != S.baz(S.bar));369 try expect(S.usedAsGenericParameterBaz(S.usedAsGenericParameterFoo) !=
370 S.usedAsGenericParameterBaz(S.usedAsGenericParameterBar));
371}371}
372372
373test "generic struct as parameter type" {373test "generic struct as parameter type" {
test/behavior/int128.zig-1
...@@ -43,7 +43,6 @@ test "int128" {...@@ -43,7 +43,6 @@ test "int128" {
43 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO43 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
44 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO44 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO45 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
46 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
4746
48 var buff: i128 = -1;47 var buff: i128 = -1;
49 try expect(buff < 0 and (buff + 1) == 0);48 try expect(buff < 0 and (buff + 1) == 0);
test/behavior/math.zig-41
...@@ -376,7 +376,6 @@ fn testBinaryNot(x: u16) !void {...@@ -376,7 +376,6 @@ fn testBinaryNot(x: u16) !void {
376}376}
377377
378test "division" {378test "division" {
379 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
380 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO379 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO380 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
382 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO381 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -453,7 +452,6 @@ fn testDivision() !void {...@@ -453,7 +452,6 @@ fn testDivision() !void {
453}452}
454453
455test "division half-precision floats" {454test "division half-precision floats" {
456 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
457 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO455 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
458 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO456 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
459 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -603,7 +601,6 @@ fn should_not_be_zero(x: f128) !void {...@@ -603,7 +601,6 @@ fn should_not_be_zero(x: f128) !void {
603}601}
604602
605test "128-bit multiplication" {603test "128-bit multiplication" {
606 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
607 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO604 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
608 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO605 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
609 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO606 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -616,8 +613,6 @@ test "128-bit multiplication" {...@@ -616,8 +613,6 @@ test "128-bit multiplication" {
616}613}
617614
618test "@addWithOverflow" {615test "@addWithOverflow" {
619 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
620
621 {616 {
622 var result: u8 = undefined;617 var result: u8 = undefined;
623 try expect(@addWithOverflow(u8, 250, 100, &result));618 try expect(@addWithOverflow(u8, 250, 100, &result));
...@@ -652,8 +647,6 @@ test "@addWithOverflow" {...@@ -652,8 +647,6 @@ test "@addWithOverflow" {
652}647}
653648
654test "small int addition" {649test "small int addition" {
655 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
656
657 var x: u2 = 0;650 var x: u2 = 0;
658 try expect(x == 0);651 try expect(x == 0);
659652
...@@ -673,8 +666,6 @@ test "small int addition" {...@@ -673,8 +666,6 @@ test "small int addition" {
673}666}
674667
675test "basic @mulWithOverflow" {668test "basic @mulWithOverflow" {
676 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
677
678 var result: u8 = undefined;669 var result: u8 = undefined;
679 try expect(@mulWithOverflow(u8, 86, 3, &result));670 try expect(@mulWithOverflow(u8, 86, 3, &result));
680 try expect(result == 2);671 try expect(result == 2);
...@@ -693,7 +684,6 @@ test "basic @mulWithOverflow" {...@@ -693,7 +684,6 @@ test "basic @mulWithOverflow" {
693684
694// TODO migrate to this for all backends once they handle more cases685// TODO migrate to this for all backends once they handle more cases
695test "extensive @mulWithOverflow" {686test "extensive @mulWithOverflow" {
696 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
697 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO687 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
698688
699 {689 {
...@@ -843,7 +833,6 @@ test "extensive @mulWithOverflow" {...@@ -843,7 +833,6 @@ test "extensive @mulWithOverflow" {
843}833}
844834
845test "@mulWithOverflow bitsize > 32" {835test "@mulWithOverflow bitsize > 32" {
846 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
847 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO836 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
848 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO837 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
849838
...@@ -897,8 +886,6 @@ test "@mulWithOverflow bitsize > 32" {...@@ -897,8 +886,6 @@ test "@mulWithOverflow bitsize > 32" {
897}886}
898887
899test "@subWithOverflow" {888test "@subWithOverflow" {
900 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
901
902 {889 {
903 var result: u8 = undefined;890 var result: u8 = undefined;
904 try expect(@subWithOverflow(u8, 1, 2, &result));891 try expect(@subWithOverflow(u8, 1, 2, &result));
...@@ -933,8 +920,6 @@ test "@subWithOverflow" {...@@ -933,8 +920,6 @@ test "@subWithOverflow" {
933}920}
934921
935test "@shlWithOverflow" {922test "@shlWithOverflow" {
936 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
937
938 {923 {
939 var result: u4 = undefined;924 var result: u4 = undefined;
940 var a: u4 = 2;925 var a: u4 = 2;
...@@ -977,8 +962,6 @@ test "@shlWithOverflow" {...@@ -977,8 +962,6 @@ test "@shlWithOverflow" {
977}962}
978963
979test "overflow arithmetic with u0 values" {964test "overflow arithmetic with u0 values" {
980 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
981
982 var result: u0 = undefined;965 var result: u0 = undefined;
983 try expect(!@addWithOverflow(u0, 0, 0, &result));966 try expect(!@addWithOverflow(u0, 0, 0, &result));
984 try expect(result == 0);967 try expect(result == 0);
...@@ -1007,7 +990,6 @@ test "allow signed integer division/remainder when values are comptime-known and...@@ -1007,7 +990,6 @@ test "allow signed integer division/remainder when values are comptime-known and
1007}990}
1008991
1009test "quad hex float literal parsing accurate" {992test "quad hex float literal parsing accurate" {
1010 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1011 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO993 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1012 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO994 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1013 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO995 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1163,7 +1145,6 @@ test "comptime float rem int" {...@@ -1163,7 +1145,6 @@ test "comptime float rem int" {
11631145
1164test "remainder division" {1146test "remainder division" {
1165 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1147 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1166 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1148 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1169 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1196,7 +1177,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void {...@@ -1196,7 +1177,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void {
11961177
1197test "float remainder division using @rem" {1178test "float remainder division using @rem" {
1198 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1179 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1199 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1200 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1201 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1181 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1182 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1240,7 +1220,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {...@@ -1240,7 +1220,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
12401220
1241test "float modulo division using @mod" {1221test "float modulo division using @mod" {
1242 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1222 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1243 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1245 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1246 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1225 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -1286,7 +1265,6 @@ test "@sqrt" {...@@ -1286,7 +1265,6 @@ test "@sqrt" {
1286 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1265 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1287 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1266 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1288 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1267 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1289 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12901268
1291 try testSqrt(f64, 12.0);1269 try testSqrt(f64, 12.0);
1292 comptime try testSqrt(f64, 12.0);1270 comptime try testSqrt(f64, 12.0);
...@@ -1312,7 +1290,6 @@ test "@fabs" {...@@ -1312,7 +1290,6 @@ test "@fabs" {
1312 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1291 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1314 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1292 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1315 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
13161293
1317 try testFabs(f128, 12.0);1294 try testFabs(f128, 12.0);
1318 comptime try testFabs(f128, 12.0);1295 comptime try testFabs(f128, 12.0);
...@@ -1334,7 +1311,6 @@ test "@fabs f80" {...@@ -1334,7 +1311,6 @@ test "@fabs f80" {
1334 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1311 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1335 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1336 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1313 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1337 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
13381314
1339 try testFabs(f80, 12.0);1315 try testFabs(f80, 12.0);
1340 comptime try testFabs(f80, 12.0);1316 comptime try testFabs(f80, 12.0);
...@@ -1351,7 +1327,6 @@ test "@floor" {...@@ -1351,7 +1327,6 @@ test "@floor" {
1351 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1327 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1352 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1328 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1353 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1329 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1354 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
13551330
1356 try testFloor(f64, 12.0);1331 try testFloor(f64, 12.0);
1357 comptime try testFloor(f64, 12.0);1332 comptime try testFloor(f64, 12.0);
...@@ -1371,7 +1346,6 @@ test "@floor f80" {...@@ -1371,7 +1346,6 @@ test "@floor f80" {
1371 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1346 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1372 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1373 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1348 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1374 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1375 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/126021349 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602
13761350
1377 try testFloor(f80, 12.0);1351 try testFloor(f80, 12.0);
...@@ -1383,7 +1357,6 @@ test "@floor f128" {...@@ -1383,7 +1357,6 @@ test "@floor f128" {
1383 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1357 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1384 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1358 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1385 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1359 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1386 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
13871360
1388 try testFloor(f128, 12.0);1361 try testFloor(f128, 12.0);
1389 comptime try testFloor(f128, 12.0);1362 comptime try testFloor(f128, 12.0);
...@@ -1400,7 +1373,6 @@ test "@ceil" {...@@ -1400,7 +1373,6 @@ test "@ceil" {
1400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1373 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1402 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1375 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1403 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14041376
1405 try testCeil(f64, 12.0);1377 try testCeil(f64, 12.0);
1406 comptime try testCeil(f64, 12.0);1378 comptime try testCeil(f64, 12.0);
...@@ -1420,7 +1392,6 @@ test "@ceil f80" {...@@ -1420,7 +1392,6 @@ test "@ceil f80" {
1420 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1392 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1421 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1422 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1394 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1423 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1424 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/126021395 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602
14251396
1426 try testCeil(f80, 12.0);1397 try testCeil(f80, 12.0);
...@@ -1432,7 +1403,6 @@ test "@ceil f128" {...@@ -1432,7 +1403,6 @@ test "@ceil f128" {
1432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1403 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1433 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1434 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1405 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1435 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14361406
1437 try testCeil(f128, 12.0);1407 try testCeil(f128, 12.0);
1438 comptime try testCeil(f128, 12.0);1408 comptime try testCeil(f128, 12.0);
...@@ -1449,7 +1419,6 @@ test "@trunc" {...@@ -1449,7 +1419,6 @@ test "@trunc" {
1449 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1450 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1420 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1451 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1421 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1452 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14531422
1454 try testTrunc(f64, 12.0);1423 try testTrunc(f64, 12.0);
1455 comptime try testTrunc(f64, 12.0);1424 comptime try testTrunc(f64, 12.0);
...@@ -1469,7 +1438,6 @@ test "@trunc f80" {...@@ -1469,7 +1438,6 @@ test "@trunc f80" {
1469 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1438 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1470 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1439 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1471 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1440 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1472 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1473 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/126021441 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602
14741442
1475 try testTrunc(f80, 12.0);1443 try testTrunc(f80, 12.0);
...@@ -1487,7 +1455,6 @@ test "@trunc f128" {...@@ -1487,7 +1455,6 @@ test "@trunc f128" {
1487 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1488 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1489 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1457 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1490 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14911458
1492 try testTrunc(f128, 12.0);1459 try testTrunc(f128, 12.0);
1493 comptime try testTrunc(f128, 12.0);1460 comptime try testTrunc(f128, 12.0);
...@@ -1512,7 +1479,6 @@ test "@round" {...@@ -1512,7 +1479,6 @@ test "@round" {
1512 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1479 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1513 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1480 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1514 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1481 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1515 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
15161482
1517 try testRound(f64, 12.0);1483 try testRound(f64, 12.0);
1518 comptime try testRound(f64, 12.0);1484 comptime try testRound(f64, 12.0);
...@@ -1532,7 +1498,6 @@ test "@round f80" {...@@ -1532,7 +1498,6 @@ test "@round f80" {
1532 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1498 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1533 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1534 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1500 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1535 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1536 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/126021501 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602
15371502
1538 try testRound(f80, 12.0);1503 try testRound(f80, 12.0);
...@@ -1544,7 +1509,6 @@ test "@round f128" {...@@ -1544,7 +1509,6 @@ test "@round f128" {
1544 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1509 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1510 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1546 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1511 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1547 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
15481512
1549 try testRound(f128, 12.0);1513 try testRound(f128, 12.0);
1550 comptime try testRound(f128, 12.0);1514 comptime try testRound(f128, 12.0);
...@@ -1578,7 +1542,6 @@ test "vector integer addition" {...@@ -1578,7 +1542,6 @@ test "vector integer addition" {
1578}1542}
15791543
1580test "NaN comparison" {1544test "NaN comparison" {
1581 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1582 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1545 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1583 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1546 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1584 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1547 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1595,7 +1558,6 @@ test "NaN comparison" {...@@ -1595,7 +1558,6 @@ test "NaN comparison" {
1595}1558}
15961559
1597test "NaN comparison f80" {1560test "NaN comparison f80" {
1598 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1599 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1561 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1600 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1562 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1601 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1563 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1647,7 +1609,6 @@ test "compare undefined literal with comptime_int" {...@@ -1647,7 +1609,6 @@ test "compare undefined literal with comptime_int" {
1647}1609}
16481610
1649test "signed zeros are represented properly" {1611test "signed zeros are represented properly" {
1650 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1651 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1612 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1652 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1613 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1653 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1614 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1688,7 +1649,6 @@ test "fabs" {...@@ -1688,7 +1649,6 @@ test "fabs" {
1688 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1649 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1689 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1650 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1690 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1651 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1691 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16921652
1693 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {1653 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
1694 // normals1654 // normals
...@@ -1717,7 +1677,6 @@ test "absFloat" {...@@ -1717,7 +1677,6 @@ test "absFloat" {
1717 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1677 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1718 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1678 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1719 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1679 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1720 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
17211680
1722 try testAbsFloat();1681 try testAbsFloat();
1723 comptime try testAbsFloat();1682 comptime try testAbsFloat();
test/behavior/maximum_minimum.zig-2
...@@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual;...@@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual;
66
7test "@max" {7test "@max" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1211
...@@ -55,7 +54,6 @@ test "@min" {...@@ -55,7 +54,6 @@ test "@min" {
55 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5957
60 const S = struct {58 const S = struct {
61 fn doTheTest() !void {59 fn doTheTest() !void {
test/behavior/muladd.zig-4
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
2const expect = @import("std").testing.expect;2const expect = @import("std").testing.expect;
33
4test "@mulAdd" {4test "@mulAdd" {
5 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -28,7 +27,6 @@ fn testMulAdd() !void {...@@ -28,7 +27,6 @@ fn testMulAdd() !void {
2827
29test "@mulAdd f16" {28test "@mulAdd f16" {
30 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO29 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
31 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO30 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
34 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -46,7 +44,6 @@ fn testMulAdd16() !void {...@@ -46,7 +44,6 @@ fn testMulAdd16() !void {
4644
47test "@mulAdd f80" {45test "@mulAdd f80" {
48 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO46 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
52 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -65,7 +62,6 @@ fn testMulAdd80() !void {...@@ -65,7 +62,6 @@ fn testMulAdd80() !void {
65}62}
6663
67test "@mulAdd f128" {64test "@mulAdd f128" {
68 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO65 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO66 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/optional.zig-3
...@@ -66,7 +66,6 @@ test "optional with void type" {...@@ -66,7 +66,6 @@ test "optional with void type" {
66}66}
6767
68test "address of unwrap optional" {68test "address of unwrap optional" {
69 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;69 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO70 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO71 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -270,7 +269,6 @@ test "0-bit child type coerced to optional return ptr result location" {...@@ -270,7 +269,6 @@ test "0-bit child type coerced to optional return ptr result location" {
270}269}
271270
272test "0-bit child type coerced to optional" {271test "0-bit child type coerced to optional" {
273 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO272 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
276274
...@@ -333,7 +331,6 @@ test "array of optional unaligned types" {...@@ -333,7 +331,6 @@ test "array of optional unaligned types" {
333}331}
334332
335test "optional pointer to zero bit optional payload" {333test "optional pointer to zero bit optional payload" {
336 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
337 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO334 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
338 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO335 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO336 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/packed-struct.zig-6
...@@ -150,7 +150,6 @@ test "consistent size of packed structs" {...@@ -150,7 +150,6 @@ test "consistent size of packed structs" {
150150
151test "correct sizeOf and offsets in packed structs" {151test "correct sizeOf and offsets in packed structs" {
152 if (builtin.zig_backend == .stage1) return error.SkipZigTest;152 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
153 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO153 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO154 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO155 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -221,7 +220,6 @@ test "correct sizeOf and offsets in packed structs" {...@@ -221,7 +220,6 @@ test "correct sizeOf and offsets in packed structs" {
221220
222test "nested packed structs" {221test "nested packed structs" {
223 if (builtin.zig_backend == .stage1) return error.SkipZigTest;222 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO223 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
226 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO224 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -270,7 +268,6 @@ test "nested packed structs" {...@@ -270,7 +268,6 @@ test "nested packed structs" {
270268
271test "regular in irregular packed struct" {269test "regular in irregular packed struct" {
272 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;270 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
273 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;271 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;272 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;273 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -293,7 +290,6 @@ test "regular in irregular packed struct" {...@@ -293,7 +290,6 @@ test "regular in irregular packed struct" {
293test "byte-aligned field pointer offsets" {290test "byte-aligned field pointer offsets" {
294 if (builtin.zig_backend == .stage1) return error.SkipZigTest;291 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
295 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;292 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
296 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
297 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;293 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;295 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -396,7 +392,6 @@ test "byte-aligned field pointer offsets" {...@@ -396,7 +392,6 @@ test "byte-aligned field pointer offsets" {
396392
397test "load pointer from packed struct" {393test "load pointer from packed struct" {
398 if (builtin.zig_backend == .stage1) return error.SkipZigTest;394 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
399 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
400 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;395 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;396 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -418,7 +413,6 @@ test "load pointer from packed struct" {...@@ -418,7 +413,6 @@ test "load pointer from packed struct" {
418}413}
419414
420test "@ptrToInt on a packed struct field" {415test "@ptrToInt on a packed struct field" {
421 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
422 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;416 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
423 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;417 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
424 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;418 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
test/behavior/packed_struct_explicit_backing_int.zig-1
...@@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian();...@@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian();
66
7test "packed struct explicit backing integer" {7test "packed struct explicit backing integer" {
8 assert(builtin.zig_backend != .stage1);8 assert(builtin.zig_backend != .stage1);
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/pointers.zig-4
...@@ -157,7 +157,6 @@ test "implicit casting between C pointer and optional non-C pointer" {...@@ -157,7 +157,6 @@ test "implicit casting between C pointer and optional non-C pointer" {
157}157}
158158
159test "implicit cast error unions with non-optional to optional pointer" {159test "implicit cast error unions with non-optional to optional pointer" {
160 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
161 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO160 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO162 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -205,7 +204,6 @@ test "allowzero pointer and slice" {...@@ -205,7 +204,6 @@ test "allowzero pointer and slice" {
205}204}
206205
207test "assign null directly to C pointer and test null equality" {206test "assign null directly to C pointer and test null equality" {
208 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO207 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
210 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO208 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
211 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO209 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -337,7 +335,6 @@ test "pointer sentinel with optional element" {...@@ -337,7 +335,6 @@ test "pointer sentinel with optional element" {
337335
338test "pointer sentinel with +inf" {336test "pointer sentinel with +inf" {
339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;337 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
340 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO338 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
342 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO339 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
343 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO340 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
...@@ -404,7 +401,6 @@ test "@ptrToInt on null optional at comptime" {...@@ -404,7 +401,6 @@ test "@ptrToInt on null optional at comptime" {
404}401}
405402
406test "indexing array with sentinel returns correct type" {403test "indexing array with sentinel returns correct type" {
407 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
410 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO406 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/ptrcast.zig-1
...@@ -133,7 +133,6 @@ test "lower reinterpreted comptime field ptr (with under-aligned fields)" {...@@ -133,7 +133,6 @@ test "lower reinterpreted comptime field ptr (with under-aligned fields)" {
133 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO133 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
134 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO134 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
135 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO135 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
136 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO: CBE does not yet support under-aligned fields
137136
138 // Test lowering a field ptr137 // Test lowering a field ptr
139 comptime var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 };138 comptime var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 };
test/behavior/saturating_arithmetic.zig-7
...@@ -8,7 +8,6 @@ test "saturating add" {...@@ -8,7 +8,6 @@ test "saturating add" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1211
13 const S = struct {12 const S = struct {
14 fn doTheTest() !void {13 fn doTheTest() !void {
...@@ -55,7 +54,6 @@ test "saturating add 128bit" {...@@ -55,7 +54,6 @@ test "saturating add 128bit" {
55 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
59 const S = struct {57 const S = struct {
60 fn doTheTest() !void {58 fn doTheTest() !void {
61 try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0);59 try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0);
...@@ -79,7 +77,6 @@ test "saturating subtraction" {...@@ -79,7 +77,6 @@ test "saturating subtraction" {
79 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO77 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO78 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8380
84 const S = struct {81 const S = struct {
85 fn doTheTest() !void {82 fn doTheTest() !void {
...@@ -125,7 +122,6 @@ test "saturating subtraction 128bit" {...@@ -125,7 +122,6 @@ test "saturating subtraction 128bit" {
125 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO122 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
128 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
129125
130 const S = struct {126 const S = struct {
131 fn doTheTest() !void {127 fn doTheTest() !void {
...@@ -152,7 +148,6 @@ test "saturating multiplication" {...@@ -152,7 +148,6 @@ test "saturating multiplication" {
152 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO148 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
153 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO150 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
156151
157 if (builtin.zig_backend == .stage1 and builtin.cpu.arch == .wasm32) {152 if (builtin.zig_backend == .stage1 and builtin.cpu.arch == .wasm32) {
158 // https://github.com/ziglang/zig/issues/9660153 // https://github.com/ziglang/zig/issues/9660
...@@ -200,7 +195,6 @@ test "saturating shift-left" {...@@ -200,7 +195,6 @@ test "saturating shift-left" {
200 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
201 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
202 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
204198
205 const S = struct {199 const S = struct {
206 fn doTheTest() !void {200 fn doTheTest() !void {
...@@ -239,7 +233,6 @@ test "saturating shl uses the LHS type" {...@@ -239,7 +233,6 @@ test "saturating shl uses the LHS type" {
239 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO233 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO234 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO235 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
242 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
243236
244 const lhs_const: u8 = 1;237 const lhs_const: u8 = 1;
245 var lhs_var: u8 = 1;238 var lhs_var: u8 = 1;
test/behavior/sizeof_and_typeof.zig-1
...@@ -19,7 +19,6 @@ test "@sizeOf on compile-time types" {...@@ -19,7 +19,6 @@ test "@sizeOf on compile-time types" {
1919
20test "@TypeOf() with multiple arguments" {20test "@TypeOf() with multiple arguments" {
21 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;21 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
23 {22 {
24 var var_1: u32 = undefined;23 var var_1: u32 = undefined;
25 var var_2: u8 = undefined;24 var var_2: u8 = undefined;
test/behavior/slice.zig-11
...@@ -169,7 +169,6 @@ test "comptime pointer cast array and then slice" {...@@ -169,7 +169,6 @@ test "comptime pointer cast array and then slice" {
169169
170test "slicing zero length array" {170test "slicing zero length array" {
171 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;171 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
172 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
173 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;172 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
174173
175 const s1 = ""[0..];174 const s1 = ""[0..];
...@@ -206,8 +205,6 @@ test "slice string literal has correct type" {...@@ -206,8 +205,6 @@ test "slice string literal has correct type" {
206}205}
207206
208test "result location zero sized array inside struct field implicit cast to slice" {207test "result location zero sized array inside struct field implicit cast to slice" {
209 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
210
211 const E = struct {208 const E = struct {
212 entries: []u32,209 entries: []u32,
213 };210 };
...@@ -229,7 +226,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {...@@ -229,7 +226,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
229226
230test "C pointer" {227test "C pointer" {
231 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;228 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
232 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
233229
234 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";230 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
235 var len: u32 = 10;231 var len: u32 = 10;
...@@ -323,7 +319,6 @@ test "empty array to slice" {...@@ -323,7 +319,6 @@ test "empty array to slice" {
323319
324test "@ptrCast slice to pointer" {320test "@ptrCast slice to pointer" {
325 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
326 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
327322
328 const S = struct {323 const S = struct {
329 fn doTheTest() !void {324 fn doTheTest() !void {
...@@ -339,7 +334,6 @@ test "@ptrCast slice to pointer" {...@@ -339,7 +334,6 @@ test "@ptrCast slice to pointer" {
339}334}
340335
341test "slice syntax resulting in pointer-to-array" {336test "slice syntax resulting in pointer-to-array" {
342 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
343 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO337 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO338 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
345 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO339 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -477,7 +471,6 @@ test "slice syntax resulting in pointer-to-array" {...@@ -477,7 +471,6 @@ test "slice syntax resulting in pointer-to-array" {
477}471}
478472
479test "slice pointer-to-array null terminated" {473test "slice pointer-to-array null terminated" {
480 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
481 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO474 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
482 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO475 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
483476
...@@ -503,7 +496,6 @@ test "slice pointer-to-array null terminated" {...@@ -503,7 +496,6 @@ test "slice pointer-to-array null terminated" {
503}496}
504497
505test "slice pointer-to-array zero length" {498test "slice pointer-to-array zero length" {
506 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO499 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
508500
509 comptime {501 comptime {
...@@ -541,7 +533,6 @@ test "slice pointer-to-array zero length" {...@@ -541,7 +533,6 @@ test "slice pointer-to-array zero length" {
541}533}
542534
543test "type coercion of pointer to anon struct literal to pointer to slice" {535test "type coercion of pointer to anon struct literal to pointer to slice" {
544 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
545 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO536 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
546 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO537 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO538 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -637,7 +628,6 @@ test "slice sentinel access at comptime" {...@@ -637,7 +628,6 @@ test "slice sentinel access at comptime" {
637test "slicing array with sentinel as end index" {628test "slicing array with sentinel as end index" {
638 // Doesn't work in stage1629 // Doesn't work in stage1
639 if (builtin.zig_backend == .stage1) return error.SkipZigTest;630 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
640 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
641 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;631 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
642632
643 const S = struct {633 const S = struct {
...@@ -657,7 +647,6 @@ test "slicing array with sentinel as end index" {...@@ -657,7 +647,6 @@ test "slicing array with sentinel as end index" {
657test "slicing slice with sentinel as end index" {647test "slicing slice with sentinel as end index" {
658 // Doesn't work in stage1648 // Doesn't work in stage1
659 if (builtin.zig_backend == .stage1) return error.SkipZigTest;649 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
660 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
661 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;650 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
662651
663 const S = struct {652 const S = struct {
test/behavior/struct.zig-33
...@@ -284,7 +284,6 @@ const Val = struct {...@@ -284,7 +284,6 @@ const Val = struct {
284284
285test "struct point to self" {285test "struct point to self" {
286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
287 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
289288
290 var root: Node = undefined;289 var root: Node = undefined;
...@@ -319,7 +318,6 @@ const VoidStructFieldsFoo = struct {...@@ -319,7 +318,6 @@ const VoidStructFieldsFoo = struct {
319318
320test "return empty struct from fn" {319test "return empty struct from fn" {
321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
324322
325 _ = testReturnEmptyStructFromFn();323 _ = testReturnEmptyStructFromFn();
...@@ -331,7 +329,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {...@@ -331,7 +329,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {
331329
332test "pass slice of empty struct to fn" {330test "pass slice of empty struct to fn" {
333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;331 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
334 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
335 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO332 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
336333
337 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);334 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
...@@ -342,7 +339,6 @@ fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {...@@ -342,7 +339,6 @@ fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
342339
343test "self-referencing struct via array member" {340test "self-referencing struct via array member" {
344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
345 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
346 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
347 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO343 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO344 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -356,8 +352,6 @@ test "self-referencing struct via array member" {...@@ -356,8 +352,6 @@ test "self-referencing struct via array member" {
356}352}
357353
358test "empty struct method call" {354test "empty struct method call" {
359 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
360
361 const es = EmptyStruct{};355 const es = EmptyStruct{};
362 try expect(es.method() == 1234);356 try expect(es.method() == 1234);
363}357}
...@@ -370,7 +364,6 @@ const EmptyStruct = struct {...@@ -370,7 +364,6 @@ const EmptyStruct = struct {
370364
371test "align 1 field before self referential align 8 field as slice return type" {365test "align 1 field before self referential align 8 field as slice return type" {
372 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
373 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
374 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
375368
376 const result = alloc(Expr);369 const result = alloc(Expr);
...@@ -394,7 +387,6 @@ const APackedStruct = packed struct {...@@ -394,7 +387,6 @@ const APackedStruct = packed struct {
394test "packed struct" {387test "packed struct" {
395 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;388 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
396 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO389 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO390 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO391 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
400 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO392 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -421,7 +413,6 @@ const Foo96Bits = packed struct {...@@ -421,7 +413,6 @@ const Foo96Bits = packed struct {
421test "packed struct 24bits" {413test "packed struct 24bits" {
422 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
423 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO415 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
424 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
426 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO417 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
427 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO418 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO
...@@ -470,7 +461,6 @@ test "packed struct 24bits" {...@@ -470,7 +461,6 @@ test "packed struct 24bits" {
470test "runtime struct initialization of bitfield" {461test "runtime struct initialization of bitfield" {
471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;462 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
472 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO463 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
473 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
474 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO464 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
475 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO465 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO466 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -515,7 +505,6 @@ test "packed struct fields are ordered from LSB to MSB" {...@@ -515,7 +505,6 @@ test "packed struct fields are ordered from LSB to MSB" {
515 }505 }
516 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
517 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO507 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
518 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
519 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO508 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
520 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO509 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO510 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -537,7 +526,6 @@ test "packed struct fields are ordered from LSB to MSB" {...@@ -537,7 +526,6 @@ test "packed struct fields are ordered from LSB to MSB" {
537test "implicit cast packed struct field to const ptr" {526test "implicit cast packed struct field to const ptr" {
538 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;527 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
539 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO528 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
540 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
541 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO529 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
542 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO530 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
543 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO531 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -559,7 +547,6 @@ test "implicit cast packed struct field to const ptr" {...@@ -559,7 +547,6 @@ test "implicit cast packed struct field to const ptr" {
559547
560test "zero-bit field in packed struct" {548test "zero-bit field in packed struct" {
561 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO549 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
562 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
563 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO550 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
564 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO551 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
565552
...@@ -605,7 +592,6 @@ const bit_field_1 = BitField1{...@@ -605,7 +592,6 @@ const bit_field_1 = BitField1{
605test "bit field access" {592test "bit field access" {
606 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;593 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
607 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO594 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
608 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
609 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO595 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
610 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO596 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
611 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO597 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -638,7 +624,6 @@ fn getC(data: *const BitField1) u2 {...@@ -638,7 +624,6 @@ fn getC(data: *const BitField1) u2 {
638624
639test "default struct initialization fields" {625test "default struct initialization fields" {
640 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;626 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
641 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
642 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO627 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
643628
644 const S = struct {629 const S = struct {
...@@ -771,7 +756,6 @@ test "pointer to packed struct member in a stack variable" {...@@ -771,7 +756,6 @@ test "pointer to packed struct member in a stack variable" {
771test "packed struct with u0 field access" {756test "packed struct with u0 field access" {
772 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO757 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
773 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO758 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
774 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
775 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO759 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
776760
777 const S = packed struct {761 const S = packed struct {
...@@ -783,7 +767,6 @@ test "packed struct with u0 field access" {...@@ -783,7 +767,6 @@ test "packed struct with u0 field access" {
783767
784test "access to global struct fields" {768test "access to global struct fields" {
785 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO769 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
786 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
787 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO770 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
788771
789 g_foo.bar.value = 42;772 g_foo.bar.value = 42;
...@@ -810,7 +793,6 @@ test "packed struct with fp fields" {...@@ -810,7 +793,6 @@ test "packed struct with fp fields" {
810 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO793 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
811 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO794 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
812 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO795 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
813 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
814796
815 const S = packed struct {797 const S = packed struct {
816 data0: f32,798 data0: f32,
...@@ -886,7 +868,6 @@ test "packed struct field passed to generic function" {...@@ -886,7 +868,6 @@ test "packed struct field passed to generic function" {
886 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO868 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
887 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO869 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
888 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO870 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
889 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
890 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO871 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
891872
892 const S = struct {873 const S = struct {
...@@ -910,7 +891,6 @@ test "packed struct field passed to generic function" {...@@ -910,7 +891,6 @@ test "packed struct field passed to generic function" {
910891
911test "anonymous struct literal syntax" {892test "anonymous struct literal syntax" {
912 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;893 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
913 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
914894
915 const S = struct {895 const S = struct {
916 const Point = struct {896 const Point = struct {
...@@ -932,8 +912,6 @@ test "anonymous struct literal syntax" {...@@ -932,8 +912,6 @@ test "anonymous struct literal syntax" {
932}912}
933913
934test "fully anonymous struct" {914test "fully anonymous struct" {
935 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
936
937 const S = struct {915 const S = struct {
938 fn doTheTest() !void {916 fn doTheTest() !void {
939 try dump(.{917 try dump(.{
...@@ -956,8 +934,6 @@ test "fully anonymous struct" {...@@ -956,8 +934,6 @@ test "fully anonymous struct" {
956}934}
957935
958test "fully anonymous list literal" {936test "fully anonymous list literal" {
959 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
960
961 const S = struct {937 const S = struct {
962 fn doTheTest() !void {938 fn doTheTest() !void {
963 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });939 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
...@@ -1000,7 +976,6 @@ test "comptime struct field" {...@@ -1000,7 +976,6 @@ test "comptime struct field" {
1000}976}
1001977
1002test "tuple element initialized with fn call" {978test "tuple element initialized with fn call" {
1003 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1004 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO979 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1005 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO980 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1006 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO981 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -1039,7 +1014,6 @@ test "struct with union field" {...@@ -1039,7 +1014,6 @@ test "struct with union field" {
1039}1014}
10401015
1041test "type coercion of anon struct literal to struct" {1016test "type coercion of anon struct literal to struct" {
1042 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1043 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1044 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1018 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1045 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1019 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1078,7 +1052,6 @@ test "type coercion of anon struct literal to struct" {...@@ -1078,7 +1052,6 @@ test "type coercion of anon struct literal to struct" {
10781052
1079test "type coercion of pointer to anon struct literal to pointer to struct" {1053test "type coercion of pointer to anon struct literal to pointer to struct" {
1080 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1054 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1081 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1082 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1055 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1083 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1056 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1084 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1057 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1118,7 +1091,6 @@ test "type coercion of pointer to anon struct literal to pointer to struct" {...@@ -1118,7 +1091,6 @@ test "type coercion of pointer to anon struct literal to pointer to struct" {
1118test "packed struct with undefined initializers" {1091test "packed struct with undefined initializers" {
1119 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1092 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1120 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1093 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1121 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1094 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1123 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1095 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1124 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1096 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1190,7 +1162,6 @@ test "for loop over pointers to struct, getting field from struct pointer" {...@@ -1190,7 +1162,6 @@ test "for loop over pointers to struct, getting field from struct pointer" {
11901162
1191test "anon init through error unions and optionals" {1163test "anon init through error unions and optionals" {
1192 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1164 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1193 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1194 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1165 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1195 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1166 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1196 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1219,7 +1190,6 @@ test "anon init through error unions and optionals" {...@@ -1219,7 +1190,6 @@ test "anon init through error unions and optionals" {
12191190
1220test "anon init through optional" {1191test "anon init through optional" {
1221 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1192 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1222 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1223 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1193 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1225 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1195 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1241,7 +1211,6 @@ test "anon init through optional" {...@@ -1241,7 +1211,6 @@ test "anon init through optional" {
12411211
1242test "anon init through error union" {1212test "anon init through error union" {
1243 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1213 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1244 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1245 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1214 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1215 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1263,7 +1232,6 @@ test "anon init through error union" {...@@ -1263,7 +1232,6 @@ test "anon init through error union" {
12631232
1264test "typed init through error unions and optionals" {1233test "typed init through error unions and optionals" {
1265 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1234 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1266 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1267 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1235 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1268 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1236 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1269 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1332,7 +1300,6 @@ test "packed struct aggregate init" {...@@ -1332,7 +1300,6 @@ test "packed struct aggregate init" {
1332 }1300 }
1333 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1301 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1334 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1302 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1335 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1336 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1303 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1304 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1305 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/struct_contains_null_ptr_itself.zig-1
...@@ -5,7 +5,6 @@ const builtin = @import("builtin");...@@ -5,7 +5,6 @@ const builtin = @import("builtin");
5test "struct contains null pointer which contains original struct" {5test "struct contains null pointer which contains original struct" {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
9 var x: ?*NodeLineComment = null;8 var x: ?*NodeLineComment = null;
10 try expect(x == null);9 try expect(x == null);
11}10}
test/behavior/struct_contains_slice_of_itself.zig-2
...@@ -12,7 +12,6 @@ const NodeAligned = struct {...@@ -12,7 +12,6 @@ const NodeAligned = struct {
12};12};
1313
14test "struct contains slice of itself" {14test "struct contains slice of itself" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1716
18 var other_nodes = [_]Node{17 var other_nodes = [_]Node{
...@@ -52,7 +51,6 @@ test "struct contains slice of itself" {...@@ -52,7 +51,6 @@ test "struct contains slice of itself" {
52}51}
5352
54test "struct contains aligned slice of itself" {53test "struct contains aligned slice of itself" {
55 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5755
58 var other_nodes = [_]NodeAligned{56 var other_nodes = [_]NodeAligned{
test/behavior/switch.zig-3
...@@ -420,7 +420,6 @@ test "else prong of switch on error set excludes other cases" {...@@ -420,7 +420,6 @@ test "else prong of switch on error set excludes other cases" {
420 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO420 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
422 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO422 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
423 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
424423
425 const S = struct {424 const S = struct {
426 fn doTheTest() !void {425 fn doTheTest() !void {
...@@ -455,7 +454,6 @@ test "switch prongs with error set cases make a new error set type for capture v...@@ -455,7 +454,6 @@ test "switch prongs with error set cases make a new error set type for capture v
455 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO454 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
456 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
458 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
459457
460 const S = struct {458 const S = struct {
461 fn doTheTest() !void {459 fn doTheTest() !void {
...@@ -621,7 +619,6 @@ test "switch capture copies its payload" {...@@ -621,7 +619,6 @@ test "switch capture copies its payload" {
621 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO619 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO620 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
623 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
625622
626 const S = struct {623 const S = struct {
627 fn doTheTest() !void {624 fn doTheTest() !void {
test/behavior/switch_prong_err_enum.zig-1
...@@ -24,7 +24,6 @@ test "switch prong returns error enum" {...@@ -24,7 +24,6 @@ test "switch prong returns error enum" {
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
28 switch (doThing(17) catch unreachable) {27 switch (doThing(17) catch unreachable) {
29 FormValue.Address => |payload| {28 FormValue.Address => |payload| {
30 try expect(payload == 1);29 try expect(payload == 1);
test/behavior/switch_prong_implicit_cast.zig-1
...@@ -18,7 +18,6 @@ test "switch prong implicit cast" {...@@ -18,7 +18,6 @@ test "switch prong implicit cast" {
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
22 const result = switch (foo(2) catch unreachable) {21 const result = switch (foo(2) catch unreachable) {
23 FormValue.One => false,22 FormValue.One => false,
24 FormValue.Two => |x| x,23 FormValue.Two => |x| x,
test/behavior/translate_c_macros.zig-8
...@@ -21,7 +21,6 @@ test "casting to void with a macro" {...@@ -21,7 +21,6 @@ test "casting to void with a macro" {
21}21}
2222
23test "initializer list expression" {23test "initializer list expression" {
24 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO26 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -48,7 +47,6 @@ test "reference to a struct type" {...@@ -48,7 +47,6 @@ test "reference to a struct type" {
48test "cast negative integer to pointer" {47test "cast negative integer to pointer" {
49 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
52 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO50 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
53 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5452
...@@ -58,7 +56,6 @@ test "cast negative integer to pointer" {...@@ -58,7 +56,6 @@ test "cast negative integer to pointer" {
58test "casting to union with a macro" {56test "casting to union with a macro" {
59 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO57 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO58 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
62 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
63 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6461
...@@ -75,7 +72,6 @@ test "casting to union with a macro" {...@@ -75,7 +72,6 @@ test "casting to union with a macro" {
75test "casting or calling a value with a paren-surrounded macro" {72test "casting or calling a value with a paren-surrounded macro" {
76 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO73 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO74 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO75 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO76 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8177
...@@ -95,7 +91,6 @@ test "casting or calling a value with a paren-surrounded macro" {...@@ -95,7 +91,6 @@ test "casting or calling a value with a paren-surrounded macro" {
95test "nested comma operator" {91test "nested comma operator" {
96 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO92 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO93 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO94 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO95 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10196
...@@ -106,7 +101,6 @@ test "nested comma operator" {...@@ -106,7 +101,6 @@ test "nested comma operator" {
106test "cast functions" {101test "cast functions" {
107 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO102 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
108 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO103 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO104 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO105 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
112106
...@@ -120,7 +114,6 @@ test "cast functions" {...@@ -120,7 +114,6 @@ test "cast functions" {
120test "large integer macro" {114test "large integer macro" {
121 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
122 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
125 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO118 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
126119
...@@ -151,7 +144,6 @@ test "string and char literals that are not UTF-8 encoded. Issue #12784" {...@@ -151,7 +144,6 @@ test "string and char literals that are not UTF-8 encoded. Issue #12784" {
151test "Macro that uses division operator. Issue #13162" {144test "Macro that uses division operator. Issue #13162" {
152 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO145 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
153 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO146 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
157149
test/behavior/tuple.zig-5
...@@ -205,7 +205,6 @@ test "initializing anon struct with explicit type" {...@@ -205,7 +205,6 @@ test "initializing anon struct with explicit type" {
205}205}
206206
207test "fieldParentPtr of tuple" {207test "fieldParentPtr of tuple" {
208 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;208 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;209 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;210 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -216,7 +215,6 @@ test "fieldParentPtr of tuple" {...@@ -216,7 +215,6 @@ test "fieldParentPtr of tuple" {
216}215}
217216
218test "fieldParentPtr of anon struct" {217test "fieldParentPtr of anon struct" {
219 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
220 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;218 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;219 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;220 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
...@@ -257,7 +255,6 @@ test "initializing anon struct with mixed comptime-runtime fields" {...@@ -257,7 +255,6 @@ test "initializing anon struct with mixed comptime-runtime fields" {
257}255}
258256
259test "tuple in tuple passed to generic function" {257test "tuple in tuple passed to generic function" {
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO258 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;260 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
...@@ -277,7 +274,6 @@ test "tuple in tuple passed to generic function" {...@@ -277,7 +274,6 @@ test "tuple in tuple passed to generic function" {
277}274}
278275
279test "coerce tuple to tuple" {276test "coerce tuple to tuple" {
280 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO277 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO278 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;279 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
...@@ -292,7 +288,6 @@ test "coerce tuple to tuple" {...@@ -292,7 +288,6 @@ test "coerce tuple to tuple" {
292}288}
293289
294test "tuple type with void field" {290test "tuple type with void field" {
295 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
296 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO291 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
297 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO292 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO293 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/type.zig-7
...@@ -200,7 +200,6 @@ test "Type.ErrorUnion" {...@@ -200,7 +200,6 @@ test "Type.ErrorUnion" {
200200
201test "Type.Opaque" {201test "Type.Opaque" {
202 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO202 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
204 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO203 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
205 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -248,7 +247,6 @@ fn add(a: i32, b: i32) i32 {...@@ -248,7 +247,6 @@ fn add(a: i32, b: i32) i32 {
248247
249test "Type.ErrorSet" {248test "Type.ErrorSet" {
250 if (builtin.zig_backend == .stage1) return error.SkipZigTest;249 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
251 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
252250
253 try testing.expect(@Type(.{ .ErrorSet = null }) == anyerror);251 try testing.expect(@Type(.{ .ErrorSet = null }) == anyerror);
254252
...@@ -351,7 +349,6 @@ test "Type.Struct" {...@@ -351,7 +349,6 @@ test "Type.Struct" {
351}349}
352350
353test "Type.Enum" {351test "Type.Enum" {
354 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
355 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO352 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
356 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
357 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO354 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -396,7 +393,6 @@ test "Type.Enum" {...@@ -396,7 +393,6 @@ test "Type.Enum" {
396393
397test "Type.Union" {394test "Type.Union" {
398 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO395 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
400 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO396 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
401 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
402 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO398 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -462,7 +458,6 @@ test "Type.Union" {...@@ -462,7 +458,6 @@ test "Type.Union" {
462}458}
463459
464test "Type.Union from Type.Enum" {460test "Type.Union from Type.Enum" {
465 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
466 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO461 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
467462
468 const Tag = @Type(.{463 const Tag = @Type(.{
...@@ -490,7 +485,6 @@ test "Type.Union from Type.Enum" {...@@ -490,7 +485,6 @@ test "Type.Union from Type.Enum" {
490}485}
491486
492test "Type.Union from regular enum" {487test "Type.Union from regular enum" {
493 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
494 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO488 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
495489
496 const E = enum { working_as_expected };490 const E = enum { working_as_expected };
...@@ -509,7 +503,6 @@ test "Type.Union from regular enum" {...@@ -509,7 +503,6 @@ test "Type.Union from regular enum" {
509503
510test "Type.Fn" {504test "Type.Fn" {
511 if (builtin.zig_backend == .stage1) return error.SkipZigTest;505 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
512 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
513506
514 if (true) {507 if (true) {
515 // https://github.com/ziglang/zig/issues/12360508 // https://github.com/ziglang/zig/issues/12360
test/behavior/type_info.zig+4-13
...@@ -355,19 +355,12 @@ fn testOpaque() !void {...@@ -355,19 +355,12 @@ fn testOpaque() !void {
355}355}
356356
357test "type info: function type info" {357test "type info: function type info" {
358 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
359 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
360 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
361
362 // wasm doesn't support align attributes on functions
363 if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest;
364
365 try testFunction();358 try testFunction();
366 comptime try testFunction();359 comptime try testFunction();
367}360}
368361
369fn testFunction() !void {362fn testFunction() !void {
370 const fn_info = @typeInfo(@TypeOf(foo));363 const fn_info = @typeInfo(@TypeOf(typeInfoFoo));
371 try expect(fn_info == .Fn);364 try expect(fn_info == .Fn);
372 try expect(fn_info.Fn.alignment > 0);365 try expect(fn_info.Fn.alignment > 0);
373 try expect(fn_info.Fn.calling_convention == .C);366 try expect(fn_info.Fn.calling_convention == .C);
...@@ -375,16 +368,14 @@ fn testFunction() !void {...@@ -375,16 +368,14 @@ fn testFunction() !void {
375 try expect(fn_info.Fn.args.len == 2);368 try expect(fn_info.Fn.args.len == 2);
376 try expect(fn_info.Fn.is_var_args);369 try expect(fn_info.Fn.is_var_args);
377 try expect(fn_info.Fn.return_type.? == usize);370 try expect(fn_info.Fn.return_type.? == usize);
378 const fn_aligned_info = @typeInfo(@TypeOf(fooAligned));371 const fn_aligned_info = @typeInfo(@TypeOf(typeInfoFooAligned));
379 try expect(fn_aligned_info.Fn.alignment == 4);372 try expect(fn_aligned_info.Fn.alignment == 4);
380}373}
381374
382extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;375extern fn typeInfoFoo(a: usize, b: bool, ...) callconv(.C) usize;
383extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;376extern fn typeInfoFooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
384377
385test "type info: generic function types" {378test "type info: generic function types" {
386 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
387
388 if (builtin.zig_backend != .stage1) {379 if (builtin.zig_backend != .stage1) {
389 // stage1 marks all args/return types as null if the function380 // stage1 marks all args/return types as null if the function
390 // is generic at all. stage2 is more specific.381 // is generic at all. stage2 is more specific.
test/behavior/undefined.zig-1
...@@ -15,7 +15,6 @@ const static_array = initStaticArray();...@@ -15,7 +15,6 @@ const static_array = initStaticArray();
15test "init static array to undefined" {15test "init static array to undefined" {
16 // This test causes `initStaticArray()` to be codegen'd, and the16 // This test causes `initStaticArray()` to be codegen'd, and the
17 // C backend does not yet support returning arrays, so it fails17 // C backend does not yet support returning arrays, so it fails
18 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2120
test/behavior/union.zig-13
...@@ -431,7 +431,6 @@ const Foo1 = union(enum) {...@@ -431,7 +431,6 @@ const Foo1 = union(enum) {
431var glbl: Foo1 = undefined;431var glbl: Foo1 = undefined;
432432
433test "global union with single field is correctly initialized" {433test "global union with single field is correctly initialized" {
434 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
435 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;434 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
436 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;435 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
437 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;436 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -476,7 +475,6 @@ test "update the tag value for zero-sized unions" {...@@ -476,7 +475,6 @@ test "update the tag value for zero-sized unions" {
476}475}
477476
478test "union initializer generates padding only if needed" {477test "union initializer generates padding only if needed" {
479 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
480 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;478 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
481 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;479 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
482 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;480 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -753,7 +751,6 @@ fn Setter(comptime attr: Attribute) type {...@@ -753,7 +751,6 @@ fn Setter(comptime attr: Attribute) type {
753}751}
754752
755test "return union init with void payload" {753test "return union init with void payload" {
756 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
757 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;754 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
758 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;755 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
759 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;756 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
...@@ -779,7 +776,6 @@ test "return union init with void payload" {...@@ -779,7 +776,6 @@ test "return union init with void payload" {
779}776}
780777
781test "@unionInit stored to a const" {778test "@unionInit stored to a const" {
782 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
783 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO779 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
784 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO780 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
785 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO781 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -942,7 +938,6 @@ test "function call result coerces from tagged union to the tag" {...@@ -942,7 +938,6 @@ test "function call result coerces from tagged union to the tag" {
942}938}
943939
944test "cast from anonymous struct to union" {940test "cast from anonymous struct to union" {
945 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
946 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO941 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
947 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO942 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
948 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO943 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -975,7 +970,6 @@ test "cast from anonymous struct to union" {...@@ -975,7 +970,6 @@ test "cast from anonymous struct to union" {
975}970}
976971
977test "cast from pointer to anonymous struct to pointer to union" {972test "cast from pointer to anonymous struct to pointer to union" {
978 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
979 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO973 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
980 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO974 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
981 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO975 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1062,7 +1056,6 @@ test "containers with single-field enums" {...@@ -1062,7 +1056,6 @@ test "containers with single-field enums" {
1062}1056}
10631057
1064test "@unionInit on union with tag but no fields" {1058test "@unionInit on union with tag but no fields" {
1065 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1066 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1059 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1067 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1060 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1068 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1061 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -1138,7 +1131,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel...@@ -1138,7 +1131,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel
1138}1131}
11391132
1140test "union with no result loc initiated with a runtime value" {1133test "union with no result loc initiated with a runtime value" {
1141 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1134 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1144 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1136 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -1155,7 +1147,6 @@ test "union with no result loc initiated with a runtime value" {...@@ -1155,7 +1147,6 @@ test "union with no result loc initiated with a runtime value" {
1155}1147}
11561148
1157test "union with a large struct field" {1149test "union with a large struct field" {
1158 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1159 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1150 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1161 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1152 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -1189,7 +1180,6 @@ test "comptime equality of extern unions with same tag" {...@@ -1189,7 +1180,6 @@ test "comptime equality of extern unions with same tag" {
1189}1180}
11901181
1191test "union tag is set when initiated as a temporary value at runtime" {1182test "union tag is set when initiated as a temporary value at runtime" {
1192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1183 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1184 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11951185
...@@ -1325,7 +1315,6 @@ test "union and enum field order doesn't match" {...@@ -1325,7 +1315,6 @@ test "union and enum field order doesn't match" {
1325}1315}
13261316
1327test "@unionInit uses tag value instead of field index" {1317test "@unionInit uses tag value instead of field index" {
1328 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1329 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1318 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1330 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1319 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1331 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1320 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1353,7 +1342,6 @@ test "@unionInit uses tag value instead of field index" {...@@ -1353,7 +1342,6 @@ test "@unionInit uses tag value instead of field index" {
1353}1342}
13541343
1355test "union field ptr - zero sized payload" {1344test "union field ptr - zero sized payload" {
1356 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1357 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1345 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1358 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1346 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13591347
...@@ -1367,7 +1355,6 @@ test "union field ptr - zero sized payload" {...@@ -1367,7 +1355,6 @@ test "union field ptr - zero sized payload" {
1367}1355}
13681356
1369test "union field ptr - zero sized field" {1357test "union field ptr - zero sized field" {
1370 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1371 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1358 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1372 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1359 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13731360
test/behavior/union_with_members.zig-1
...@@ -19,7 +19,6 @@ const ET = union(enum) {...@@ -19,7 +19,6 @@ const ET = union(enum) {
19test "enum with members" {19test "enum with members" {
20 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO20 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO21 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2524
test/behavior/vector.zig-2
...@@ -811,7 +811,6 @@ test "vector reduce operation" {...@@ -811,7 +811,6 @@ test "vector reduce operation" {
811test "vector @reduce comptime" {811test "vector @reduce comptime" {
812 if (builtin.zig_backend == .stage1) return error.SkipZigTest;812 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
813 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO813 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
814 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
815 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO814 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
816 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO815 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
817 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO816 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1138,7 +1137,6 @@ test "array of vectors is copied" {...@@ -1138,7 +1137,6 @@ test "array of vectors is copied" {
11381137
1139test "byte vector initialized in inline function" {1138test "byte vector initialized in inline function" {
1140 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1139 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1141 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1140 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/widening.zig-4
...@@ -8,7 +8,6 @@ test "integer widening" {...@@ -8,7 +8,6 @@ test "integer widening" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1211
13 var a: u8 = 250;12 var a: u8 = 250;
14 var b: u16 = a;13 var b: u16 = a;
...@@ -30,7 +29,6 @@ test "integer widening u0 to u8" {...@@ -30,7 +29,6 @@ test "integer widening u0 to u8" {
30test "implicit unsigned integer to signed integer" {29test "implicit unsigned integer to signed integer" {
31 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO30 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO31 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
3432
35 var a: u8 = 250;33 var a: u8 = 250;
36 var b: i16 = a;34 var b: i16 = a;
...@@ -42,7 +40,6 @@ test "float widening" {...@@ -42,7 +40,6 @@ test "float widening" {
42 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO40 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
43 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO41 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
44 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO42 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
4643
47 var a: f16 = 12.34;44 var a: f16 = 12.34;
48 var b: f32 = a;45 var b: f32 = a;
...@@ -62,7 +59,6 @@ test "float widening f16 to f128" {...@@ -62,7 +59,6 @@ test "float widening f16 to f128" {
62 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
63 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
64 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO61 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
65 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
6662
67 // TODO https://github.com/ziglang/zig/issues/328263 // TODO https://github.com/ziglang/zig/issues/3282
68 if (builtin.cpu.arch == .aarch64) return error.SkipZigTest;64 if (builtin.cpu.arch == .aarch64) return error.SkipZigTest;
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=aarch64-macos3// target=aarch64-macos
4//4//
5// :109:9: error: root struct of file 'tmp' has no member named 'main'5// :108:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-linux3// target=x86_64-linux
4//4//
5// :109:9: error: root struct of file 'tmp' has no member named 'main'5// :108:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-macos3// target=x86_64-macos
4//4//
5// :109:9: error: root struct of file 'tmp' has no member named 'main'5// :108:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-windows/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-windows3// target=x86_64-windows
4//4//
5// :130:9: error: root struct of file 'tmp' has no member named 'main'5// :129:9: error: root struct of file 'tmp' has no member named 'main'
test/stage2/cbe.zig+11-11
...@@ -951,7 +951,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -951,7 +951,7 @@ pub fn addCases(ctx: *TestContext) !void {
951 ctx.h("simple header", linux_x64,951 ctx.h("simple header", linux_x64,
952 \\export fn start() void{}952 \\export fn start() void{}
953 ,953 ,
954 \\ZIG_EXTERN_C void start(void);954 \\zig_extern_c zig_void start(zig_void);
955 \\955 \\
956 );956 );
957 ctx.h("header with single param function", linux_x64,957 ctx.h("header with single param function", linux_x64,
...@@ -959,7 +959,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -959,7 +959,7 @@ pub fn addCases(ctx: *TestContext) !void {
959 \\ _ = a;959 \\ _ = a;
960 \\}960 \\}
961 ,961 ,
962 \\ZIG_EXTERN_C void start(uint8_t a0);962 \\zig_extern_c zig_void start(zig_u8 const a0);
963 \\963 \\
964 );964 );
965 ctx.h("header with multiple param function", linux_x64,965 ctx.h("header with multiple param function", linux_x64,
...@@ -967,25 +967,25 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -967,25 +967,25 @@ pub fn addCases(ctx: *TestContext) !void {
967 \\ _ = a; _ = b; _ = c;967 \\ _ = a; _ = b; _ = c;
968 \\}968 \\}
969 ,969 ,
970 \\ZIG_EXTERN_C void start(uint8_t a0, uint8_t a1, uint8_t a2);970 \\zig_extern_c zig_void start(zig_u8 const a0, zig_u8 const a1, zig_u8 const a2);
971 \\971 \\
972 );972 );
973 ctx.h("header with u32 param function", linux_x64,973 ctx.h("header with u32 param function", linux_x64,
974 \\export fn start(a: u32) void{ _ = a; }974 \\export fn start(a: u32) void{ _ = a; }
975 ,975 ,
976 \\ZIG_EXTERN_C void start(uint32_t a0);976 \\zig_extern_c zig_void start(zig_u32 const a0);
977 \\977 \\
978 );978 );
979 ctx.h("header with usize param function", linux_x64,979 ctx.h("header with usize param function", linux_x64,
980 \\export fn start(a: usize) void{ _ = a; }980 \\export fn start(a: usize) void{ _ = a; }
981 ,981 ,
982 \\ZIG_EXTERN_C void start(uintptr_t a0);982 \\zig_extern_c zig_void start(zig_usize const a0);
983 \\983 \\
984 );984 );
985 ctx.h("header with bool param function", linux_x64,985 ctx.h("header with bool param function", linux_x64,
986 \\export fn start(a: bool) void{_ = a;}986 \\export fn start(a: bool) void{_ = a;}
987 ,987 ,
988 \\ZIG_EXTERN_C void start(bool a0);988 \\zig_extern_c zig_void start(zig_bool const a0);
989 \\989 \\
990 );990 );
991 ctx.h("header with noreturn function", linux_x64,991 ctx.h("header with noreturn function", linux_x64,
...@@ -993,7 +993,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -993,7 +993,7 @@ pub fn addCases(ctx: *TestContext) !void {
993 \\ unreachable;993 \\ unreachable;
994 \\}994 \\}
995 ,995 ,
996 \\ZIG_EXTERN_C zig_noreturn void start(void);996 \\zig_extern_c zig_noreturn start(zig_void);
997 \\997 \\
998 );998 );
999 ctx.h("header with multiple functions", linux_x64,999 ctx.h("header with multiple functions", linux_x64,
...@@ -1001,15 +1001,15 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1001,15 +1001,15 @@ pub fn addCases(ctx: *TestContext) !void {
1001 \\export fn b() void{}1001 \\export fn b() void{}
1002 \\export fn c() void{}1002 \\export fn c() void{}
1003 ,1003 ,
1004 \\ZIG_EXTERN_C void a(void);1004 \\zig_extern_c zig_void a(zig_void);
1005 \\ZIG_EXTERN_C void b(void);1005 \\zig_extern_c zig_void b(zig_void);
1006 \\ZIG_EXTERN_C void c(void);1006 \\zig_extern_c zig_void c(zig_void);
1007 \\1007 \\
1008 );1008 );
1009 ctx.h("header with multiple includes", linux_x64,1009 ctx.h("header with multiple includes", linux_x64,
1010 \\export fn start(a: u32, b: usize) void{ _ = a; _ = b; }1010 \\export fn start(a: u32, b: usize) void{ _ = a; _ = b; }
1011 ,1011 ,
1012 \\ZIG_EXTERN_C void start(uint32_t a0, uintptr_t a1);1012 \\zig_extern_c zig_void start(zig_u32 const a0, zig_usize const a1);
1013 \\1013 \\
1014 );1014 );
1015}1015}