authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-10 04:08:52-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
log87d432328e564ac138a1b773ab025324b5c191ed
treead251a5754a841b10c657387da6427fc59131fb8
parentfeb8f81cd9d8df282d57441422dc70cee079a993

cbe: implement aggregate_init of struct


3 files changed, 54 insertions(+), 64 deletions(-)

src/codegen/c.zig+54-61
...@@ -62,7 +62,6 @@ const FormatTypeAsCIdentContext = struct {...@@ -62,7 +62,6 @@ const FormatTypeAsCIdentContext = struct {
62};62};
6363
64const ValueRenderLocation = enum {64const ValueRenderLocation = enum {
65 Identifier,
66 FunctionArgument,65 FunctionArgument,
67 Other,66 Other,
68};67};
...@@ -340,7 +339,7 @@ pub const Function = struct {...@@ -340,7 +339,7 @@ pub const Function = struct {
340 }339 }
341340
342 fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {341 fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
343 return f.object.dg.fmtIntLiteral(ty, val, .Other);342 return f.object.dg.fmtIntLiteral(ty, val);
344 }343 }
345};344};
346345
...@@ -533,16 +532,13 @@ pub const DeclGen = struct {...@@ -533,16 +532,13 @@ pub const DeclGen = struct {
533 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)532 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
534 // with 'error: expected expression' (including when built with 'zig cc')533 // with 'error: expected expression' (including when built with 'zig cc')
535 .Bool => return writer.writeAll("false"),534 .Bool => return writer.writeAll("false"),
536 .Int,535 .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val)}),
537 .Enum,
538 .ErrorSet,
539 => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),
540 .Float => switch (ty.tag()) {536 .Float => switch (ty.tag()) {
541 .f32 => return writer.print("zig_bitcast_f32_u32({x})", .{537 .f32 => return writer.print("zig_bitcast_f32_u32({x})", .{
542 try dg.fmtIntLiteral(Type.u32, val, location),538 try dg.fmtIntLiteral(Type.u32, val),
543 }),539 }),
544 .f64 => return writer.print("zig_bitcast_f64_u64({x})", .{540 .f64 => return writer.print("zig_bitcast_f64_u64({x})", .{
545 try dg.fmtIntLiteral(Type.u64, val, location),541 try dg.fmtIntLiteral(Type.u64, val),
546 }),542 }),
547 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),543 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
548 },544 },
...@@ -554,14 +550,12 @@ pub const DeclGen = struct {...@@ -554,14 +550,12 @@ pub const DeclGen = struct {
554 var buf: Type.SlicePtrFieldTypeBuffer = undefined;550 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
555 const ptr_ty = ty.slicePtrFieldType(&buf);551 const ptr_ty = ty.slicePtrFieldType(&buf);
556 try dg.renderTypecast(writer, ptr_ty);552 try dg.renderTypecast(writer, ptr_ty);
557 return writer.print("){x}, {0x}}}", .{553 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)});
558 try dg.fmtIntLiteral(Type.usize, val, location),
559 });
560 },554 },
561 .Many, .C, .One => {555 .Many, .C, .One => {
562 try writer.writeAll("((");556 try writer.writeAll("((");
563 try dg.renderTypecast(writer, ty);557 try dg.renderTypecast(writer, ty);
564 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, location)});558 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
565 },559 },
566 },560 },
567 .Optional => {561 .Optional => {
...@@ -598,9 +592,7 @@ pub const DeclGen = struct {...@@ -598,9 +592,7 @@ pub const DeclGen = struct {
598592
599 empty = false;593 empty = false;
600 }594 }
601 if (empty) try writer.print("{x}", .{595 if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
602 try dg.fmtIntLiteral(Type.u8, Value.undef, location),
603 });
604596
605 return writer.writeByte('}');597 return writer.writeByte('}');
606 },598 },
...@@ -613,9 +605,7 @@ pub const DeclGen = struct {...@@ -613,9 +605,7 @@ pub const DeclGen = struct {
613 if (!field.ty.hasRuntimeBits()) continue;605 if (!field.ty.hasRuntimeBits()) continue;
614 try dg.renderValue(writer, field.ty, val, location);606 try dg.renderValue(writer, field.ty, val, location);
615 break;607 break;
616 } else try writer.print("{x}", .{608 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
617 try dg.fmtIntLiteral(Type.u8, Value.undef, location),
618 });
619609
620 return writer.writeByte('}');610 return writer.writeByte('}');
621 },611 },
...@@ -625,7 +615,7 @@ pub const DeclGen = struct {...@@ -625,7 +615,7 @@ pub const DeclGen = struct {
625 try writer.writeAll("){ .payload = ");615 try writer.writeAll("){ .payload = ");
626 try dg.renderValue(writer, ty.errorUnionPayload(), val, location);616 try dg.renderValue(writer, ty.errorUnionPayload(), val, location);
627 return writer.print(", .error = {x} }}", .{617 return writer.print(", .error = {x} }}", .{
628 try dg.fmtIntLiteral(ty.errorUnionSet(), Value.undef, location),618 try dg.fmtIntLiteral(ty.errorUnionSet(), Value.undef),
629 });619 });
630 },620 },
631 .Array => {621 .Array => {
...@@ -670,7 +660,7 @@ pub const DeclGen = struct {...@@ -670,7 +660,7 @@ pub const DeclGen = struct {
670 .decl_ref_mut,660 .decl_ref_mut,
671 .decl_ref,661 .decl_ref,
672 => try dg.renderParentPtr(writer, val, ty),662 => try dg.renderParentPtr(writer, val, ty),
673 else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}),663 else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val)}),
674 },664 },
675 .Float => {665 .Float => {
676 if (ty.floatBits(target) <= 64) {666 if (ty.floatBits(target) <= 64) {
...@@ -682,22 +672,20 @@ pub const DeclGen = struct {...@@ -682,22 +672,20 @@ pub const DeclGen = struct {
682 .base = .{ .tag = .int_u64 },672 .base = .{ .tag = .int_u64 },
683 .data = @bitCast(u32, val.toFloat(f32)),673 .data = @bitCast(u32, val.toFloat(f32)),
684 };674 };
685 return writer.print("zig_bitcast_f32_u32({x})", .{try dg.fmtIntLiteral(675 const bitcast_val = Value.initPayload(&bitcast_val_pl.base);
686 Type.u32,676 return writer.print("zig_bitcast_f32_u32({x})", .{
687 Value.initPayload(&bitcast_val_pl.base),677 try dg.fmtIntLiteral(Type.u32, bitcast_val),
688 location,678 });
689 )});
690 },679 },
691 .f64 => {680 .f64 => {
692 var bitcast_val_pl = Value.Payload.U64{681 var bitcast_val_pl = Value.Payload.U64{
693 .base = .{ .tag = .int_u64 },682 .base = .{ .tag = .int_u64 },
694 .data = @bitCast(u64, val.toFloat(f64)),683 .data = @bitCast(u64, val.toFloat(f64)),
695 };684 };
696 return writer.print("zig_bitcast_f32_u32({x})", .{try dg.fmtIntLiteral(685 const bitcast_val = Value.initPayload(&bitcast_val_pl.base);
697 Type.u64,686 return writer.print("zig_bitcast_f64_u64({x})", .{
698 Value.initPayload(&bitcast_val_pl.base),687 try dg.fmtIntLiteral(Type.u64, bitcast_val),
699 location,688 });
700 )});
701 },689 },
702 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),690 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
703 }691 }
...@@ -740,7 +728,7 @@ pub const DeclGen = struct {...@@ -740,7 +728,7 @@ pub const DeclGen = struct {
740 .int_u64, .one => {728 .int_u64, .one => {
741 try writer.writeAll("((");729 try writer.writeAll("((");
742 try dg.renderTypecast(writer, ty);730 try dg.renderTypecast(writer, ty);
743 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, location)});731 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
744 },732 },
745 .field_ptr,733 .field_ptr,
746 .elem_ptr,734 .elem_ptr,
...@@ -918,7 +906,7 @@ pub const DeclGen = struct {...@@ -918,7 +906,7 @@ pub const DeclGen = struct {
918906
919 empty = false;907 empty = false;
920 }908 }
921 if (empty) try writer.writeByte('0');909 if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)});
922910
923 try writer.writeByte('}');911 try writer.writeByte('}');
924 },912 },
...@@ -1730,7 +1718,7 @@ pub const DeclGen = struct {...@@ -1730,7 +1718,7 @@ pub const DeclGen = struct {
1730 var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };1718 var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
1731 const len_val = Value.initPayload(&len_val_pl.base);1719 const len_val = Value.initPayload(&len_val_pl.base);
17321720
1733 try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val, .Other)});1721 try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)});
1734 try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);1722 try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);
1735 try buffer.appendSlice(" = ");1723 try buffer.appendSlice(" = ");
1736 try dg.renderValue(bw, name_ty, name_val, .Other);1724 try dg.renderValue(bw, name_ty, name_val, .Other);
...@@ -1738,7 +1726,7 @@ pub const DeclGen = struct {...@@ -1738,7 +1726,7 @@ pub const DeclGen = struct {
1738 try dg.renderTypecast(bw, name_slice_ty);1726 try dg.renderTypecast(bw, name_slice_ty);
1739 try bw.print("){{{}, {}}};\n", .{1727 try bw.print("){{{}, {}}};\n", .{
1740 fmtIdent("name"),1728 fmtIdent("name"),
1741 try dg.fmtIntLiteral(Type.usize, len_val, .Other),1729 try dg.fmtIntLiteral(Type.usize, len_val),
1742 });1730 });
17431731
1744 try buffer.appendSlice(" }\n");1732 try buffer.appendSlice(" }\n");
...@@ -1793,7 +1781,7 @@ pub const DeclGen = struct {...@@ -1793,7 +1781,7 @@ pub const DeclGen = struct {
1793 .undefined_ptr => |ty| {1781 .undefined_ptr => |ty| {
1794 try w.writeAll("((");1782 try w.writeAll("((");
1795 try dg.renderTypecast(w, ty);1783 try dg.renderTypecast(w, ty);
1796 return w.print("){x})", .{try dg.fmtIntLiteral(Type.usize, Value.undef, .Other)});1784 return w.print("){x})", .{try dg.fmtIntLiteral(Type.usize, Value.undef)});
1797 },1785 },
1798 .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),1786 .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
1799 .bytes => |bytes| return w.writeAll(bytes),1787 .bytes => |bytes| return w.writeAll(bytes),
...@@ -1843,7 +1831,6 @@ pub const DeclGen = struct {...@@ -1843,7 +1831,6 @@ pub const DeclGen = struct {
1843 dg: *DeclGen,1831 dg: *DeclGen,
1844 ty: Type,1832 ty: Type,
1845 val: Value,1833 val: Value,
1846 location: ValueRenderLocation,
1847 ) !std.fmt.Formatter(formatIntLiteral) {1834 ) !std.fmt.Formatter(formatIntLiteral) {
1848 const int_info = ty.intInfo(dg.module.getTarget());1835 const int_info = ty.intInfo(dg.module.getTarget());
1849 const c_bits = toCIntBits(int_info.bits);1836 const c_bits = toCIntBits(int_info.bits);
...@@ -1853,7 +1840,6 @@ pub const DeclGen = struct {...@@ -1853,7 +1840,6 @@ pub const DeclGen = struct {
1853 .ty = ty,1840 .ty = ty,
1854 .val = val,1841 .val = val,
1855 .mod = dg.module,1842 .mod = dg.module,
1856 .location = location,
1857 } };1843 } };
1858 }1844 }
1859};1845};
...@@ -1916,7 +1902,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -1916,7 +1902,7 @@ pub fn genErrDecls(o: *Object) !void {
19161902
1917 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{1903 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{
1918 fmtIdent(name),1904 fmtIdent(name),
1919 try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),1905 try o.dg.fmtIntLiteral(Type.usize, len_val),
1920 });1906 });
1921 }1907 }
1922 try writer.writeAll("};\n");1908 try writer.writeAll("};\n");
...@@ -4415,27 +4401,44 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4415,27 +4401,44 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
44154401
4416 const inst_ty = f.air.typeOfIndex(inst);4402 const inst_ty = f.air.typeOfIndex(inst);
4417 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4403 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4418 const vector_ty = f.air.getRefType(ty_pl.ty);4404 const len = @intCast(usize, inst_ty.arrayLen());
4419 const len = vector_ty.vectorLen();
4420 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);4405 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
44214406
4422 const writer = f.object.writer();4407 const writer = f.object.writer();
4423 const local = try f.allocLocal(inst_ty, .Const);4408 const local = try f.allocLocal(inst_ty, .Const);
4424 try writer.writeAll(" = {");4409 try writer.writeAll(" = {");
4425 switch (vector_ty.zigTypeTag()) {4410 switch (inst_ty.zigTypeTag()) {
4411 .Array => {
4412 const elem_ty = inst_ty.childType();
4413 var empty = true;
4414 for (elements) |element| {
4415 if (empty) try writer.writeAll(", ");
4416 try f.writeCValue(writer, try f.resolveInst(element));
4417 empty = false;
4418 }
4419 if (inst_ty.sentinel()) |sentinel| {
4420 if (empty) try writer.writeAll(", ");
4421 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
4422 empty = false;
4423 }
4424 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
4425 },
4426 .Struct => {4426 .Struct => {
4427 const tuple = vector_ty.tupleFields();4427 var empty = true;
4428 var i: usize = 0;4428 for (elements) |element, index| {
4429 for (elements) |elem, elem_index| {4429 if (inst_ty.structFieldValueComptime(index)) |_| continue;
4430 if (tuple.values[elem_index].tag() != .unreachable_value) continue;4430
44314431 if (!empty) try writer.writeAll(", ");
4432 const value = try f.resolveInst(elem);4432 if (!inst_ty.isTupleOrAnonStruct()) {
4433 if (i != 0) try writer.writeAll(", ");4433 try writer.print(".{ } = ", .{fmtIdent(inst_ty.structFieldName(index))});
4434 try f.writeCValue(writer, value);4434 }
4435 i += 1;4435 try f.writeCValue(writer, try f.resolveInst(element));
4436 empty = false;
4436 }4437 }
4438 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
4437 },4439 },
4438 else => |tag| return f.fail("TODO: C backend: implement airAggregateInit for type {s}", .{@tagName(tag)}),4440 .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),
4441 else => unreachable,
4439 }4442 }
4440 try writer.writeAll("};\n");4443 try writer.writeAll("};\n");
44414444
...@@ -4706,7 +4709,6 @@ const FormatIntLiteralContext = struct {...@@ -4706,7 +4709,6 @@ const FormatIntLiteralContext = struct {
4706 ty: Type,4709 ty: Type,
4707 val: Value,4710 val: Value,
4708 mod: *Module,4711 mod: *Module,
4709 location: ValueRenderLocation,
4710};4712};
4711fn formatIntLiteral(4713fn formatIntLiteral(
4712 data: FormatIntLiteralContext,4714 data: FormatIntLiteralContext,
...@@ -4755,13 +4757,6 @@ fn formatIntLiteral(...@@ -4755,13 +4757,6 @@ fn formatIntLiteral(
4755 } else data.val.toBigInt(&int_buf, target);4757 } else data.val.toBigInt(&int_buf, target);
4756 assert(int.fitsInTwosComp(int_info.signedness, int_info.bits));4758 assert(int.fitsInTwosComp(int_info.signedness, int_info.bits));
47574759
4758 if (data.location == .Identifier) {
4759 const str = try int.toStringAlloc(allocator, 10, undefined);
4760 defer allocator.free(str);
4761
4762 return writer.writeAll(str);
4763 }
4764
4765 const limbs_count_64 = @divExact(64, @bitSizeOf(Limb));4760 const limbs_count_64 = @divExact(64, @bitSizeOf(Limb));
4766 const c_bits = toCIntBits(int_info.bits) orelse unreachable;4761 const c_bits = toCIntBits(int_info.bits) orelse unreachable;
4767 if (c_bits == 128) {4762 if (c_bits == 128) {
...@@ -4788,7 +4783,6 @@ fn formatIntLiteral(...@@ -4788,7 +4783,6 @@ fn formatIntLiteral(
4788 .ty = Type.u64,4783 .ty = Type.u64,
4789 .val = upper_val,4784 .val = upper_val,
4790 .mod = data.mod,4785 .mod = data.mod,
4791 .location = data.location,
4792 }, fmt, options, writer);4786 }, fmt, options, writer);
4793 try writer.writeAll("<<64|");4787 try writer.writeAll("<<64|");
4794 }4788 }
...@@ -4802,7 +4796,6 @@ fn formatIntLiteral(...@@ -4802,7 +4796,6 @@ fn formatIntLiteral(
4802 .ty = Type.u64,4796 .ty = Type.u64,
4803 .val = lower_val,4797 .val = lower_val,
4804 .mod = data.mod,4798 .mod = data.mod,
4805 .location = data.location,
4806 }, fmt, options, writer);4799 }, fmt, options, writer);
48074800
4808 if (have_upper) try writer.writeByte(')');4801 if (have_upper) try writer.writeByte(')');
test/behavior/call.zig-1
...@@ -86,7 +86,6 @@ test "tuple parameters" {...@@ -86,7 +86,6 @@ test "tuple parameters" {
86}86}
8787
88test "result location of function call argument through runtime condition and struct init" {88test "result location of function call argument through runtime condition and struct init" {
89 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
90 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO89 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO90 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9291
test/behavior/struct.zig-2
...@@ -1017,7 +1017,6 @@ test "struct with union field" {...@@ -1017,7 +1017,6 @@ test "struct with union field" {
1017}1017}
10181018
1019test "type coercion of anon struct literal to struct" {1019test "type coercion of anon struct literal to struct" {
1020 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1020 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1022 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1023 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1022 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1056,7 +1055,6 @@ test "type coercion of anon struct literal to struct" {...@@ -1056,7 +1055,6 @@ test "type coercion of anon struct literal to struct" {
10561055
1057test "type coercion of pointer to anon struct literal to pointer to struct" {1056test "type coercion of pointer to anon struct literal to pointer to struct" {
1058 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1057 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1059 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1060 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1058 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1061 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1059 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1062 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1060 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO