Commit e8bda9eb3a

Jacob Young <jacobly0@users.noreply.github.com>
2022-10-10 11:43:51
cbe: implement ptr slice ptr
1 parent 87d4323
Changed files (4)
src
codegen
test
src/codegen/c.zig
@@ -791,7 +791,8 @@ pub const DeclGen = struct {
                 }
 
                 if (ty.optionalReprIsPayload()) {
-                    return dg.renderValue(writer, payload_ty, val, location);
+                    const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val;
+                    return dg.renderValue(writer, payload_ty, payload_val, location);
                 }
 
                 try writer.writeByte('(');
@@ -1457,7 +1458,7 @@ pub const DeclGen = struct {
                     .c_ulong => try w.writeAll("unsigned long"),
                     .c_longlong => try w.writeAll("long long"),
                     .c_ulonglong => try w.writeAll("unsigned long long"),
-                    .int_signed, .int_unsigned => {
+                    .u29, .int_signed, .int_unsigned => {
                         const info = t.intInfo(target);
                         const sign_prefix = switch (info.signedness) {
                             .signed => "",
@@ -2242,11 +2243,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
             .field_parent_ptr => try airFieldParentPtr(f, inst),
 
             .struct_field_val => try airStructFieldVal(f, inst),
-            .slice_ptr        => try airSliceField(f, inst, ".ptr;\n"),
-            .slice_len        => try airSliceField(f, inst, ".len;\n"),
+            .slice_ptr        => try airSliceField(f, inst, " = ", ".ptr;\n"),
+            .slice_len        => try airSliceField(f, inst, " = ", ".len;\n"),
 
-            .ptr_slice_len_ptr => try airPtrSliceFieldPtr(f, inst, ".len;\n"),
-            .ptr_slice_ptr_ptr => try airPtrSliceFieldPtr(f, inst, ".ptr;\n"),
+            .ptr_slice_len_ptr => try airSliceField(f, inst, " = &", ".len;\n"),
+            .ptr_slice_ptr_ptr => try airSliceField(f, inst, " = &", ".ptr;\n"),
 
             .ptr_elem_val       => try airPtrElemVal(f, inst),
             .ptr_elem_ptr       => try airPtrElemPtr(f, inst),
@@ -2306,7 +2307,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
     try writer.writeByte('}');
 }
 
-fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
+fn airSliceField(f: *Function, inst: Air.Inst.Index, prefix: []const u8, suffix: []const u8) !CValue {
     if (f.liveness.isUnused(inst)) return CValue.none;
 
     const inst_ty = f.air.typeOfIndex(inst);
@@ -2314,27 +2315,12 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue
     const operand = try f.resolveInst(ty_op.operand);
     const writer = f.object.writer();
     const local = try f.allocLocal(inst_ty, .Const);
-    try writer.writeAll(" = ");
+    try writer.writeAll(prefix);
     try f.writeCValue(writer, operand);
     try writer.writeAll(suffix);
     return local;
 }
 
-fn airPtrSliceFieldPtr(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
-    if (f.liveness.isUnused(inst))
-        return CValue.none;
-
-    const ty_op = f.air.instructions.items(.data)[inst].ty_op;
-    const operand = try f.resolveInst(ty_op.operand);
-    const writer = f.object.writer();
-
-    _ = writer;
-    _ = operand;
-    _ = suffix;
-
-    return f.fail("TODO: C backend: airPtrSliceFieldPtr", .{});
-}
-
 fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
     const bin_op = f.air.instructions.items(.data)[inst].bin_op;
     const ptr_ty = f.air.typeOf(bin_op.lhs);
@@ -3581,7 +3567,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
         // for the string, we still use the next u32 for the null terminator.
         extra_i += (constraint.len + name.len + (2 + 3)) / 4;
 
-        try f.writeCValueDeref(writer, if (output == .none) .{ .local_ref = local.local } else try f.resolveInst(output));
+        try f.writeCValueDeref(writer, if (output == .none) CValue{
+            .local_ref = local.local,
+        } else try f.resolveInst(output));
         try writer.writeAll(" = ");
         try f.writeCValue(writer, .{ .identifier = name });
         try writer.writeAll(";\n");
test/behavior/bugs/2578.zig
@@ -15,7 +15,6 @@ test "fixed" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
 
     bar(t);
 }
test/behavior/cast.zig
@@ -1260,7 +1260,6 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {
 var global_struct: struct { f0: usize } = undefined;
 test "assignment to optional pointer result loc" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 
     var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
test/behavior/fn.zig
@@ -97,7 +97,6 @@ test "discard the result of a function that returns a struct" {
 }
 
 test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage1) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;