authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-03 13:43:10+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 13:45:06-07:00
loga7b8d011a3e3ae01765541439df7a67891f3b7b4
tree39c6c9f3a004a7f4cfa7b5f0fc79cd732faa5707
parentee8af8cffb42603ead90db6a3d7b7df9f2b2a683

Merge pull request #13420 from jacobly0/c-backend

cbe: enough fixes to bootstrap a compiler with a working c backend

3 files changed, 92 insertions(+), 79 deletions(-)

lib/include/zig.h+52-51
...@@ -66,9 +66,9 @@...@@ -66,9 +66,9 @@
66#endif66#endif
6767
68#if defined(__cplusplus)68#if defined(__cplusplus)
69#define zig_extern_c extern "C"69#define zig_extern extern "C"
70#else70#else
71#define zig_extern_c71#define zig_extern extern
72#endif72#endif
7373
74#if zig_has_builtin(debugtrap)74#if zig_has_builtin(debugtrap)
...@@ -265,8 +265,8 @@ typedef int64_t zig_i64;...@@ -265,8 +265,8 @@ typedef int64_t zig_i64;
265#define zig_compiler_rt_abbrev_f80 xf265#define zig_compiler_rt_abbrev_f80 xf
266#define zig_compiler_rt_abbrev_f128 tf266#define zig_compiler_rt_abbrev_f128 tf
267267
268zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);268zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);
269zig_extern_c void *memset (void *, int, zig_usize);269zig_extern void *memset (void *, int, zig_usize);
270270
271/* ==================== 8/16/32/64-bit Integer Routines ===================== */271/* ==================== 8/16/32/64-bit Integer Routines ===================== */
272272
...@@ -279,24 +279,21 @@ zig_extern_c void *memset (void *, int, zig_usize);...@@ -279,24 +279,21 @@ zig_extern_c void *memset (void *, int, zig_usize);
279 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \279 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \
280 return lhs operator rhs; \280 return lhs operator rhs; \
281 }281 }
282#define zig_int_operators(w) \282#define zig_int_basic_operator(Type, operation, operator) \
283 zig_int_operator(u##w, u##w, and, &) \283 zig_int_operator(Type, Type, operation, operator)
284 zig_int_operator(i##w, i##w, and, &) \284#define zig_int_shift_operator(Type, operation, operator) \
285 zig_int_operator(u##w, u##w, or, |) \285 zig_int_operator(Type, u8, operation, operator)
286 zig_int_operator(i##w, i##w, or, |) \
287 zig_int_operator(u##w, u##w, xor, ^) \
288 zig_int_operator(i##w, i##w, xor, ^) \
289 zig_int_operator(u##w, u8, shl, <<) \
290 zig_int_operator(i##w, u8, shl, <<) \
291 zig_int_operator(u##w, u8, shr, >>) \
292 zig_int_operator(u##w, u##w, div_floor, /) \
293 zig_int_operator(u##w, u##w, mod, %)
294zig_int_operators(8)
295zig_int_operators(16)
296zig_int_operators(32)
297zig_int_operators(64)
298
299#define zig_int_helpers(w) \286#define zig_int_helpers(w) \
287 zig_int_basic_operator(u##w, and, &) \
288 zig_int_basic_operator(i##w, and, &) \
289 zig_int_basic_operator(u##w, or, |) \
290 zig_int_basic_operator(i##w, or, |) \
291 zig_int_basic_operator(u##w, xor, ^) \
292 zig_int_basic_operator(i##w, xor, ^) \
293 zig_int_shift_operator(u##w, shl, <<) \
294 zig_int_shift_operator(i##w, shl, <<) \
295 zig_int_shift_operator(u##w, shr, >>) \
296\
300 static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \297 static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \
301 zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \298 zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \
302 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \299 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
...@@ -319,10 +316,14 @@ zig_int_operators(64)...@@ -319,10 +316,14 @@ zig_int_operators(64)
319 return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \316 return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \
320 ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \317 ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \
321 } \318 } \
319\
320 zig_int_basic_operator(u##w, div_floor, /) \
322\321\
323 static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \322 static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \
324 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \323 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \
325 } \324 } \
325\
326 zig_int_basic_operator(u##w, mod, %) \
326\327\
327 static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \328 static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \
328 zig_i##w rem = lhs % rhs; \329 zig_i##w rem = lhs % rhs; \
...@@ -345,7 +346,7 @@ static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -345,7 +346,7 @@ static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
345#endif346#endif
346}347}
347348
348zig_extern_c zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);349zig_extern zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
349static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {350static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
350#if zig_has_builtin(add_overflow)351#if zig_has_builtin(add_overflow)
351 zig_i32 full_res;352 zig_i32 full_res;
...@@ -371,7 +372,7 @@ static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -371,7 +372,7 @@ static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
371#endif372#endif
372}373}
373374
374zig_extern_c zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);375zig_extern zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
375static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {376static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
376#if zig_has_builtin(add_overflow)377#if zig_has_builtin(add_overflow)
377 zig_i64 full_res;378 zig_i64 full_res;
...@@ -441,7 +442,7 @@ static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -441,7 +442,7 @@ static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
441#endif442#endif
442}443}
443444
444zig_extern_c zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);445zig_extern zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
445static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {446static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
446#if zig_has_builtin(sub_overflow)447#if zig_has_builtin(sub_overflow)
447 zig_i32 full_res;448 zig_i32 full_res;
...@@ -467,7 +468,7 @@ static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -467,7 +468,7 @@ static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
467#endif468#endif
468}469}
469470
470zig_extern_c zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);471zig_extern zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
471static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {472static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
472#if zig_has_builtin(sub_overflow)473#if zig_has_builtin(sub_overflow)
473 zig_i64 full_res;474 zig_i64 full_res;
...@@ -537,7 +538,7 @@ static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -537,7 +538,7 @@ static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
537#endif538#endif
538}539}
539540
540zig_extern_c zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);541zig_extern zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
541static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {542static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
542#if zig_has_builtin(mul_overflow)543#if zig_has_builtin(mul_overflow)
543 zig_i32 full_res;544 zig_i32 full_res;
...@@ -563,7 +564,7 @@ static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -563,7 +564,7 @@ static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
563#endif564#endif
564}565}
565566
566zig_extern_c zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);567zig_extern zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
567static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {568static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
568#if zig_has_builtin(mul_overflow)569#if zig_has_builtin(mul_overflow)
569 zig_i64 full_res;570 zig_i64 full_res;
...@@ -1210,7 +1211,7 @@ static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,...@@ -1210,7 +1211,7 @@ static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
1210#endif1211#endif
1211}1212}
12121213
1213zig_extern_c zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);1214zig_extern zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1214static inline zig_bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {1215static inline zig_bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1215#if zig_has_builtin(add_overflow)1216#if zig_has_builtin(add_overflow)
1216 zig_i128 full_res;1217 zig_i128 full_res;
...@@ -1236,7 +1237,7 @@ static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,...@@ -1236,7 +1237,7 @@ static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
1236#endif1237#endif
1237}1238}
12381239
1239zig_extern_c zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);1240zig_extern zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1240static inline zig_bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {1241static inline zig_bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1241#if zig_has_builtin(sub_overflow)1242#if zig_has_builtin(sub_overflow)
1242 zig_i128 full_res;1243 zig_i128 full_res;
...@@ -1262,7 +1263,7 @@ static inline zig_bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,...@@ -1262,7 +1263,7 @@ static inline zig_bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
1262#endif1263#endif
1263}1264}
12641265
1265zig_extern_c zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);1266zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1266static inline zig_bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {1267static inline zig_bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1267#if zig_has_builtin(mul_overflow)1268#if zig_has_builtin(mul_overflow)
1268 zig_i128 full_res;1269 zig_i128 full_res;
...@@ -1552,7 +1553,7 @@ typedef long double zig_c_longdouble;...@@ -1552,7 +1553,7 @@ typedef long double zig_c_longdouble;
1552#define zig_as_special_c_longdouble(sign, name, arg, repr) sign __builtin_##name##l(arg)1553#define zig_as_special_c_longdouble(sign, name, arg, repr) sign __builtin_##name##l(arg)
15531554
1554#define zig_convert_builtin(ResType, operation, ArgType, version) \1555#define zig_convert_builtin(ResType, operation, ArgType, version) \
1555 zig_extern_c zig_##ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \1556 zig_extern zig_##ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
1556 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(zig_##ArgType);1557 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(zig_##ArgType);
1557zig_convert_builtin(f16, trunc, f32, 2)1558zig_convert_builtin(f16, trunc, f32, 2)
1558zig_convert_builtin(f16, trunc, f64, 2)1559zig_convert_builtin(f16, trunc, f64, 2)
...@@ -1585,7 +1586,7 @@ zig_convert_builtin(f128, extend, f80, 2)...@@ -1585,7 +1586,7 @@ zig_convert_builtin(f128, extend, f80, 2)
1585 }1586 }
15861587
1587#define zig_float_less_builtin_0(Type, operation) \1588#define zig_float_less_builtin_0(Type, operation) \
1588 zig_extern_c zig_i8 zig_expand_concat(zig_expand_concat(__##operation, \1589 zig_extern zig_i8 zig_expand_concat(zig_expand_concat(__##operation, \
1589 zig_compiler_rt_abbrev_##Type), 2)(zig_##Type, zig_##Type); \1590 zig_compiler_rt_abbrev_##Type), 2)(zig_##Type, zig_##Type); \
1590 static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \1591 static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
1591 return (zig_i8)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 2)(lhs, rhs); \1592 return (zig_i8)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 2)(lhs, rhs); \
...@@ -1603,7 +1604,7 @@ zig_convert_builtin(f128, extend, f80, 2)...@@ -1603,7 +1604,7 @@ zig_convert_builtin(f128, extend, f80, 2)
1603 }1604 }
16041605
1605#define zig_float_binary_builtin_0(Type, operation, operator) \1606#define zig_float_binary_builtin_0(Type, operation, operator) \
1606 zig_extern_c zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \1607 zig_extern zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \
1607 zig_compiler_rt_abbrev_##Type), 3)(zig_##Type, zig_##Type); \1608 zig_compiler_rt_abbrev_##Type), 3)(zig_##Type, zig_##Type); \
1608 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \1609 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
1609 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 3)(lhs, rhs); \1610 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 3)(lhs, rhs); \
...@@ -1638,24 +1639,24 @@ zig_convert_builtin(f128, extend, f80, 2)...@@ -1638,24 +1639,24 @@ zig_convert_builtin(f128, extend, f80, 2)
1638 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, sub, -) \1639 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, sub, -) \
1639 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, mul, *) \1640 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, mul, *) \
1640 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, div, /) \1641 zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, div, /) \
1641 zig_extern_c zig_##Type zig_libc_name_##Type(sqrt)(zig_##Type); \1642 zig_extern zig_##Type zig_libc_name_##Type(sqrt)(zig_##Type); \
1642 zig_extern_c zig_##Type zig_libc_name_##Type(sin)(zig_##Type); \1643 zig_extern zig_##Type zig_libc_name_##Type(sin)(zig_##Type); \
1643 zig_extern_c zig_##Type zig_libc_name_##Type(cos)(zig_##Type); \1644 zig_extern zig_##Type zig_libc_name_##Type(cos)(zig_##Type); \
1644 zig_extern_c zig_##Type zig_libc_name_##Type(tan)(zig_##Type); \1645 zig_extern zig_##Type zig_libc_name_##Type(tan)(zig_##Type); \
1645 zig_extern_c zig_##Type zig_libc_name_##Type(exp)(zig_##Type); \1646 zig_extern zig_##Type zig_libc_name_##Type(exp)(zig_##Type); \
1646 zig_extern_c zig_##Type zig_libc_name_##Type(exp2)(zig_##Type); \1647 zig_extern zig_##Type zig_libc_name_##Type(exp2)(zig_##Type); \
1647 zig_extern_c zig_##Type zig_libc_name_##Type(log)(zig_##Type); \1648 zig_extern zig_##Type zig_libc_name_##Type(log)(zig_##Type); \
1648 zig_extern_c zig_##Type zig_libc_name_##Type(log2)(zig_##Type); \1649 zig_extern zig_##Type zig_libc_name_##Type(log2)(zig_##Type); \
1649 zig_extern_c zig_##Type zig_libc_name_##Type(log10)(zig_##Type); \1650 zig_extern zig_##Type zig_libc_name_##Type(log10)(zig_##Type); \
1650 zig_extern_c zig_##Type zig_libc_name_##Type(fabs)(zig_##Type); \1651 zig_extern zig_##Type zig_libc_name_##Type(fabs)(zig_##Type); \
1651 zig_extern_c zig_##Type zig_libc_name_##Type(floor)(zig_##Type); \1652 zig_extern zig_##Type zig_libc_name_##Type(floor)(zig_##Type); \
1652 zig_extern_c zig_##Type zig_libc_name_##Type(ceil)(zig_##Type); \1653 zig_extern zig_##Type zig_libc_name_##Type(ceil)(zig_##Type); \
1653 zig_extern_c zig_##Type zig_libc_name_##Type(round)(zig_##Type); \1654 zig_extern zig_##Type zig_libc_name_##Type(round)(zig_##Type); \
1654 zig_extern_c zig_##Type zig_libc_name_##Type(trunc)(zig_##Type); \1655 zig_extern zig_##Type zig_libc_name_##Type(trunc)(zig_##Type); \
1655 zig_extern_c zig_##Type zig_libc_name_##Type(fmod)(zig_##Type, zig_##Type); \1656 zig_extern zig_##Type zig_libc_name_##Type(fmod)(zig_##Type, zig_##Type); \
1656 zig_extern_c zig_##Type zig_libc_name_##Type(fmin)(zig_##Type, zig_##Type); \1657 zig_extern zig_##Type zig_libc_name_##Type(fmin)(zig_##Type, zig_##Type); \
1657 zig_extern_c zig_##Type zig_libc_name_##Type(fmax)(zig_##Type, zig_##Type); \1658 zig_extern zig_##Type zig_libc_name_##Type(fmax)(zig_##Type, zig_##Type); \
1658 zig_extern_c zig_##Type zig_libc_name_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \1659 zig_extern zig_##Type zig_libc_name_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \
1659\1660\
1660 static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \1661 static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \
1661 return zig_libc_name_##Type(trunc)(zig_div_##Type(lhs, rhs)); \1662 return zig_libc_name_##Type(trunc)(zig_div_##Type(lhs, rhs)); \
src/codegen/c.zig+29-17
...@@ -704,9 +704,13 @@ pub const DeclGen = struct {...@@ -704,9 +704,13 @@ pub const DeclGen = struct {
704704
705 try writer.writeByte('{');705 try writer.writeByte('{');
706 if (ty.unionTagTypeSafety()) |tag_ty| {706 if (ty.unionTagTypeSafety()) |tag_ty| {
707 try writer.writeAll(" .tag = ");707 const layout = ty.unionGetLayout(target);
708 try dg.renderValue(writer, tag_ty, val, .Initializer);708 if (layout.tag_size != 0) {
709 try writer.writeAll(", .payload = {");709 try writer.writeAll(" .tag = ");
710 try dg.renderValue(writer, tag_ty, val, .Initializer);
711 try writer.writeByte(',');
712 }
713 try writer.writeAll(" .payload = {");
710 }714 }
711 for (ty.unionFields().values()) |field| {715 for (ty.unionFields().values()) |field| {
712 if (!field.ty.hasRuntimeBits()) continue;716 if (!field.ty.hasRuntimeBits()) continue;
...@@ -1115,7 +1119,6 @@ pub const DeclGen = struct {...@@ -1115,7 +1119,6 @@ pub const DeclGen = struct {
1115 },1119 },
1116 .Union => {1120 .Union => {
1117 const union_obj = val.castTag(.@"union").?.data;1121 const union_obj = val.castTag(.@"union").?.data;
1118 const layout = ty.unionGetLayout(target);
11191122
1120 if (location != .Initializer) {1123 if (location != .Initializer) {
1121 try writer.writeByte('(');1124 try writer.writeByte('(');
...@@ -1125,6 +1128,7 @@ pub const DeclGen = struct {...@@ -1125,6 +1128,7 @@ pub const DeclGen = struct {
11251128
1126 try writer.writeByte('{');1129 try writer.writeByte('{');
1127 if (ty.unionTagTypeSafety()) |tag_ty| {1130 if (ty.unionTagTypeSafety()) |tag_ty| {
1131 const layout = ty.unionGetLayout(target);
1128 if (layout.tag_size != 0) {1132 if (layout.tag_size != 0) {
1129 try writer.writeAll(".tag = ");1133 try writer.writeAll(".tag = ");
1130 try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer);1134 try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer);
...@@ -2215,7 +2219,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2215,7 +2219,7 @@ pub fn genFunc(f: *Function) !void {
22152219
2216 const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl);2220 const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl);
2217 const fwd_decl_writer = o.dg.fwd_decl.writer();2221 const fwd_decl_writer = o.dg.fwd_decl.writer();
2218 try fwd_decl_writer.writeAll(if (is_global) "zig_extern_c " else "static ");2222 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2219 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);2223 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
2220 try fwd_decl_writer.writeAll(";\n");2224 try fwd_decl_writer.writeAll(";\n");
22212225
...@@ -2252,9 +2256,10 @@ pub fn genDecl(o: *Object) !void {...@@ -2252,9 +2256,10 @@ pub fn genDecl(o: *Object) !void {
2252 .ty = o.dg.decl.ty,2256 .ty = o.dg.decl.ty,
2253 .val = o.dg.decl.val,2257 .val = o.dg.decl.val,
2254 };2258 };
2259 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime()) return;
2255 if (tv.val.tag() == .extern_fn) {2260 if (tv.val.tag() == .extern_fn) {
2256 const fwd_decl_writer = o.dg.fwd_decl.writer();2261 const fwd_decl_writer = o.dg.fwd_decl.writer();
2257 try fwd_decl_writer.writeAll("zig_extern_c ");2262 try fwd_decl_writer.writeAll("zig_extern ");
2258 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);2263 try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
2259 try fwd_decl_writer.writeAll(";\n");2264 try fwd_decl_writer.writeAll(";\n");
2260 } else if (tv.val.castTag(.variable)) |var_payload| {2265 } else if (tv.val.castTag(.variable)) |var_payload| {
...@@ -2268,22 +2273,19 @@ pub fn genDecl(o: *Object) !void {...@@ -2268,22 +2273,19 @@ pub fn genDecl(o: *Object) !void {
2268 .decl = o.dg.decl_index,2273 .decl = o.dg.decl_index,
2269 };2274 };
22702275
2271 if (is_global) try fwd_decl_writer.writeAll("zig_extern_c ");2276 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2272 if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal ");2277 if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal ");
2273 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);2278 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
2274 try fwd_decl_writer.writeAll(";\n");2279 try fwd_decl_writer.writeAll(";\n");
22752280
2276 if (variable.is_extern or variable.init.isUndefDeep()) {2281 if (variable.is_extern) return;
2277 return;
2278 }
22792282
2280 const w = o.writer();2283 const w = o.writer();
2284 if (!is_global) try w.writeAll("static ");
2281 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");2285 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
2282 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);2286 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
2283 try w.writeAll(" = ");2287 try w.writeAll(" = ");
2284 if (variable.init.tag() != .unreachable_value) {2288 try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
2285 try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
2286 }
2287 try w.writeByte(';');2289 try w.writeByte(';');
2288 try o.indent_writer.insertNewline();2290 try o.indent_writer.insertNewline();
2289 } else {2291 } else {
...@@ -2319,7 +2321,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -2319,7 +2321,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
2319 .Fn => {2321 .Fn => {
2320 const is_global = dg.declIsGlobal(tv);2322 const is_global = dg.declIsGlobal(tv);
2321 if (is_global) {2323 if (is_global) {
2322 try writer.writeAll("zig_extern_c ");2324 try writer.writeAll("zig_extern ");
2323 try dg.renderFunctionSignature(writer, .Complete);2325 try dg.renderFunctionSignature(writer, .Complete);
2324 try dg.fwd_decl.appendSlice(";\n");2326 try dg.fwd_decl.appendSlice(";\n");
2325 }2327 }
...@@ -2432,7 +2434,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2432,7 +2434,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2432 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),2434 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),
2433 .xor => try airBinOp(f, inst, "^", "xor", .None),2435 .xor => try airBinOp(f, inst, "^", "xor", .None),
2434 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),2436 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),
2435 .shl, => try airBinBuiltinCall(f, inst, "shl", .None),2437 .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits),
2436 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),2438 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),
2437 .not => try airNot (f, inst),2439 .not => try airNot (f, inst),
24382440
...@@ -3701,7 +3703,6 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3701,7 +3703,6 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3701 const local = try f.allocLocal(inst_ty, .Const);3703 const local = try f.allocLocal(inst_ty, .Const);
3702 try writer.writeAll(" = (");3704 try writer.writeAll(" = (");
3703 try f.renderTypecast(writer, inst_ty);3705 try f.renderTypecast(writer, inst_ty);
3704
3705 try writer.writeByte(')');3706 try writer.writeByte(')');
3706 try f.writeCValue(writer, operand, .Other);3707 try f.writeCValue(writer, operand, .Other);
3707 try writer.writeAll(";\n");3708 try writer.writeAll(";\n");
...@@ -3719,6 +3720,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3719,6 +3720,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3719 try f.renderTypecast(writer, inst_ty);3720 try f.renderTypecast(writer, inst_ty);
3720 try writer.writeAll("));\n");3721 try writer.writeAll("));\n");
37213722
3723 // Ensure padding bits have the expected value.
3724 if (inst_ty.isAbiInt()) {
3725 try f.writeCValue(writer, local, .Other);
3726 try writer.writeAll(" = zig_wrap_");
3727 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
3728 try writer.writeByte('(');
3729 try f.writeCValue(writer, local, .Other);
3730 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);
3731 try writer.writeAll(");\n");
3732 }
3733
3722 return local;3734 return local;
3723}3735}
37243736
...@@ -5307,7 +5319,6 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5307,7 +5319,6 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
5307 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;5319 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
5308 const union_ty = f.air.typeOfIndex(inst);5320 const union_ty = f.air.typeOfIndex(inst);
5309 const target = f.object.dg.module.getTarget();5321 const target = f.object.dg.module.getTarget();
5310 const layout = union_ty.unionGetLayout(target);
5311 const union_obj = union_ty.cast(Type.Payload.Union).?.data;5322 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
5312 const field_name = union_obj.fields.keys()[extra.field_index];5323 const field_name = union_obj.fields.keys()[extra.field_index];
5313 const payload = try f.resolveInst(extra.init);5324 const payload = try f.resolveInst(extra.init);
...@@ -5316,6 +5327,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5316,6 +5327,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
5316 const local = try f.allocLocal(union_ty, .Const);5327 const local = try f.allocLocal(union_ty, .Const);
5317 try writer.writeAll(" = {");5328 try writer.writeAll(" = {");
5318 if (union_ty.unionTagTypeSafety()) |tag_ty| {5329 if (union_ty.unionTagTypeSafety()) |tag_ty| {
5330 const layout = union_ty.unionGetLayout(target);
5319 if (layout.tag_size != 0) {5331 if (layout.tag_size != 0) {
5320 const field_index = tag_ty.enumFieldIndex(field_name).?;5332 const field_index = tag_ty.enumFieldIndex(field_name).?;
53215333
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 zig_void start(zig_void);954 \\zig_extern 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 zig_void start(zig_u8 const a0);962 \\zig_extern 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 zig_void start(zig_u8 const a0, zig_u8 const a1, zig_u8 const a2);970 \\zig_extern 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 zig_void start(zig_u32 const a0);976 \\zig_extern 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 zig_void start(zig_usize const a0);982 \\zig_extern 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 zig_void start(zig_bool const a0);988 \\zig_extern 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 start(zig_void);996 \\zig_extern 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 zig_void a(zig_void);1004 \\zig_extern zig_void a(zig_void);
1005 \\zig_extern_c zig_void b(zig_void);1005 \\zig_extern zig_void b(zig_void);
1006 \\zig_extern_c zig_void c(zig_void);1006 \\zig_extern 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 zig_void start(zig_u32 const a0, zig_usize const a1);1012 \\zig_extern zig_void start(zig_u32 const a0, zig_usize const a1);
1013 \\1013 \\
1014 );1014 );
1015}1015}