authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-19 23:18:46-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
log4fdac5f1c9cad90450cbad5a8dd276a597aba870
treedf83e2a4cff08172b0f2b3872687446e012406bb
parent4765294ca4bd7dd54207892b199f3053702d9a2a

cbe: fix C syntax when rendering initializers


1 files changed, 448 insertions(+), 430 deletions(-)

src/codegen/c.zig+448-430
...@@ -63,6 +63,7 @@ const FormatTypeAsCIdentContext = struct {...@@ -63,6 +63,7 @@ const FormatTypeAsCIdentContext = struct {
6363
64const ValueRenderLocation = enum {64const ValueRenderLocation = enum {
65 FunctionArgument,65 FunctionArgument,
66 Initializer,
66 Other,67 Other,
67};68};
6869
...@@ -256,7 +257,7 @@ pub const Function = struct {...@@ -256,7 +257,7 @@ pub const Function = struct {
256 0,257 0,
257 );258 );
258 try writer.writeAll(" = ");259 try writer.writeAll(" = ");
259 try f.object.dg.renderValue(writer, ty, val, .Other);260 try f.object.dg.renderValue(writer, ty, val, .Initializer);
260 try writer.writeAll(";\n ");261 try writer.writeAll(";\n ");
261 return decl_c_value;262 return decl_c_value;
262 },263 },
...@@ -297,13 +298,14 @@ pub const Function = struct {...@@ -297,13 +298,14 @@ pub const Function = struct {
297 return local_value;298 return local_value;
298 }299 }
299300
300 fn writeCValue(f: *Function, w: anytype, c_value: CValue) !void {301 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
301 switch (c_value) {302 switch (c_value) {
302 .constant => |inst| {303 .constant => |inst| {
303 const ty = f.air.typeOf(inst);304 const ty = f.air.typeOf(inst);
304 const val = f.air.value(inst).?;305 const val = f.air.value(inst).?;
305 return f.object.dg.renderValue(w, ty, val, .Other);306 return f.object.dg.renderValue(w, ty, val, location);
306 },307 },
308 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
307 else => return f.object.dg.writeCValue(w, c_value),309 else => return f.object.dg.writeCValue(w, c_value),
308 }310 }
309 }311 }
...@@ -425,13 +427,17 @@ pub const DeclGen = struct {...@@ -425,13 +427,17 @@ pub const DeclGen = struct {
425 if (ty.isSlice()) {427 if (ty.isSlice()) {
426 try writer.writeByte('(');428 try writer.writeByte('(');
427 try dg.renderTypecast(writer, ty);429 try dg.renderTypecast(writer, ty);
428 try writer.writeAll("){");430 try writer.writeAll("){ .ptr = ");
431
429 var buf: Type.SlicePtrFieldTypeBuffer = undefined;432 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
430 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other);433 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer);
431 try writer.writeAll(", ");434
432 try writer.print("{d}", .{val.sliceLen(dg.module)});435 var len_pl: Value.Payload.U64 = .{
433 try writer.writeByte('}');436 .base = .{ .tag = .int_u64 },
434 return;437 .data = val.sliceLen(dg.module),
438 };
439 const len_val = Value.initPayload(&len_pl.base);
440 return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)});
435 }441 }
436442
437 // We shouldn't cast C function pointers as this is UB (when you call443 // We shouldn't cast C function pointers as this is UB (when you call
...@@ -567,9 +573,13 @@ pub const DeclGen = struct {...@@ -567,9 +573,13 @@ pub const DeclGen = struct {
567 },573 },
568 .Pointer => switch (ty.ptrSize()) {574 .Pointer => switch (ty.ptrSize()) {
569 .Slice => {575 .Slice => {
570 try writer.writeByte('(');576 if (location != .Initializer) {
571 try dg.renderTypecast(writer, ty);577 try writer.writeByte('(');
572 try writer.writeAll("){(");578 try dg.renderTypecast(writer, ty);
579 try writer.writeByte(')');
580 }
581
582 try writer.writeAll("{(");
573 var buf: Type.SlicePtrFieldTypeBuffer = undefined;583 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
574 const ptr_ty = ty.slicePtrFieldType(&buf);584 const ptr_ty = ty.slicePtrFieldType(&buf);
575 try dg.renderTypecast(writer, ptr_ty);585 try dg.renderTypecast(writer, ptr_ty);
...@@ -593,69 +603,86 @@ pub const DeclGen = struct {...@@ -593,69 +603,86 @@ pub const DeclGen = struct {
593 return dg.renderValue(writer, payload_ty, val, location);603 return dg.renderValue(writer, payload_ty, val, location);
594 }604 }
595605
596 try writer.writeByte('(');606 if (location != .Initializer) {
597 try dg.renderTypecast(writer, ty);607 try writer.writeByte('(');
598 try writer.writeAll("){ .payload = ");608 try dg.renderTypecast(writer, ty);
599 try dg.renderValue(writer, payload_ty, val, location);609 try writer.writeByte(')');
610 }
611
612 try writer.writeAll("{ .payload = ");
613 try dg.renderValue(writer, payload_ty, val, .Initializer);
600 try writer.writeAll(", .is_null = ");614 try writer.writeAll(", .is_null = ");
601 try dg.renderValue(writer, Type.bool, val, location);615 try dg.renderValue(writer, Type.bool, val, .Initializer);
602 return writer.writeAll(" }");616 return writer.writeAll(" }");
603 },617 },
604 .Struct => {618 .Struct => {
605 try writer.writeByte('(');619 if (location != .Initializer) {
606 try dg.renderTypecast(writer, ty);620 try writer.writeByte('(');
607 try writer.writeAll("){");621 try dg.renderTypecast(writer, ty);
622 try writer.writeByte(')');
623 }
608624
625 try writer.writeByte('{');
609 var empty = true;626 var empty = true;
610 for (ty.structFields().values()) |field| {627 for (ty.structFields().values()) |field| {
611 if (!field.ty.hasRuntimeBits()) continue;628 if (!field.ty.hasRuntimeBits()) continue;
612629
613 if (!empty) try writer.writeByte(',');630 if (!empty) try writer.writeByte(',');
614 try dg.renderValue(writer, field.ty, val, location);631 try dg.renderValue(writer, field.ty, val, .Initializer);
615632
616 empty = false;633 empty = false;
617 }634 }
618 if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});635 if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
619
620 return writer.writeByte('}');636 return writer.writeByte('}');
621 },637 },
622 .Union => {638 .Union => {
623 try writer.writeByte('(');639 if (location != .Initializer) {
624 try dg.renderTypecast(writer, ty);640 try writer.writeByte('(');
625 try writer.writeAll("){");641 try dg.renderTypecast(writer, ty);
642 try writer.writeByte(')');
643 }
626644
645 try writer.writeByte('{');
627 if (ty.unionTagTypeSafety()) |tag_ty| {646 if (ty.unionTagTypeSafety()) |tag_ty| {
628 try writer.writeAll(".tag = ");647 try writer.writeAll(" .tag = ");
629 try dg.renderValue(writer, tag_ty, val, location);648 try dg.renderValue(writer, tag_ty, val, .Initializer);
630 try writer.writeAll(", .payload = {");649 try writer.writeAll(", .payload = {");
631 }650 }
632 for (ty.unionFields().values()) |field| {651 for (ty.unionFields().values()) |field| {
633 if (!field.ty.hasRuntimeBits()) continue;652 if (!field.ty.hasRuntimeBits()) continue;
634 try dg.renderValue(writer, field.ty, val, location);653 try dg.renderValue(writer, field.ty, val, .Initializer);
635 break;654 break;
636 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});655 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
637 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');656 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
638 return writer.writeByte('}');657 return writer.writeByte('}');
639 },658 },
640 .ErrorUnion => {659 .ErrorUnion => {
641 try writer.writeByte('(');660 if (location != .Initializer) {
642 try dg.renderTypecast(writer, ty);661 try writer.writeByte('(');
643 try writer.writeAll("){ .payload = ");662 try dg.renderTypecast(writer, ty);
644 try dg.renderValue(writer, ty.errorUnionPayload(), val, location);663 try writer.writeByte(')');
664 }
665
666 try writer.writeAll("{ .payload = ");
667 try dg.renderValue(writer, ty.errorUnionPayload(), val, .Initializer);
645 return writer.print(", .error = {x} }}", .{668 return writer.print(", .error = {x} }}", .{
646 try dg.fmtIntLiteral(ty.errorUnionSet(), val),669 try dg.fmtIntLiteral(ty.errorUnionSet(), val),
647 });670 });
648 },671 },
649 .Array => {672 .Array => {
650 try writer.writeByte('{');673 if (location != .Initializer) {
674 try writer.writeByte('(');
675 try dg.renderTypecast(writer, ty);
676 try writer.writeByte(')');
677 }
651678
679 try writer.writeByte('{');
652 const c_len = ty.arrayLenIncludingSentinel();680 const c_len = ty.arrayLenIncludingSentinel();
653 var index: usize = 0;681 var index: usize = 0;
654 while (index < c_len) : (index += 1) {682 while (index < c_len) : (index += 1) {
655 if (index > 0) try writer.writeAll(", ");683 if (index > 0) try writer.writeAll(", ");
656 try dg.renderValue(writer, ty.childType(), val, location);684 try dg.renderValue(writer, ty.childType(), val, .Initializer);
657 }685 }
658
659 return writer.writeByte('}');686 return writer.writeByte('}');
660 },687 },
661 .ComptimeInt,688 .ComptimeInt,
...@@ -696,21 +723,21 @@ pub const DeclGen = struct {...@@ -696,21 +723,21 @@ pub const DeclGen = struct {
696 // just generate a bit cast (exactly like we do in airBitcast)723 // just generate a bit cast (exactly like we do in airBitcast)
697 switch (ty.tag()) {724 switch (ty.tag()) {
698 .f32 => {725 .f32 => {
699 var bitcast_val_pl = Value.Payload.U64{726 var bitcast_pl = Value.Payload.U64{
700 .base = .{ .tag = .int_u64 },727 .base = .{ .tag = .int_u64 },
701 .data = @bitCast(u32, val.toFloat(f32)),728 .data = @bitCast(u32, val.toFloat(f32)),
702 };729 };
703 const bitcast_val = Value.initPayload(&bitcast_val_pl.base);730 const bitcast_val = Value.initPayload(&bitcast_pl.base);
704 return writer.print("zig_bitcast_f32_u32({x})", .{731 return writer.print("zig_bitcast_f32_u32({x})", .{
705 try dg.fmtIntLiteral(Type.u32, bitcast_val),732 try dg.fmtIntLiteral(Type.u32, bitcast_val),
706 });733 });
707 },734 },
708 .f64 => {735 .f64 => {
709 var bitcast_val_pl = Value.Payload.U64{736 var bitcast_pl = Value.Payload.U64{
710 .base = .{ .tag = .int_u64 },737 .base = .{ .tag = .int_u64 },
711 .data = @bitCast(u64, val.toFloat(f64)),738 .data = @bitCast(u64, val.toFloat(f64)),
712 };739 };
713 const bitcast_val = Value.initPayload(&bitcast_val_pl.base);740 const bitcast_val = Value.initPayload(&bitcast_pl.base);
714 return writer.print("zig_bitcast_f64_u64({x})", .{741 return writer.print("zig_bitcast_f64_u64({x})", .{
715 try dg.fmtIntLiteral(Type.u64, bitcast_val),742 try dg.fmtIntLiteral(Type.u64, bitcast_val),
716 });743 });
...@@ -737,12 +764,16 @@ pub const DeclGen = struct {...@@ -737,12 +764,16 @@ pub const DeclGen = struct {
737 const slice = val.castTag(.slice).?.data;764 const slice = val.castTag(.slice).?.data;
738 var buf: Type.SlicePtrFieldTypeBuffer = undefined;765 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
739766
740 try writer.writeByte('(');767 if (location != .Initializer) {
741 try dg.renderTypecast(writer, ty);768 try writer.writeByte('(');
742 try writer.writeAll("){");769 try dg.renderTypecast(writer, ty);
743 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location);770 try writer.writeByte(')');
771 }
772
773 try writer.writeByte('{');
774 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, .Initializer);
744 try writer.writeAll(", ");775 try writer.writeAll(", ");
745 try dg.renderValue(writer, Type.usize, slice.len, location);776 try dg.renderValue(writer, Type.usize, slice.len, .Initializer);
746 try writer.writeByte('}');777 try writer.writeByte('}');
747 },778 },
748 .function => {779 .function => {
...@@ -768,13 +799,19 @@ pub const DeclGen = struct {...@@ -768,13 +799,19 @@ pub const DeclGen = struct {
768 else => unreachable,799 else => unreachable,
769 },800 },
770 .Array => {801 .Array => {
802 if (location == .FunctionArgument) {
803 try writer.writeByte('(');
804 try dg.renderTypecast(writer, ty);
805 try writer.writeByte(')');
806 }
807
771 // First try specific tag representations for more efficiency.808 // First try specific tag representations for more efficiency.
772 switch (val.tag()) {809 switch (val.tag()) {
773 .undef, .empty_struct_value, .empty_array => {810 .undef, .empty_struct_value, .empty_array => {
774 try writer.writeByte('{');811 try writer.writeByte('{');
775 const ai = ty.arrayInfo();812 const ai = ty.arrayInfo();
776 if (ai.sentinel) |s| {813 if (ai.sentinel) |s| {
777 try dg.renderValue(writer, ai.elem_type, s, location);814 try dg.renderValue(writer, ai.elem_type, s, .Initializer);
778 } else {815 } else {
779 try writer.writeByte('0');816 try writer.writeByte('0');
780 }817 }
...@@ -786,23 +823,17 @@ pub const DeclGen = struct {...@@ -786,23 +823,17 @@ pub const DeclGen = struct {
786 defer arena.deinit();823 defer arena.deinit();
787 const arena_allocator = arena.allocator();824 const arena_allocator = arena.allocator();
788825
789 if (location == .FunctionArgument) {
790 try writer.writeByte('(');
791 try dg.renderTypecast(writer, ty);
792 try writer.writeByte(')');
793 }
794
795 try writer.writeByte('{');826 try writer.writeByte('{');
796 const ai = ty.arrayInfo();827 const ai = ty.arrayInfo();
797 var index: usize = 0;828 var index: usize = 0;
798 while (index < ai.len) : (index += 1) {829 while (index < ai.len) : (index += 1) {
799 if (index != 0) try writer.writeByte(',');830 if (index != 0) try writer.writeByte(',');
800 const elem_val = try val.elemValue(dg.module, arena_allocator, index);831 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
801 try dg.renderValue(writer, ai.elem_type, elem_val, .Other);832 try dg.renderValue(writer, ai.elem_type, elem_val, .Initializer);
802 }833 }
803 if (ai.sentinel) |s| {834 if (ai.sentinel) |s| {
804 if (index != 0) try writer.writeByte(',');835 if (index != 0) try writer.writeByte(',');
805 try dg.renderValue(writer, ai.elem_type, s, .Other);836 try dg.renderValue(writer, ai.elem_type, s, .Initializer);
806 }837 }
807 try writer.writeByte('}');838 try writer.writeByte('}');
808 },839 },
...@@ -823,19 +854,17 @@ pub const DeclGen = struct {...@@ -823,19 +854,17 @@ pub const DeclGen = struct {
823 return dg.renderValue(writer, payload_ty, payload_val, location);854 return dg.renderValue(writer, payload_ty, payload_val, location);
824 }855 }
825856
826 try writer.writeByte('(');857 if (location != .Initializer) {
827 try dg.renderTypecast(writer, ty);858 try writer.writeByte('(');
828 try writer.writeAll("){");859 try dg.renderTypecast(writer, ty);
829 if (val.castTag(.opt_payload)) |pl| {860 try writer.writeByte(')');
830 const payload_val = pl.data;
831 try writer.writeAll(" .payload = ");
832 try dg.renderValue(writer, payload_ty, payload_val, location);
833 try writer.writeAll(", .is_null = false }");
834 } else {
835 try writer.writeAll(" .payload = ");
836 try dg.renderValue(writer, payload_ty, Value.undef, location);
837 try writer.writeAll(", .is_null = true }");
838 }861 }
862
863 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else Value.undef;
864
865 try writer.writeAll("{ .payload = ");
866 try dg.renderValue(writer, payload_ty, payload_val, .Initializer);
867 try writer.print(", .is_null = {} }}", .{val.tag() == .null_value});
839 },868 },
840 .ErrorSet => {869 .ErrorSet => {
841 switch (val.tag()) {870 switch (val.tag()) {
...@@ -861,23 +890,20 @@ pub const DeclGen = struct {...@@ -861,23 +890,20 @@ pub const DeclGen = struct {
861 return dg.renderValue(writer, error_ty, err_val, location);890 return dg.renderValue(writer, error_ty, err_val, location);
862 }891 }
863892
864 try writer.writeByte('(');893 if (location != .Initializer) {
865 try dg.renderTypecast(writer, ty);894 try writer.writeByte('(');
866 try writer.writeAll("){");895 try dg.renderTypecast(writer, ty);
867 if (val.castTag(.eu_payload)) |pl| {896 try writer.writeByte(')');
868 const payload_val = pl.data;
869 try writer.writeAll(" .payload = ");
870 try dg.renderValue(writer, payload_ty, payload_val, location);
871 try writer.print(", .error = {} }}", .{
872 try dg.fmtIntLiteral(error_ty, Value.zero),
873 });
874 } else {
875 try writer.writeAll(" .payload = ");
876 try dg.renderValue(writer, payload_ty, Value.undef, location);
877 try writer.writeAll(", .error = ");
878 try dg.renderValue(writer, error_ty, val, location);
879 try writer.writeAll(" }");
880 }897 }
898
899 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef;
900 const error_val = if (val.tag() == .eu_payload) Value.zero else val;
901
902 try writer.writeAll("{ .payload = ");
903 try dg.renderValue(writer, payload_ty, payload_val, .Initializer);
904 try writer.writeAll(", .error = ");
905 try dg.renderValue(writer, error_ty, error_val, .Initializer);
906 try writer.writeAll(" }");
881 },907 },
882 .Enum => {908 .Enum => {
883 switch (val.tag()) {909 switch (val.tag()) {
...@@ -927,36 +953,41 @@ pub const DeclGen = struct {...@@ -927,36 +953,41 @@ pub const DeclGen = struct {
927 .Struct => {953 .Struct => {
928 const field_vals = val.castTag(.aggregate).?.data;954 const field_vals = val.castTag(.aggregate).?.data;
929955
930 try writer.writeByte('(');956 if (location != .Initializer) {
931 try dg.renderTypecast(writer, ty);957 try writer.writeByte('(');
932 try writer.writeAll("){");958 try dg.renderTypecast(writer, ty);
959 try writer.writeByte(')');
960 }
933961
962 try writer.writeByte('{');
934 var empty = true;963 var empty = true;
935 for (field_vals) |field_val, field_index| {964 for (field_vals) |field_val, field_index| {
936 const field_ty = ty.structFieldType(field_index);965 const field_ty = ty.structFieldType(field_index);
937 if (!field_ty.hasRuntimeBits()) continue;966 if (!field_ty.hasRuntimeBits()) continue;
938967
939 if (!empty) try writer.writeByte(',');968 if (!empty) try writer.writeByte(',');
940 try dg.renderValue(writer, field_ty, field_val, location);969 try dg.renderValue(writer, field_ty, field_val, .Initializer);
941970
942 empty = false;971 empty = false;
943 }972 }
944 if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)});973 if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)});
945
946 try writer.writeByte('}');974 try writer.writeByte('}');
947 },975 },
948 .Union => {976 .Union => {
949 const union_obj = val.castTag(.@"union").?.data;977 const union_obj = val.castTag(.@"union").?.data;
950 const layout = ty.unionGetLayout(target);978 const layout = ty.unionGetLayout(target);
951979
952 try writer.writeByte('(');980 if (location != .Initializer) {
953 try dg.renderTypecast(writer, ty);981 try writer.writeByte('(');
954 try writer.writeAll("){");982 try dg.renderTypecast(writer, ty);
983 try writer.writeByte(')');
984 }
955985
986 try writer.writeByte('{');
956 if (ty.unionTagTypeSafety()) |tag_ty| {987 if (ty.unionTagTypeSafety()) |tag_ty| {
957 if (layout.tag_size != 0) {988 if (layout.tag_size != 0) {
958 try writer.writeAll(".tag = ");989 try writer.writeAll(".tag = ");
959 try dg.renderValue(writer, tag_ty, union_obj.tag, location);990 try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer);
960 try writer.writeAll(", ");991 try writer.writeAll(", ");
961 }992 }
962 try writer.writeAll(".payload = {");993 try writer.writeAll(".payload = {");
...@@ -967,11 +998,9 @@ pub const DeclGen = struct {...@@ -967,11 +998,9 @@ pub const DeclGen = struct {
967 const field_name = ty.unionFields().keys()[index];998 const field_name = ty.unionFields().keys()[index];
968 if (field_ty.hasRuntimeBits()) {999 if (field_ty.hasRuntimeBits()) {
969 try writer.print(".{ } = ", .{fmtIdent(field_name)});1000 try writer.print(".{ } = ", .{fmtIdent(field_name)});
970 try dg.renderValue(writer, field_ty, union_obj.val, location);1001 try dg.renderValue(writer, field_ty, union_obj.val, .Initializer);
971 } else try writer.writeByte('0');1002 } else try writer.writeByte('0');
972 if (ty.unionTagTypeSafety()) |_| {1003 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
973 try writer.writeByte('}');
974 }
975 try writer.writeByte('}');1004 try writer.writeByte('}');
976 },1005 },
9771006
...@@ -1029,7 +1058,7 @@ pub const DeclGen = struct {...@@ -1029,7 +1058,7 @@ pub const DeclGen = struct {
1029 try w.writeAll(", ");1058 try w.writeAll(", ");
1030 }1059 }
1031 const name = CValue{ .arg = index };1060 const name = CValue{ .arg = index };
1032 try dg.renderTypeAndName(w, param_type, name, .Mut, 0);1061 try dg.renderTypeAndName(w, param_type, name, .Const, 0);
1033 index += 1;1062 index += 1;
1034 }1063 }
10351064
...@@ -1737,28 +1766,28 @@ pub const DeclGen = struct {...@@ -1737,28 +1766,28 @@ pub const DeclGen = struct {
1737 defer dg.typedefs.allocator.free(name_z);1766 defer dg.typedefs.allocator.free(name_z);
1738 const name_bytes = name_z[0 .. name_z.len + 1];1767 const name_bytes = name_z[0 .. name_z.len + 1];
17391768
1740 var tag_val_pl: Value.Payload.U32 = .{1769 var tag_pl: Value.Payload.U32 = .{
1741 .base = .{ .tag = .enum_field_index },1770 .base = .{ .tag = .enum_field_index },
1742 .data = @intCast(u32, index),1771 .data = @intCast(u32, index),
1743 };1772 };
1744 const tag_val = Value.initPayload(&tag_val_pl.base);1773 const tag_val = Value.initPayload(&tag_pl.base);
17451774
1746 var int_val_pl: Value.Payload.U64 = undefined;1775 var int_pl: Value.Payload.U64 = undefined;
1747 const int_val = tag_val.enumToInt(enum_ty, &int_val_pl);1776 const int_val = tag_val.enumToInt(enum_ty, &int_pl);
17481777
1749 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };1778 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
1750 const name_ty = Type.initPayload(&name_ty_pl.base);1779 const name_ty = Type.initPayload(&name_ty_pl.base);
17511780
1752 var name_val_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes };1781 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes };
1753 const name_val = Value.initPayload(&name_val_pl.base);1782 const name_val = Value.initPayload(&name_pl.base);
17541783
1755 var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };1784 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
1756 const len_val = Value.initPayload(&len_val_pl.base);1785 const len_val = Value.initPayload(&len_pl.base);
17571786
1758 try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)});1787 try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)});
1759 try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);1788 try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);
1760 try buffer.appendSlice(" = ");1789 try buffer.appendSlice(" = ");
1761 try dg.renderValue(bw, name_ty, name_val, .Other);1790 try dg.renderValue(bw, name_ty, name_val, .Initializer);
1762 try buffer.appendSlice(";\n return (");1791 try buffer.appendSlice(";\n return (");
1763 try dg.renderTypecast(bw, name_slice_ty);1792 try dg.renderTypecast(bw, name_slice_ty);
1764 try bw.print("){{{}, {}}};\n", .{1793 try bw.print("){{{}, {}}};\n", .{
...@@ -1893,8 +1922,8 @@ pub fn genErrDecls(o: *Object) !void {...@@ -1893,8 +1922,8 @@ pub fn genErrDecls(o: *Object) !void {
1893 var max_name_len: usize = 0;1922 var max_name_len: usize = 0;
1894 for (o.dg.module.error_name_list.items) |name, value| {1923 for (o.dg.module.error_name_list.items) |name, value| {
1895 max_name_len = std.math.max(name.len, max_name_len);1924 max_name_len = std.math.max(name.len, max_name_len);
1896 var err_val_pl = Value.Payload.Error{ .data = .{ .name = name } };1925 var err_pl = Value.Payload.Error{ .data = .{ .name = name } };
1897 try o.dg.renderValue(writer, Type.anyerror, Value.initPayload(&err_val_pl.base), .Other);1926 try o.dg.renderValue(writer, Type.anyerror, Value.initPayload(&err_pl.base), .Other);
1898 try writer.print(" = {d}u,\n", .{value});1927 try writer.print(" = {d}u,\n", .{value});
1899 }1928 }
1900 o.indent_writer.popIndent();1929 o.indent_writer.popIndent();
...@@ -1915,13 +1944,13 @@ pub fn genErrDecls(o: *Object) !void {...@@ -1915,13 +1944,13 @@ pub fn genErrDecls(o: *Object) !void {
1915 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };1944 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
1916 const name_ty = Type.initPayload(&name_ty_pl.base);1945 const name_ty = Type.initPayload(&name_ty_pl.base);
19171946
1918 var name_val_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z };1947 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z };
1919 const name_val = Value.initPayload(&name_val_pl.base);1948 const name_val = Value.initPayload(&name_pl.base);
19201949
1921 try writer.writeAll("static ");1950 try writer.writeAll("static ");
1922 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .Const, 0);1951 try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .Const, 0);
1923 try writer.writeAll(" = ");1952 try writer.writeAll(" = ");
1924 try o.dg.renderValue(writer, name_ty, name_val, .Other);1953 try o.dg.renderValue(writer, name_ty, name_val, .Initializer);
1925 try writer.writeAll(";\n");1954 try writer.writeAll(";\n");
1926 }1955 }
19271956
...@@ -1937,8 +1966,8 @@ pub fn genErrDecls(o: *Object) !void {...@@ -1937,8 +1966,8 @@ pub fn genErrDecls(o: *Object) !void {
1937 for (o.dg.module.error_name_list.items) |name, value| {1966 for (o.dg.module.error_name_list.items) |name, value| {
1938 if (value != 0) try writer.writeByte(',');1967 if (value != 0) try writer.writeByte(',');
19391968
1940 var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };1969 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
1941 const len_val = Value.initPayload(&len_val_pl.base);1970 const len_val = Value.initPayload(&len_pl.base);
19421971
1943 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{1972 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{
1944 fmtIdent(name),1973 fmtIdent(name),
...@@ -2031,7 +2060,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2031,7 +2060,7 @@ pub fn genDecl(o: *Object) !void {
2031 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");2060 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");
2032 try w.writeAll(" = ");2061 try w.writeAll(" = ");
2033 if (variable.init.tag() != .unreachable_value) {2062 if (variable.init.tag() != .unreachable_value) {
2034 try o.dg.renderValue(w, tv.ty, variable.init, .Other);2063 try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
2035 }2064 }
2036 try w.writeByte(';');2065 try w.writeByte(';');
2037 try o.indent_writer.insertNewline();2066 try o.indent_writer.insertNewline();
...@@ -2046,7 +2075,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2046,7 +2075,7 @@ pub fn genDecl(o: *Object) !void {
2046 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align");2075 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align");
20472076
2048 try writer.writeAll(" = ");2077 try writer.writeAll(" = ");
2049 try o.dg.renderValue(writer, tv.ty, tv.val, .Other);2078 try o.dg.renderValue(writer, tv.ty, tv.val, .Initializer);
2050 try writer.writeAll(";\n");2079 try writer.writeAll(";\n");
2051 }2080 }
2052}2081}
...@@ -2099,15 +2128,15 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2099,15 +2128,15 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2099 .unreach => try airUnreach(f),2128 .unreach => try airUnreach(f),
2100 .fence => try airFence(f, inst),2129 .fence => try airFence(f, inst),
21012130
2102 .ptr_add => try airPtrAddSub(f, inst, " + "),2131 .ptr_add => try airPtrAddSub(f, inst, '+'),
2103 .ptr_sub => try airPtrAddSub(f, inst, " - "),2132 .ptr_sub => try airPtrAddSub(f, inst, '-'),
21042133
2105 // TODO use a different strategy for add, sub, mul, div2134 // TODO use a different strategy for add, sub, mul, div
2106 // that communicates to the optimizer that wrapping is UB.2135 // that communicates to the optimizer that wrapping is UB.
2107 .add => try airBinOp (f, inst, " + "),2136 .add => try airBinOp(f, inst, "+"),
2108 .sub => try airBinOp (f, inst, " - "),2137 .sub => try airBinOp(f, inst, "-"),
2109 .mul => try airBinOp (f, inst, " * "),2138 .mul => try airBinOp(f, inst, "*"),
2110 .div_float, .div_exact => try airBinOp( f, inst, " / "),2139 .div_float, .div_exact => try airBinOp(f, inst, "/"),
21112140
2112 .rem => blk: {2141 .rem => blk: {
2113 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2142 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
...@@ -2115,7 +2144,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2115,7 +2144,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2115 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2144 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2116 // so we only check one.2145 // so we only check one.
2117 break :blk if (lhs_ty.isInt())2146 break :blk if (lhs_ty.isInt())
2118 try airBinOp(f, inst, " % ")2147 try airBinOp(f, inst, "%")
2119 else2148 else
2120 try airBinFloatOp(f, inst, "fmod"); // yes, @rem() => fmod()2149 try airBinFloatOp(f, inst, "fmod"); // yes, @rem() => fmod()
2121 },2150 },
...@@ -2125,21 +2154,21 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2125,21 +2154,21 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2125 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2154 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2126 // so we only check one.2155 // so we only check one.
2127 break :blk if (lhs_ty.isInt())2156 break :blk if (lhs_ty.isInt())
2128 try airBinOp(f, inst, " / ")2157 try airBinOp(f, inst, "/")
2129 else2158 else
2130 try airBinOpBuiltinCall(f, inst, "div_trunc");2159 try airBinOpBuiltinCall(f, inst, "div_trunc");
2131 },2160 },
2132 .div_floor => try airBinOpBuiltinCall(f, inst, "div_floor"),2161 .div_floor => try airBinOpBuiltinCall(f, inst, "div_floor"),
2133 .mod => try airBinOpBuiltinCall(f, inst, "mod"),2162 .mod => try airBinOpBuiltinCall(f, inst, "mod"),
21342163
2135 .addwrap => try airWrapOp(f, inst, " + ", "addw_"),2164 .addwrap => try airWrapOp(f, inst, "+", "add"),
2136 .subwrap => try airWrapOp(f, inst, " - ", "subw_"),2165 .subwrap => try airWrapOp(f, inst, "-", "sub"),
2137 .mulwrap => try airWrapOp(f, inst, " * ", "mulw_"),2166 .mulwrap => try airWrapOp(f, inst, "*", "mul"),
21382167
2139 .add_sat => try airSatOp(f, inst, "adds_"),2168 .add_sat => try airSatOp(f, inst, "add"),
2140 .sub_sat => try airSatOp(f, inst, "subs_"),2169 .sub_sat => try airSatOp(f, inst, "sub"),
2141 .mul_sat => try airSatOp(f, inst, "muls_"),2170 .mul_sat => try airSatOp(f, inst, "mul"),
2142 .shl_sat => try airSatOp(f, inst, "shls_"),2171 .shl_sat => try airSatOp(f, inst, "shl"),
21432172
2144 .neg => try airNeg(f, inst),2173 .neg => try airNeg(f, inst),
21452174
...@@ -2161,20 +2190,20 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2161,20 +2190,20 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
21612190
2162 .mul_add => try airMulAdd(f, inst),2191 .mul_add => try airMulAdd(f, inst),
21632192
2164 .add_with_overflow => try airOverflow(f, inst, "addo_", .range),2193 .add_with_overflow => try airOverflow(f, inst, "add", .range),
2165 .sub_with_overflow => try airOverflow(f, inst, "subo_", .range),2194 .sub_with_overflow => try airOverflow(f, inst, "sub", .range),
2166 .mul_with_overflow => try airOverflow(f, inst, "mulo_", .range),2195 .mul_with_overflow => try airOverflow(f, inst, "mul", .range),
2167 .shl_with_overflow => try airOverflow(f, inst, "shlo_", .bits),2196 .shl_with_overflow => try airOverflow(f, inst, "shl", .bits),
21682197
2169 .min => try airMinMax(f, inst, "<"),2198 .min => try airMinMax(f, inst, '<'),
2170 .max => try airMinMax(f, inst, ">"),2199 .max => try airMinMax(f, inst, '>'),
21712200
2172 .slice => try airSlice(f, inst),2201 .slice => try airSlice(f, inst),
21732202
2174 .cmp_gt => try airBinOp(f, inst, " > "),2203 .cmp_gt => try airBinOp(f, inst, ">"),
2175 .cmp_gte => try airBinOp(f, inst, " >= "),2204 .cmp_gte => try airBinOp(f, inst, ">="),
2176 .cmp_lt => try airBinOp(f, inst, " < "),2205 .cmp_lt => try airBinOp(f, inst, "<"),
2177 .cmp_lte => try airBinOp(f, inst, " <= "),2206 .cmp_lte => try airBinOp(f, inst, "<="),
21782207
2179 .cmp_eq => try airEquality(f, inst, "((", "=="),2208 .cmp_eq => try airEquality(f, inst, "((", "=="),
2180 .cmp_neq => try airEquality(f, inst, "!((", "!="),2209 .cmp_neq => try airEquality(f, inst, "!((", "!="),
...@@ -2183,13 +2212,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2183,13 +2212,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2183 .cmp_lt_errors_len => return f.fail("TODO: C backend: implement cmp_lt_errors_len", .{}),2212 .cmp_lt_errors_len => return f.fail("TODO: C backend: implement cmp_lt_errors_len", .{}),
21842213
2185 // bool_and and bool_or are non-short-circuit operations2214 // bool_and and bool_or are non-short-circuit operations
2186 .bool_and => try airBinOp(f, inst, " & "),2215 .bool_and, .bit_and => try airBinOp(f, inst, "&"),
2187 .bool_or => try airBinOp(f, inst, " | "),2216 .bool_or, .bit_or => try airBinOp(f, inst, "|"),
2188 .bit_and => try airBinOp(f, inst, " & "),2217 .xor => try airBinOp(f, inst, "^"),
2189 .bit_or => try airBinOp(f, inst, " | "),2218 .shr, .shr_exact => try airBinOp(f, inst, ">>"),
2190 .xor => try airBinOp(f, inst, " ^ "),2219 .shl, .shl_exact => try airBinOp(f, inst, "<<"),
2191 .shr, .shr_exact => try airBinOp(f, inst, " >> "),
2192 .shl, .shl_exact => try airBinOp(f, inst, " << "),
2193 .not => try airNot (f, inst),2220 .not => try airNot (f, inst),
21942221
2195 .optional_payload => try airOptionalPayload(f, inst),2222 .optional_payload => try airOptionalPayload(f, inst),
...@@ -2202,10 +2229,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2202,10 +2229,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2202 .is_err_ptr => try airIsErr(f, inst, true, "!="),2229 .is_err_ptr => try airIsErr(f, inst, true, "!="),
2203 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),2230 .is_non_err_ptr => try airIsErr(f, inst, true, "=="),
22042231
2205 .is_null => try airIsNull(f, inst, "==", ""),2232 .is_null => try airIsNull(f, inst, "==", false),
2206 .is_non_null => try airIsNull(f, inst, "!=", ""),2233 .is_non_null => try airIsNull(f, inst, "!=", false),
2207 .is_null_ptr => try airIsNull(f, inst, "==", "[0]"),2234 .is_null_ptr => try airIsNull(f, inst, "==", true),
2208 .is_non_null_ptr => try airIsNull(f, inst, "!=", "[0]"),2235 .is_non_null_ptr => try airIsNull(f, inst, "!=", true),
22092236
2210 .alloc => try airAlloc(f, inst),2237 .alloc => try airAlloc(f, inst),
2211 .ret_ptr => try airRetPtr(f, inst),2238 .ret_ptr => try airRetPtr(f, inst),
...@@ -2291,11 +2318,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2291,11 +2318,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2291 .field_parent_ptr => try airFieldParentPtr(f, inst),2318 .field_parent_ptr => try airFieldParentPtr(f, inst),
22922319
2293 .struct_field_val => try airStructFieldVal(f, inst),2320 .struct_field_val => try airStructFieldVal(f, inst),
2294 .slice_ptr => try airSliceField(f, inst, " = ", ".ptr;\n"),2321 .slice_ptr => try airSliceField(f, inst, false, "ptr"),
2295 .slice_len => try airSliceField(f, inst, " = ", ".len;\n"),2322 .slice_len => try airSliceField(f, inst, false, "len"),
22962323
2297 .ptr_slice_len_ptr => try airSliceField(f, inst, " = &", "->len;\n"),2324 .ptr_slice_len_ptr => try airSliceField(f, inst, true, "len"),
2298 .ptr_slice_ptr_ptr => try airSliceField(f, inst, " = &", "->ptr;\n"),2325 .ptr_slice_ptr_ptr => try airSliceField(f, inst, true, "ptr"),
22992326
2300 .ptr_elem_val => try airPtrElemVal(f, inst),2327 .ptr_elem_val => try airPtrElemVal(f, inst),
2301 .ptr_elem_ptr => try airPtrElemPtr(f, inst),2328 .ptr_elem_ptr => try airPtrElemPtr(f, inst),
...@@ -2303,8 +2330,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2303,8 +2330,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2303 .slice_elem_ptr => try airSliceElemPtr(f, inst),2330 .slice_elem_ptr => try airSliceElemPtr(f, inst),
2304 .array_elem_val => try airArrayElemVal(f, inst),2331 .array_elem_val => try airArrayElemVal(f, inst),
23052332
2306 .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""),2333 .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, false),
2307 .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"),2334 .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, true),
2308 .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst),2335 .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst),
2309 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),2336 .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
2310 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),2337 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
...@@ -2355,7 +2382,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2355,7 +2382,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2355 try writer.writeByte('}');2382 try writer.writeByte('}');
2356}2383}
23572384
2358fn airSliceField(f: *Function, inst: Air.Inst.Index, prefix: []const u8, suffix: []const u8) !CValue {2385fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {
2359 if (f.liveness.isUnused(inst)) return CValue.none;2386 if (f.liveness.isUnused(inst)) return CValue.none;
23602387
2361 const inst_ty = f.air.typeOfIndex(inst);2388 const inst_ty = f.air.typeOfIndex(inst);
...@@ -2363,9 +2390,12 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, prefix: []const u8, suffix:...@@ -2363,9 +2390,12 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, prefix: []const u8, suffix:
2363 const operand = try f.resolveInst(ty_op.operand);2390 const operand = try f.resolveInst(ty_op.operand);
2364 const writer = f.object.writer();2391 const writer = f.object.writer();
2365 const local = try f.allocLocal(inst_ty, .Const);2392 const local = try f.allocLocal(inst_ty, .Const);
2366 try writer.writeAll(prefix);2393 try writer.writeAll(" = ");
2367 try f.writeCValue(writer, operand);2394 if (is_ptr) try writer.writeByte('&');
2368 try writer.writeAll(suffix);2395 try f.writeCValue(writer, operand, .Other);
2396 try if (is_ptr) writer.writeAll("->") else writer.writeByte('.');
2397 try writer.writeAll(field_name);
2398 try writer.writeAll(";\n");
2369 return local;2399 return local;
2370}2400}
23712401
...@@ -2379,9 +2409,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2379,9 +2409,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2379 const writer = f.object.writer();2409 const writer = f.object.writer();
2380 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2410 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2381 try writer.writeAll(" = ");2411 try writer.writeAll(" = ");
2382 try f.writeCValue(writer, ptr);2412 try f.writeCValue(writer, ptr, .Other);
2383 try writer.writeByte('[');2413 try writer.writeByte('[');
2384 try f.writeCValue(writer, index);2414 try f.writeCValue(writer, index, .Other);
2385 try writer.writeAll("];\n");2415 try writer.writeAll("];\n");
2386 return local;2416 return local;
2387}2417}
...@@ -2403,10 +2433,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2403,10 +2433,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
2403 // It's a pointer to an array, so we need to de-reference.2433 // It's a pointer to an array, so we need to de-reference.
2404 try f.writeCValueDeref(writer, ptr);2434 try f.writeCValueDeref(writer, ptr);
2405 } else {2435 } else {
2406 try f.writeCValue(writer, ptr);2436 try f.writeCValue(writer, ptr, .Other);
2407 }2437 }
2408 try writer.writeAll(")[");2438 try writer.writeAll(")[");
2409 try f.writeCValue(writer, index);2439 try f.writeCValue(writer, index, .Other);
2410 try writer.writeAll("];\n");2440 try writer.writeAll("];\n");
2411 return local;2441 return local;
2412}2442}
...@@ -2421,9 +2451,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2421,9 +2451,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2421 const writer = f.object.writer();2451 const writer = f.object.writer();
2422 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2452 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2423 try writer.writeAll(" = ");2453 try writer.writeAll(" = ");
2424 try f.writeCValue(writer, slice);2454 try f.writeCValue(writer, slice, .Other);
2425 try writer.writeAll(".ptr[");2455 try writer.writeAll(".ptr[");
2426 try f.writeCValue(writer, index);2456 try f.writeCValue(writer, index, .Other);
2427 try writer.writeAll("];\n");2457 try writer.writeAll("];\n");
2428 return local;2458 return local;
2429}2459}
...@@ -2439,9 +2469,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2439,9 +2469,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
2439 const writer = f.object.writer();2469 const writer = f.object.writer();
2440 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2470 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2441 try writer.writeAll(" = &");2471 try writer.writeAll(" = &");
2442 try f.writeCValue(writer, slice);2472 try f.writeCValue(writer, slice, .Other);
2443 try writer.writeAll(".ptr[");2473 try writer.writeAll(".ptr[");
2444 try f.writeCValue(writer, index);2474 try f.writeCValue(writer, index, .Other);
2445 try writer.writeAll("];\n");2475 try writer.writeAll("];\n");
2446 return local;2476 return local;
2447}2477}
...@@ -2455,9 +2485,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2455,9 +2485,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2455 const writer = f.object.writer();2485 const writer = f.object.writer();
2456 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2486 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2457 try writer.writeAll(" = ");2487 try writer.writeAll(" = ");
2458 try f.writeCValue(writer, array);2488 try f.writeCValue(writer, array, .Other);
2459 try writer.writeByte('[');2489 try writer.writeByte('[');
2460 try f.writeCValue(writer, index);2490 try f.writeCValue(writer, index, .Other);
2461 try writer.writeAll("];\n");2491 try writer.writeAll("];\n");
2462 return local;2492 return local;
2463}2493}
...@@ -2523,11 +2553,11 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2523,11 +2553,11 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2523 // and thus we only need to know size/type information from the local type/dest.2553 // and thus we only need to know size/type information from the local type/dest.
2524 try writer.writeAll(";\n");2554 try writer.writeAll(";\n");
2525 try writer.writeAll("memcpy(");2555 try writer.writeAll("memcpy(");
2526 try f.writeCValue(writer, local);2556 try f.writeCValue(writer, local, .FunctionArgument);
2527 try writer.writeAll(", ");2557 try writer.writeAll(", ");
2528 try f.writeCValue(writer, operand);2558 try f.writeCValue(writer, operand, .FunctionArgument);
2529 try writer.writeAll(", sizeof(");2559 try writer.writeAll(", sizeof(");
2530 try f.writeCValue(writer, local);2560 try f.renderTypecast(writer, inst_ty);
2531 try writer.writeAll("));\n");2561 try writer.writeAll("));\n");
2532 } else {2562 } else {
2533 try writer.writeAll(" = ");2563 try writer.writeAll(" = ");
...@@ -2544,7 +2574,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2544,7 +2574,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index) !CValue {
2544 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {2574 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {
2545 const operand = try f.resolveInst(un_op);2575 const operand = try f.resolveInst(un_op);
2546 try writer.writeAll("return ");2576 try writer.writeAll("return ");
2547 try f.writeCValue(writer, operand);2577 try f.writeCValue(writer, operand, .Other);
2548 try writer.writeAll(";\n");2578 try writer.writeAll(";\n");
2549 } else if (ret_ty.isError()) {2579 } else if (ret_ty.isError()) {
2550 try writer.writeAll("return 0;");2580 try writer.writeAll("return 0;");
...@@ -2563,7 +2593,7 @@ fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2563,7 +2593,7 @@ fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2563 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {2593 if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {
2564 const ptr = try f.resolveInst(un_op);2594 const ptr = try f.resolveInst(un_op);
2565 try writer.writeAll("return *");2595 try writer.writeAll("return *");
2566 try f.writeCValue(writer, ptr);2596 try f.writeCValue(writer, ptr, .Other);
2567 try writer.writeAll(";\n");2597 try writer.writeAll(";\n");
2568 } else if (ret_ty.isError()) {2598 } else if (ret_ty.isError()) {
2569 try writer.writeAll("return 0;\n");2599 try writer.writeAll("return 0;\n");
...@@ -2586,7 +2616,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2586,7 +2616,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
2586 try writer.writeAll(" = (");2616 try writer.writeAll(" = (");
2587 try f.renderTypecast(writer, inst_ty);2617 try f.renderTypecast(writer, inst_ty);
2588 try writer.writeByte(')');2618 try writer.writeByte(')');
2589 try f.writeCValue(writer, operand);2619 try f.writeCValue(writer, operand, .Other);
2590 try writer.writeAll(";\n");2620 try writer.writeAll(";\n");
2591 return local;2621 return local;
2592}2622}
...@@ -2603,32 +2633,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2603,32 +2633,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
2603 const dest_int_info = inst_ty.intInfo(target);2633 const dest_int_info = inst_ty.intInfo(target);
2604 const dest_bits = dest_int_info.bits;2634 const dest_bits = dest_int_info.bits;
26052635
2606 try writer.writeAll(" = ");2636 try writer.writeAll(" = (");
2637 try f.renderTypecast(writer, inst_ty);
2638 try writer.writeByte(')');
26072639
2608 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {2640 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
2609 try f.writeCValue(writer, operand);2641 try f.writeCValue(writer, operand, .Other);
2610 try writer.writeAll(";\n");2642 try writer.writeAll(";\n");
2611 return local;2643 } else switch (dest_int_info.signedness) {
2612 }
2613
2614 switch (dest_int_info.signedness) {
2615 .unsigned => {2644 .unsigned => {
2616 try f.writeCValue(writer, operand);2645 var arena = std.heap.ArenaAllocator.init(f.object.dg.module.gpa);
2617 const mask = (@as(u65, 1) << @intCast(u7, dest_bits)) - 1;2646 defer arena.deinit();
2618 try writer.print(" & {d}ULL;\n", .{mask});2647
2619 return local;2648 const expected_contents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
2649 var stack align(@alignOf(expected_contents)) =
2650 std.heap.stackFallback(@sizeOf(expected_contents), arena.allocator());
2651
2652 const mask_val = try inst_ty.maxInt(stack.get(), target);
2653
2654 try writer.writeByte('(');
2655 try f.writeCValue(writer, operand, .Other);
2656 try writer.print(" & {x});\n", .{try f.fmtIntLiteral(inst_ty, mask_val)});
2620 },2657 },
2621 .signed => {2658 .signed => {
2622 const operand_ty = f.air.typeOf(ty_op.operand);2659 const operand_ty = f.air.typeOf(ty_op.operand);
2623 const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse2660 const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse
2624 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});2661 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
2625 const shift_rhs = c_bits - dest_bits;2662 var shift_pl = Value.Payload.U64{
2626 try writer.print("(int{d}_t)((uint{d}_t)", .{ c_bits, c_bits });2663 .base = .{ .tag = .int_u64 },
2627 try f.writeCValue(writer, operand);2664 .data = c_bits - dest_bits,
2628 try writer.print(" << {d}) >> {d};\n", .{ shift_rhs, shift_rhs });2665 };
2629 return local;2666 const shift_val = Value.initPayload(&shift_pl.base);
2667
2668 try writer.print("((int{d}_t)((uint{0d}_t)", .{c_bits});
2669 try f.writeCValue(writer, operand, .Other);
2670 try writer.print(" << {}) >> {0});\n", .{try f.fmtIntLiteral(Type.u8, shift_val)});
2630 },2671 },
2631 }2672 }
2673 return local;
2632}2674}
26332675
2634fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {2676fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -2640,18 +2682,18 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2640,18 +2682,18 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
2640 const operand = try f.resolveInst(un_op);2682 const operand = try f.resolveInst(un_op);
2641 const local = try f.allocLocal(inst_ty, .Const);2683 const local = try f.allocLocal(inst_ty, .Const);
2642 try writer.writeAll(" = ");2684 try writer.writeAll(" = ");
2643 try f.writeCValue(writer, operand);2685 try f.writeCValue(writer, operand, .Other);
2644 try writer.writeAll(";\n");2686 try writer.writeAll(";\n");
2645 return local;2687 return local;
2646}2688}
26472689
2648fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue {2690fn airStoreUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue {
2649 if (f.wantSafety()) {2691 if (f.wantSafety()) {
2650 const writer = f.object.writer();2692 const writer = f.object.writer();
2651 try writer.writeAll("memset(");2693 try writer.writeAll("memset(");
2652 try f.writeCValue(writer, dest_ptr);2694 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
2653 try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)});2695 try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)});
2654 try f.writeCValueDeref(writer, dest_ptr);2696 try f.renderTypecast(writer, lhs_child_ty);
2655 try writer.writeAll("));\n");2697 try writer.writeAll("));\n");
2656 }2698 }
2657 return CValue.none;2699 return CValue.none;
...@@ -2660,8 +2702,8 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue {...@@ -2660,8 +2702,8 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue {
2660fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {2702fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2661 // *a = b;2703 // *a = b;
2662 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2704 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2663 const lhs_child_type = f.air.typeOf(bin_op.lhs).childType();2705 const lhs_child_ty = f.air.typeOf(bin_op.lhs).childType();
2664 if (!lhs_child_type.hasRuntimeBitsIgnoreComptime()) return CValue.none;2706 if (!lhs_child_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
26652707
2666 const dest_ptr = try f.resolveInst(bin_op.lhs);2708 const dest_ptr = try f.resolveInst(bin_op.lhs);
2667 const src_val = try f.resolveInst(bin_op.rhs);2709 const src_val = try f.resolveInst(bin_op.rhs);
...@@ -2671,14 +2713,14 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2671,14 +2713,14 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2671 const src_val_is_undefined =2713 const src_val_is_undefined =
2672 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;2714 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
2673 if (src_val_is_undefined)2715 if (src_val_is_undefined)
2674 return try airStoreUndefined(f, dest_ptr);2716 return try airStoreUndefined(f, lhs_child_ty, dest_ptr);
26752717
2676 const writer = f.object.writer();2718 const writer = f.object.writer();
2677 if (lhs_child_type.zigTypeTag() == .Array) {2719 if (lhs_child_ty.zigTypeTag() == .Array) {
2678 // For this memcpy to safely work we need the rhs to have the same2720 // For this memcpy to safely work we need the rhs to have the same
2679 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).2721 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
2680 const rhs_type = f.air.typeOf(bin_op.rhs);2722 const rhs_type = f.air.typeOf(bin_op.rhs);
2681 assert(rhs_type.eql(lhs_child_type, f.object.dg.module));2723 assert(rhs_type.eql(lhs_child_ty, f.object.dg.module));
26822724
2683 // If the source is a constant, writeCValue will emit a brace initialization2725 // If the source is a constant, writeCValue will emit a brace initialization
2684 // so work around this by initializing into new local.2726 // so work around this by initializing into new local.
...@@ -2686,37 +2728,30 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2686,37 +2728,30 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2686 const array_src = if (src_val == .constant) blk: {2728 const array_src = if (src_val == .constant) blk: {
2687 const new_local = try f.allocLocal(rhs_type, .Const);2729 const new_local = try f.allocLocal(rhs_type, .Const);
2688 try writer.writeAll(" = ");2730 try writer.writeAll(" = ");
2689 try f.writeCValue(writer, src_val);2731 try f.writeCValue(writer, src_val, .Initializer);
2690 try writer.writeByte(';');2732 try writer.writeAll(";\n");
2691 try f.object.indent_writer.insertNewline();
26922733
2693 break :blk new_local;2734 break :blk new_local;
2694 } else src_val;2735 } else src_val;
26952736
2696 try writer.writeAll("memcpy(");2737 try writer.writeAll("memcpy(");
2697 try f.writeCValue(writer, dest_ptr);2738 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
2698 try writer.writeAll(", ");2739 try writer.writeAll(", ");
2699 try f.writeCValue(writer, array_src);2740 try f.writeCValue(writer, array_src, .FunctionArgument);
2700 try writer.writeAll(", sizeof(");2741 try writer.writeAll(", sizeof(");
2701 try f.writeCValue(writer, array_src);2742 try f.renderTypecast(writer, lhs_child_ty);
2702 try writer.writeAll("));\n");2743 try writer.writeAll("));\n");
2703 } else {2744 } else {
2704 try f.writeCValueDeref(writer, dest_ptr);2745 try f.writeCValueDeref(writer, dest_ptr);
2705 try writer.writeAll(" = ");2746 try writer.writeAll(" = ");
2706 try f.writeCValue(writer, src_val);2747 try f.writeCValue(writer, src_val, .Other);
2707 try writer.writeAll(";\n");2748 try writer.writeAll(";\n");
2708 }2749 }
2709 return CValue.none;2750 return CValue.none;
2710}2751}
27112752
2712fn airWrapOp(2753fn airWrapOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, fn_name: []const u8) !CValue {
2713 f: *Function,2754 if (f.liveness.isUnused(inst)) return CValue.none;
2714 inst: Air.Inst.Index,
2715 str_op: [*:0]const u8,
2716 fn_op: [*:0]const u8,
2717) !CValue {
2718 if (f.liveness.isUnused(inst))
2719 return CValue.none;
27202755
2721 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2756 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2722 const inst_ty = f.air.typeOfIndex(inst);2757 const inst_ty = f.air.typeOfIndex(inst);
...@@ -2725,26 +2760,18 @@ fn airWrapOp(...@@ -2725,26 +2760,18 @@ fn airWrapOp(
2725 const bits = int_info.bits;2760 const bits = int_info.bits;
27262761
2727 // if it's an unsigned int with non-arbitrary bit size then we can just add2762 // if it's an unsigned int with non-arbitrary bit size then we can just add
2728 if (int_info.signedness == .unsigned) {2763 if (int_info.signedness == .unsigned and bits == toCIntBits(bits)) {
2729 const ok_bits = switch (bits) {2764 return try airBinOp(f, inst, operator);
2730 8, 16, 32, 64, 128 => true,
2731 else => false,
2732 };
2733 if (ok_bits or inst_ty.tag() != .int_unsigned) {
2734 return try airBinOp(f, inst, str_op);
2735 }
2736 }2765 }
27372766
2738 if (bits > 64) {2767 if (bits > 64) return f.fail("TODO: C backend: airWrapOp for large integers", .{});
2739 return f.fail("TODO: C backend: airWrapOp for large integers", .{});
2740 }
27412768
2742 const lhs = try f.resolveInst(bin_op.lhs);2769 const lhs = try f.resolveInst(bin_op.lhs);
2743 const rhs = try f.resolveInst(bin_op.rhs);2770 const rhs = try f.resolveInst(bin_op.rhs);
2744 const w = f.object.writer();2771 const w = f.object.writer();
27452772
2746 const ret = try f.allocLocal(inst_ty, .Mut);2773 const local = try f.allocLocal(inst_ty, .Mut);
2747 try w.print(" = zig_{s}", .{fn_op});2774 try w.print(" = zig_{s}w_", .{fn_name});
27482775
2749 switch (inst_ty.tag()) {2776 switch (inst_ty.tag()) {
2750 .isize => try w.writeAll("isize"),2777 .isize => try w.writeAll("isize"),
...@@ -2766,9 +2793,9 @@ fn airWrapOp(...@@ -2766,9 +2793,9 @@ fn airWrapOp(
2766 }2793 }
27672794
2768 try w.writeByte('(');2795 try w.writeByte('(');
2769 try f.writeCValue(w, lhs);2796 try f.writeCValue(w, lhs, .FunctionArgument);
2770 try w.writeAll(", ");2797 try w.writeAll(", ");
2771 try f.writeCValue(w, rhs);2798 try f.writeCValue(w, rhs, .FunctionArgument);
2772 {2799 {
2773 var arena = std.heap.ArenaAllocator.init(f.object.dg.module.gpa);2800 var arena = std.heap.ArenaAllocator.init(f.object.dg.module.gpa);
2774 defer arena.deinit();2801 defer arena.deinit();
...@@ -2787,12 +2814,11 @@ fn airWrapOp(...@@ -2787,12 +2814,11 @@ fn airWrapOp(
2787 }2814 }
2788 try f.object.indent_writer.insertNewline();2815 try f.object.indent_writer.insertNewline();
27892816
2790 return ret;2817 return local;
2791}2818}
27922819
2793fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {2820fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_name: []const u8) !CValue {
2794 if (f.liveness.isUnused(inst))2821 if (f.liveness.isUnused(inst)) return CValue.none;
2795 return CValue.none;
27962822
2797 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2823 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2798 const inst_ty = f.air.typeOfIndex(inst);2824 const inst_ty = f.air.typeOfIndex(inst);
...@@ -2800,22 +2826,14 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {...@@ -2800,22 +2826,14 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2800 const int_info = inst_ty.intInfo(target);2826 const int_info = inst_ty.intInfo(target);
2801 const bits = int_info.bits;2827 const bits = int_info.bits;
28022828
2803 switch (bits) {2829 if (bits > 64) return f.object.dg.fail("TODO: C backend: airSatOp for large integers", .{});
2804 8, 16, 32, 64, 128 => {},
2805 else => return f.object.dg.fail("TODO: C backend: airSatOp for non power of 2 integers", .{}),
2806 }
2807
2808 // if it's an unsigned int with non-arbitrary bit size then we can just add
2809 if (bits > 64) {
2810 return f.object.dg.fail("TODO: C backend: airSatOp for large integers", .{});
2811 }
28122830
2813 const lhs = try f.resolveInst(bin_op.lhs);2831 const lhs = try f.resolveInst(bin_op.lhs);
2814 const rhs = try f.resolveInst(bin_op.rhs);2832 const rhs = try f.resolveInst(bin_op.rhs);
2815 const w = f.object.writer();2833 const w = f.object.writer();
28162834
2817 const ret = try f.allocLocal(inst_ty, .Mut);2835 const local = try f.allocLocal(inst_ty, .Mut);
2818 try w.print(" = zig_{s}", .{fn_op});2836 try w.print(" = zig_{s}s_", .{fn_name});
28192837
2820 switch (inst_ty.tag()) {2838 switch (inst_ty.tag()) {
2821 .isize => try w.writeAll("isize"),2839 .isize => try w.writeAll("isize"),
...@@ -2837,9 +2855,9 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {...@@ -2837,9 +2855,9 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2837 }2855 }
28382856
2839 try w.writeByte('(');2857 try w.writeByte('(');
2840 try f.writeCValue(w, lhs);2858 try f.writeCValue(w, lhs, .FunctionArgument);
2841 try w.writeAll(", ");2859 try w.writeAll(", ");
2842 try f.writeCValue(w, rhs);2860 try f.writeCValue(w, rhs, .FunctionArgument);
2843 {2861 {
2844 var arena = std.heap.ArenaAllocator.init(f.object.dg.module.gpa);2862 var arena = std.heap.ArenaAllocator.init(f.object.dg.module.gpa);
2845 defer arena.deinit();2863 defer arena.deinit();
...@@ -2858,10 +2876,10 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {...@@ -2858,10 +2876,10 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2858 }2876 }
2859 try f.object.indent_writer.insertNewline();2877 try f.object.indent_writer.insertNewline();
28602878
2861 return ret;2879 return local;
2862}2880}
28632881
2864fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8, kind: enum { range, bits }) !CValue {2882fn airOverflow(f: *Function, inst: Air.Inst.Index, fn_name: []const u8, kind: enum { range, bits }) !CValue {
2865 if (f.liveness.isUnused(inst))2883 if (f.liveness.isUnused(inst))
2866 return CValue.none;2884 return CValue.none;
28672885
...@@ -2879,19 +2897,18 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8, kin...@@ -2879,19 +2897,18 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8, kin
2879 const c_bits = toCIntBits(int_info.bits) orelse2897 const c_bits = toCIntBits(int_info.bits) orelse
2880 return f.fail("TODO: C backend: implement integer arithmetic larger than 128 bits", .{});2898 return f.fail("TODO: C backend: implement integer arithmetic larger than 128 bits", .{});
28812899
2882 const ret = try f.allocLocal(inst_ty, .Mut);2900 const local = try f.allocLocal(inst_ty, .Mut);
2883 try w.writeByte(';');2901 try w.writeAll(";\n");
2884 try f.object.indent_writer.insertNewline();
2885 try f.writeCValue(w, ret);
28862902
2887 try w.print(".field_1 = zig_{s}{c}{d}(", .{2903 try f.writeCValue(w, local, .Other);
2888 op_abbrev, signAbbrev(int_info.signedness), c_bits,2904 try w.print(".field_1 = zig_{s}o_{c}{d}(", .{
2905 fn_name, signAbbrev(int_info.signedness), c_bits,
2889 });2906 });
2890 try f.writeCValue(w, lhs);2907 try f.writeCValue(w, lhs, .FunctionArgument);
2891 try w.writeAll(", ");2908 try w.writeAll(", ");
2892 try f.writeCValue(w, rhs);2909 try f.writeCValue(w, rhs, .FunctionArgument);
2893 try w.writeAll(", &");2910 try w.writeAll(", &");
2894 try f.writeCValue(w, ret);2911 try f.writeCValue(w, local, .Other);
2895 try w.writeAll(".field_0, ");2912 try w.writeAll(".field_0, ");
2896 switch (kind) {2913 switch (kind) {
2897 .range => {2914 .range => {
...@@ -2916,7 +2933,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8, kin...@@ -2916,7 +2933,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8, kin
2916 try w.print("{x});\n", .{try f.fmtIntLiteral(Type.u8, bits_val)});2933 try w.print("{x});\n", .{try f.fmtIntLiteral(Type.u8, bits_val)});
2917 },2934 },
2918 }2935 }
2919 return ret;2936 return local;
2920}2937}
29212938
2922fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {2939fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -2932,13 +2949,13 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2932,13 +2949,13 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
29322949
2933 try writer.writeAll(" = ");2950 try writer.writeAll(" = ");
2934 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');2951 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
2935 try f.writeCValue(writer, op);2952 try f.writeCValue(writer, op, .Other);
2936 try writer.writeAll(";\n");2953 try writer.writeAll(";\n");
29372954
2938 return local;2955 return local;
2939}2956}
29402957
2941fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {2958fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue {
2942 if (f.liveness.isUnused(inst))2959 if (f.liveness.isUnused(inst))
2943 return CValue.none;2960 return CValue.none;
29442961
...@@ -2951,9 +2968,11 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue...@@ -2951,9 +2968,11 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue
2951 const local = try f.allocLocal(inst_ty, .Const);2968 const local = try f.allocLocal(inst_ty, .Const);
29522969
2953 try writer.writeAll(" = ");2970 try writer.writeAll(" = ");
2954 try f.writeCValue(writer, lhs);2971 try f.writeCValue(writer, lhs, .Other);
2955 try writer.print("{s}", .{operator});2972 try writer.writeByte(' ');
2956 try f.writeCValue(writer, rhs);2973 try writer.writeAll(operator);
2974 try writer.writeByte(' ');
2975 try f.writeCValue(writer, rhs, .Other);
2957 try writer.writeAll(";\n");2976 try writer.writeAll(";\n");
29582977
2959 return local;2978 return local;
...@@ -2983,31 +3002,31 @@ fn airEquality(...@@ -2983,31 +3002,31 @@ fn airEquality(
2983 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload3002 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
29843003
2985 try writer.writeAll(negate_prefix);3004 try writer.writeAll(negate_prefix);
2986 try f.writeCValue(writer, lhs);3005 try f.writeCValue(writer, lhs, .Other);
2987 try writer.writeAll(".is_null && ");3006 try writer.writeAll(".is_null && ");
2988 try f.writeCValue(writer, rhs);3007 try f.writeCValue(writer, rhs, .Other);
2989 try writer.writeAll(".is_null) || (");3008 try writer.writeAll(".is_null) || (");
2990 try f.writeCValue(writer, lhs);3009 try f.writeCValue(writer, lhs, .Other);
2991 try writer.writeAll(".payload == ");3010 try writer.writeAll(".payload == ");
2992 try f.writeCValue(writer, rhs);3011 try f.writeCValue(writer, rhs, .Other);
2993 try writer.writeAll(".payload && ");3012 try writer.writeAll(".payload && ");
2994 try f.writeCValue(writer, lhs);3013 try f.writeCValue(writer, lhs, .Other);
2995 try writer.writeAll(".is_null == ");3014 try writer.writeAll(".is_null == ");
2996 try f.writeCValue(writer, rhs);3015 try f.writeCValue(writer, rhs, .Other);
2997 try writer.writeAll(".is_null));\n");3016 try writer.writeAll(".is_null));\n");
29983017
2999 return local;3018 return local;
3000 }3019 }
30013020
3002 try f.writeCValue(writer, lhs);3021 try f.writeCValue(writer, lhs, .Other);
3003 try writer.writeAll(eq_op_str);3022 try writer.writeAll(eq_op_str);
3004 try f.writeCValue(writer, rhs);3023 try f.writeCValue(writer, rhs, .Other);
3005 try writer.writeAll(";\n");3024 try writer.writeAll(";\n");
30063025
3007 return local;3026 return local;
3008}3027}
30093028
3010fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {3029fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3011 if (f.liveness.isUnused(inst)) return CValue.none;3030 if (f.liveness.isUnused(inst)) return CValue.none;
30123031
3013 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3032 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
...@@ -3031,17 +3050,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV...@@ -3031,17 +3050,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV
3031 try writer.writeAll(" = (");3050 try writer.writeAll(" = (");
3032 try f.renderTypecast(writer, inst_ty);3051 try f.renderTypecast(writer, inst_ty);
3033 try writer.writeAll(")(((uintptr_t)");3052 try writer.writeAll(")(((uintptr_t)");
3034 try f.writeCValue(writer, lhs);3053 try f.writeCValue(writer, lhs, .Other);
3035 try writer.print("){s}(", .{operator});3054 try writer.writeAll(") ");
3036 try f.writeCValue(writer, rhs);3055 try writer.writeByte(operator);
3056 try writer.writeAll(" (");
3057 try f.writeCValue(writer, rhs, .Other);
3037 try writer.writeAll("*sizeof(");3058 try writer.writeAll("*sizeof(");
3038 try f.renderTypecast(writer, elem_ty);3059 try f.renderTypecast(writer, elem_ty);
3039 try writer.print(")));\n", .{});3060 try writer.writeAll(")));\n");
30403061
3041 return local;3062 return local;
3042}3063}
30433064
3044fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue {3065fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3045 if (f.liveness.isUnused(inst)) return CValue.none;3066 if (f.liveness.isUnused(inst)) return CValue.none;
30463067
3047 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3068 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
...@@ -3054,13 +3075,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu...@@ -3054,13 +3075,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu
30543075
3055 // (lhs <> rhs) ? lhs : rhs3076 // (lhs <> rhs) ? lhs : rhs
3056 try writer.writeAll(" = (");3077 try writer.writeAll(" = (");
3057 try f.writeCValue(writer, lhs);3078 try f.writeCValue(writer, lhs, .Other);
3058 try writer.print("{s}", .{operator});3079 try writer.writeByte(' ');
3059 try f.writeCValue(writer, rhs);3080 try writer.writeByte(operator);
3081 try writer.writeByte(' ');
3082 try f.writeCValue(writer, rhs, .Other);
3060 try writer.writeAll(") ? ");3083 try writer.writeAll(") ? ");
3061 try f.writeCValue(writer, lhs);3084 try f.writeCValue(writer, lhs, .Other);
3062 try writer.writeAll(" : ");3085 try writer.writeAll(" : ");
3063 try f.writeCValue(writer, rhs);3086 try f.writeCValue(writer, rhs, .Other);
3064 try writer.writeAll(";\n");3087 try writer.writeAll(";\n");
30653088
3066 return local;3089 return local;
...@@ -3082,9 +3105,9 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3082,9 +3105,9 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
3082 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3105 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3083 try f.renderTypecast(writer, inst_ty.slicePtrFieldType(&buf));3106 try f.renderTypecast(writer, inst_ty.slicePtrFieldType(&buf));
3084 try writer.writeByte(')');3107 try writer.writeByte(')');
3085 try f.writeCValue(writer, ptr);3108 try f.writeCValue(writer, ptr, .Other);
3086 try writer.writeAll(", ");3109 try writer.writeAll(", ");
3087 try f.writeCValue(writer, len);3110 try f.writeCValue(writer, len, .Initializer);
3088 try writer.writeAll("};\n");3111 try writer.writeAll("};\n");
30893112
3090 return local;3113 return local;
...@@ -3151,7 +3174,7 @@ fn airCall(...@@ -3151,7 +3174,7 @@ fn airCall(
3151 }3174 }
3152 // Fall back to function pointer call.3175 // Fall back to function pointer call.
3153 const callee = try f.resolveInst(pl_op.operand);3176 const callee = try f.resolveInst(pl_op.operand);
3154 try f.writeCValue(writer, callee);3177 try f.writeCValue(writer, callee, .Other);
3155 }3178 }
31563179
3157 try writer.writeByte('(');3180 try writer.writeByte('(');
...@@ -3171,12 +3194,7 @@ fn airCall(...@@ -3171,12 +3194,7 @@ fn airCall(
3171 if (ty.isVolatilePtr()) try writer.writeAll(" volatile");3194 if (ty.isVolatilePtr()) try writer.writeAll(" volatile");
3172 try writer.writeAll(" *)");3195 try writer.writeAll(" *)");
3173 }3196 }
3174 if (f.air.value(arg)) |val| {3197 try f.writeCValue(writer, try f.resolveInst(arg), .FunctionArgument);
3175 try f.object.dg.renderValue(writer, f.air.typeOf(arg), val, .FunctionArgument);
3176 } else {
3177 const val = try f.resolveInst(arg);
3178 try f.writeCValue(writer, val);
3179 }
3180 args_written += 1;3198 args_written += 1;
3181 }3199 }
3182 try writer.writeAll(");\n");3200 try writer.writeAll(");\n");
...@@ -3286,18 +3304,18 @@ fn lowerTry(...@@ -3286,18 +3304,18 @@ fn lowerTry(
3286 } else {3304 } else {
3287 try writer.writeAll("if(");3305 try writer.writeAll("if(");
3288 }3306 }
3289 try f.writeCValue(writer, err_union);3307 try f.writeCValue(writer, err_union, .Other);
3290 try writer.writeByte(')');3308 try writer.writeByte(')');
3291 break :err;3309 break :err;
3292 }3310 }
3293 if (operand_is_ptr or isByRef(err_union_ty)) {3311 if (operand_is_ptr or isByRef(err_union_ty)) {
3294 try writer.writeAll("if(");3312 try writer.writeAll("if(");
3295 try f.writeCValue(writer, err_union);3313 try f.writeCValue(writer, err_union, .Other);
3296 try writer.writeAll("->error)");3314 try writer.writeAll("->error)");
3297 break :err;3315 break :err;
3298 }3316 }
3299 try writer.writeAll("if(");3317 try writer.writeAll("if(");
3300 try f.writeCValue(writer, err_union);3318 try f.writeCValue(writer, err_union, .Other);
3301 try writer.writeAll(".error)");3319 try writer.writeAll(".error)");
3302 }3320 }
33033321
...@@ -3318,20 +3336,20 @@ fn lowerTry(...@@ -3318,20 +3336,20 @@ fn lowerTry(
3318 if (is_array) {3336 if (is_array) {
3319 try writer.writeAll(";\n");3337 try writer.writeAll(";\n");
3320 try writer.writeAll("memcpy(");3338 try writer.writeAll("memcpy(");
3321 try f.writeCValue(writer, local);3339 try f.writeCValue(writer, local, .FunctionArgument);
3322 try writer.writeAll(", ");3340 try writer.writeAll(", ");
3323 try f.writeCValue(writer, err_union);3341 try f.writeCValue(writer, err_union, .Other);
3324 try writer.writeAll(".payload, sizeof(");3342 try writer.writeAll(".payload, sizeof(");
3325 try f.writeCValue(writer, local);3343 try f.renderTypecast(writer, payload_ty);
3326 try writer.writeAll("));\n");3344 try writer.writeAll("));\n");
3327 } else {3345 } else {
3328 if (operand_is_ptr or isByRef(payload_ty)) {3346 if (operand_is_ptr or isByRef(payload_ty)) {
3329 try writer.writeAll(" = &");3347 try writer.writeAll(" = &");
3330 try f.writeCValue(writer, err_union);3348 try f.writeCValue(writer, err_union, .Other);
3331 try writer.writeAll("->payload;\n");3349 try writer.writeAll("->payload;\n");
3332 } else {3350 } else {
3333 try writer.writeAll(" = ");3351 try writer.writeAll(" = ");
3334 try f.writeCValue(writer, err_union);3352 try f.writeCValue(writer, err_union, .Other);
3335 try writer.writeAll(".payload;\n");3353 try writer.writeAll(".payload;\n");
3336 }3354 }
3337 }3355 }
...@@ -3347,9 +3365,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3347,9 +3365,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
3347 // If result is .none then the value of the block is unused.3365 // If result is .none then the value of the block is unused.
3348 if (result != .none) {3366 if (result != .none) {
3349 const operand = try f.resolveInst(branch.operand);3367 const operand = try f.resolveInst(branch.operand);
3350 try f.writeCValue(writer, result);3368 try f.writeCValue(writer, result, .Other);
3351 try writer.writeAll(" = ");3369 try writer.writeAll(" = ");
3352 try f.writeCValue(writer, operand);3370 try f.writeCValue(writer, operand, .Other);
3353 try writer.writeAll(";\n");3371 try writer.writeAll(";\n");
3354 }3372 }
33553373
...@@ -3374,7 +3392,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3374,7 +3392,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3374 try f.renderTypecast(writer, inst_ty);3392 try f.renderTypecast(writer, inst_ty);
33753393
3376 try writer.writeByte(')');3394 try writer.writeByte(')');
3377 try f.writeCValue(writer, operand);3395 try f.writeCValue(writer, operand, .Other);
3378 try writer.writeAll(";\n");3396 try writer.writeAll(";\n");
3379 return local;3397 return local;
3380 }3398 }
...@@ -3383,11 +3401,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3383,11 +3401,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3383 try writer.writeAll(";\n");3401 try writer.writeAll(";\n");
33843402
3385 try writer.writeAll("memcpy(&");3403 try writer.writeAll("memcpy(&");
3386 try f.writeCValue(writer, local);3404 try f.writeCValue(writer, local, .Other);
3387 try writer.writeAll(", &");3405 try writer.writeAll(", &");
3388 try f.writeCValue(writer, operand);3406 try f.writeCValue(writer, operand, .Other);
3389 try writer.writeAll(", sizeof(");3407 try writer.writeAll(", sizeof(");
3390 try f.writeCValue(writer, local);3408 try f.renderTypecast(writer, inst_ty);
3391 try writer.writeAll("));\n");3409 try writer.writeAll("));\n");
33923410
3393 return local;3411 return local;
...@@ -3456,7 +3474,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3456,7 +3474,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
3456 const writer = f.object.writer();3474 const writer = f.object.writer();
34573475
3458 try writer.writeAll("if (");3476 try writer.writeAll("if (");
3459 try f.writeCValue(writer, cond);3477 try f.writeCValue(writer, cond, .Other);
3460 try writer.writeAll(") ");3478 try writer.writeAll(") ");
3461 try genBody(f, then_body);3479 try genBody(f, then_body);
3462 try writer.writeAll(" else ");3480 try writer.writeAll(" else ");
...@@ -3475,7 +3493,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3475,7 +3493,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
34753493
3476 try writer.writeAll("switch (");3494 try writer.writeAll("switch (");
3477 if (condition_ty.tag() == .bool) try writer.writeAll("(int)");3495 if (condition_ty.tag() == .bool) try writer.writeAll("(int)");
3478 try f.writeCValue(writer, condition);3496 try f.writeCValue(writer, condition, .Other);
3479 try writer.writeAll(") {");3497 try writer.writeAll(") {");
3480 f.object.indent_writer.pushIndent();3498 f.object.indent_writer.pushIndent();
34813499
...@@ -3527,7 +3545,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3527,7 +3545,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3527 const local = try f.allocLocal(inst_ty, .Mut);3545 const local = try f.allocLocal(inst_ty, .Mut);
3528 if (f.wantSafety()) {3546 if (f.wantSafety()) {
3529 try writer.writeAll(" = ");3547 try writer.writeAll(" = ");
3530 try f.writeCValue(writer, .{ .undef = inst_ty });3548 try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);
3531 }3549 }
3532 try writer.writeAll(";\n");3550 try writer.writeAll(";\n");
3533 break :local local;3551 break :local local;
...@@ -3555,7 +3573,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3555,7 +3573,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3555 try writer.writeAll("\")");3573 try writer.writeAll("\")");
3556 if (f.wantSafety()) {3574 if (f.wantSafety()) {
3557 try writer.writeAll(" = ");3575 try writer.writeAll(" = ");
3558 try f.writeCValue(writer, .{ .undef = output_ty });3576 try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer);
3559 }3577 }
3560 try writer.writeAll(";\n");3578 try writer.writeAll(";\n");
3561 } else if (constraint.len < 2 or constraint[0] != '=') {3579 } else if (constraint.len < 2 or constraint[0] != '=') {
...@@ -3581,7 +3599,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3581,7 +3599,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3581 try writer.writeAll(" __asm(\"");3599 try writer.writeAll(" __asm(\"");
3582 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);3600 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
3583 try writer.writeAll("\") = ");3601 try writer.writeAll("\") = ");
3584 try f.writeCValue(writer, try f.resolveInst(input));3602 try f.writeCValue(writer, try f.resolveInst(input), .Initializer);
3585 try writer.writeAll(";\n");3603 try writer.writeAll(";\n");
3586 } else if (constraint.len >= 1 and std.mem.indexOfScalar(u8, "=+&%", constraint[0]) == null) {3604 } else if (constraint.len >= 1 and std.mem.indexOfScalar(u8, "=+&%", constraint[0]) == null) {
3587 const input_val = try f.resolveInst(input);3605 const input_val = try f.resolveInst(input);
...@@ -3590,7 +3608,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3590,7 +3608,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3590 .local = input_locals_begin + index,3608 .local = input_locals_begin + index,
3591 }, .Const, 0);3609 }, .Const, 0);
3592 try writer.writeAll(" = ");3610 try writer.writeAll(" = ");
3593 try f.writeCValue(writer, input_val);3611 try f.writeCValue(writer, input_val, .Initializer);
3594 try writer.writeAll(";\n");3612 try writer.writeAll(";\n");
3595 }3613 }
3596 } else {3614 } else {
...@@ -3626,7 +3644,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3626,7 +3644,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3626 try writer.writeByte(' ');3644 try writer.writeByte(' ');
3627 if (constraint[1] == '{') {3645 if (constraint[1] == '{') {
3628 try writer.print("{s}(", .{fmtStringLiteral("=r")});3646 try writer.print("{s}(", .{fmtStringLiteral("=r")});
3629 try f.writeCValue(writer, .{ .local = output_locals_begin + index });3647 try f.writeCValue(writer, .{ .local = output_locals_begin + index }, .Other);
3630 } else {3648 } else {
3631 try writer.print("{s}(", .{fmtStringLiteral(constraint)});3649 try writer.print("{s}(", .{fmtStringLiteral(constraint)});
3632 try f.writeCValueDeref(writer, try f.resolveInst(output));3650 try f.writeCValueDeref(writer, try f.resolveInst(output));
...@@ -3646,13 +3664,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3646,13 +3664,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3646 try writer.writeByte(' ');3664 try writer.writeByte(' ');
3647 if (constraint[0] == '{') {3665 if (constraint[0] == '{') {
3648 try writer.print("{s}(", .{fmtStringLiteral("r")});3666 try writer.print("{s}(", .{fmtStringLiteral("r")});
3649 try f.writeCValue(writer, .{ .local = input_locals_begin + index });3667 try f.writeCValue(writer, .{ .local = input_locals_begin + index }, .Other);
3650 } else {3668 } else {
3651 const input_val = try f.resolveInst(input);3669 const input_val = try f.resolveInst(input);
3652 try writer.print("{s}(", .{fmtStringLiteral(constraint)});3670 try writer.print("{s}(", .{fmtStringLiteral(constraint)});
3653 try f.writeCValue(writer, if (input_val == .constant) CValue{3671 try f.writeCValue(writer, if (input_val == .constant)
3654 .local = input_locals_begin + index,3672 CValue{ .local = input_locals_begin + index }
3655 } else input_val);3673 else
3674 input_val, .Other);
3656 }3675 }
3657 try writer.writeByte(')');3676 try writer.writeByte(')');
3658 }3677 }
...@@ -3683,11 +3702,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3683,11 +3702,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3683 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3702 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
36843703
3685 if (constraint[1] == '{') {3704 if (constraint[1] == '{') {
3686 try f.writeCValueDeref(writer, if (output == .none) CValue{3705 try f.writeCValueDeref(writer, if (output == .none)
3687 .local_ref = local.local,3706 CValue{ .local_ref = local.local }
3688 } else try f.resolveInst(output));3707 else
3708 try f.resolveInst(output));
3689 try writer.writeAll(" = ");3709 try writer.writeAll(" = ");
3690 try f.writeCValue(writer, .{ .local = output_locals_begin + index });3710 try f.writeCValue(writer, .{ .local = output_locals_begin + index }, .Other);
3691 try writer.writeAll(";\n");3711 try writer.writeAll(";\n");
3692 }3712 }
3693 }3713 }
...@@ -3698,8 +3718,8 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3698,8 +3718,8 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3698fn airIsNull(3718fn airIsNull(
3699 f: *Function,3719 f: *Function,
3700 inst: Air.Inst.Index,3720 inst: Air.Inst.Index,
3701 operator: [*:0]const u8,3721 operator: []const u8,
3702 deref_suffix: [*:0]const u8,3722 is_ptr: bool,
3703) !CValue {3723) !CValue {
3704 if (f.liveness.isUnused(inst))3724 if (f.liveness.isUnused(inst))
3705 return CValue.none;3725 return CValue.none;
...@@ -3709,25 +3729,23 @@ fn airIsNull(...@@ -3709,25 +3729,23 @@ fn airIsNull(
3709 const operand = try f.resolveInst(un_op);3729 const operand = try f.resolveInst(un_op);
37103730
3711 const local = try f.allocLocal(Type.initTag(.bool), .Const);3731 const local = try f.allocLocal(Type.initTag(.bool), .Const);
3712 try writer.writeAll(" = (");3732 try writer.writeAll(" = ");
3713 try f.writeCValue(writer, operand);3733 try if (is_ptr) f.writeCValueDeref(writer, operand) else f.writeCValue(writer, operand, .Other);
37143734
3715 const ty = f.air.typeOf(un_op);3735 const operand_ty = f.air.typeOf(un_op);
3716 var opt_buf: Type.Payload.ElemType = undefined;3736 const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty;
3717 const payload_ty = if (deref_suffix[0] != 0)3737 var payload_buf: Type.Payload.ElemType = undefined;
3718 ty.childType().optionalChild(&opt_buf)3738 const payload_ty = optional_ty.optionalChild(&payload_buf);
3719 else
3720 ty.optionalChild(&opt_buf);
37213739
3722 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3740 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3723 try writer.print("){s} {s} true;\n", .{ deref_suffix, operator });3741 try writer.print(" {s} true;\n", .{operator});
3724 } else if (ty.isPtrLikeOptional()) {3742 } else if (operand_ty.isPtrLikeOptional()) {
3725 // operand is a regular pointer, test `operand !=/== NULL`3743 // operand is a regular pointer, test `operand !=/== NULL`
3726 try writer.print("){s} {s} NULL;\n", .{ deref_suffix, operator });3744 try writer.print(" {s} NULL;\n", .{operator});
3727 } else if (payload_ty.zigTypeTag() == .ErrorSet) {3745 } else if (payload_ty.zigTypeTag() == .ErrorSet) {
3728 try writer.print("){s} {s} 0;\n", .{ deref_suffix, operator });3746 try writer.print(" {s} 0;\n", .{operator});
3729 } else {3747 } else {
3730 try writer.print("){s}.is_null {s} true;\n", .{ deref_suffix, operator });3748 try writer.print(".is_null {s} true;\n", .{operator});
3731 }3749 }
3732 return local;3750 return local;
3733}3751}
...@@ -3754,7 +3772,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3754,7 +3772,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
3754 const inst_ty = f.air.typeOfIndex(inst);3772 const inst_ty = f.air.typeOfIndex(inst);
3755 const local = try f.allocLocal(inst_ty, .Const);3773 const local = try f.allocLocal(inst_ty, .Const);
3756 try writer.writeAll(" = (");3774 try writer.writeAll(" = (");
3757 try f.writeCValue(writer, operand);3775 try f.writeCValue(writer, operand, .Other);
3758 try writer.writeAll(").payload;\n");3776 try writer.writeAll(").payload;\n");
3759 return local;3777 return local;
3760}3778}
...@@ -3781,7 +3799,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3781,7 +3799,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
37813799
3782 const local = try f.allocLocal(inst_ty, .Const);3800 const local = try f.allocLocal(inst_ty, .Const);
3783 try writer.writeAll(" = &(");3801 try writer.writeAll(" = &(");
3784 try f.writeCValue(writer, operand);3802 try f.writeCValue(writer, operand, .Other);
3785 try writer.writeAll(")->payload;\n");3803 try writer.writeAll(")->payload;\n");
3786 return local;3804 return local;
3787}3805}
...@@ -3882,7 +3900,7 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -3882,7 +3900,7 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
3882 try writer.writeAll(" = (");3900 try writer.writeAll(" = (");
3883 try f.renderTypecast(writer, inst_ty);3901 try f.renderTypecast(writer, inst_ty);
3884 try writer.writeByte(')');3902 try writer.writeByte(')');
3885 try f.writeCValue(writer, struct_ptr);3903 try f.writeCValue(writer, struct_ptr, .Other);
3886 try writer.writeAll(";\n");3904 try writer.writeAll(";\n");
3887 }3905 }
3888 return local;3906 return local;
...@@ -3920,15 +3938,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3920,15 +3938,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
3920 if (is_array) {3938 if (is_array) {
3921 try writer.writeAll(";\n");3939 try writer.writeAll(";\n");
3922 try writer.writeAll("memcpy(");3940 try writer.writeAll("memcpy(");
3923 try f.writeCValue(writer, local);3941 try f.writeCValue(writer, local, .FunctionArgument);
3924 try writer.writeAll(", ");3942 try writer.writeAll(", ");
3925 try f.writeCValue(writer, struct_byval);3943 try f.writeCValue(writer, struct_byval, .Other);
3926 try writer.print(".{s}{ }, sizeof(", .{ payload, fmtIdent(field_name) });3944 try writer.print(".{s}{ }, sizeof(", .{ payload, fmtIdent(field_name) });
3927 try f.writeCValue(writer, local);3945 try f.renderTypecast(writer, inst_ty);
3928 try writer.writeAll("));\n");3946 try writer.writeAll("));\n");
3929 } else {3947 } else {
3930 try writer.writeAll(" = ");3948 try writer.writeAll(" = ");
3931 try f.writeCValue(writer, struct_byval);3949 try f.writeCValue(writer, struct_byval, .Other);
3932 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });3950 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });
3933 }3951 }
3934 return local;3952 return local;
...@@ -3956,7 +3974,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3956,7 +3974,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3956 }3974 }
3957 const local = try f.allocLocal(inst_ty, .Const);3975 const local = try f.allocLocal(inst_ty, .Const);
3958 try writer.writeAll(" = *");3976 try writer.writeAll(" = *");
3959 try f.writeCValue(writer, operand);3977 try f.writeCValue(writer, operand, .Other);
3960 try writer.writeAll(";\n");3978 try writer.writeAll(";\n");
3961 return local;3979 return local;
3962 }3980 }
...@@ -3972,13 +3990,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3972,13 +3990,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
3972 if (operand_ty.zigTypeTag() == .Pointer) {3990 if (operand_ty.zigTypeTag() == .Pointer) {
3973 try f.writeCValueDeref(writer, operand);3991 try f.writeCValueDeref(writer, operand);
3974 } else {3992 } else {
3975 try f.writeCValue(writer, operand);3993 try f.writeCValue(writer, operand, .Other);
3976 }3994 }
3977 try writer.writeAll(".error;\n");3995 try writer.writeAll(".error;\n");
3978 return local;3996 return local;
3979}3997}
39803998
3981fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]const u8) !CValue {3999fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3982 if (f.liveness.isUnused(inst))4000 if (f.liveness.isUnused(inst))
3983 return CValue.none;4001 return CValue.none;
39844002
...@@ -3994,13 +4012,15 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]c...@@ -3994,13 +4012,15 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]c
3994 }4012 }
39954013
3996 const inst_ty = f.air.typeOfIndex(inst);4014 const inst_ty = f.air.typeOfIndex(inst);
3997 const maybe_deref = if (operand_is_ptr) "->" else ".";
39984015
3999 const local = try f.allocLocal(inst_ty, .Const);4016 const local = try f.allocLocal(inst_ty, .Const);
4000 try writer.print(" = {s}(", .{maybe_addrof});4017 try writer.writeAll(" = ");
4001 try f.writeCValue(writer, operand);4018 if (is_ptr) try writer.writeByte('&');
40024019 try writer.writeByte('(');
4003 try writer.print("){s}payload;\n", .{maybe_deref});4020 try f.writeCValue(writer, operand, .Other);
4021 try writer.writeByte(')');
4022 try if (operand_is_ptr) writer.writeAll("->") else writer.writeByte('.');
4023 try writer.writeAll("payload;\n");
4004 return local;4024 return local;
4005}4025}
40064026
...@@ -4020,7 +4040,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4020,7 +4040,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
4020 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.4040 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.
4021 const local = try f.allocLocal(inst_ty, .Const);4041 const local = try f.allocLocal(inst_ty, .Const);
4022 try writer.writeAll(" = { .payload = ");4042 try writer.writeAll(" = { .payload = ");
4023 try f.writeCValue(writer, operand);4043 try f.writeCValue(writer, operand, .Initializer);
4024 try writer.writeAll(", .is_null = false };\n");4044 try writer.writeAll(", .is_null = false };\n");
4025 return local;4045 return local;
4026}4046}
...@@ -4039,9 +4059,9 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4039,9 +4059,9 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
40394059
4040 const local = try f.allocLocal(err_un_ty, .Const);4060 const local = try f.allocLocal(err_un_ty, .Const);
4041 try writer.writeAll(" = { .payload = ");4061 try writer.writeAll(" = { .payload = ");
4042 try f.writeCValue(writer, .{ .undef = payload_ty });4062 try f.writeCValue(writer, .{ .undef = payload_ty }, .Initializer);
4043 try writer.writeAll(", .error = ");4063 try writer.writeAll(", .error = ");
4044 try f.writeCValue(writer, operand);4064 try f.writeCValue(writer, operand, .Initializer);
4045 try writer.writeAll(" };\n");4065 try writer.writeAll(" };\n");
4046 return local;4066 return local;
4047}4067}
...@@ -4104,33 +4124,29 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4104,33 +4124,29 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
41044124
4105 const inst_ty = f.air.typeOfIndex(inst);4125 const inst_ty = f.air.typeOfIndex(inst);
4106 const payload_ty = inst_ty.errorUnionPayload();4126 const payload_ty = inst_ty.errorUnionPayload();
4127 const error_ty = inst_ty.errorUnionSet();
4107 const is_array = payload_ty.zigTypeTag() == .Array;4128 const is_array = payload_ty.zigTypeTag() == .Array;
4108 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);4129 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4109 try writer.writeAll(" = { .payload = ");4130 try writer.writeAll(" = { .payload = ");
4110 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand);4131 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer);
4111 try writer.print(", .error = {} }};\n", .{4132 try writer.writeAll(", .error = ");
4112 try f.fmtIntLiteral(inst_ty.errorUnionSet(), Value.zero),4133 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
4113 });4134 try writer.writeAll(" };\n");
41144135
4115 if (is_array) {4136 if (is_array) {
4116 try writer.writeAll("memcpy(");4137 try writer.writeAll("memcpy(");
4117 try f.writeCValue(writer, local);4138 try f.writeCValue(writer, local, .Other);
4118 try writer.writeAll(".payload, ");4139 try writer.writeAll(".payload, ");
4119 try f.writeCValue(writer, operand);4140 try f.writeCValue(writer, operand, .FunctionArgument);
4120 try writer.writeAll(", sizeof(");4141 try writer.writeAll(", sizeof(");
4121 try f.writeCValue(writer, local);4142 try f.renderTypecast(writer, payload_ty);
4122 try writer.writeAll(".payload));\n");4143 try writer.writeAll("));\n");
4123 }4144 }
41244145
4125 return local;4146 return local;
4126}4147}
41274148
4128fn airIsErr(4149fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
4129 f: *Function,
4130 inst: Air.Inst.Index,
4131 is_ptr: bool,
4132 op_str: [*:0]const u8,
4133) !CValue {
4134 if (f.liveness.isUnused(inst))4150 if (f.liveness.isUnused(inst))
4135 return CValue.none;4151 return CValue.none;
41364152
...@@ -4146,18 +4162,17 @@ fn airIsErr(...@@ -4146,18 +4162,17 @@ fn airIsErr(
4146 try writer.writeAll(" = ");4162 try writer.writeAll(" = ");
41474163
4148 if (error_ty.errorSetIsEmpty()) {4164 if (error_ty.errorSetIsEmpty()) {
4149 try writer.print("0 {s} 0;\n", .{op_str});4165 try writer.writeByte('0');
4150 } else {4166 } else {
4151 if (is_ptr) {4167 try f.writeCValue(writer, operand, .Other);
4152 try f.writeCValueDeref(writer, operand);
4153 } else {
4154 try f.writeCValue(writer, operand);
4155 }
4156 if (payload_ty.hasRuntimeBits()) {4168 if (payload_ty.hasRuntimeBits()) {
4157 try writer.writeAll(".error");4169 try if (is_ptr) writer.writeAll("->") else writer.writeByte('.');
4170 try writer.writeAll("error");
4158 }4171 }
4159 try writer.print(" {s} 0;\n", .{op_str});
4160 }4172 }
4173 try writer.writeByte(' ');
4174 try writer.writeAll(operator);
4175 try writer.writeAll(" 0;\n");
4161 return local;4176 return local;
4162}4177}
41634178
...@@ -4177,13 +4192,16 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4177,13 +4192,16 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4177 // Unfortunately, C does not support any equivalent to4192 // Unfortunately, C does not support any equivalent to
4178 // &(*(void *)p)[0], although LLVM does via GetElementPtr4193 // &(*(void *)p)[0], although LLVM does via GetElementPtr
4179 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4194 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4180 try f.writeCValue(writer, CValue{ .undef = inst_ty.slicePtrFieldType(&buf) });4195 try f.writeCValue(writer, CValue{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
4181 } else {4196 } else {
4182 try writer.writeAll("&(");4197 try writer.writeAll("&(");
4183 try f.writeCValueDeref(writer, operand);4198 try f.writeCValueDeref(writer, operand);
4184 try writer.writeAll(")[0]");4199 try writer.writeAll(")[0]");
4185 }4200 }
4186 try writer.print(", .len = {d} }};\n", .{array_len});4201
4202 var len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = array_len };
4203 const len_val = Value.initPayload(&len_pl.base);
4204 try writer.print(", .len = {} }};\n", .{try f.fmtIntLiteral(Type.usize, len_val)});
4187 return local;4205 return local;
4188}4206}
41894207
...@@ -4199,7 +4217,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4199,7 +4217,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
4199 const operand = try f.resolveInst(ty_op.operand);4217 const operand = try f.resolveInst(ty_op.operand);
42004218
4201 try writer.writeAll(" = ");4219 try writer.writeAll(" = ");
4202 try f.writeCValue(writer, operand);4220 try f.writeCValue(writer, operand, .Other);
4203 try writer.writeAll(";\n");4221 try writer.writeAll(";\n");
4204 return local;4222 return local;
4205}4223}
...@@ -4216,7 +4234,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4216,7 +4234,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
4216 try writer.writeAll(" = (");4234 try writer.writeAll(" = (");
4217 try f.renderTypecast(writer, inst_ty);4235 try f.renderTypecast(writer, inst_ty);
4218 try writer.writeByte(')');4236 try writer.writeByte(')');
4219 try f.writeCValue(writer, operand);4237 try f.writeCValue(writer, operand, .Other);
4220 try writer.writeAll(";\n");4238 try writer.writeAll(";\n");
4221 return local;4239 return local;
4222}4240}
...@@ -4237,7 +4255,7 @@ fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !C...@@ -4237,7 +4255,7 @@ fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !C
42374255
4238 try writer.print(" = zig_{s}_", .{fn_name});4256 try writer.print(" = zig_{s}_", .{fn_name});
4239 try writer.print("{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits });4257 try writer.print("{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits });
4240 try f.writeCValue(writer, try f.resolveInst(operand));4258 try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument);
4241 try writer.print(", {d});\n", .{int_info.bits});4259 try writer.print(", {d});\n", .{int_info.bits});
4242 return local;4260 return local;
4243}4261}
...@@ -4266,9 +4284,9 @@ fn airBinOpBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u...@@ -4266,9 +4284,9 @@ fn airBinOpBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u
4266 }4284 }
42674285
4268 try writer.writeByte('(');4286 try writer.writeByte('(');
4269 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs));4287 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
4270 try writer.writeAll(", ");4288 try writer.writeAll(", ");
4271 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs));4289 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
4272 try writer.writeAll(");\n");4290 try writer.writeAll(");\n");
4273 return local;4291 return local;
4274}4292}
...@@ -4287,12 +4305,12 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -4287,12 +4305,12 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
4287 const local = try f.allocLocal(inst_ty, .Mut);4305 const local = try f.allocLocal(inst_ty, .Mut);
4288 try writer.writeAll(" = ");4306 try writer.writeAll(" = ");
4289 if (is_struct) try writer.writeAll("{ .payload = ");4307 if (is_struct) try writer.writeAll("{ .payload = ");
4290 try f.writeCValue(writer, expected_value);4308 try f.writeCValue(writer, expected_value, .Initializer);
4291 if (is_struct) try writer.writeAll(", .is_null = false }");4309 if (is_struct) try writer.writeAll(", .is_null = false }");
4292 try writer.writeAll(";\n");4310 try writer.writeAll(";\n");
42934311
4294 if (is_struct) {4312 if (is_struct) {
4295 try f.writeCValue(writer, local);4313 try f.writeCValue(writer, local, .Other);
4296 try writer.writeAll(".is_null = ");4314 try writer.writeAll(".is_null = ");
4297 } else {4315 } else {
4298 try writer.writeAll("if (");4316 try writer.writeAll("if (");
...@@ -4302,14 +4320,14 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -4302,14 +4320,14 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
4302 try writer.writeByte(')');4320 try writer.writeByte(')');
4303 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");4321 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4304 try writer.writeAll(" *)");4322 try writer.writeAll(" *)");
4305 try f.writeCValue(writer, ptr);4323 try f.writeCValue(writer, ptr, .Other);
4306 try writer.writeAll(", ");4324 try writer.writeAll(", ");
4307 try f.writeCValue(writer, local);4325 try f.writeCValue(writer, local, .FunctionArgument);
4308 if (is_struct) {4326 if (is_struct) {
4309 try writer.writeAll(".payload");4327 try writer.writeAll(".payload");
4310 }4328 }
4311 try writer.writeAll(", ");4329 try writer.writeAll(", ");
4312 try f.writeCValue(writer, new_value);4330 try f.writeCValue(writer, new_value, .FunctionArgument);
4313 try writer.writeAll(", ");4331 try writer.writeAll(", ");
4314 try writeMemoryOrder(writer, extra.successOrder());4332 try writeMemoryOrder(writer, extra.successOrder());
4315 try writer.writeAll(", ");4333 try writer.writeAll(", ");
...@@ -4320,7 +4338,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -4320,7 +4338,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
4320 } else {4338 } else {
4321 try writer.writeAll(") {\n");4339 try writer.writeAll(") {\n");
4322 f.object.indent_writer.pushIndent();4340 f.object.indent_writer.pushIndent();
4323 try f.writeCValue(writer, local);4341 try f.writeCValue(writer, local, .Other);
4324 try writer.writeAll(" = NULL;\n");4342 try writer.writeAll(" = NULL;\n");
4325 f.object.indent_writer.popIndent();4343 f.object.indent_writer.popIndent();
4326 try writer.writeAll("}\n");4344 try writer.writeAll("}\n");
...@@ -4353,9 +4371,9 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4353,9 +4371,9 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
4353 }4371 }
4354 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");4372 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4355 try writer.writeAll(" *)");4373 try writer.writeAll(" *)");
4356 try f.writeCValue(writer, ptr);4374 try f.writeCValue(writer, ptr, .Other);
4357 try writer.writeAll(", ");4375 try writer.writeAll(", ");
4358 try f.writeCValue(writer, operand);4376 try f.writeCValue(writer, operand, .FunctionArgument);
4359 try writer.writeAll(", ");4377 try writer.writeAll(", ");
4360 try writeMemoryOrder(writer, extra.ordering());4378 try writeMemoryOrder(writer, extra.ordering());
4361 try writer.writeAll(");\n");4379 try writer.writeAll(");\n");
...@@ -4379,7 +4397,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4379,7 +4397,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
4379 try writer.writeByte(')');4397 try writer.writeByte(')');
4380 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");4398 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4381 try writer.writeAll(" *)");4399 try writer.writeAll(" *)");
4382 try f.writeCValue(writer, ptr);4400 try f.writeCValue(writer, ptr, .Other);
4383 try writer.writeAll(", ");4401 try writer.writeAll(", ");
4384 try writeMemoryOrder(writer, atomic_load.order);4402 try writeMemoryOrder(writer, atomic_load.order);
4385 try writer.writeAll(");\n");4403 try writer.writeAll(");\n");
...@@ -4399,9 +4417,9 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -4399,9 +4417,9 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
4399 try writer.writeByte(')');4417 try writer.writeByte(')');
4400 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");4418 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
4401 try writer.writeAll(" *)");4419 try writer.writeAll(" *)");
4402 try f.writeCValue(writer, ptr);4420 try f.writeCValue(writer, ptr, .Other);
4403 try writer.writeAll(", ");4421 try writer.writeAll(", ");
4404 try f.writeCValue(writer, element);4422 try f.writeCValue(writer, element, .FunctionArgument);
4405 try writer.print(", {s});\n", .{order});4423 try writer.print(", {s});\n", .{order});
44064424
4407 return CValue.none;4425 return CValue.none;
...@@ -4416,11 +4434,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4416,11 +4434,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {
4416 const writer = f.object.writer();4434 const writer = f.object.writer();
44174435
4418 try writer.writeAll("memset(");4436 try writer.writeAll("memset(");
4419 try f.writeCValue(writer, dest_ptr);4437 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
4420 try writer.writeAll(", ");4438 try writer.writeAll(", ");
4421 try f.writeCValue(writer, value);4439 try f.writeCValue(writer, value, .FunctionArgument);
4422 try writer.writeAll(", ");4440 try writer.writeAll(", ");
4423 try f.writeCValue(writer, len);4441 try f.writeCValue(writer, len, .FunctionArgument);
4424 try writer.writeAll(");\n");4442 try writer.writeAll(");\n");
44254443
4426 return CValue.none;4444 return CValue.none;
...@@ -4435,11 +4453,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4435,11 +4453,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
4435 const writer = f.object.writer();4453 const writer = f.object.writer();
44364454
4437 try writer.writeAll("memcpy(");4455 try writer.writeAll("memcpy(");
4438 try f.writeCValue(writer, dest_ptr);4456 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
4439 try writer.writeAll(", ");4457 try writer.writeAll(", ");
4440 try f.writeCValue(writer, src_ptr);4458 try f.writeCValue(writer, src_ptr, .FunctionArgument);
4441 try writer.writeAll(", ");4459 try writer.writeAll(", ");
4442 try f.writeCValue(writer, len);4460 try f.writeCValue(writer, len, .FunctionArgument);
4443 try writer.writeAll(");\n");4461 try writer.writeAll(");\n");
44444462
4445 return CValue.none;4463 return CValue.none;
...@@ -4457,9 +4475,9 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4457,9 +4475,9 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
4457 if (layout.tag_size == 0) return CValue.none;4475 if (layout.tag_size == 0) return CValue.none;
44584476
4459 try writer.writeByte('(');4477 try writer.writeByte('(');
4460 try f.writeCValue(writer, union_ptr);4478 try f.writeCValue(writer, union_ptr, .Other);
4461 try writer.writeAll(")->tag = ");4479 try writer.writeAll(")->tag = ");
4462 try f.writeCValue(writer, new_tag);4480 try f.writeCValue(writer, new_tag, .Other);
4463 try writer.writeAll(";\n");4481 try writer.writeAll(";\n");
44644482
4465 return CValue.none;4483 return CValue.none;
...@@ -4481,7 +4499,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4481,7 +4499,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
4481 if (layout.tag_size == 0) return CValue.none;4499 if (layout.tag_size == 0) return CValue.none;
44824500
4483 try writer.writeAll(" = ");4501 try writer.writeAll(" = ");
4484 try f.writeCValue(writer, operand);4502 try f.writeCValue(writer, operand, .Other);
4485 try writer.writeAll(".tag;\n");4503 try writer.writeAll(".tag;\n");
4486 return local;4504 return local;
4487}4505}
...@@ -4497,7 +4515,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4497,7 +4515,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
4497 const writer = f.object.writer();4515 const writer = f.object.writer();
4498 const local = try f.allocLocal(inst_ty, .Const);4516 const local = try f.allocLocal(inst_ty, .Const);
4499 try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)});4517 try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)});
4500 try f.writeCValue(writer, operand);4518 try f.writeCValue(writer, operand, .Other);
4501 try writer.writeAll(");\n");4519 try writer.writeAll(");\n");
45024520
4503 try f.object.dg.fwd_decl.writer().writeAll("// This is where the fwd decl for tagName ended up\n");4521 try f.object.dg.fwd_decl.writer().writeAll("// This is where the fwd decl for tagName ended up\n");
...@@ -4515,7 +4533,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4515,7 +4533,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
4515 const local = try f.allocLocal(inst_ty, .Const);4533 const local = try f.allocLocal(inst_ty, .Const);
45164534
4517 try writer.writeAll(" = zig_errorName[");4535 try writer.writeAll(" = zig_errorName[");
4518 try f.writeCValue(writer, operand);4536 try f.writeCValue(writer, operand, .Other);
4519 try writer.writeAll("];\n");4537 try writer.writeAll("];\n");
4520 return local;4538 return local;
4521}4539}
...@@ -4600,12 +4618,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4600,12 +4618,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
4600 var empty = true;4618 var empty = true;
4601 for (elements) |element| {4619 for (elements) |element| {
4602 if (!empty) try writer.writeAll(", ");4620 if (!empty) try writer.writeAll(", ");
4603 try f.writeCValue(writer, try f.resolveInst(element));4621 try f.writeCValue(writer, try f.resolveInst(element), .Initializer);
4604 empty = false;4622 empty = false;
4605 }4623 }
4606 if (inst_ty.sentinel()) |sentinel| {4624 if (inst_ty.sentinel()) |sentinel| {
4607 if (!empty) try writer.writeAll(", ");4625 if (!empty) try writer.writeAll(", ");
4608 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);4626 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer);
4609 empty = false;4627 empty = false;
4610 }4628 }
4611 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});4629 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
...@@ -4625,7 +4643,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4625,7 +4643,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
4625 try f.writeCValue(writer, switch (element_ty.zigTypeTag()) {4643 try f.writeCValue(writer, switch (element_ty.zigTypeTag()) {
4626 .Array => CValue{ .undef = element_ty },4644 .Array => CValue{ .undef = element_ty },
4627 else => try f.resolveInst(element),4645 else => try f.resolveInst(element),
4628 });4646 }, .Initializer);
4629 empty = false;4647 empty = false;
4630 }4648 }
4631 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});4649 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
...@@ -4647,12 +4665,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4647,12 +4665,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
46474665
4648 try writer.writeAll(";\n");4666 try writer.writeAll(";\n");
4649 try writer.writeAll("memcpy(");4667 try writer.writeAll("memcpy(");
4650 try f.writeCValue(writer, local);4668 try f.writeCValue(writer, local, .Other);
4651 try writer.print(".{ }, ", .{fmtIdent(field_name)});4669 try writer.print(".{ }, ", .{fmtIdent(field_name)});
4652 try f.writeCValue(writer, try f.resolveInst(element));4670 try f.writeCValue(writer, try f.resolveInst(element), .FunctionArgument);
4653 try writer.writeAll(", sizeof(");4671 try writer.writeAll(", sizeof(");
4654 try f.writeCValue(writer, local);4672 try f.renderTypecast(writer, element_ty);
4655 try writer.print(".{ }));\n", .{fmtIdent(field_name)});4673 try writer.writeAll("));\n");
4656 }4674 }
4657 },4675 },
4658 .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),4676 .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),
...@@ -4681,14 +4699,14 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4681,14 +4699,14 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
4681 if (layout.tag_size != 0) {4699 if (layout.tag_size != 0) {
4682 const field_index = tag_ty.enumFieldIndex(field_name).?;4700 const field_index = tag_ty.enumFieldIndex(field_name).?;
46834701
4684 var tag_val_pl: Value.Payload.U32 = .{4702 var tag_pl: Value.Payload.U32 = .{
4685 .base = .{ .tag = .enum_field_index },4703 .base = .{ .tag = .enum_field_index },
4686 .data = @intCast(u32, field_index),4704 .data = @intCast(u32, field_index),
4687 };4705 };
4688 const tag_val = Value.initPayload(&tag_val_pl.base);4706 const tag_val = Value.initPayload(&tag_pl.base);
46894707
4690 var int_val_pl: Value.Payload.U64 = undefined;4708 var int_pl: Value.Payload.U64 = undefined;
4691 const int_val = tag_val.enumToInt(tag_ty, &int_val_pl);4709 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
46924710
4693 try writer.print(".tag = {}, ", .{try f.fmtIntLiteral(tag_ty, int_val)});4711 try writer.print(".tag = {}, ", .{try f.fmtIntLiteral(tag_ty, int_val)});
4694 }4712 }
...@@ -4696,7 +4714,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4696,7 +4714,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
4696 }4714 }
46974715
4698 try writer.print(".{ } = ", .{fmtIdent(field_name)});4716 try writer.print(".{ } = ", .{fmtIdent(field_name)});
4699 try f.writeCValue(writer, payload);4717 try f.writeCValue(writer, payload, .Initializer);
47004718
4701 if (union_ty.unionTagTypeSafety()) |_| try writer.writeByte('}');4719 if (union_ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
4702 try writer.writeAll("};\n");4720 try writer.writeAll("};\n");
...@@ -4716,7 +4734,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4716,7 +4734,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
4716 const ptr = try f.resolveInst(prefetch.ptr);4734 const ptr = try f.resolveInst(prefetch.ptr);
4717 const writer = f.object.writer();4735 const writer = f.object.writer();
4718 try writer.writeAll("zig_prefetch(");4736 try writer.writeAll("zig_prefetch(");
4719 try f.writeCValue(writer, ptr);4737 try f.writeCValue(writer, ptr, .FunctionArgument);
4720 try writer.print(", {d}, {d});\n", .{4738 try writer.print(", {d}, {d});\n", .{
4721 @enumToInt(prefetch.rw), prefetch.locality,4739 @enumToInt(prefetch.rw), prefetch.locality,
4722 });4740 });
...@@ -4748,7 +4766,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4748,7 +4766,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
47484766
4749 try writer.writeAll(" = ");4767 try writer.writeAll(" = ");
4750 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});4768 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
4751 try f.writeCValue(writer, operand);4769 try f.writeCValue(writer, operand, .FunctionArgument);
4752 try writer.writeAll(");\n");4770 try writer.writeAll(");\n");
4753 return local;4771 return local;
4754}4772}
...@@ -4762,7 +4780,7 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4762,7 +4780,7 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {
4762 const operand = try f.resolveInst(un_op);4780 const operand = try f.resolveInst(un_op);
4763 const local = try f.allocLocal(inst_ty, .Const);4781 const local = try f.allocLocal(inst_ty, .Const);
4764 try writer.writeAll(" = -");4782 try writer.writeAll(" = -");
4765 try f.writeCValue(writer, operand);4783 try f.writeCValue(writer, operand, .Other);
4766 try writer.writeAll(";\n");4784 try writer.writeAll(";\n");
4767 return local;4785 return local;
4768}4786}
...@@ -4777,7 +4795,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, fn_name: []const u8) !CValue...@@ -4777,7 +4795,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, fn_name: []const u8) !CValue
4777 try writer.writeAll(" = ");4795 try writer.writeAll(" = ");
4778 try f.renderFloatFnName(fn_name, inst_ty);4796 try f.renderFloatFnName(fn_name, inst_ty);
4779 try writer.writeByte('(');4797 try writer.writeByte('(');
4780 try f.writeCValue(writer, operand);4798 try f.writeCValue(writer, operand, .FunctionArgument);
4781 try writer.writeAll(");\n");4799 try writer.writeAll(");\n");
4782 return local;4800 return local;
4783}4801}
...@@ -4793,9 +4811,9 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, fn_name: []const u8) !CValu...@@ -4793,9 +4811,9 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, fn_name: []const u8) !CValu
4793 try writer.writeAll(" = ");4811 try writer.writeAll(" = ");
4794 try f.renderFloatFnName(fn_name, inst_ty);4812 try f.renderFloatFnName(fn_name, inst_ty);
4795 try writer.writeByte('(');4813 try writer.writeByte('(');
4796 try f.writeCValue(writer, lhs);4814 try f.writeCValue(writer, lhs, .FunctionArgument);
4797 try writer.writeAll(", ");4815 try writer.writeAll(", ");
4798 try f.writeCValue(writer, rhs);4816 try f.writeCValue(writer, rhs, .FunctionArgument);
4799 try writer.writeAll(");\n");4817 try writer.writeAll(");\n");
4800 return local;4818 return local;
4801}4819}
...@@ -4813,11 +4831,11 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4813,11 +4831,11 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
4813 try writer.writeAll(" = ");4831 try writer.writeAll(" = ");
4814 try f.renderFloatFnName("fma", inst_ty);4832 try f.renderFloatFnName("fma", inst_ty);
4815 try writer.writeByte('(');4833 try writer.writeByte('(');
4816 try f.writeCValue(writer, mulend1);4834 try f.writeCValue(writer, mulend1, .FunctionArgument);
4817 try writer.writeAll(", ");4835 try writer.writeAll(", ");
4818 try f.writeCValue(writer, mulend2);4836 try f.writeCValue(writer, mulend2, .FunctionArgument);
4819 try writer.writeAll(", ");4837 try writer.writeAll(", ");
4820 try f.writeCValue(writer, addend);4838 try f.writeCValue(writer, addend, .FunctionArgument);
4821 try writer.writeAll(");\n");4839 try writer.writeAll(");\n");
4822 return local;4840 return local;
4823}4841}
...@@ -5013,15 +5031,15 @@ fn formatIntLiteral(...@@ -5013,15 +5031,15 @@ fn formatIntLiteral(
5013 }5031 }
50145032
5015 const split = std.math.min(int.limbs.len, limbs_count_64);5033 const split = std.math.min(int.limbs.len, limbs_count_64);
5016 var upper_val_pl = Value.Payload.BigInt{5034 var upper_pl = Value.Payload.BigInt{
5017 .base = .{ .tag = .int_big_positive },5035 .base = .{ .tag = .int_big_positive },
5018 .data = int.limbs[split..],5036 .data = int.limbs[split..],
5019 };5037 };
5020 const have_upper = !upper_val_pl.asBigInt().eqZero();5038 const have_upper = !upper_pl.asBigInt().eqZero();
5021 if (have_upper) try writer.writeByte('(');5039 if (have_upper) try writer.writeByte('(');
5022 if (have_upper or !int.positive) try writer.writeAll("(uint128_t)");5040 if (have_upper or !int.positive) try writer.writeAll("(uint128_t)");
5023 if (have_upper) {5041 if (have_upper) {
5024 const upper_val = Value.initPayload(&upper_val_pl.base);5042 const upper_val = Value.initPayload(&upper_pl.base);
5025 try formatIntLiteral(.{5043 try formatIntLiteral(.{
5026 .ty = Type.u64,5044 .ty = Type.u64,
5027 .val = upper_val,5045 .val = upper_val,
...@@ -5030,11 +5048,11 @@ fn formatIntLiteral(...@@ -5030,11 +5048,11 @@ fn formatIntLiteral(
5030 try writer.writeAll("<<64|");5048 try writer.writeAll("<<64|");
5031 }5049 }
50325050
5033 var lower_val_pl = Value.Payload.BigInt{5051 var lower_pl = Value.Payload.BigInt{
5034 .base = .{ .tag = .int_big_positive },5052 .base = .{ .tag = .int_big_positive },
5035 .data = int.limbs[0..split],5053 .data = int.limbs[0..split],
5036 };5054 };
5037 const lower_val = Value.initPayload(&lower_val_pl.base);5055 const lower_val = Value.initPayload(&lower_pl.base);
5038 try formatIntLiteral(.{5056 try formatIntLiteral(.{
5039 .ty = Type.u64,5057 .ty = Type.u64,
5040 .val = lower_val,5058 .val = lower_val,