| ... | @@ -434,7 +434,7 @@ pub const Function = struct { | ... | @@ -434,7 +434,7 @@ pub const Function = struct { |
| 434 | return f.object.dg.renderCType(w, t); | 434 | return f.object.dg.renderCType(w, t); |
| 435 | } | 435 | } |
| 436 | | 436 | |
| 437 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void { | 437 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void { |
| 438 | return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); | 438 | return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); |
| 439 | } | 439 | } |
| 440 | | 440 | |
| ... | @@ -811,11 +811,13 @@ pub const DeclGen = struct { | ... | @@ -811,11 +811,13 @@ pub const DeclGen = struct { |
| 811 | | 811 | |
| 812 | try writer.writeByte('{'); | 812 | try writer.writeByte('{'); |
| 813 | var empty = true; | 813 | var empty = true; |
| 814 | for (ty.structFields().values()) |field| { | 814 | for (0..ty.structFieldCount()) |field_i| { |
| 815 | if (!field.ty.hasRuntimeBits()) continue; | 815 | if (ty.structFieldIsComptime(field_i)) continue; |
| | 816 | const field_ty = ty.structFieldType(field_i); |
| | 817 | if (!field_ty.hasRuntimeBits()) continue; |
| 816 | | 818 | |
| 817 | if (!empty) try writer.writeByte(','); | 819 | if (!empty) try writer.writeByte(','); |
| 818 | try dg.renderValue(writer, field.ty, val, initializer_type); | 820 | try dg.renderValue(writer, field_ty, val, initializer_type); |
| 819 | | 821 | |
| 820 | empty = false; | 822 | empty = false; |
| 821 | } | 823 | } |
| ... | @@ -837,19 +839,27 @@ pub const DeclGen = struct { | ... | @@ -837,19 +839,27 @@ pub const DeclGen = struct { |
| 837 | if (layout.tag_size != 0) { | 839 | if (layout.tag_size != 0) { |
| 838 | try writer.writeAll(" .tag = "); | 840 | try writer.writeAll(" .tag = "); |
| 839 | try dg.renderValue(writer, tag_ty, val, initializer_type); | 841 | try dg.renderValue(writer, tag_ty, val, initializer_type); |
| 840 | try writer.writeByte(','); | | |
| 841 | } | 842 | } |
| | 843 | if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}'); |
| | 844 | if (layout.tag_size != 0) try writer.writeByte(','); |
| 842 | try writer.writeAll(" .payload = {"); | 845 | try writer.writeAll(" .payload = {"); |
| 843 | } | 846 | } |
| 844 | for (ty.unionFields().values()) |field| { | 847 | for (ty.unionFields().values()) |field| { |
| 845 | if (!field.ty.hasRuntimeBits()) continue; | 848 | if (!field.ty.hasRuntimeBits()) continue; |
| 846 | try dg.renderValue(writer, field.ty, val, initializer_type); | 849 | try dg.renderValue(writer, field.ty, val, initializer_type); |
| 847 | break; | 850 | break; |
| 848 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)}); | 851 | } |
| 849 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); | 852 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 850 | return writer.writeByte('}'); | 853 | return writer.writeByte('}'); |
| 851 | }, | 854 | }, |
| 852 | .ErrorUnion => { | 855 | .ErrorUnion => { |
| | 856 | const payload_ty = ty.errorUnionPayload(); |
| | 857 | const error_ty = ty.errorUnionSet(); |
| | 858 | |
| | 859 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| | 860 | return dg.renderValue(writer, error_ty, val, location); |
| | 861 | } |
| | 862 | |
| 853 | if (!location.isInitializer()) { | 863 | if (!location.isInitializer()) { |
| 854 | try writer.writeByte('('); | 864 | try writer.writeByte('('); |
| 855 | try dg.renderType(writer, ty); | 865 | try dg.renderType(writer, ty); |
| ... | @@ -857,18 +867,12 @@ pub const DeclGen = struct { | ... | @@ -857,18 +867,12 @@ pub const DeclGen = struct { |
| 857 | } | 867 | } |
| 858 | | 868 | |
| 859 | try writer.writeAll("{ .payload = "); | 869 | try writer.writeAll("{ .payload = "); |
| 860 | try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type); | 870 | try dg.renderValue(writer, payload_ty, val, initializer_type); |
| 861 | return writer.print(", .error = {x} }}", .{ | 871 | try writer.writeAll(", .error = "); |
| 862 | try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other), | 872 | try dg.renderValue(writer, error_ty, val, initializer_type); |
| 863 | }); | 873 | return writer.writeAll(" }"); |
| 864 | }, | 874 | }, |
| 865 | .Array, .Vector => { | 875 | .Array, .Vector => { |
| 866 | if (!location.isInitializer()) { | | |
| 867 | try writer.writeByte('('); | | |
| 868 | try dg.renderType(writer, ty); | | |
| 869 | try writer.writeByte(')'); | | |
| 870 | } | | |
| 871 | | | |
| 872 | const ai = ty.arrayInfo(); | 876 | const ai = ty.arrayInfo(); |
| 873 | if (ai.elem_type.eql(Type.u8, dg.module)) { | 877 | if (ai.elem_type.eql(Type.u8, dg.module)) { |
| 874 | var literal = stringLiteral(writer); | 878 | var literal = stringLiteral(writer); |
| ... | @@ -879,6 +883,12 @@ pub const DeclGen = struct { | ... | @@ -879,6 +883,12 @@ pub const DeclGen = struct { |
| 879 | try literal.writeChar(0xaa); | 883 | try literal.writeChar(0xaa); |
| 880 | return literal.end(); | 884 | return literal.end(); |
| 881 | } else { | 885 | } else { |
| | 886 | if (!location.isInitializer()) { |
| | 887 | try writer.writeByte('('); |
| | 888 | try dg.renderType(writer, ty); |
| | 889 | try writer.writeByte(')'); |
| | 890 | } |
| | 891 | |
| 882 | try writer.writeByte('{'); | 892 | try writer.writeByte('{'); |
| 883 | const c_len = ty.arrayLenIncludingSentinel(); | 893 | const c_len = ty.arrayLenIncludingSentinel(); |
| 884 | var index: u64 = 0; | 894 | var index: u64 = 0; |
| ... | @@ -1199,23 +1209,20 @@ pub const DeclGen = struct { | ... | @@ -1199,23 +1209,20 @@ pub const DeclGen = struct { |
| 1199 | try writer.writeAll(" }"); | 1209 | try writer.writeAll(" }"); |
| 1200 | }, | 1210 | }, |
| 1201 | .ErrorSet => { | 1211 | .ErrorSet => { |
| 1202 | const error_name = if (val.castTag(.@"error")) |error_pl| | 1212 | if (val.castTag(.@"error")) |error_pl| { |
| 1203 | error_pl.data.name | 1213 | // Error values are already defined by genErrDecls. |
| 1204 | else | 1214 | try writer.print("zig_error_{}", .{fmtIdent(error_pl.data.name)}); |
| 1205 | dg.module.error_name_list.items[0]; | 1215 | } else { |
| 1206 | // Error values are already defined by genErrDecls. | 1216 | try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, .Other)}); |
| 1207 | try writer.print("zig_error_{}", .{fmtIdent(error_name)}); | 1217 | } |
| 1208 | }, | 1218 | }, |
| 1209 | .ErrorUnion => { | 1219 | .ErrorUnion => { |
| 1210 | const error_ty = ty.errorUnionSet(); | | |
| 1211 | const payload_ty = ty.errorUnionPayload(); | 1220 | const payload_ty = ty.errorUnionPayload(); |
| | 1221 | const error_ty = ty.errorUnionSet(); |
| | 1222 | const error_val = if (val.errorUnionIsPayload()) Value.zero else val; |
| 1212 | | 1223 | |
| 1213 | if (!payload_ty.hasRuntimeBits()) { | 1224 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1214 | // We use the error type directly as the type. | 1225 | return dg.renderValue(writer, error_ty, error_val, location); |
| 1215 | if (val.errorUnionIsPayload()) { | | |
| 1216 | return try writer.writeByte('0'); | | |
| 1217 | } | | |
| 1218 | return dg.renderValue(writer, error_ty, val, location); | | |
| 1219 | } | 1226 | } |
| 1220 | | 1227 | |
| 1221 | if (!location.isInitializer()) { | 1228 | if (!location.isInitializer()) { |
| ... | @@ -1225,8 +1232,6 @@ pub const DeclGen = struct { | ... | @@ -1225,8 +1232,6 @@ pub const DeclGen = struct { |
| 1225 | } | 1232 | } |
| 1226 | | 1233 | |
| 1227 | const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef; | 1234 | const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef; |
| 1228 | const error_val = if (val.errorUnionIsPayload()) Value.zero else val; | | |
| 1229 | | | |
| 1230 | try writer.writeAll("{ .payload = "); | 1235 | try writer.writeAll("{ .payload = "); |
| 1231 | try dg.renderValue(writer, payload_ty, payload_val, initializer_type); | 1236 | try dg.renderValue(writer, payload_ty, payload_val, initializer_type); |
| 1232 | try writer.writeAll(", .error = "); | 1237 | try writer.writeAll(", .error = "); |
| ... | @@ -1290,9 +1295,10 @@ pub const DeclGen = struct { | ... | @@ -1290,9 +1295,10 @@ pub const DeclGen = struct { |
| 1290 | | 1295 | |
| 1291 | try writer.writeByte('{'); | 1296 | try writer.writeByte('{'); |
| 1292 | var empty = true; | 1297 | var empty = true; |
| 1293 | for (field_vals, 0..) |field_val, field_index| { | 1298 | for (field_vals, 0..) |field_val, field_i| { |
| 1294 | const field_ty = ty.structFieldType(field_index); | 1299 | if (ty.structFieldIsComptime(field_i)) continue; |
| 1295 | if (!field_ty.hasRuntimeBits()) continue; | 1300 | const field_ty = ty.structFieldType(field_i); |
| | 1301 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1296 | | 1302 | |
| 1297 | if (!empty) try writer.writeByte(','); | 1303 | if (!empty) try writer.writeByte(','); |
| 1298 | try dg.renderValue(writer, field_ty, field_val, initializer_type); | 1304 | try dg.renderValue(writer, field_ty, field_val, initializer_type); |
| ... | @@ -1315,8 +1321,9 @@ pub const DeclGen = struct { | ... | @@ -1315,8 +1321,9 @@ pub const DeclGen = struct { |
| 1315 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); | 1321 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 1316 | | 1322 | |
| 1317 | var eff_num_fields: usize = 0; | 1323 | var eff_num_fields: usize = 0; |
| 1318 | for (0..field_vals.len) |index| { | 1324 | for (0..field_vals.len) |field_i| { |
| 1319 | const field_ty = ty.structFieldType(index); | 1325 | if (ty.structFieldIsComptime(field_i)) continue; |
| | 1326 | const field_ty = ty.structFieldType(field_i); |
| 1320 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 1327 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1321 | | 1328 | |
| 1322 | eff_num_fields += 1; | 1329 | eff_num_fields += 1; |
| ... | @@ -1337,8 +1344,9 @@ pub const DeclGen = struct { | ... | @@ -1337,8 +1344,9 @@ pub const DeclGen = struct { |
| 1337 | | 1344 | |
| 1338 | var eff_index: usize = 0; | 1345 | var eff_index: usize = 0; |
| 1339 | var needs_closing_paren = false; | 1346 | var needs_closing_paren = false; |
| 1340 | for (field_vals, 0..) |field_val, index| { | 1347 | for (field_vals, 0..) |field_val, field_i| { |
| 1341 | const field_ty = ty.structFieldType(index); | 1348 | if (ty.structFieldIsComptime(field_i)) continue; |
| | 1349 | const field_ty = ty.structFieldType(field_i); |
| 1342 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 1350 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1343 | | 1351 | |
| 1344 | const cast_context = IntCastContext{ .value = .{ .value = field_val } }; | 1352 | const cast_context = IntCastContext{ .value = .{ .value = field_val } }; |
| ... | @@ -1365,8 +1373,9 @@ pub const DeclGen = struct { | ... | @@ -1365,8 +1373,9 @@ pub const DeclGen = struct { |
| 1365 | try writer.writeByte('('); | 1373 | try writer.writeByte('('); |
| 1366 | // a << a_off | b << b_off | c << c_off | 1374 | // a << a_off | b << b_off | c << c_off |
| 1367 | var empty = true; | 1375 | var empty = true; |
| 1368 | for (field_vals, 0..) |field_val, index| { | 1376 | for (field_vals, 0..) |field_val, field_i| { |
| 1369 | const field_ty = ty.structFieldType(index); | 1377 | if (ty.structFieldIsComptime(field_i)) continue; |
| | 1378 | const field_ty = ty.structFieldType(field_i); |
| 1370 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 1379 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1371 | | 1380 | |
| 1372 | if (!empty) try writer.writeAll(" | "); | 1381 | if (!empty) try writer.writeAll(" | "); |
| ... | @@ -1398,9 +1407,9 @@ pub const DeclGen = struct { | ... | @@ -1398,9 +1407,9 @@ pub const DeclGen = struct { |
| 1398 | try writer.writeByte(')'); | 1407 | try writer.writeByte(')'); |
| 1399 | } | 1408 | } |
| 1400 | | 1409 | |
| 1401 | const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?; | 1410 | const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?; |
| 1402 | const field_ty = ty.unionFields().values()[index].ty; | 1411 | const field_ty = ty.unionFields().values()[field_i].ty; |
| 1403 | const field_name = ty.unionFields().keys()[index]; | 1412 | const field_name = ty.unionFields().keys()[field_i]; |
| 1404 | if (ty.containerLayout() == .Packed) { | 1413 | if (ty.containerLayout() == .Packed) { |
| 1405 | if (field_ty.hasRuntimeBits()) { | 1414 | if (field_ty.hasRuntimeBits()) { |
| 1406 | if (field_ty.isPtrAtRuntime()) { | 1415 | if (field_ty.isPtrAtRuntime()) { |
| ... | @@ -1419,32 +1428,27 @@ pub const DeclGen = struct { | ... | @@ -1419,32 +1428,27 @@ pub const DeclGen = struct { |
| 1419 | return; | 1428 | return; |
| 1420 | } | 1429 | } |
| 1421 | | 1430 | |
| 1422 | var has_payload_init = false; | | |
| 1423 | try writer.writeByte('{'); | 1431 | try writer.writeByte('{'); |
| 1424 | if (ty.unionTagTypeSafety()) |tag_ty| { | 1432 | if (ty.unionTagTypeSafety()) |tag_ty| { |
| 1425 | const layout = ty.unionGetLayout(target); | 1433 | const layout = ty.unionGetLayout(target); |
| 1426 | if (layout.tag_size != 0) { | 1434 | if (layout.tag_size != 0) { |
| 1427 | try writer.writeAll(".tag = "); | 1435 | try writer.writeAll(" .tag = "); |
| 1428 | try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type); | 1436 | try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type); |
| 1429 | try writer.writeAll(", "); | | |
| 1430 | } | | |
| 1431 | if (!ty.unionHasAllZeroBitFieldTypes()) { | | |
| 1432 | try writer.writeAll(".payload = {"); | | |
| 1433 | has_payload_init = true; | | |
| 1434 | } | 1437 | } |
| | 1438 | if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}'); |
| | 1439 | if (layout.tag_size != 0) try writer.writeByte(','); |
| | 1440 | try writer.writeAll(" .payload = {"); |
| 1435 | } | 1441 | } |
| 1436 | | | |
| 1437 | var it = ty.unionFields().iterator(); | | |
| 1438 | if (field_ty.hasRuntimeBits()) { | 1442 | if (field_ty.hasRuntimeBits()) { |
| 1439 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); | 1443 | try writer.print(" .{ } = ", .{fmtIdent(field_name)}); |
| 1440 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); | 1444 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); |
| 1441 | } else while (it.next()) |field| { | 1445 | try writer.writeByte(' '); |
| 1442 | if (!field.value_ptr.ty.hasRuntimeBits()) continue; | 1446 | } else for (ty.unionFields().values()) |field| { |
| 1443 | try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)}); | 1447 | if (!field.ty.hasRuntimeBits()) continue; |
| 1444 | try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type); | 1448 | try dg.renderValue(writer, field.ty, Value.undef, initializer_type); |
| 1445 | break; | 1449 | break; |
| 1446 | } | 1450 | } |
| 1447 | if (has_payload_init) try writer.writeByte('}'); | 1451 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 1448 | try writer.writeByte('}'); | 1452 | try writer.writeByte('}'); |
| 1449 | }, | 1453 | }, |
| 1450 | | 1454 | |
| ... | @@ -1585,7 +1589,7 @@ pub const DeclGen = struct { | ... | @@ -1585,7 +1589,7 @@ pub const DeclGen = struct { |
| 1585 | c_value: struct { | 1589 | c_value: struct { |
| 1586 | f: *Function, | 1590 | f: *Function, |
| 1587 | value: CValue, | 1591 | value: CValue, |
| 1588 | v: Vectorizer, | 1592 | v: Vectorize, |
| 1589 | }, | 1593 | }, |
| 1590 | value: struct { | 1594 | value: struct { |
| 1591 | value: Value, | 1595 | value: Value, |
| ... | @@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ | ... | @@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 3073 | const inst_ty = f.air.typeOfIndex(inst); | 3077 | const inst_ty = f.air.typeOfIndex(inst); |
| 3074 | const operand = try f.resolveInst(ty_op.operand); | 3078 | const operand = try f.resolveInst(ty_op.operand); |
| 3075 | try reap(f, inst, &.{ty_op.operand}); | 3079 | try reap(f, inst, &.{ty_op.operand}); |
| | 3080 | |
| 3076 | const writer = f.object.writer(); | 3081 | const writer = f.object.writer(); |
| 3077 | const local = try f.allocLocal(inst, inst_ty); | 3082 | const local = try f.allocLocal(inst, inst_ty); |
| | 3083 | const a = try Assignment.start(f, writer, inst_ty); |
| 3078 | try f.writeCValue(writer, local, .Other); | 3084 | try f.writeCValue(writer, local, .Other); |
| 3079 | try writer.writeAll(" = "); | 3085 | try a.assign(f, writer); |
| 3080 | if (is_ptr) { | 3086 | if (is_ptr) { |
| 3081 | try writer.writeByte('&'); | 3087 | try writer.writeByte('&'); |
| 3082 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name }); | 3088 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name }); |
| 3083 | } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name }); | 3089 | } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name }); |
| 3084 | try writer.writeAll(";\n"); | 3090 | try a.end(f, writer); |
| 3085 | return local; | 3091 | return local; |
| 3086 | } | 3092 | } |
| 3087 | | 3093 | |
| ... | @@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3097 | const index = try f.resolveInst(bin_op.rhs); | 3103 | const index = try f.resolveInst(bin_op.rhs); |
| 3098 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3104 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3099 | | 3105 | |
| 3100 | const target = f.object.dg.module.getTarget(); | | |
| 3101 | const is_array = lowersToArray(inst_ty, target); | | |
| 3102 | | | |
| 3103 | const local = try f.allocLocal(inst, inst_ty); | | |
| 3104 | const writer = f.object.writer(); | 3106 | const writer = f.object.writer(); |
| 3105 | if (is_array) { | 3107 | const local = try f.allocLocal(inst, inst_ty); |
| 3106 | try writer.writeAll("memcpy("); | 3108 | const a = try Assignment.start(f, writer, inst_ty); |
| 3107 | try f.writeCValue(writer, local, .FunctionArgument); | 3109 | try f.writeCValue(writer, local, .Other); |
| 3108 | try writer.writeAll(", "); | 3110 | try a.assign(f, writer); |
| 3109 | } else { | | |
| 3110 | try f.writeCValue(writer, local, .Other); | | |
| 3111 | try writer.writeAll(" = "); | | |
| 3112 | } | | |
| 3113 | try f.writeCValue(writer, ptr, .Other); | 3111 | try f.writeCValue(writer, ptr, .Other); |
| 3114 | try writer.writeByte('['); | 3112 | try writer.writeByte('['); |
| 3115 | try f.writeCValue(writer, index, .Other); | 3113 | try f.writeCValue(writer, index, .Other); |
| 3116 | try writer.writeByte(']'); | 3114 | try writer.writeByte(']'); |
| 3117 | if (is_array) { | 3115 | try a.end(f, writer); |
| 3118 | try writer.writeAll(", sizeof("); | | |
| 3119 | try f.renderType(writer, inst_ty); | | |
| 3120 | try writer.writeAll("))"); | | |
| 3121 | } | | |
| 3122 | try writer.writeAll(";\n"); | | |
| 3123 | return local; | 3116 | return local; |
| 3124 | } | 3117 | } |
| 3125 | | 3118 | |
| ... | @@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3129 | | 3122 | |
| 3130 | const inst_ty = f.air.typeOfIndex(inst); | 3123 | const inst_ty = f.air.typeOfIndex(inst); |
| 3131 | const ptr_ty = f.air.typeOf(bin_op.lhs); | 3124 | const ptr_ty = f.air.typeOf(bin_op.lhs); |
| 3132 | const child_ty = ptr_ty.childType(); | 3125 | const elem_ty = ptr_ty.childType(); |
| | 3126 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(); |
| 3133 | | 3127 | |
| 3134 | const ptr = try f.resolveInst(bin_op.lhs); | 3128 | const ptr = try f.resolveInst(bin_op.lhs); |
| 3135 | const index = try f.resolveInst(bin_op.rhs); | 3129 | const index = try f.resolveInst(bin_op.rhs); |
| 3136 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3130 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3137 | | 3131 | |
| 3138 | const writer = f.object.writer(); | 3132 | const writer = f.object.writer(); |
| 3139 | const local = try f.allocLocal(inst, f.air.typeOfIndex(inst)); | 3133 | const local = try f.allocLocal(inst, inst_ty); |
| | 3134 | const a = try Assignment.start(f, writer, inst_ty); |
| 3140 | try f.writeCValue(writer, local, .Other); | 3135 | try f.writeCValue(writer, local, .Other); |
| 3141 | try writer.writeAll(" = "); | 3136 | try a.assign(f, writer); |
| 3142 | | | |
| 3143 | if (!child_ty.hasRuntimeBitsIgnoreComptime()) { | | |
| 3144 | try f.writeCValue(writer, ptr, .Initializer); | | |
| 3145 | try writer.writeAll(";\n"); | | |
| 3146 | return local; | | |
| 3147 | } | | |
| 3148 | | | |
| 3149 | try writer.writeByte('('); | 3137 | try writer.writeByte('('); |
| 3150 | try f.renderType(writer, inst_ty); | 3138 | try f.renderType(writer, inst_ty); |
| 3151 | try writer.writeAll(")&("); | 3139 | try writer.writeByte(')'); |
| 3152 | if (ptr_ty.ptrSize() == .One) { | 3140 | if (elem_has_bits) try writer.writeByte('&'); |
| | 3141 | if (elem_has_bits and ptr_ty.ptrSize() == .One) { |
| 3153 | // It's a pointer to an array, so we need to de-reference. | 3142 | // It's a pointer to an array, so we need to de-reference. |
| 3154 | try f.writeCValueDeref(writer, ptr); | 3143 | try f.writeCValueDeref(writer, ptr); |
| 3155 | } else { | 3144 | } else try f.writeCValue(writer, ptr, .Other); |
| 3156 | try f.writeCValue(writer, ptr, .Other); | 3145 | if (elem_has_bits) { |
| | 3146 | try writer.writeByte('['); |
| | 3147 | try f.writeCValue(writer, index, .Other); |
| | 3148 | try writer.writeByte(']'); |
| 3157 | } | 3149 | } |
| 3158 | try writer.writeAll(")["); | 3150 | try a.end(f, writer); |
| 3159 | try f.writeCValue(writer, index, .Other); | | |
| 3160 | try writer.writeAll("];\n"); | | |
| 3161 | return local; | 3151 | return local; |
| 3162 | } | 3152 | } |
| 3163 | | 3153 | |
| ... | @@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3173 | const index = try f.resolveInst(bin_op.rhs); | 3163 | const index = try f.resolveInst(bin_op.rhs); |
| 3174 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3164 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3175 | | 3165 | |
| 3176 | const target = f.object.dg.module.getTarget(); | | |
| 3177 | const is_array = lowersToArray(inst_ty, target); | | |
| 3178 | | | |
| 3179 | const local = try f.allocLocal(inst, inst_ty); | | |
| 3180 | const writer = f.object.writer(); | 3166 | const writer = f.object.writer(); |
| 3181 | if (is_array) { | 3167 | const local = try f.allocLocal(inst, inst_ty); |
| 3182 | try writer.writeAll("memcpy("); | 3168 | const a = try Assignment.start(f, writer, inst_ty); |
| 3183 | try f.writeCValue(writer, local, .FunctionArgument); | 3169 | try f.writeCValue(writer, local, .Other); |
| 3184 | try writer.writeAll(", "); | 3170 | try a.assign(f, writer); |
| 3185 | } else { | 3171 | try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" }); |
| 3186 | try f.writeCValue(writer, local, .Other); | 3172 | try writer.writeByte('['); |
| 3187 | try writer.writeAll(" = "); | | |
| 3188 | } | | |
| 3189 | try f.writeCValue(writer, slice, .Other); | | |
| 3190 | try writer.writeAll(".ptr["); | | |
| 3191 | try f.writeCValue(writer, index, .Other); | 3173 | try f.writeCValue(writer, index, .Other); |
| 3192 | try writer.writeByte(']'); | 3174 | try writer.writeByte(']'); |
| 3193 | if (is_array) { | 3175 | try a.end(f, writer); |
| 3194 | try writer.writeAll(", sizeof("); | | |
| 3195 | try f.renderType(writer, inst_ty); | | |
| 3196 | try writer.writeAll("))"); | | |
| 3197 | } | | |
| 3198 | try writer.writeAll(";\n"); | | |
| 3199 | return local; | 3176 | return local; |
| 3200 | } | 3177 | } |
| 3201 | | 3178 | |
| ... | @@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3203 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 3180 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3204 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 3181 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3205 | | 3182 | |
| | 3183 | const inst_ty = f.air.typeOfIndex(inst); |
| 3206 | const slice_ty = f.air.typeOf(bin_op.lhs); | 3184 | const slice_ty = f.air.typeOf(bin_op.lhs); |
| 3207 | const child_ty = slice_ty.elemType2(); | 3185 | const elem_ty = slice_ty.elemType2(); |
| | 3186 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(); |
| | 3187 | |
| 3208 | const slice = try f.resolveInst(bin_op.lhs); | 3188 | const slice = try f.resolveInst(bin_op.lhs); |
| 3209 | const index = try f.resolveInst(bin_op.rhs); | 3189 | const index = try f.resolveInst(bin_op.rhs); |
| 3210 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3190 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3211 | | 3191 | |
| 3212 | const writer = f.object.writer(); | 3192 | const writer = f.object.writer(); |
| 3213 | const local = try f.allocLocal(inst, f.air.typeOfIndex(inst)); | 3193 | const local = try f.allocLocal(inst, inst_ty); |
| | 3194 | const a = try Assignment.start(f, writer, inst_ty); |
| 3214 | try f.writeCValue(writer, local, .Other); | 3195 | try f.writeCValue(writer, local, .Other); |
| 3215 | try writer.writeAll(" = "); | 3196 | try a.assign(f, writer); |
| 3216 | if (child_ty.hasRuntimeBitsIgnoreComptime()) try writer.writeByte('&'); | 3197 | if (elem_has_bits) try writer.writeByte('&'); |
| 3217 | try f.writeCValue(writer, slice, .Other); | 3198 | try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" }); |
| 3218 | try writer.writeAll(".ptr"); | 3199 | if (elem_has_bits) { |
| 3219 | if (child_ty.hasRuntimeBitsIgnoreComptime()) { | | |
| 3220 | try writer.writeByte('['); | 3200 | try writer.writeByte('['); |
| 3221 | try f.writeCValue(writer, index, .Other); | 3201 | try f.writeCValue(writer, index, .Other); |
| 3222 | try writer.writeByte(']'); | 3202 | try writer.writeByte(']'); |
| 3223 | } | 3203 | } |
| 3224 | try writer.writeAll(";\n"); | 3204 | try a.end(f, writer); |
| 3225 | return local; | 3205 | return local; |
| 3226 | } | 3206 | } |
| 3227 | | 3207 | |
| ... | @@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3237 | const index = try f.resolveInst(bin_op.rhs); | 3217 | const index = try f.resolveInst(bin_op.rhs); |
| 3238 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3218 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3239 | | 3219 | |
| 3240 | const target = f.object.dg.module.getTarget(); | | |
| 3241 | const is_array = lowersToArray(inst_ty, target); | | |
| 3242 | | | |
| 3243 | const local = try f.allocLocal(inst, inst_ty); | | |
| 3244 | const writer = f.object.writer(); | 3220 | const writer = f.object.writer(); |
| 3245 | if (is_array) { | 3221 | const local = try f.allocLocal(inst, inst_ty); |
| 3246 | try writer.writeAll("memcpy("); | 3222 | const a = try Assignment.start(f, writer, inst_ty); |
| 3247 | try f.writeCValue(writer, local, .FunctionArgument); | 3223 | try f.writeCValue(writer, local, .Other); |
| 3248 | try writer.writeAll(", "); | 3224 | try a.assign(f, writer); |
| 3249 | } else { | | |
| 3250 | try f.writeCValue(writer, local, .Other); | | |
| 3251 | try writer.writeAll(" = "); | | |
| 3252 | } | | |
| 3253 | try f.writeCValue(writer, array, .Other); | 3225 | try f.writeCValue(writer, array, .Other); |
| 3254 | try writer.writeByte('['); | 3226 | try writer.writeByte('['); |
| 3255 | try f.writeCValue(writer, index, .Other); | 3227 | try f.writeCValue(writer, index, .Other); |
| 3256 | try writer.writeByte(']'); | 3228 | try writer.writeByte(']'); |
| 3257 | if (is_array) { | 3229 | try a.end(f, writer); |
| 3258 | try writer.writeAll(", sizeof("); | | |
| 3259 | try f.renderType(writer, inst_ty); | | |
| 3260 | try writer.writeAll("))"); | | |
| 3261 | } | | |
| 3262 | try writer.writeAll(";\n"); | | |
| 3263 | return local; | 3230 | return local; |
| 3264 | } | 3231 | } |
| 3265 | | 3232 | |
| ... | @@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3343 | | 3310 | |
| 3344 | const writer = f.object.writer(); | 3311 | const writer = f.object.writer(); |
| 3345 | const local = try f.allocLocal(inst, src_ty); | 3312 | const local = try f.allocLocal(inst, src_ty); |
| 3346 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | 3313 | const v = try Vectorize.start(f, inst, writer, ptr_ty); |
| 3347 | | 3314 | |
| 3348 | if (need_memcpy) { | 3315 | if (need_memcpy) { |
| 3349 | try writer.writeAll("memcpy("); | 3316 | try writer.writeAll("memcpy("); |
| ... | @@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3484 | | 3451 | |
| 3485 | const writer = f.object.writer(); | 3452 | const writer = f.object.writer(); |
| 3486 | const local = try f.allocLocal(inst, inst_ty); | 3453 | const local = try f.allocLocal(inst, inst_ty); |
| 3487 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 3454 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| | 3455 | const a = try Assignment.start(f, writer, scalar_ty); |
| 3488 | try f.writeCValue(writer, local, .Other); | 3456 | try f.writeCValue(writer, local, .Other); |
| 3489 | try v.elem(f, writer); | 3457 | try v.elem(f, writer); |
| 3490 | try writer.writeAll(" = "); | 3458 | try a.assign(f, writer); |
| 3491 | try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other); | 3459 | try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other); |
| 3492 | try writer.writeAll(";\n"); | 3460 | try a.end(f, writer); |
| 3493 | try v.end(f, inst, writer); | 3461 | try v.end(f, inst, writer); |
| 3494 | | 3462 | |
| 3495 | return local; | 3463 | return local; |
| ... | @@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3513 | | 3481 | |
| 3514 | const writer = f.object.writer(); | 3482 | const writer = f.object.writer(); |
| 3515 | const local = try f.allocLocal(inst, inst_ty); | 3483 | const local = try f.allocLocal(inst, inst_ty); |
| 3516 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 3484 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 3517 | | 3485 | |
| 3518 | try f.writeCValue(writer, local, .Other); | 3486 | try f.writeCValue(writer, local, .Other); |
| 3519 | try v.elem(f, writer); | 3487 | try v.elem(f, writer); |
| ... | @@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3597 | const writer = f.object.writer(); | 3565 | const writer = f.object.writer(); |
| 3598 | const inst_ty = f.air.typeOfIndex(inst); | 3566 | const inst_ty = f.air.typeOfIndex(inst); |
| 3599 | const local = try f.allocLocal(inst, inst_ty); | 3567 | const local = try f.allocLocal(inst, inst_ty); |
| | 3568 | const a = try Assignment.start(f, writer, inst_ty); |
| 3600 | try f.writeCValue(writer, local, .Other); | 3569 | try f.writeCValue(writer, local, .Other); |
| 3601 | try writer.writeAll(" = "); | 3570 | try a.assign(f, writer); |
| 3602 | try f.writeCValue(writer, operand, .Other); | 3571 | try f.writeCValue(writer, operand, .Other); |
| 3603 | try writer.writeAll(";\n"); | 3572 | try a.end(f, writer); |
| 3604 | return local; | 3573 | return local; |
| 3605 | } | 3574 | } |
| 3606 | | 3575 | |
| ... | @@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3632 | const src_val_is_undefined = | 3601 | const src_val_is_undefined = |
| 3633 | if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; | 3602 | if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; |
| 3634 | if (src_val_is_undefined) { | 3603 | if (src_val_is_undefined) { |
| 3635 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3604 | if (ptr_info.host_size == 0) { |
| 3636 | return try storeUndefined(f, ptr_info.pointee_type, ptr_val); | 3605 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| | 3606 | return try storeUndefined(f, ptr_info.pointee_type, ptr_val); |
| | 3607 | } else if (!f.wantSafety()) { |
| | 3608 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| | 3609 | return .none; |
| | 3610 | } |
| 3637 | } | 3611 | } |
| 3638 | | 3612 | |
| 3639 | const target = f.object.dg.module.getTarget(); | 3613 | const target = f.object.dg.module.getTarget(); |
| ... | @@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3646 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3620 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3647 | | 3621 | |
| 3648 | const writer = f.object.writer(); | 3622 | const writer = f.object.writer(); |
| 3649 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | 3623 | const v = try Vectorize.start(f, inst, writer, ptr_ty); |
| 3650 | | 3624 | |
| 3651 | if (need_memcpy) { | 3625 | if (need_memcpy) { |
| 3652 | // For this memcpy to safely work we need the rhs to have the same | 3626 | // For this memcpy to safely work we need the rhs to have the same |
| ... | @@ -3775,7 +3749,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: | ... | @@ -3775,7 +3749,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 3775 | | 3749 | |
| 3776 | const w = f.object.writer(); | 3750 | const w = f.object.writer(); |
| 3777 | const local = try f.allocLocal(inst, inst_ty); | 3751 | const local = try f.allocLocal(inst, inst_ty); |
| 3778 | const v = try Vectorizer.start(f, inst, w, operand_ty); | 3752 | const v = try Vectorize.start(f, inst, w, operand_ty); |
| 3779 | try f.writeCValueMember(w, local, .{ .field = 1 }); | 3753 | try f.writeCValueMember(w, local, .{ .field = 1 }); |
| 3780 | try v.elem(f, w); | 3754 | try v.elem(f, w); |
| 3781 | try w.writeAll(" = zig_"); | 3755 | try w.writeAll(" = zig_"); |
| ... | @@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3811 | | 3785 | |
| 3812 | const writer = f.object.writer(); | 3786 | const writer = f.object.writer(); |
| 3813 | const local = try f.allocLocal(inst, inst_ty); | 3787 | const local = try f.allocLocal(inst, inst_ty); |
| 3814 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 3788 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 3815 | try f.writeCValue(writer, local, .Other); | 3789 | try f.writeCValue(writer, local, .Other); |
| 3816 | try v.elem(f, writer); | 3790 | try v.elem(f, writer); |
| 3817 | try writer.writeAll(" = "); | 3791 | try writer.writeAll(" = "); |
| ... | @@ -3846,7 +3820,7 @@ fn airBinOp( | ... | @@ -3846,7 +3820,7 @@ fn airBinOp( |
| 3846 | | 3820 | |
| 3847 | const writer = f.object.writer(); | 3821 | const writer = f.object.writer(); |
| 3848 | const local = try f.allocLocal(inst, inst_ty); | 3822 | const local = try f.allocLocal(inst, inst_ty); |
| 3849 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 3823 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 3850 | try f.writeCValue(writer, local, .Other); | 3824 | try f.writeCValue(writer, local, .Other); |
| 3851 | try v.elem(f, writer); | 3825 | try v.elem(f, writer); |
| 3852 | try writer.writeAll(" = "); | 3826 | try writer.writeAll(" = "); |
| ... | @@ -3893,7 +3867,7 @@ fn airCmpOp( | ... | @@ -3893,7 +3867,7 @@ fn airCmpOp( |
| 3893 | | 3867 | |
| 3894 | const writer = f.object.writer(); | 3868 | const writer = f.object.writer(); |
| 3895 | const local = try f.allocLocal(inst, inst_ty); | 3869 | const local = try f.allocLocal(inst, inst_ty); |
| 3896 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 3870 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 3897 | try f.writeCValue(writer, local, .Other); | 3871 | try f.writeCValue(writer, local, .Other); |
| 3898 | try v.elem(f, writer); | 3872 | try v.elem(f, writer); |
| 3899 | try writer.writeAll(" = "); | 3873 | try writer.writeAll(" = "); |
| ... | @@ -3942,7 +3916,7 @@ fn airEquality( | ... | @@ -3942,7 +3916,7 @@ fn airEquality( |
| 3942 | try f.writeCValue(writer, local, .Other); | 3916 | try f.writeCValue(writer, local, .Other); |
| 3943 | try writer.writeAll(" = "); | 3917 | try writer.writeAll(" = "); |
| 3944 | | 3918 | |
| 3945 | if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) { | 3919 | if (operand_ty.zigTypeTag() == .Optional and !operand_ty.optionalReprIsPayload()) { |
| 3946 | // (A && B) || (C && (A == B)) | 3920 | // (A && B) || (C && (A == B)) |
| 3947 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload | 3921 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| 3948 | | 3922 | |
| ... | @@ -4008,7 +3982,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ... | @@ -4008,7 +3982,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 4008 | | 3982 | |
| 4009 | const local = try f.allocLocal(inst, inst_ty); | 3983 | const local = try f.allocLocal(inst, inst_ty); |
| 4010 | const writer = f.object.writer(); | 3984 | const writer = f.object.writer(); |
| 4011 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 3985 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 4012 | try f.writeCValue(writer, local, .Other); | 3986 | try f.writeCValue(writer, local, .Other); |
| 4013 | try v.elem(f, writer); | 3987 | try v.elem(f, writer); |
| 4014 | try writer.writeAll(" = "); | 3988 | try writer.writeAll(" = "); |
| ... | @@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons | ... | @@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4059 | | 4033 | |
| 4060 | const writer = f.object.writer(); | 4034 | const writer = f.object.writer(); |
| 4061 | const local = try f.allocLocal(inst, inst_ty); | 4035 | const local = try f.allocLocal(inst, inst_ty); |
| 4062 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 4036 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 4063 | try f.writeCValue(writer, local, .Other); | 4037 | try f.writeCValue(writer, local, .Other); |
| 4064 | try v.elem(f, writer); | 4038 | try v.elem(f, writer); |
| 4065 | // (lhs <> rhs) ? lhs : rhs | 4039 | // (lhs <> rhs) ? lhs : rhs |
| ... | @@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4091 | const len = try f.resolveInst(bin_op.rhs); | 4065 | const len = try f.resolveInst(bin_op.rhs); |
| 4092 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 4066 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 4093 | | 4067 | |
| 4094 | const writer = f.object.writer(); | | |
| 4095 | const inst_ty = f.air.typeOfIndex(inst); | 4068 | const inst_ty = f.air.typeOfIndex(inst); |
| 4096 | const local = try f.allocLocal(inst, inst_ty); | | |
| 4097 | try f.writeCValue(writer, local, .Other); | | |
| 4098 | try writer.writeAll(".ptr = ("); | | |
| 4099 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4069 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 4100 | try f.renderType(writer, inst_ty.slicePtrFieldType(&buf)); | 4070 | const ptr_ty = inst_ty.slicePtrFieldType(&buf); |
| 4101 | try writer.writeByte(')'); | | |
| 4102 | try f.writeCValue(writer, ptr, .Other); | | |
| 4103 | try writer.writeAll("; "); | | |
| 4104 | try f.writeCValue(writer, local, .Other); | | |
| 4105 | try writer.writeAll(".len = "); | | |
| 4106 | try f.writeCValue(writer, len, .Initializer); | | |
| 4107 | try writer.writeAll(";\n"); | | |
| 4108 | | 4071 | |
| | 4072 | const writer = f.object.writer(); |
| | 4073 | const local = try f.allocLocal(inst, inst_ty); |
| | 4074 | { |
| | 4075 | const a = try Assignment.start(f, writer, ptr_ty); |
| | 4076 | try f.writeCValueMember(writer, local, .{ .identifier = "ptr" }); |
| | 4077 | try a.assign(f, writer); |
| | 4078 | try writer.writeByte('('); |
| | 4079 | try f.renderType(writer, ptr_ty); |
| | 4080 | try writer.writeByte(')'); |
| | 4081 | try f.writeCValue(writer, ptr, .Other); |
| | 4082 | try a.end(f, writer); |
| | 4083 | } |
| | 4084 | { |
| | 4085 | const a = try Assignment.start(f, writer, Type.usize); |
| | 4086 | try f.writeCValueMember(writer, local, .{ .identifier = "len" }); |
| | 4087 | try a.assign(f, writer); |
| | 4088 | try f.writeCValue(writer, len, .Other); |
| | 4089 | try a.end(f, writer); |
| | 4090 | } |
| 4109 | return local; | 4091 | return local; |
| 4110 | } | 4092 | } |
| 4111 | | 4093 | |
| ... | @@ -4346,10 +4328,10 @@ fn lowerTry( | ... | @@ -4346,10 +4328,10 @@ fn lowerTry( |
| 4346 | operand: Air.Inst.Ref, | 4328 | operand: Air.Inst.Ref, |
| 4347 | body: []const Air.Inst.Index, | 4329 | body: []const Air.Inst.Index, |
| 4348 | err_union_ty: Type, | 4330 | err_union_ty: Type, |
| 4349 | operand_is_ptr: bool, | 4331 | is_ptr: bool, |
| 4350 | ) !CValue { | 4332 | ) !CValue { |
| 4351 | const err_union = try f.resolveInst(operand); | 4333 | const err_union = try f.resolveInst(operand); |
| 4352 | const result_ty = f.air.typeOfIndex(inst); | 4334 | const inst_ty = f.air.typeOfIndex(inst); |
| 4353 | const liveness_condbr = f.liveness.getCondBr(inst); | 4335 | const liveness_condbr = f.liveness.getCondBr(inst); |
| 4354 | const writer = f.object.writer(); | 4336 | const writer = f.object.writer(); |
| 4355 | const payload_ty = err_union_ty.errorUnionPayload(); | 4337 | const payload_ty = err_union_ty.errorUnionPayload(); |
| ... | @@ -4358,7 +4340,7 @@ fn lowerTry( | ... | @@ -4358,7 +4340,7 @@ fn lowerTry( |
| 4358 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { | 4340 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 4359 | try writer.writeAll("if ("); | 4341 | try writer.writeAll("if ("); |
| 4360 | if (!payload_has_bits) { | 4342 | if (!payload_has_bits) { |
| 4361 | if (operand_is_ptr) | 4343 | if (is_ptr) |
| 4362 | try f.writeCValueDeref(writer, err_union) | 4344 | try f.writeCValueDeref(writer, err_union) |
| 4363 | else | 4345 | else |
| 4364 | try f.writeCValue(writer, err_union, .Other); | 4346 | try f.writeCValue(writer, err_union, .Other); |
| ... | @@ -4367,7 +4349,7 @@ fn lowerTry( | ... | @@ -4367,7 +4349,7 @@ fn lowerTry( |
| 4367 | // Remember we must avoid calling reap() twice for the same operand | 4349 | // Remember we must avoid calling reap() twice for the same operand |
| 4368 | // in this function. | 4350 | // in this function. |
| 4369 | try reap(f, inst, &.{operand}); | 4351 | try reap(f, inst, &.{operand}); |
| 4370 | if (operand_is_ptr or isByRef(err_union_ty)) | 4352 | if (is_ptr) |
| 4371 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" }) | 4353 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" }) |
| 4372 | else | 4354 | else |
| 4373 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); | 4355 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); |
| ... | @@ -4384,7 +4366,7 @@ fn lowerTry( | ... | @@ -4384,7 +4366,7 @@ fn lowerTry( |
| 4384 | } | 4366 | } |
| 4385 | | 4367 | |
| 4386 | if (!payload_has_bits) { | 4368 | if (!payload_has_bits) { |
| 4387 | if (!operand_is_ptr) { | 4369 | if (!is_ptr) { |
| 4388 | return .none; | 4370 | return .none; |
| 4389 | } else { | 4371 | } else { |
| 4390 | return err_union; | 4372 | return err_union; |
| ... | @@ -4397,26 +4379,15 @@ fn lowerTry( | ... | @@ -4397,26 +4379,15 @@ fn lowerTry( |
| 4397 | return .none; | 4379 | return .none; |
| 4398 | } | 4380 | } |
| 4399 | | 4381 | |
| 4400 | const target = f.object.dg.module.getTarget(); | 4382 | const local = try f.allocLocal(inst, inst_ty); |
| 4401 | const is_array = lowersToArray(payload_ty, target); | 4383 | const a = try Assignment.start(f, writer, inst_ty); |
| 4402 | const local = try f.allocLocal(inst, result_ty); | 4384 | try f.writeCValue(writer, local, .Other); |
| 4403 | if (is_array) { | 4385 | try a.assign(f, writer); |
| 4404 | try writer.writeAll("memcpy("); | 4386 | if (is_ptr) { |
| 4405 | try f.writeCValue(writer, local, .FunctionArgument); | 4387 | try writer.writeByte('&'); |
| 4406 | try writer.writeAll(", "); | 4388 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" }); |
| 4407 | try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); | 4389 | } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); |
| 4408 | try writer.writeAll(", sizeof("); | 4390 | try a.end(f, writer); |
| 4409 | try f.renderType(writer, payload_ty); | | |
| 4410 | try writer.writeAll("));\n"); | | |
| 4411 | } else { | | |
| 4412 | try f.writeCValue(writer, local, .Other); | | |
| 4413 | try writer.writeAll(" = "); | | |
| 4414 | if (operand_is_ptr or isByRef(payload_ty)) { | | |
| 4415 | try writer.writeByte('&'); | | |
| 4416 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" }); | | |
| 4417 | } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); | | |
| 4418 | try writer.writeAll(";\n"); | | |
| 4419 | } | | |
| 4420 | return local; | 4391 | return local; |
| 4421 | } | 4392 | } |
| 4422 | | 4393 | |
| ... | @@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4428 | | 4399 | |
| 4429 | // If result is .none then the value of the block is unused. | 4400 | // If result is .none then the value of the block is unused. |
| 4430 | if (result != .none) { | 4401 | if (result != .none) { |
| | 4402 | const operand_ty = f.air.typeOf(branch.operand); |
| 4431 | const operand = try f.resolveInst(branch.operand); | 4403 | const operand = try f.resolveInst(branch.operand); |
| 4432 | try reap(f, inst, &.{branch.operand}); | 4404 | try reap(f, inst, &.{branch.operand}); |
| 4433 | | 4405 | |
| 4434 | const operand_ty = f.air.typeOf(branch.operand); | 4406 | const a = try Assignment.start(f, writer, operand_ty); |
| 4435 | const target = f.object.dg.module.getTarget(); | 4407 | try f.writeCValue(writer, result, .Other); |
| 4436 | if (lowersToArray(operand_ty, target)) { | 4408 | try a.assign(f, writer); |
| 4437 | try writer.writeAll("memcpy("); | 4409 | try f.writeCValue(writer, operand, .Other); |
| 4438 | try f.writeCValue(writer, result, .FunctionArgument); | 4410 | try a.end(f, writer); |
| 4439 | try writer.writeAll(", "); | | |
| 4440 | try f.writeCValue(writer, operand, .FunctionArgument); | | |
| 4441 | try writer.writeAll(", sizeof("); | | |
| 4442 | try f.renderType(writer, operand_ty); | | |
| 4443 | try writer.writeAll("))"); | | |
| 4444 | } else { | | |
| 4445 | try f.writeCValue(writer, result, .Other); | | |
| 4446 | try writer.writeAll(" = "); | | |
| 4447 | try f.writeCValue(writer, operand, .Other); | | |
| 4448 | } | | |
| 4449 | try writer.writeAll(";\n"); | | |
| 4450 | } | 4411 | } |
| 4451 | | 4412 | |
| 4452 | try writer.print("goto zig_block_{d};\n", .{block.block_id}); | 4413 | try writer.print("goto zig_block_{d};\n", .{block.block_id}); |
| ... | @@ -4771,7 +4732,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4771,7 +4732,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4771 | if (f.wantSafety()) { | 4732 | if (f.wantSafety()) { |
| 4772 | try f.writeCValue(writer, local, .Other); | 4733 | try f.writeCValue(writer, local, .Other); |
| 4773 | try writer.writeAll(" = "); | 4734 | try writer.writeAll(" = "); |
| 4774 | try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer); | 4735 | try f.writeCValue(writer, .{ .undef = inst_ty }, .Other); |
| 4775 | try writer.writeAll(";\n"); | 4736 | try writer.writeAll(";\n"); |
| 4776 | } | 4737 | } |
| 4777 | break :local local; | 4738 | break :local local; |
| ... | @@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4806 | try writer.writeAll("\")"); | 4767 | try writer.writeAll("\")"); |
| 4807 | if (f.wantSafety()) { | 4768 | if (f.wantSafety()) { |
| 4808 | try writer.writeAll(" = "); | 4769 | try writer.writeAll(" = "); |
| 4809 | try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer); | 4770 | try f.writeCValue(writer, .{ .undef = output_ty }, .Other); |
| 4810 | } | 4771 | } |
| 4811 | try writer.writeAll(";\n"); | 4772 | try writer.writeAll(";\n"); |
| 4812 | } | 4773 | } |
| ... | @@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4840 | try writer.writeAll("\")"); | 4801 | try writer.writeAll("\")"); |
| 4841 | } | 4802 | } |
| 4842 | try writer.writeAll(" = "); | 4803 | try writer.writeAll(" = "); |
| 4843 | try f.writeCValue(writer, input_val, .Initializer); | 4804 | try f.writeCValue(writer, input_val, .Other); |
| 4844 | try writer.writeAll(";\n"); | 4805 | try writer.writeAll(";\n"); |
| 4845 | } | 4806 | } |
| 4846 | } | 4807 | } |
| ... | @@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5072 | } | 5033 | } |
| 5073 | | 5034 | |
| 5074 | const inst_ty = f.air.typeOfIndex(inst); | 5035 | const inst_ty = f.air.typeOfIndex(inst); |
| 5075 | const local = try f.allocLocal(inst, inst_ty); | | |
| 5076 | const writer = f.object.writer(); | 5036 | const writer = f.object.writer(); |
| | 5037 | const local = try f.allocLocal(inst, inst_ty); |
| 5077 | | 5038 | |
| 5078 | if (opt_ty.optionalReprIsPayload()) { | 5039 | if (opt_ty.optionalReprIsPayload()) { |
| 5079 | try f.writeCValue(writer, local, .Other); | 5040 | try f.writeCValue(writer, local, .Other); |
| ... | @@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5083 | return local; | 5044 | return local; |
| 5084 | } | 5045 | } |
| 5085 | | 5046 | |
| 5086 | const target = f.object.dg.module.getTarget(); | 5047 | const a = try Assignment.start(f, writer, inst_ty); |
| 5087 | const is_array = lowersToArray(inst_ty, target); | 5048 | try f.writeCValue(writer, local, .Other); |
| 5088 | | 5049 | try a.assign(f, writer); |
| 5089 | if (is_array) { | | |
| 5090 | try writer.writeAll("memcpy("); | | |
| 5091 | try f.writeCValue(writer, local, .FunctionArgument); | | |
| 5092 | try writer.writeAll(", "); | | |
| 5093 | } else { | | |
| 5094 | try f.writeCValue(writer, local, .Other); | | |
| 5095 | try writer.writeAll(" = "); | | |
| 5096 | } | | |
| 5097 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); | 5050 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5098 | if (is_array) { | 5051 | try a.end(f, writer); |
| 5099 | try writer.writeAll(", sizeof("); | | |
| 5100 | try f.renderType(writer, inst_ty); | | |
| 5101 | try writer.writeAll("))"); | | |
| 5102 | } | | |
| 5103 | try writer.writeAll(";\n"); | | |
| 5104 | return local; | 5052 | return local; |
| 5105 | } | 5053 | } |
| 5106 | | 5054 | |
| ... | @@ -5193,6 +5141,7 @@ fn fieldLocation( | ... | @@ -5193,6 +5141,7 @@ fn fieldLocation( |
| 5193 | if (container_ty.structFieldIsComptime(next_field_index)) continue; | 5141 | if (container_ty.structFieldIsComptime(next_field_index)) continue; |
| 5194 | const field_ty = container_ty.structFieldType(next_field_index); | 5142 | const field_ty = container_ty.structFieldType(next_field_index); |
| 5195 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 5143 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| | 5144 | |
| 5196 | break .{ .field = if (container_ty.isSimpleTuple()) | 5145 | break .{ .field = if (container_ty.isSimpleTuple()) |
| 5197 | .{ .field = next_field_index } | 5146 | .{ .field = next_field_index } |
| 5198 | else | 5147 | else |
| ... | @@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5437 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); | 5386 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5438 | try writer.writeByte('('); | 5387 | try writer.writeByte('('); |
| 5439 | } | 5388 | } |
| 5440 | try writer.writeAll("zig_shr_"); | 5389 | if (bit_offset_val_pl.data > 0) { |
| 5441 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); | 5390 | try writer.writeAll("zig_shr_"); |
| 5442 | try writer.writeByte('('); | 5391 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| | 5392 | try writer.writeByte('('); |
| | 5393 | } |
| 5443 | try f.writeCValue(writer, struct_byval, .Other); | 5394 | try f.writeCValue(writer, struct_byval, .Other); |
| 5444 | try writer.writeAll(", "); | 5395 | if (bit_offset_val_pl.data > 0) { |
| 5445 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); | 5396 | try writer.writeAll(", "); |
| 5446 | try writer.writeByte(')'); | 5397 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| | 5398 | try writer.writeByte(')'); |
| | 5399 | } |
| 5447 | if (cant_cast) try writer.writeByte(')'); | 5400 | if (cant_cast) try writer.writeByte(')'); |
| 5448 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); | 5401 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); |
| 5449 | try writer.writeAll(");\n"); | 5402 | try writer.writeAll(");\n"); |
| ... | @@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5473 | | 5426 | |
| 5474 | const local = try f.allocLocal(inst, inst_ty); | 5427 | const local = try f.allocLocal(inst, inst_ty); |
| 5475 | try writer.writeAll("memcpy(&"); | 5428 | try writer.writeAll("memcpy(&"); |
| 5476 | try f.writeCValue(writer, local, .FunctionArgument); | 5429 | try f.writeCValue(writer, local, .Other); |
| 5477 | try writer.writeAll(", &"); | 5430 | try writer.writeAll(", &"); |
| 5478 | try f.writeCValue(writer, operand_lval, .FunctionArgument); | 5431 | try f.writeCValue(writer, operand_lval, .Other); |
| 5479 | try writer.writeAll(", sizeof("); | 5432 | try writer.writeAll(", sizeof("); |
| 5480 | try f.renderType(writer, inst_ty); | 5433 | try f.renderType(writer, inst_ty); |
| 5481 | try writer.writeAll("));\n"); | 5434 | try writer.writeAll("));\n"); |
| ... | @@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5496 | }; | 5449 | }; |
| 5497 | | 5450 | |
| 5498 | const local = try f.allocLocal(inst, inst_ty); | 5451 | const local = try f.allocLocal(inst, inst_ty); |
| 5499 | if (lowersToArray(inst_ty, target)) { | 5452 | const a = try Assignment.start(f, writer, inst_ty); |
| 5500 | try writer.writeAll("memcpy("); | 5453 | try f.writeCValue(writer, local, .Other); |
| 5501 | try f.writeCValue(writer, local, .FunctionArgument); | 5454 | try a.assign(f, writer); |
| 5502 | try writer.writeAll(", "); | 5455 | try f.writeCValueMember(writer, struct_byval, field_name); |
| 5503 | try f.writeCValueMember(writer, struct_byval, field_name); | 5456 | try a.end(f, writer); |
| 5504 | try writer.writeAll(", sizeof("); | | |
| 5505 | try f.renderType(writer, inst_ty); | | |
| 5506 | try writer.writeAll("))"); | | |
| 5507 | } else { | | |
| 5508 | try f.writeCValue(writer, local, .Other); | | |
| 5509 | try writer.writeAll(" = "); | | |
| 5510 | try f.writeCValueMember(writer, struct_byval, field_name); | | |
| 5511 | } | | |
| 5512 | try writer.writeAll(";\n"); | | |
| 5513 | return local; | 5457 | return local; |
| 5514 | } | 5458 | } |
| 5515 | | 5459 | |
| ... | @@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu | ... | @@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 5554 | const operand = try f.resolveInst(ty_op.operand); | 5498 | const operand = try f.resolveInst(ty_op.operand); |
| 5555 | try reap(f, inst, &.{ty_op.operand}); | 5499 | try reap(f, inst, &.{ty_op.operand}); |
| 5556 | const operand_ty = f.air.typeOf(ty_op.operand); | 5500 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 5557 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; | 5501 | const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty; |
| 5558 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; | | |
| 5559 | | 5502 | |
| | 5503 | const writer = f.object.writer(); |
| 5560 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { | 5504 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { |
| 5561 | if (!is_ptr) return .none; | 5505 | if (!is_ptr) return .none; |
| 5562 | | 5506 | |
| 5563 | const w = f.object.writer(); | | |
| 5564 | const local = try f.allocLocal(inst, inst_ty); | 5507 | const local = try f.allocLocal(inst, inst_ty); |
| 5565 | try f.writeCValue(w, local, .Other); | 5508 | try f.writeCValue(writer, local, .Other); |
| 5566 | try w.writeAll(" = ("); | 5509 | try writer.writeAll(" = ("); |
| 5567 | try f.renderType(w, inst_ty); | 5510 | try f.renderType(writer, inst_ty); |
| 5568 | try w.writeByte(')'); | 5511 | try writer.writeByte(')'); |
| 5569 | try f.writeCValue(w, operand, .Initializer); | 5512 | try f.writeCValue(writer, operand, .Initializer); |
| 5570 | try w.writeAll(";\n"); | 5513 | try writer.writeAll(";\n"); |
| 5571 | return local; | 5514 | return local; |
| 5572 | } | 5515 | } |
| 5573 | | 5516 | |
| 5574 | const writer = f.object.writer(); | | |
| 5575 | const local = try f.allocLocal(inst, inst_ty); | 5517 | const local = try f.allocLocal(inst, inst_ty); |
| | 5518 | const a = try Assignment.start(f, writer, inst_ty); |
| 5576 | try f.writeCValue(writer, local, .Other); | 5519 | try f.writeCValue(writer, local, .Other); |
| 5577 | try writer.writeAll(" = "); | 5520 | try a.assign(f, writer); |
| 5578 | if (is_ptr) try writer.writeByte('&'); | 5521 | if (is_ptr) { |
| 5579 | if (operand_is_ptr) | 5522 | try writer.writeByte('&'); |
| 5580 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }) | 5523 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }); |
| 5581 | else | 5524 | } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5582 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); | 5525 | try a.end(f, writer); |
| 5583 | try writer.writeAll(";\n"); | | |
| 5584 | return local; | 5526 | return local; |
| 5585 | } | 5527 | } |
| 5586 | | 5528 | |
| ... | @@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5588 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 5530 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 5589 | | 5531 | |
| 5590 | const inst_ty = f.air.typeOfIndex(inst); | 5532 | const inst_ty = f.air.typeOfIndex(inst); |
| | 5533 | const repr_is_payload = inst_ty.optionalReprIsPayload(); |
| | 5534 | const payload_ty = f.air.typeOf(ty_op.operand); |
| 5591 | const payload = try f.resolveInst(ty_op.operand); | 5535 | const payload = try f.resolveInst(ty_op.operand); |
| 5592 | try reap(f, inst, &.{ty_op.operand}); | 5536 | try reap(f, inst, &.{ty_op.operand}); |
| 5593 | const writer = f.object.writer(); | | |
| 5594 | | | |
| 5595 | if (inst_ty.optionalReprIsPayload()) { | | |
| 5596 | const local = try f.allocLocal(inst, inst_ty); | | |
| 5597 | try f.writeCValue(writer, local, .Other); | | |
| 5598 | try writer.writeAll(" = "); | | |
| 5599 | try f.writeCValue(writer, payload, .Other); | | |
| 5600 | try writer.writeAll(";\n"); | | |
| 5601 | return local; | | |
| 5602 | } | | |
| 5603 | | | |
| 5604 | const payload_ty = f.air.typeOf(ty_op.operand); | | |
| 5605 | const target = f.object.dg.module.getTarget(); | | |
| 5606 | const is_array = lowersToArray(payload_ty, target); | | |
| 5607 | | 5537 | |
| | 5538 | const writer = f.object.writer(); |
| 5608 | const local = try f.allocLocal(inst, inst_ty); | 5539 | const local = try f.allocLocal(inst, inst_ty); |
| 5609 | if (!is_array) { | 5540 | { |
| 5610 | try f.writeCValue(writer, local, .Other); | 5541 | const a = try Assignment.start(f, writer, payload_ty); |
| 5611 | try writer.writeAll(".payload = "); | 5542 | if (repr_is_payload) |
| | 5543 | try f.writeCValue(writer, local, .Other) |
| | 5544 | else |
| | 5545 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| | 5546 | try a.assign(f, writer); |
| 5612 | try f.writeCValue(writer, payload, .Other); | 5547 | try f.writeCValue(writer, payload, .Other); |
| 5613 | try writer.writeAll("; "); | 5548 | try a.end(f, writer); |
| 5614 | } | 5549 | } |
| 5615 | try f.writeCValue(writer, local, .Other); | 5550 | if (!repr_is_payload) { |
| 5616 | try writer.writeAll(".is_null = false;\n"); | 5551 | const a = try Assignment.start(f, writer, Type.bool); |
| 5617 | if (is_array) { | 5552 | try f.writeCValueMember(writer, local, .{ .identifier = "is_null" }); |
| 5618 | try writer.writeAll("memcpy("); | 5553 | try a.assign(f, writer); |
| 5619 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); | 5554 | try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other); |
| 5620 | try writer.writeAll(", "); | 5555 | try a.end(f, writer); |
| 5621 | try f.writeCValue(writer, payload, .FunctionArgument); | | |
| 5622 | try writer.writeAll(", sizeof("); | | |
| 5623 | try f.renderType(writer, payload_ty); | | |
| 5624 | try writer.writeAll("));\n"); | | |
| 5625 | } | 5556 | } |
| 5626 | return local; | 5557 | return local; |
| 5627 | } | 5558 | } |
| ... | @@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5629 | fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | 5560 | fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5630 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 5561 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 5631 | | 5562 | |
| 5632 | const writer = f.object.writer(); | 5563 | const inst_ty = f.air.typeOfIndex(inst); |
| 5633 | const operand = try f.resolveInst(ty_op.operand); | 5564 | const payload_ty = inst_ty.errorUnionPayload(); |
| | 5565 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(); |
| | 5566 | const err_ty = inst_ty.errorUnionSet(); |
| | 5567 | const err = try f.resolveInst(ty_op.operand); |
| 5634 | try reap(f, inst, &.{ty_op.operand}); | 5568 | try reap(f, inst, &.{ty_op.operand}); |
| 5635 | const error_union_ty = f.air.typeOfIndex(inst); | | |
| 5636 | const payload_ty = error_union_ty.errorUnionPayload(); | | |
| 5637 | const local = try f.allocLocal(inst, error_union_ty); | | |
| 5638 | | 5569 | |
| 5639 | if (!payload_ty.hasRuntimeBits()) { | 5570 | const writer = f.object.writer(); |
| 5640 | try f.writeCValue(writer, local, .Other); | 5571 | const local = try f.allocLocal(inst, inst_ty); |
| 5641 | try writer.writeAll(" = "); | 5572 | if (!repr_is_err) { |
| 5642 | try f.writeCValue(writer, operand, .Other); | 5573 | const a = try Assignment.start(f, writer, payload_ty); |
| 5643 | try writer.writeAll(";\n"); | 5574 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 5644 | return local; | 5575 | try a.assign(f, writer); |
| | 5576 | try f.object.dg.renderValue(writer, payload_ty, Value.undef, .Other); |
| | 5577 | try a.end(f, writer); |
| 5645 | } | 5578 | } |
| 5646 | | | |
| 5647 | { | 5579 | { |
| 5648 | // TODO: set the payload to undefined | 5580 | const a = try Assignment.start(f, writer, err_ty); |
| 5649 | //try f.writeCValue(writer, local, .Other); | 5581 | if (repr_is_err) |
| | 5582 | try f.writeCValue(writer, local, .Other) |
| | 5583 | else |
| | 5584 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); |
| | 5585 | try a.assign(f, writer); |
| | 5586 | try f.writeCValue(writer, err, .Other); |
| | 5587 | try a.end(f, writer); |
| 5650 | } | 5588 | } |
| 5651 | try f.writeCValue(writer, local, .Other); | | |
| 5652 | try writer.writeAll(".error = "); | | |
| 5653 | try f.writeCValue(writer, operand, .Other); | | |
| 5654 | try writer.writeAll(";\n"); | | |
| 5655 | return local; | 5589 | return local; |
| 5656 | } | 5590 | } |
| 5657 | | 5591 | |
| ... | @@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5711 | const inst_ty = f.air.typeOfIndex(inst); | 5645 | const inst_ty = f.air.typeOfIndex(inst); |
| 5712 | const payload_ty = inst_ty.errorUnionPayload(); | 5646 | const payload_ty = inst_ty.errorUnionPayload(); |
| 5713 | const payload = try f.resolveInst(ty_op.operand); | 5647 | const payload = try f.resolveInst(ty_op.operand); |
| | 5648 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(); |
| | 5649 | const err_ty = inst_ty.errorUnionSet(); |
| 5714 | try reap(f, inst, &.{ty_op.operand}); | 5650 | try reap(f, inst, &.{ty_op.operand}); |
| 5715 | | 5651 | |
| 5716 | const target = f.object.dg.module.getTarget(); | | |
| 5717 | const is_array = lowersToArray(payload_ty, target); | | |
| 5718 | | | |
| 5719 | const writer = f.object.writer(); | 5652 | const writer = f.object.writer(); |
| 5720 | const local = try f.allocLocal(inst, inst_ty); | 5653 | const local = try f.allocLocal(inst, inst_ty); |
| 5721 | if (!is_array) { | 5654 | if (!repr_is_err) { |
| 5722 | try f.writeCValue(writer, local, .Other); | 5655 | const a = try Assignment.start(f, writer, payload_ty); |
| 5723 | try writer.writeAll(".payload = "); | 5656 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| | 5657 | try a.assign(f, writer); |
| 5724 | try f.writeCValue(writer, payload, .Other); | 5658 | try f.writeCValue(writer, payload, .Other); |
| 5725 | try writer.writeAll("; "); | 5659 | try a.end(f, writer); |
| 5726 | } | 5660 | } |
| 5727 | try f.writeCValue(writer, local, .Other); | 5661 | { |
| 5728 | try writer.writeAll(".error = 0;\n"); | 5662 | const a = try Assignment.start(f, writer, err_ty); |
| 5729 | if (is_array) { | 5663 | if (repr_is_err) |
| 5730 | try writer.writeAll("memcpy("); | 5664 | try f.writeCValue(writer, local, .Other) |
| 5731 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); | 5665 | else |
| 5732 | try writer.writeAll(", "); | 5666 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); |
| 5733 | try f.writeCValue(writer, payload, .FunctionArgument); | 5667 | try a.assign(f, writer); |
| 5734 | try writer.writeAll(", sizeof("); | 5668 | try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other); |
| 5735 | try f.renderType(writer, payload_ty); | 5669 | try a.end(f, writer); |
| 5736 | try writer.writeAll("));\n"); | | |
| 5737 | } | 5670 | } |
| 5738 | return local; | 5671 | return local; |
| 5739 | } | 5672 | } |
| ... | @@ -5885,7 +5818,7 @@ fn airUnBuiltinCall( | ... | @@ -5885,7 +5818,7 @@ fn airUnBuiltinCall( |
| 5885 | | 5818 | |
| 5886 | const writer = f.object.writer(); | 5819 | const writer = f.object.writer(); |
| 5887 | const local = try f.allocLocal(inst, inst_ty); | 5820 | const local = try f.allocLocal(inst, inst_ty); |
| 5888 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 5821 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 5889 | if (!ref_ret) { | 5822 | if (!ref_ret) { |
| 5890 | try f.writeCValue(writer, local, .Other); | 5823 | try f.writeCValue(writer, local, .Other); |
| 5891 | try v.elem(f, writer); | 5824 | try v.elem(f, writer); |
| ... | @@ -5934,7 +5867,7 @@ fn airBinBuiltinCall( | ... | @@ -5934,7 +5867,7 @@ fn airBinBuiltinCall( |
| 5934 | const writer = f.object.writer(); | 5867 | const writer = f.object.writer(); |
| 5935 | const local = try f.allocLocal(inst, inst_ty); | 5868 | const local = try f.allocLocal(inst, inst_ty); |
| 5936 | if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 5869 | if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 5937 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 5870 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 5938 | if (!ref_ret) { | 5871 | if (!ref_ret) { |
| 5939 | try f.writeCValue(writer, local, .Other); | 5872 | try f.writeCValue(writer, local, .Other); |
| 5940 | try v.elem(f, writer); | 5873 | try v.elem(f, writer); |
| ... | @@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall( | ... | @@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall( |
| 5982 | | 5915 | |
| 5983 | const writer = f.object.writer(); | 5916 | const writer = f.object.writer(); |
| 5984 | const local = try f.allocLocal(inst, inst_ty); | 5917 | const local = try f.allocLocal(inst, inst_ty); |
| 5985 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 5918 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 5986 | if (!ref_ret) { | 5919 | if (!ref_ret) { |
| 5987 | try f.writeCValue(writer, local, .Other); | 5920 | try f.writeCValue(writer, local, .Other); |
| 5988 | try v.elem(f, writer); | 5921 | try v.elem(f, writer); |
| ... | @@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6262 | const union_ptr = try f.resolveInst(bin_op.lhs); | 6195 | const union_ptr = try f.resolveInst(bin_op.lhs); |
| 6263 | const new_tag = try f.resolveInst(bin_op.rhs); | 6196 | const new_tag = try f.resolveInst(bin_op.rhs); |
| 6264 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 6197 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6265 | const writer = f.object.writer(); | | |
| 6266 | | 6198 | |
| 6267 | const union_ty = f.air.typeOf(bin_op.lhs).childType(); | | |
| 6268 | const target = f.object.dg.module.getTarget(); | 6199 | const target = f.object.dg.module.getTarget(); |
| | 6200 | const union_ty = f.air.typeOf(bin_op.lhs).childType(); |
| 6269 | const layout = union_ty.unionGetLayout(target); | 6201 | const layout = union_ty.unionGetLayout(target); |
| 6270 | if (layout.tag_size == 0) return .none; | 6202 | if (layout.tag_size == 0) return .none; |
| | 6203 | const tag_ty = union_ty.unionTagTypeSafety().?; |
| 6271 | | 6204 | |
| 6272 | try writer.writeByte('('); | 6205 | const writer = f.object.writer(); |
| 6273 | try f.writeCValue(writer, union_ptr, .Other); | 6206 | const a = try Assignment.start(f, writer, tag_ty); |
| 6274 | try writer.writeAll(")->tag = "); | 6207 | try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" }); |
| | 6208 | try a.assign(f, writer); |
| 6275 | try f.writeCValue(writer, new_tag, .Other); | 6209 | try f.writeCValue(writer, new_tag, .Other); |
| 6276 | try writer.writeAll(";\n"); | 6210 | try a.end(f, writer); |
| 6277 | | | |
| 6278 | return .none; | 6211 | return .none; |
| 6279 | } | 6212 | } |
| 6280 | | 6213 | |
| ... | @@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6284 | const operand = try f.resolveInst(ty_op.operand); | 6217 | const operand = try f.resolveInst(ty_op.operand); |
| 6285 | try reap(f, inst, &.{ty_op.operand}); | 6218 | try reap(f, inst, &.{ty_op.operand}); |
| 6286 | | 6219 | |
| 6287 | const un_ty = f.air.typeOf(ty_op.operand); | 6220 | const union_ty = f.air.typeOf(ty_op.operand); |
| 6288 | | | |
| 6289 | const target = f.object.dg.module.getTarget(); | 6221 | const target = f.object.dg.module.getTarget(); |
| 6290 | const layout = un_ty.unionGetLayout(target); | 6222 | const layout = union_ty.unionGetLayout(target); |
| 6291 | if (layout.tag_size == 0) return .none; | 6223 | if (layout.tag_size == 0) return .none; |
| 6292 | | 6224 | |
| 6293 | const inst_ty = f.air.typeOfIndex(inst); | 6225 | const inst_ty = f.air.typeOfIndex(inst); |
| 6294 | const writer = f.object.writer(); | 6226 | const writer = f.object.writer(); |
| 6295 | const local = try f.allocLocal(inst, inst_ty); | 6227 | const local = try f.allocLocal(inst, inst_ty); |
| | 6228 | const a = try Assignment.start(f, writer, inst_ty); |
| 6296 | try f.writeCValue(writer, local, .Other); | 6229 | try f.writeCValue(writer, local, .Other); |
| 6297 | | 6230 | try a.assign(f, writer); |
| 6298 | try writer.writeAll(" = "); | 6231 | try f.writeCValueMember(writer, operand, .{ .identifier = "tag" }); |
| 6299 | try f.writeCValue(writer, operand, .Other); | 6232 | try a.end(f, writer); |
| 6300 | try writer.writeAll(".tag;\n"); | | |
| 6301 | return local; | 6233 | return local; |
| 6302 | } | 6234 | } |
| 6303 | | 6235 | |
| ... | @@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6350 | | 6282 | |
| 6351 | const writer = f.object.writer(); | 6283 | const writer = f.object.writer(); |
| 6352 | const local = try f.allocLocal(inst, inst_ty); | 6284 | const local = try f.allocLocal(inst, inst_ty); |
| 6353 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 6285 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 6354 | if (need_memcpy) try writer.writeAll("memcpy(&"); | 6286 | if (need_memcpy) try writer.writeAll("memcpy(&"); |
| 6355 | try f.writeCValue(writer, local, .Other); | 6287 | try f.writeCValue(writer, local, .Other); |
| 6356 | try v.elem(f, writer); | 6288 | try v.elem(f, writer); |
| ... | @@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6380 | | 6312 | |
| 6381 | const writer = f.object.writer(); | 6313 | const writer = f.object.writer(); |
| 6382 | const local = try f.allocLocal(inst, inst_ty); | 6314 | const local = try f.allocLocal(inst, inst_ty); |
| 6383 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 6315 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 6384 | try f.writeCValue(writer, local, .Other); | 6316 | try f.writeCValue(writer, local, .Other); |
| 6385 | try v.elem(f, writer); | 6317 | try v.elem(f, writer); |
| 6386 | try writer.writeAll(" = "); | 6318 | try writer.writeAll(" = "); |
| ... | @@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6547 | }, .Initializer); | 6479 | }, .Initializer); |
| 6548 | try writer.writeAll(";\n"); | 6480 | try writer.writeAll(";\n"); |
| 6549 | | 6481 | |
| 6550 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 6482 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 6551 | try f.writeCValue(writer, accum, .Other); | 6483 | try f.writeCValue(writer, accum, .Other); |
| 6552 | switch (op) { | 6484 | switch (op) { |
| 6553 | .float_op => |func| { | 6485 | .float_op => |func| { |
| ... | @@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6621 | switch (inst_ty.zigTypeTag()) { | 6553 | switch (inst_ty.zigTypeTag()) { |
| 6622 | .Array, .Vector => { | 6554 | .Array, .Vector => { |
| 6623 | const elem_ty = inst_ty.childType(); | 6555 | const elem_ty = inst_ty.childType(); |
| 6624 | | 6556 | const a = try Assignment.init(f, elem_ty); |
| 6625 | const is_array = lowersToArray(elem_ty, target); | 6557 | for (resolved_elements, 0..) |element, i| { |
| 6626 | const need_memcpy = is_array; | 6558 | try a.restart(f, writer); |
| 6627 | if (need_memcpy) { | 6559 | try f.writeCValue(writer, local, .Other); |
| 6628 | for (resolved_elements, 0..) |element, i| { | 6560 | try writer.print("[{d}]", .{i}); |
| 6629 | try writer.writeAll("memcpy("); | 6561 | try a.assign(f, writer); |
| 6630 | try f.writeCValue(writer, local, .Other); | 6562 | try f.writeCValue(writer, element, .Other); |
| 6631 | try writer.print("[{d}]", .{i}); | 6563 | try a.end(f, writer); |
| 6632 | try writer.writeAll(", "); | 6564 | } |
| 6633 | try f.writeCValue(writer, element, .Other); | 6565 | if (inst_ty.sentinel()) |sentinel| { |
| 6634 | try writer.writeAll(", sizeof("); | 6566 | try a.restart(f, writer); |
| 6635 | try f.renderType(writer, elem_ty); | 6567 | try f.writeCValue(writer, local, .Other); |
| 6636 | try writer.writeAll("))"); | 6568 | try writer.print("[{d}]", .{resolved_elements.len}); |
| 6637 | try writer.writeAll(";\n"); | 6569 | try a.assign(f, writer); |
| 6638 | } | 6570 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); |
| 6639 | assert(inst_ty.sentinel() == null); | 6571 | try a.end(f, writer); |
| 6640 | } else { | | |
| 6641 | for (resolved_elements, 0..) |element, i| { | | |
| 6642 | try f.writeCValue(writer, local, .Other); | | |
| 6643 | try writer.print("[{d}] = ", .{i}); | | |
| 6644 | try f.writeCValue(writer, element, .Other); | | |
| 6645 | try writer.writeAll(";\n"); | | |
| 6646 | } | | |
| 6647 | if (inst_ty.sentinel()) |sentinel| { | | |
| 6648 | try f.writeCValue(writer, local, .Other); | | |
| 6649 | try writer.print("[{d}] = ", .{resolved_elements.len}); | | |
| 6650 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); | | |
| 6651 | try writer.writeAll(";\n"); | | |
| 6652 | } | | |
| 6653 | } | 6572 | } |
| 6654 | }, | 6573 | }, |
| 6655 | .Struct => switch (inst_ty.containerLayout()) { | 6574 | .Struct => switch (inst_ty.containerLayout()) { |
| 6656 | .Auto, .Extern => { | 6575 | .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| { |
| 6657 | try f.writeCValue(writer, local, .Other); | 6576 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| 6658 | try writer.writeAll(" = ("); | 6577 | const field_ty = inst_ty.structFieldType(field_i); |
| 6659 | try f.renderType(writer, inst_ty); | 6578 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6660 | try writer.writeAll(")"); | | |
| 6661 | try writer.writeByte('{'); | | |
| 6662 | var empty = true; | | |
| 6663 | for (elements, resolved_elements, 0..) |element, resolved_element, field_i| { | | |
| 6664 | if (inst_ty.structFieldValueComptime(field_i)) |_| continue; | | |
| 6665 | | | |
| 6666 | if (!empty) try writer.writeAll(", "); | | |
| 6667 | | | |
| 6668 | const field_name: CValue = if (inst_ty.isSimpleTuple()) | | |
| 6669 | .{ .field = field_i } | | |
| 6670 | else | | |
| 6671 | .{ .identifier = inst_ty.structFieldName(field_i) }; | | |
| 6672 | try writer.writeByte('.'); | | |
| 6673 | try f.object.dg.writeCValue(writer, field_name); | | |
| 6674 | try writer.writeAll(" = "); | | |
| 6675 | | | |
| 6676 | const element_ty = f.air.typeOf(element); | | |
| 6677 | try f.writeCValue(writer, switch (element_ty.zigTypeTag()) { | | |
| 6678 | .Array => .{ .undef = element_ty }, | | |
| 6679 | else => resolved_element, | | |
| 6680 | }, .Initializer); | | |
| 6681 | empty = false; | | |
| 6682 | } | | |
| 6683 | try writer.writeAll("};\n"); | | |
| 6684 | | | |
| 6685 | for (elements, resolved_elements, 0..) |element, resolved_element, field_i| { | | |
| 6686 | if (inst_ty.structFieldValueComptime(field_i)) |_| continue; | | |
| 6687 | | | |
| 6688 | const element_ty = f.air.typeOf(element); | | |
| 6689 | if (element_ty.zigTypeTag() != .Array) continue; | | |
| 6690 | | | |
| 6691 | const field_name: CValue = if (inst_ty.isSimpleTuple()) | | |
| 6692 | .{ .field = field_i } | | |
| 6693 | else | | |
| 6694 | .{ .identifier = inst_ty.structFieldName(field_i) }; | | |
| 6695 | | 6579 | |
| 6696 | try writer.writeAll(";\n"); | 6580 | const a = try Assignment.start(f, writer, field_ty); |
| 6697 | try writer.writeAll("memcpy("); | 6581 | try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple()) |
| 6698 | try f.writeCValueMember(writer, local, field_name); | 6582 | .{ .field = field_i } |
| 6699 | try writer.writeAll(", "); | 6583 | else |
| 6700 | try f.writeCValue(writer, resolved_element, .FunctionArgument); | 6584 | .{ .identifier = inst_ty.structFieldName(field_i) }); |
| 6701 | try writer.writeAll(", sizeof("); | 6585 | try a.assign(f, writer); |
| 6702 | try f.renderType(writer, element_ty); | 6586 | try f.writeCValue(writer, element, .Other); |
| 6703 | try writer.writeAll("));\n"); | 6587 | try a.end(f, writer); |
| 6704 | } | | |
| 6705 | }, | 6588 | }, |
| 6706 | .Packed => { | 6589 | .Packed => { |
| 6707 | try f.writeCValue(writer, local, .Other); | 6590 | try f.writeCValue(writer, local, .Other); |
| ... | @@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6718 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); | 6601 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 6719 | | 6602 | |
| 6720 | var empty = true; | 6603 | var empty = true; |
| 6721 | for (0..elements.len) |index| { | 6604 | for (0..elements.len) |field_i| { |
| 6722 | const field_ty = inst_ty.structFieldType(index); | 6605 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| | 6606 | const field_ty = inst_ty.structFieldType(field_i); |
| 6723 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 6607 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6724 | | 6608 | |
| 6725 | if (!empty) { | 6609 | if (!empty) { |
| ... | @@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6730 | empty = false; | 6614 | empty = false; |
| 6731 | } | 6615 | } |
| 6732 | empty = true; | 6616 | empty = true; |
| 6733 | for (resolved_elements, 0..) |element, index| { | 6617 | for (resolved_elements, 0..) |element, field_i| { |
| 6734 | const field_ty = inst_ty.structFieldType(index); | 6618 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| | 6619 | const field_ty = inst_ty.structFieldType(field_i); |
| 6735 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | 6620 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6736 | | 6621 | |
| 6737 | if (!empty) try writer.writeAll(", "); | 6622 | if (!empty) try writer.writeAll(", "); |
| ... | @@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6784 | const target = f.object.dg.module.getTarget(); | 6669 | const target = f.object.dg.module.getTarget(); |
| 6785 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | 6670 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 6786 | const field_name = union_obj.fields.keys()[extra.field_index]; | 6671 | const field_name = union_obj.fields.keys()[extra.field_index]; |
| | 6672 | const payload_ty = f.air.typeOf(extra.init); |
| 6787 | const payload = try f.resolveInst(extra.init); | 6673 | const payload = try f.resolveInst(extra.init); |
| 6788 | try reap(f, inst, &.{extra.init}); | 6674 | try reap(f, inst, &.{extra.init}); |
| 6789 | | 6675 | |
| ... | @@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6811 | var int_pl: Value.Payload.U64 = undefined; | 6697 | var int_pl: Value.Payload.U64 = undefined; |
| 6812 | const int_val = tag_val.enumToInt(tag_ty, &int_pl); | 6698 | const int_val = tag_val.enumToInt(tag_ty, &int_pl); |
| 6813 | | 6699 | |
| 6814 | try f.writeCValue(writer, local, .Other); | 6700 | const a = try Assignment.start(f, writer, tag_ty); |
| 6815 | try writer.print(".tag = {}; ", .{try f.fmtIntLiteral(tag_ty, int_val)}); | 6701 | try f.writeCValueMember(writer, local, .{ .identifier = "tag" }); |
| | 6702 | try a.assign(f, writer); |
| | 6703 | try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)}); |
| | 6704 | try a.end(f, writer); |
| 6816 | } | 6705 | } |
| 6817 | break :field .{ .payload_identifier = field_name }; | 6706 | break :field .{ .payload_identifier = field_name }; |
| 6818 | } else .{ .identifier = field_name }; | 6707 | } else .{ .identifier = field_name }; |
| 6819 | | 6708 | |
| | 6709 | const a = try Assignment.start(f, writer, payload_ty); |
| 6820 | try f.writeCValueMember(writer, local, field); | 6710 | try f.writeCValueMember(writer, local, field); |
| 6821 | try writer.writeAll(" = "); | 6711 | try a.assign(f, writer); |
| 6822 | try f.writeCValue(writer, payload, .Other); | 6712 | try f.writeCValue(writer, payload, .Other); |
| 6823 | try writer.writeAll(";\n"); | 6713 | try a.end(f, writer); |
| 6824 | return local; | 6714 | return local; |
| 6825 | } | 6715 | } |
| 6826 | | 6716 | |
| ... | @@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6887 | | 6777 | |
| 6888 | const writer = f.object.writer(); | 6778 | const writer = f.object.writer(); |
| 6889 | const local = try f.allocLocal(inst, operand_ty); | 6779 | const local = try f.allocLocal(inst, operand_ty); |
| 6890 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | 6780 | const v = try Vectorize.start(f, inst, writer, operand_ty); |
| 6891 | try f.writeCValue(writer, local, .Other); | 6781 | try f.writeCValue(writer, local, .Other); |
| 6892 | try v.elem(f, writer); | 6782 | try v.elem(f, writer); |
| 6893 | try writer.writeAll(" = zig_neg_"); | 6783 | try writer.writeAll(" = zig_neg_"); |
| ... | @@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal | ... | @@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal |
| 6912 | | 6802 | |
| 6913 | const writer = f.object.writer(); | 6803 | const writer = f.object.writer(); |
| 6914 | const local = try f.allocLocal(inst, inst_ty); | 6804 | const local = try f.allocLocal(inst, inst_ty); |
| 6915 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 6805 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 6916 | try f.writeCValue(writer, local, .Other); | 6806 | try f.writeCValue(writer, local, .Other); |
| 6917 | try v.elem(f, writer); | 6807 | try v.elem(f, writer); |
| 6918 | try writer.writeAll(" = zig_libc_name_"); | 6808 | try writer.writeAll(" = zig_libc_name_"); |
| ... | @@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa | ... | @@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa |
| 6940 | | 6830 | |
| 6941 | const writer = f.object.writer(); | 6831 | const writer = f.object.writer(); |
| 6942 | const local = try f.allocLocal(inst, inst_ty); | 6832 | const local = try f.allocLocal(inst, inst_ty); |
| 6943 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 6833 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 6944 | try f.writeCValue(writer, local, .Other); | 6834 | try f.writeCValue(writer, local, .Other); |
| 6945 | try v.elem(f, writer); | 6835 | try v.elem(f, writer); |
| 6946 | try writer.writeAll(" = zig_libc_name_"); | 6836 | try writer.writeAll(" = zig_libc_name_"); |
| ... | @@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6973 | | 6863 | |
| 6974 | const writer = f.object.writer(); | 6864 | const writer = f.object.writer(); |
| 6975 | const local = try f.allocLocal(inst, inst_ty); | 6865 | const local = try f.allocLocal(inst, inst_ty); |
| 6976 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | 6866 | const v = try Vectorize.start(f, inst, writer, inst_ty); |
| 6977 | try f.writeCValue(writer, local, .Other); | 6867 | try f.writeCValue(writer, local, .Other); |
| 6978 | try v.elem(f, writer); | 6868 | try v.elem(f, writer); |
| 6979 | try writer.writeAll(" = zig_libc_name_"); | 6869 | try writer.writeAll(" = zig_libc_name_"); |
| ... | @@ -7480,10 +7370,57 @@ fn formatIntLiteral( | ... | @@ -7480,10 +7370,57 @@ fn formatIntLiteral( |
| 7480 | try data.cty.renderLiteralSuffix(writer); | 7370 | try data.cty.renderLiteralSuffix(writer); |
| 7481 | } | 7371 | } |
| 7482 | | 7372 | |
| 7483 | const Vectorizer = struct { | 7373 | const Assignment = struct { |
| | 7374 | cty: CType.Index, |
| | 7375 | |
| | 7376 | pub fn init(f: *Function, ty: Type) !Assignment { |
| | 7377 | return .{ .cty = try f.typeToIndex(ty, .complete) }; |
| | 7378 | } |
| | 7379 | |
| | 7380 | pub fn start(f: *Function, writer: anytype, ty: Type) !Assignment { |
| | 7381 | const self = try init(f, ty); |
| | 7382 | try self.restart(f, writer); |
| | 7383 | return self; |
| | 7384 | } |
| | 7385 | |
| | 7386 | pub fn restart(self: Assignment, f: *Function, writer: anytype) !void { |
| | 7387 | switch (self.strategy(f)) { |
| | 7388 | .assign => {}, |
| | 7389 | .memcpy => try writer.writeAll("memcpy("), |
| | 7390 | } |
| | 7391 | } |
| | 7392 | |
| | 7393 | pub fn assign(self: Assignment, f: *Function, writer: anytype) !void { |
| | 7394 | switch (self.strategy(f)) { |
| | 7395 | .assign => try writer.writeAll(" = "), |
| | 7396 | .memcpy => try writer.writeAll(", "), |
| | 7397 | } |
| | 7398 | } |
| | 7399 | |
| | 7400 | pub fn end(self: Assignment, f: *Function, writer: anytype) !void { |
| | 7401 | switch (self.strategy(f)) { |
| | 7402 | .assign => {}, |
| | 7403 | .memcpy => { |
| | 7404 | try writer.writeAll(", sizeof("); |
| | 7405 | try f.renderCType(writer, self.cty); |
| | 7406 | try writer.writeAll("))"); |
| | 7407 | }, |
| | 7408 | } |
| | 7409 | try writer.writeAll(";\n"); |
| | 7410 | } |
| | 7411 | |
| | 7412 | fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } { |
| | 7413 | return switch (f.indexToCType(self.cty).tag()) { |
| | 7414 | else => .assign, |
| | 7415 | .array, .vector => .memcpy, |
| | 7416 | }; |
| | 7417 | } |
| | 7418 | }; |
| | 7419 | |
| | 7420 | const Vectorize = struct { |
| 7484 | index: CValue = .none, | 7421 | index: CValue = .none, |
| 7485 | | 7422 | |
| 7486 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorizer { | 7423 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize { |
| 7487 | return if (ty.zigTypeTag() == .Vector) index: { | 7424 | return if (ty.zigTypeTag() == .Vector) index: { |
| 7488 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; | 7425 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; |
| 7489 | | 7426 | |
| ... | @@ -7504,7 +7441,7 @@ const Vectorizer = struct { | ... | @@ -7504,7 +7441,7 @@ const Vectorizer = struct { |
| 7504 | } else .{}; | 7441 | } else .{}; |
| 7505 | } | 7442 | } |
| 7506 | | 7443 | |
| 7507 | pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void { | 7444 | pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void { |
| 7508 | if (self.index != .none) { | 7445 | if (self.index != .none) { |
| 7509 | try writer.writeByte('['); | 7446 | try writer.writeByte('['); |
| 7510 | try f.writeCValue(writer, self.index, .Other); | 7447 | try f.writeCValue(writer, self.index, .Other); |
| ... | @@ -7512,7 +7449,7 @@ const Vectorizer = struct { | ... | @@ -7512,7 +7449,7 @@ const Vectorizer = struct { |
| 7512 | } | 7449 | } |
| 7513 | } | 7450 | } |
| 7514 | | 7451 | |
| 7515 | pub fn end(self: Vectorizer, f: *Function, inst: Air.Inst.Index, writer: anytype) !void { | 7452 | pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, writer: anytype) !void { |
| 7516 | if (self.index != .none) { | 7453 | if (self.index != .none) { |
| 7517 | f.object.indent_writer.popIndent(); | 7454 | f.object.indent_writer.popIndent(); |
| 7518 | try writer.writeAll("}\n"); | 7455 | try writer.writeAll("}\n"); |
| ... | @@ -7521,11 +7458,6 @@ const Vectorizer = struct { | ... | @@ -7521,11 +7458,6 @@ const Vectorizer = struct { |
| 7521 | } | 7458 | } |
| 7522 | }; | 7459 | }; |
| 7523 | | 7460 | |
| 7524 | fn isByRef(ty: Type) bool { | | |
| 7525 | _ = ty; | | |
| 7526 | return false; | | |
| 7527 | } | | |
| 7528 | | | |
| 7529 | const LowerFnRetTyBuffer = struct { | 7461 | const LowerFnRetTyBuffer = struct { |
| 7530 | names: [1][]const u8, | 7462 | names: [1][]const u8, |
| 7531 | types: [1]Type, | 7463 | types: [1]Type, |
| ... | @@ -7557,29 +7489,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool { | ... | @@ -7557,29 +7489,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool { |
| 7557 | }; | 7489 | }; |
| 7558 | } | 7490 | } |
| 7559 | | 7491 | |
| 7560 | fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo { | | |
| 7561 | if (!lowersToArray(ty, target)) return null; | | |
| 7562 | | | |
| 7563 | switch (ty.zigTypeTag()) { | | |
| 7564 | .Array, .Vector => return ty.arrayInfo(), | | |
| 7565 | else => { | | |
| 7566 | const abi_size = ty.abiSize(target); | | |
| 7567 | const abi_align = ty.abiAlignment(target); | | |
| 7568 | return Type.ArrayInfo{ | | |
| 7569 | .elem_type = switch (abi_align) { | | |
| 7570 | 1 => Type.u8, | | |
| 7571 | 2 => Type.u16, | | |
| 7572 | 4 => Type.u32, | | |
| 7573 | 8 => Type.u64, | | |
| 7574 | 16 => Type.initTag(.u128), | | |
| 7575 | else => unreachable, | | |
| 7576 | }, | | |
| 7577 | .len = @divExact(abi_size, abi_align), | | |
| 7578 | }; | | |
| 7579 | }, | | |
| 7580 | } | | |
| 7581 | } | | |
| 7582 | | | |
| 7583 | fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void { | 7492 | fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void { |
| 7584 | assert(operands.len <= Liveness.bpi - 1); | 7493 | assert(operands.len <= Liveness.bpi - 1); |
| 7585 | var tomb_bits = f.liveness.getTombBits(inst); | 7494 | var tomb_bits = f.liveness.getTombBits(inst); |