authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-02-16 11:02:59-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-02-16 12:19:54-07:00
logc4baa6696e3580455438c756a023cafe645b91b5
tree305983c03aa5d6827bdfb636bc1fed6c1b51392e
parent1a84c23d69c7e26ba1916c1f9f0e6002ff40d116

cbe: Add `writeCValueDeref` and small re-factor


1 files changed, 74 insertions(+), 66 deletions(-)

src/codegen/c.zig+74-66
......@@ -291,6 +291,19 @@ pub const Function = struct {
291291 }
292292 }
293293
294 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {
295 switch (c_value) {
296 .constant => |inst| {
297 const ty = f.air.typeOf(inst);
298 const val = f.air.value(inst).?;
299 try w.writeAll("(*");
300 try f.object.dg.renderValue(w, ty, val);
301 return w.writeByte(')');
302 },
303 else => return f.object.dg.writeCValueDeref(w, c_value),
304 }
305 }
306
294307 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
295308 return f.object.dg.fail(format, args);
296309 }
......@@ -1259,6 +1272,28 @@ pub const DeclGen = struct {
12591272 }
12601273 }
12611274
1275 fn writeCValueDeref(dg: DeclGen, w: anytype, c_value: CValue) !void {
1276 switch (c_value) {
1277 .none => unreachable,
1278 .local => |i| return w.print("(*t{d})", .{i}),
1279 .local_ref => |i| return w.print("t{d}", .{i}),
1280 .constant => unreachable,
1281 .arg => |i| return w.print("(*a{d})", .{i}),
1282 .decl => |decl| {
1283 try w.writeAll("(*");
1284 try dg.renderDeclName(decl, w);
1285 return w.writeByte(')');
1286 },
1287 .decl_ref => |decl| return dg.renderDeclName(decl, w),
1288 .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}),
1289 .bytes => |bytes| {
1290 try w.writeAll("(*");
1291 try w.writeAll(bytes);
1292 return w.writeByte(')');
1293 },
1294 }
1295 }
1296
12621297 fn renderDeclName(dg: DeclGen, decl: *Decl, writer: anytype) !void {
12631298 if (dg.module.decl_exports.get(decl)) |exports| {
12641299 return writer.writeAll(exports[0].options.name);
......@@ -1493,10 +1528,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
14931528 .optional_payload_ptr => try airOptionalPayload(f, inst),
14941529 .optional_payload_ptr_set => try airOptionalPayloadPtrSet(f, inst),
14951530
1496 .is_err => try airIsErr(f, inst, "", ".", "!="),
1497 .is_non_err => try airIsErr(f, inst, "", ".", "=="),
1498 .is_err_ptr => try airIsErr(f, inst, "*", "->", "!="),
1499 .is_non_err_ptr => try airIsErr(f, inst, "*", "->", "=="),
1531 .is_err => try airIsErr(f, inst, false, "!="),
1532 .is_non_err => try airIsErr(f, inst, false, "=="),
1533 .is_err_ptr => try airIsErr(f, inst, true, "!="),
1534 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),
15001535
15011536 .is_null => try airIsNull(f, inst, "==", ""),
15021537 .is_non_null => try airIsNull(f, inst, "!=", ""),
......@@ -1800,8 +1835,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
18001835 try f.writeCValue(writer, local);
18011836 try writer.writeAll("));\n");
18021837 } else {
1803 try writer.writeAll(" = *");
1804 try f.writeCValue(writer, operand);
1838 try writer.writeAll(" = ");
1839 try f.writeCValueDeref(writer, operand);
18051840 try writer.writeAll(";\n");
18061841 }
18071842 },
......@@ -1916,33 +1951,15 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue, dest_child_type: Type) !CVa
19161951 return CValue.none;
19171952
19181953 const writer = f.object.writer();
1919 switch (dest_ptr) {
1920 .local_ref => |i| {
1921 const dest: CValue = .{ .local = i };
1922 try writer.writeAll("memset(&");
1923 try f.writeCValue(writer, dest);
1924 try writer.writeAll(", 0xaa, sizeof(");
1925 try f.writeCValue(writer, dest);
1926 try writer.writeAll("));\n");
1927 },
1928 .decl_ref => |decl| {
1929 const dest: CValue = .{ .decl = decl };
1930 try writer.writeAll("memset(&");
1931 try f.writeCValue(writer, dest);
1932 try writer.writeAll(", 0xaa, sizeof(");
1933 try f.writeCValue(writer, dest);
1934 try writer.writeAll("));\n");
1935 },
1936 else => {
1937 const indirection = if (dest_child_type.zigTypeTag() == .Array) "" else "*";
1938
1939 try writer.writeAll("memset(");
1940 try f.writeCValue(writer, dest_ptr);
1941 try writer.print(", 0xaa, sizeof({s}", .{indirection});
1942 try f.writeCValue(writer, dest_ptr);
1943 try writer.writeAll("));\n");
1944 },
1954 try writer.writeAll("memset(");
1955 try f.writeCValue(writer, dest_ptr);
1956 try writer.writeAll(", 0xaa, sizeof(");
1957 if (dest_child_type.zigTypeTag() == .Array) {
1958 try f.writeCValue(writer, dest_ptr);
1959 } else {
1960 try f.writeCValueDeref(writer, dest_ptr);
19451961 }
1962 try writer.writeAll("));\n");
19461963 return CValue.none;
19471964}
19481965
......@@ -2004,8 +2021,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
20042021 try f.writeCValue(writer, array_src);
20052022 try writer.writeAll("));\n");
20062023 } else {
2007 try writer.writeAll("*");
2008 try f.writeCValue(writer, dest_ptr);
2024 try f.writeCValueDeref(writer, dest_ptr);
20092025 try writer.writeAll(" = ");
20102026 try f.writeCValue(writer, src_val);
20112027 try writer.writeAll(";\n");
......@@ -2852,16 +2868,15 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
28522868 return operand;
28532869 }
28542870
2855 try writer.writeAll("(");
2856 try f.writeCValue(writer, operand);
2857 try writer.writeAll(")->is_null = false;\n");
2871 try f.writeCValueDeref(writer, operand);
2872 try writer.writeAll(".is_null = false;\n");
28582873
28592874 const inst_ty = f.air.typeOfIndex(inst);
28602875 const local = try f.allocLocal(inst_ty, .Const);
2861 try writer.writeAll(" = &(");
2862 try f.writeCValue(writer, operand);
2876 try writer.writeAll(" = &");
2877 try f.writeCValueDeref(writer, operand);
28632878
2864 try writer.writeAll(")->payload;\n");
2879 try writer.writeAll(".payload;\n");
28652880 return local;
28662881}
28672882
......@@ -2912,18 +2927,10 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
29122927
29132928 const inst_ty = f.air.typeOfIndex(inst);
29142929 const local = try f.allocLocal(inst_ty, .Const);
2915 switch (struct_ptr) {
2916 .local_ref => |i| {
2917 try writer.print(" = {s}t{d}.{s}{ };\n", .{
2918 addrof, i, payload, fmtIdent(field_name),
2919 });
2920 },
2921 else => {
2922 try writer.print(" = {s}", .{addrof});
2923 try f.writeCValue(writer, struct_ptr);
2924 try writer.print("->{s}{ };\n", .{ payload, fmtIdent(field_name) });
2925 },
2926 }
2930
2931 try writer.print(" = {s}", .{addrof});
2932 try f.writeCValueDeref(writer, struct_ptr);
2933 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });
29272934 return local;
29282935}
29292936
......@@ -2975,13 +2982,14 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
29752982 }
29762983 }
29772984
2978 const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else ".";
2979
29802985 const local = try f.allocLocal(inst_ty, .Const);
2981 try writer.writeAll(" = (");
2982 try f.writeCValue(writer, operand);
2983
2984 try writer.print("){s}error;\n", .{maybe_deref});
2986 try writer.writeAll(" = ");
2987 if (operand_ty.zigTypeTag() == .Pointer) {
2988 try f.writeCValueDeref(writer, operand);
2989 } else {
2990 try f.writeCValue(writer, operand);
2991 }
2992 try writer.writeAll(".error;\n");
29852993 return local;
29862994}
29872995
......@@ -3069,8 +3077,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
30693077fn airIsErr(
30703078 f: *Function,
30713079 inst: Air.Inst.Index,
3072 deref_prefix: [*:0]const u8,
3073 deref_suffix: [*:0]const u8,
3080 is_ptr: bool,
30743081 op_str: [*:0]const u8,
30753082) !CValue {
30763083 if (f.liveness.isUnused(inst))
......@@ -3082,15 +3089,16 @@ fn airIsErr(
30823089 const operand_ty = f.air.typeOf(un_op);
30833090 const local = try f.allocLocal(Type.initTag(.bool), .Const);
30843091 const payload_ty = operand_ty.errorUnionPayload();
3085 if (!payload_ty.hasRuntimeBits()) {
3086 try writer.print(" = {s}", .{deref_prefix});
3087 try f.writeCValue(writer, operand);
3088 try writer.print(" {s} 0;\n", .{op_str});
3092 try writer.writeAll(" = ");
3093 if (is_ptr) {
3094 try f.writeCValueDeref(writer, operand);
30893095 } else {
3090 try writer.writeAll(" = ");
30913096 try f.writeCValue(writer, operand);
3092 try writer.print("{s}error {s} 0;\n", .{ deref_suffix, op_str });
30933097 }
3098 if (payload_ty.hasRuntimeBits()) {
3099 try writer.writeAll(".error");
3100 }
3101 try writer.print(" {s} 0;\n", .{op_str});
30943102 return local;
30953103}
30963104