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 {...@@ -291,6 +291,19 @@ pub const Function = struct {
291 }291 }
292 }292 }
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
294 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {307 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
295 return f.object.dg.fail(format, args);308 return f.object.dg.fail(format, args);
296 }309 }
...@@ -1259,6 +1272,28 @@ pub const DeclGen = struct {...@@ -1259,6 +1272,28 @@ pub const DeclGen = struct {
1259 }1272 }
1260 }1273 }
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
1262 fn renderDeclName(dg: DeclGen, decl: *Decl, writer: anytype) !void {1297 fn renderDeclName(dg: DeclGen, decl: *Decl, writer: anytype) !void {
1263 if (dg.module.decl_exports.get(decl)) |exports| {1298 if (dg.module.decl_exports.get(decl)) |exports| {
1264 return writer.writeAll(exports[0].options.name);1299 return writer.writeAll(exports[0].options.name);
...@@ -1493,10 +1528,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1493,10 +1528,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1493 .optional_payload_ptr => try airOptionalPayload(f, inst),1528 .optional_payload_ptr => try airOptionalPayload(f, inst),
1494 .optional_payload_ptr_set => try airOptionalPayloadPtrSet(f, inst),1529 .optional_payload_ptr_set => try airOptionalPayloadPtrSet(f, inst),
14951530
1496 .is_err => try airIsErr(f, inst, "", ".", "!="),1531 .is_err => try airIsErr(f, inst, false, "!="),
1497 .is_non_err => try airIsErr(f, inst, "", ".", "=="),1532 .is_non_err => try airIsErr(f, inst, false, "=="),
1498 .is_err_ptr => try airIsErr(f, inst, "*", "->", "!="),1533 .is_err_ptr => try airIsErr(f, inst, true, "!="),
1499 .is_non_err_ptr => try airIsErr(f, inst, "*", "->", "=="),1534 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),
15001535
1501 .is_null => try airIsNull(f, inst, "==", ""),1536 .is_null => try airIsNull(f, inst, "==", ""),
1502 .is_non_null => try airIsNull(f, inst, "!=", ""),1537 .is_non_null => try airIsNull(f, inst, "!=", ""),
...@@ -1800,8 +1835,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -1800,8 +1835,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
1800 try f.writeCValue(writer, local);1835 try f.writeCValue(writer, local);
1801 try writer.writeAll("));\n");1836 try writer.writeAll("));\n");
1802 } else {1837 } else {
1803 try writer.writeAll(" = *");1838 try writer.writeAll(" = ");
1804 try f.writeCValue(writer, operand);1839 try f.writeCValueDeref(writer, operand);
1805 try writer.writeAll(";\n");1840 try writer.writeAll(";\n");
1806 }1841 }
1807 },1842 },
...@@ -1916,33 +1951,15 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue, dest_child_type: Type) !CVa...@@ -1916,33 +1951,15 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue, dest_child_type: Type) !CVa
1916 return CValue.none;1951 return CValue.none;
19171952
1918 const writer = f.object.writer();1953 const writer = f.object.writer();
1919 switch (dest_ptr) {1954 try writer.writeAll("memset(");
1920 .local_ref => |i| {1955 try f.writeCValue(writer, dest_ptr);
1921 const dest: CValue = .{ .local = i };1956 try writer.writeAll(", 0xaa, sizeof(");
1922 try writer.writeAll("memset(&");1957 if (dest_child_type.zigTypeTag() == .Array) {
1923 try f.writeCValue(writer, dest);1958 try f.writeCValue(writer, dest_ptr);
1924 try writer.writeAll(", 0xaa, sizeof(");1959 } else {
1925 try f.writeCValue(writer, dest);1960 try f.writeCValueDeref(writer, dest_ptr);
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 },
1945 }1961 }
1962 try writer.writeAll("));\n");
1946 return CValue.none;1963 return CValue.none;
1947}1964}
19481965
...@@ -2004,8 +2021,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2004,8 +2021,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2004 try f.writeCValue(writer, array_src);2021 try f.writeCValue(writer, array_src);
2005 try writer.writeAll("));\n");2022 try writer.writeAll("));\n");
2006 } else {2023 } else {
2007 try writer.writeAll("*");2024 try f.writeCValueDeref(writer, dest_ptr);
2008 try f.writeCValue(writer, dest_ptr);
2009 try writer.writeAll(" = ");2025 try writer.writeAll(" = ");
2010 try f.writeCValue(writer, src_val);2026 try f.writeCValue(writer, src_val);
2011 try writer.writeAll(";\n");2027 try writer.writeAll(";\n");
...@@ -2852,16 +2868,15 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2852,16 +2868,15 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
2852 return operand;2868 return operand;
2853 }2869 }
28542870
2855 try writer.writeAll("(");2871 try f.writeCValueDeref(writer, operand);
2856 try f.writeCValue(writer, operand);2872 try writer.writeAll(".is_null = false;\n");
2857 try writer.writeAll(")->is_null = false;\n");
28582873
2859 const inst_ty = f.air.typeOfIndex(inst);2874 const inst_ty = f.air.typeOfIndex(inst);
2860 const local = try f.allocLocal(inst_ty, .Const);2875 const local = try f.allocLocal(inst_ty, .Const);
2861 try writer.writeAll(" = &(");2876 try writer.writeAll(" = &");
2862 try f.writeCValue(writer, operand);2877 try f.writeCValueDeref(writer, operand);
28632878
2864 try writer.writeAll(")->payload;\n");2879 try writer.writeAll(".payload;\n");
2865 return local;2880 return local;
2866}2881}
28672882
...@@ -2912,18 +2927,10 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -2912,18 +2927,10 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
29122927
2913 const inst_ty = f.air.typeOfIndex(inst);2928 const inst_ty = f.air.typeOfIndex(inst);
2914 const local = try f.allocLocal(inst_ty, .Const);2929 const local = try f.allocLocal(inst_ty, .Const);
2915 switch (struct_ptr) {2930
2916 .local_ref => |i| {2931 try writer.print(" = {s}", .{addrof});
2917 try writer.print(" = {s}t{d}.{s}{ };\n", .{2932 try f.writeCValueDeref(writer, struct_ptr);
2918 addrof, i, payload, fmtIdent(field_name),2933 try writer.print(".{s}{ };\n", .{ 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 }
2927 return local;2934 return local;
2928}2935}
29292936
...@@ -2975,13 +2982,14 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2975,13 +2982,14 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
2975 }2982 }
2976 }2983 }
29772984
2978 const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else ".";
2979
2980 const local = try f.allocLocal(inst_ty, .Const);2985 const local = try f.allocLocal(inst_ty, .Const);
2981 try writer.writeAll(" = (");2986 try writer.writeAll(" = ");
2982 try f.writeCValue(writer, operand);2987 if (operand_ty.zigTypeTag() == .Pointer) {
29832988 try f.writeCValueDeref(writer, operand);
2984 try writer.print("){s}error;\n", .{maybe_deref});2989 } else {
2990 try f.writeCValue(writer, operand);
2991 }
2992 try writer.writeAll(".error;\n");
2985 return local;2993 return local;
2986}2994}
29872995
...@@ -3069,8 +3077,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3069,8 +3077,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
3069fn airIsErr(3077fn airIsErr(
3070 f: *Function,3078 f: *Function,
3071 inst: Air.Inst.Index,3079 inst: Air.Inst.Index,
3072 deref_prefix: [*:0]const u8,3080 is_ptr: bool,
3073 deref_suffix: [*:0]const u8,
3074 op_str: [*:0]const u8,3081 op_str: [*:0]const u8,
3075) !CValue {3082) !CValue {
3076 if (f.liveness.isUnused(inst))3083 if (f.liveness.isUnused(inst))
...@@ -3082,15 +3089,16 @@ fn airIsErr(...@@ -3082,15 +3089,16 @@ fn airIsErr(
3082 const operand_ty = f.air.typeOf(un_op);3089 const operand_ty = f.air.typeOf(un_op);
3083 const local = try f.allocLocal(Type.initTag(.bool), .Const);3090 const local = try f.allocLocal(Type.initTag(.bool), .Const);
3084 const payload_ty = operand_ty.errorUnionPayload();3091 const payload_ty = operand_ty.errorUnionPayload();
3085 if (!payload_ty.hasRuntimeBits()) {3092 try writer.writeAll(" = ");
3086 try writer.print(" = {s}", .{deref_prefix});3093 if (is_ptr) {
3087 try f.writeCValue(writer, operand);3094 try f.writeCValueDeref(writer, operand);
3088 try writer.print(" {s} 0;\n", .{op_str});
3089 } else {3095 } else {
3090 try writer.writeAll(" = ");
3091 try f.writeCValue(writer, operand);3096 try f.writeCValue(writer, operand);
3092 try writer.print("{s}error {s} 0;\n", .{ deref_suffix, op_str });
3093 }3097 }
3098 if (payload_ty.hasRuntimeBits()) {
3099 try writer.writeAll(".error");
3100 }
3101 try writer.print(" {s} 0;\n", .{op_str});
3094 return local;3102 return local;
3095}3103}
30963104