aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-11-03 13:43:10 +0200
committerGitHub <noreply@github.com>2022-11-03 13:43:10 +0200
commitb2f8c1f2ef0ab1a9577198f78393a1208b8027fa (patch)
tree95e2d98faff34c8e76a22bb5df17a2518e5ea9ec /src/codegen
parentb40fc70188fd097e9e05b5c18b635b67b718380e (diff)
parentf02b8a9cca4bf991146dab44ef8707b987ce7a1d (diff)
downloadzig-b2f8c1f2ef0ab1a9577198f78393a1208b8027fa.tar.gz
zig-b2f8c1f2ef0ab1a9577198f78393a1208b8027fa.zip
Merge pull request #13420 from jacobly0/c-backend
cbe: enough fixes to bootstrap a compiler with a working c backend
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 0f82ed79f1..e9dcbd8435 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);
@@ -2215,7 +2219,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 +2256,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 +2273,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 +2321,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");
}
@@ -2432,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),
@@ -3701,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");
@@ -3719,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;
}
@@ -5307,7 +5319,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);
@@ -5316,6 +5327,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).?;