From fa46f9a3d75e6f3693827bf524244ed3c4902133 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 2 Nov 2022 21:15:24 -0400 Subject: cbe: fix extern --- src/codegen/c.zig | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 0f82ed79f1..e1c7b80c04 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2215,7 +2215,7 @@ pub fn genFunc(f: *Function) !void { const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl); const fwd_decl_writer = o.dg.fwd_decl.writer(); - try fwd_decl_writer.writeAll(if (is_global) "zig_extern_c " else "static "); + try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); try fwd_decl_writer.writeAll(";\n"); @@ -2252,9 +2252,10 @@ pub fn genDecl(o: *Object) !void { .ty = o.dg.decl.ty, .val = o.dg.decl.val, }; + if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime()) return; if (tv.val.tag() == .extern_fn) { const fwd_decl_writer = o.dg.fwd_decl.writer(); - try fwd_decl_writer.writeAll("zig_extern_c "); + try fwd_decl_writer.writeAll("zig_extern "); try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); try fwd_decl_writer.writeAll(";\n"); } else if (tv.val.castTag(.variable)) |var_payload| { @@ -2268,22 +2269,19 @@ pub fn genDecl(o: *Object) !void { .decl = o.dg.decl_index, }; - if (is_global) try fwd_decl_writer.writeAll("zig_extern_c "); + try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); try fwd_decl_writer.writeAll(";\n"); - if (variable.is_extern or variable.init.isUndefDeep()) { - return; - } + if (variable.is_extern) return; const w = o.writer(); + if (!is_global) try w.writeAll("static "); if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); try w.writeAll(" = "); - if (variable.init.tag() != .unreachable_value) { - try o.dg.renderValue(w, tv.ty, variable.init, .Initializer); - } + try o.dg.renderValue(w, tv.ty, variable.init, .Initializer); try w.writeByte(';'); try o.indent_writer.insertNewline(); } else { @@ -2319,7 +2317,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { .Fn => { const is_global = dg.declIsGlobal(tv); if (is_global) { - try writer.writeAll("zig_extern_c "); + try writer.writeAll("zig_extern "); try dg.renderFunctionSignature(writer, .Complete); try dg.fwd_decl.appendSlice(";\n"); } -- cgit v1.2.3 From 4537c1b8b6575c853ceaa7ab329e8b84d946249d Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 2 Nov 2022 21:16:06 -0400 Subject: cbe: fix crash rendering union with zero-bit tag --- src/codegen/c.zig | 14 +++++++++----- test/behavior/union.zig | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index e1c7b80c04..4473f680c4 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -704,9 +704,13 @@ pub const DeclGen = struct { try writer.writeByte('{'); if (ty.unionTagTypeSafety()) |tag_ty| { - try writer.writeAll(" .tag = "); - try dg.renderValue(writer, tag_ty, val, .Initializer); - try writer.writeAll(", .payload = {"); + const layout = ty.unionGetLayout(target); + if (layout.tag_size != 0) { + try writer.writeAll(" .tag = "); + try dg.renderValue(writer, tag_ty, val, .Initializer); + try writer.writeByte(','); + } + try writer.writeAll(" .payload = {"); } for (ty.unionFields().values()) |field| { if (!field.ty.hasRuntimeBits()) continue; @@ -1115,7 +1119,6 @@ pub const DeclGen = struct { }, .Union => { const union_obj = val.castTag(.@"union").?.data; - const layout = ty.unionGetLayout(target); if (location != .Initializer) { try writer.writeByte('('); @@ -1125,6 +1128,7 @@ pub const DeclGen = struct { try writer.writeByte('{'); if (ty.unionTagTypeSafety()) |tag_ty| { + const layout = ty.unionGetLayout(target); if (layout.tag_size != 0) { try writer.writeAll(".tag = "); try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer); @@ -5305,7 +5309,6 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data; const union_ty = f.air.typeOfIndex(inst); const target = f.object.dg.module.getTarget(); - const layout = union_ty.unionGetLayout(target); const union_obj = union_ty.cast(Type.Payload.Union).?.data; const field_name = union_obj.fields.keys()[extra.field_index]; const payload = try f.resolveInst(extra.init); @@ -5314,6 +5317,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { const local = try f.allocLocal(union_ty, .Const); try writer.writeAll(" = {"); if (union_ty.unionTagTypeSafety()) |tag_ty| { + const layout = union_ty.unionGetLayout(target); if (layout.tag_size != 0) { const field_index = tag_ty.enumFieldIndex(field_name).?; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 300794b186..2540d780a6 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -435,7 +435,6 @@ test "global union with single field is correctly initialized" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO glbl = Foo1{ .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 }, -- cgit v1.2.3 From 085f6fd8f729423158b6f7a5f8e6f50f78fef18f Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 2 Nov 2022 22:57:10 -0400 Subject: cbe: use wrapping for left shifts --- lib/include/zig.h | 35 ++++++++++++++++++----------------- src/codegen/c.zig | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) (limited to 'src/codegen') diff --git a/lib/include/zig.h b/lib/include/zig.h index 03e462df56..c6df066162 100644 --- a/lib/include/zig.h +++ b/lib/include/zig.h @@ -279,24 +279,21 @@ zig_extern void *memset (void *, int, zig_usize); static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \ return lhs operator rhs; \ } -#define zig_int_operators(w) \ - zig_int_operator(u##w, u##w, and, &) \ - zig_int_operator(i##w, i##w, and, &) \ - zig_int_operator(u##w, u##w, or, |) \ - zig_int_operator(i##w, i##w, or, |) \ - zig_int_operator(u##w, u##w, xor, ^) \ - zig_int_operator(i##w, i##w, xor, ^) \ - zig_int_operator(u##w, u8, shl, <<) \ - zig_int_operator(i##w, u8, shl, <<) \ - zig_int_operator(u##w, u8, shr, >>) \ - zig_int_operator(u##w, u##w, div_floor, /) \ - zig_int_operator(u##w, u##w, mod, %) -zig_int_operators(8) -zig_int_operators(16) -zig_int_operators(32) -zig_int_operators(64) - +#define zig_int_basic_operator(Type, operation, operator) \ + zig_int_operator(Type, Type, operation, operator) +#define zig_int_shift_operator(Type, operation, operator) \ + zig_int_operator(Type, u8, operation, operator) #define zig_int_helpers(w) \ + zig_int_basic_operator(u##w, and, &) \ + zig_int_basic_operator(i##w, and, &) \ + zig_int_basic_operator(u##w, or, |) \ + zig_int_basic_operator(i##w, or, |) \ + zig_int_basic_operator(u##w, xor, ^) \ + zig_int_basic_operator(i##w, xor, ^) \ + zig_int_shift_operator(u##w, shl, <<) \ + zig_int_shift_operator(i##w, shl, <<) \ + zig_int_shift_operator(u##w, shr, >>) \ +\ static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \ zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \ return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ @@ -319,10 +316,14 @@ zig_int_operators(64) return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \ ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \ } \ +\ + zig_int_basic_operator(u##w, div_floor, /) \ \ static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \ return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \ } \ +\ + zig_int_basic_operator(u##w, mod, %) \ \ static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \ zig_i##w rem = lhs % rhs; \ diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 4473f680c4..980dfb5ff2 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2434,7 +2434,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None), .xor => try airBinOp(f, inst, "^", "xor", .None), .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None), - .shl, => try airBinBuiltinCall(f, inst, "shl", .None), + .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits), .shl_exact => try airBinOp(f, inst, "<<", "shl", .None), .not => try airNot (f, inst), -- cgit v1.2.3 From f02b8a9cca4bf991146dab44ef8707b987ce7a1d Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 2 Nov 2022 22:58:55 -0400 Subject: cbe: fix padding bits after a bitcast --- src/codegen/c.zig | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 980dfb5ff2..e9dcbd8435 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -3703,7 +3703,6 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { const local = try f.allocLocal(inst_ty, .Const); try writer.writeAll(" = ("); try f.renderTypecast(writer, inst_ty); - try writer.writeByte(')'); try f.writeCValue(writer, operand, .Other); try writer.writeAll(";\n"); @@ -3721,6 +3720,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { try f.renderTypecast(writer, inst_ty); try writer.writeAll("));\n"); + // Ensure padding bits have the expected value. + if (inst_ty.isAbiInt()) { + try f.writeCValue(writer, local, .Other); + try writer.writeAll(" = zig_wrap_"); + try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); + try writer.writeByte('('); + try f.writeCValue(writer, local, .Other); + try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); + try writer.writeAll(");\n"); + } + return local; } -- cgit v1.2.3