| ... | ... | @@ -434,7 +434,7 @@ pub const Function = struct { |
| 434 | 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 | 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 | 811 | |
| 812 | 812 | try writer.writeByte('{'); |
| 813 | 813 | var empty = true; |
| 814 | | for (ty.structFields().values()) |field| { |
| 815 | | if (!field.ty.hasRuntimeBits()) continue; |
| 814 | for (0..ty.structFieldCount()) |field_i| { |
| 815 | if (ty.structFieldIsComptime(field_i)) continue; |
| 816 | const field_ty = ty.structFieldType(field_i); |
| 817 | if (!field_ty.hasRuntimeBits()) continue; |
| 816 | 818 | |
| 817 | 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 | 822 | empty = false; |
| 821 | 823 | } |
| ... | ... | @@ -837,19 +839,27 @@ pub const DeclGen = struct { |
| 837 | 839 | if (layout.tag_size != 0) { |
| 838 | 840 | try writer.writeAll(" .tag = "); |
| 839 | 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 | 845 | try writer.writeAll(" .payload = {"); |
| 843 | 846 | } |
| 844 | 847 | for (ty.unionFields().values()) |field| { |
| 845 | 848 | if (!field.ty.hasRuntimeBits()) continue; |
| 846 | 849 | try dg.renderValue(writer, field.ty, val, initializer_type); |
| 847 | 850 | break; |
| 848 | | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)}); |
| 851 | } |
| 849 | 852 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 850 | 853 | return writer.writeByte('}'); |
| 851 | 854 | }, |
| 852 | 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 | 863 | if (!location.isInitializer()) { |
| 854 | 864 | try writer.writeByte('('); |
| 855 | 865 | try dg.renderType(writer, ty); |
| ... | ... | @@ -857,18 +867,12 @@ pub const DeclGen = struct { |
| 857 | 867 | } |
| 858 | 868 | |
| 859 | 869 | try writer.writeAll("{ .payload = "); |
| 860 | | try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type); |
| 861 | | return writer.print(", .error = {x} }}", .{ |
| 862 | | try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other), |
| 863 | | }); |
| 870 | try dg.renderValue(writer, payload_ty, val, initializer_type); |
| 871 | try writer.writeAll(", .error = "); |
| 872 | try dg.renderValue(writer, error_ty, val, initializer_type); |
| 873 | return writer.writeAll(" }"); |
| 864 | 874 | }, |
| 865 | 875 | .Array, .Vector => { |
| 866 | | if (!location.isInitializer()) { |
| 867 | | try writer.writeByte('('); |
| 868 | | try dg.renderType(writer, ty); |
| 869 | | try writer.writeByte(')'); |
| 870 | | } |
| 871 | | |
| 872 | 876 | const ai = ty.arrayInfo(); |
| 873 | 877 | if (ai.elem_type.eql(Type.u8, dg.module)) { |
| 874 | 878 | var literal = stringLiteral(writer); |
| ... | ... | @@ -879,6 +883,12 @@ pub const DeclGen = struct { |
| 879 | 883 | try literal.writeChar(0xaa); |
| 880 | 884 | return literal.end(); |
| 881 | 885 | } else { |
| 886 | if (!location.isInitializer()) { |
| 887 | try writer.writeByte('('); |
| 888 | try dg.renderType(writer, ty); |
| 889 | try writer.writeByte(')'); |
| 890 | } |
| 891 | |
| 882 | 892 | try writer.writeByte('{'); |
| 883 | 893 | const c_len = ty.arrayLenIncludingSentinel(); |
| 884 | 894 | var index: u64 = 0; |
| ... | ... | @@ -1199,23 +1209,20 @@ pub const DeclGen = struct { |
| 1199 | 1209 | try writer.writeAll(" }"); |
| 1200 | 1210 | }, |
| 1201 | 1211 | .ErrorSet => { |
| 1202 | | const error_name = if (val.castTag(.@"error")) |error_pl| |
| 1203 | | error_pl.data.name |
| 1204 | | else |
| 1205 | | dg.module.error_name_list.items[0]; |
| 1206 | | // Error values are already defined by genErrDecls. |
| 1207 | | try writer.print("zig_error_{}", .{fmtIdent(error_name)}); |
| 1212 | if (val.castTag(.@"error")) |error_pl| { |
| 1213 | // Error values are already defined by genErrDecls. |
| 1214 | try writer.print("zig_error_{}", .{fmtIdent(error_pl.data.name)}); |
| 1215 | } else { |
| 1216 | try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, .Other)}); |
| 1217 | } |
| 1208 | 1218 | }, |
| 1209 | 1219 | .ErrorUnion => { |
| 1210 | | const error_ty = ty.errorUnionSet(); |
| 1211 | 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()) { |
| 1214 | | // We use the error type directly as the type. |
| 1215 | | if (val.errorUnionIsPayload()) { |
| 1216 | | return try writer.writeByte('0'); |
| 1217 | | } |
| 1218 | | return dg.renderValue(writer, error_ty, val, location); |
| 1224 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1225 | return dg.renderValue(writer, error_ty, error_val, location); |
| 1219 | 1226 | } |
| 1220 | 1227 | |
| 1221 | 1228 | if (!location.isInitializer()) { |
| ... | ... | @@ -1225,8 +1232,6 @@ pub const DeclGen = struct { |
| 1225 | 1232 | } |
| 1226 | 1233 | |
| 1227 | 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 | 1235 | try writer.writeAll("{ .payload = "); |
| 1231 | 1236 | try dg.renderValue(writer, payload_ty, payload_val, initializer_type); |
| 1232 | 1237 | try writer.writeAll(", .error = "); |
| ... | ... | @@ -1290,9 +1295,10 @@ pub const DeclGen = struct { |
| 1290 | 1295 | |
| 1291 | 1296 | try writer.writeByte('{'); |
| 1292 | 1297 | var empty = true; |
| 1293 | | for (field_vals, 0..) |field_val, field_index| { |
| 1294 | | const field_ty = ty.structFieldType(field_index); |
| 1295 | | if (!field_ty.hasRuntimeBits()) continue; |
| 1298 | for (field_vals, 0..) |field_val, field_i| { |
| 1299 | if (ty.structFieldIsComptime(field_i)) continue; |
| 1300 | const field_ty = ty.structFieldType(field_i); |
| 1301 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1296 | 1302 | |
| 1297 | 1303 | if (!empty) try writer.writeByte(','); |
| 1298 | 1304 | try dg.renderValue(writer, field_ty, field_val, initializer_type); |
| ... | ... | @@ -1315,8 +1321,9 @@ pub const DeclGen = struct { |
| 1315 | 1321 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 1316 | 1322 | |
| 1317 | 1323 | var eff_num_fields: usize = 0; |
| 1318 | | for (0..field_vals.len) |index| { |
| 1319 | | const field_ty = ty.structFieldType(index); |
| 1324 | for (0..field_vals.len) |field_i| { |
| 1325 | if (ty.structFieldIsComptime(field_i)) continue; |
| 1326 | const field_ty = ty.structFieldType(field_i); |
| 1320 | 1327 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1321 | 1328 | |
| 1322 | 1329 | eff_num_fields += 1; |
| ... | ... | @@ -1337,8 +1344,9 @@ pub const DeclGen = struct { |
| 1337 | 1344 | |
| 1338 | 1345 | var eff_index: usize = 0; |
| 1339 | 1346 | var needs_closing_paren = false; |
| 1340 | | for (field_vals, 0..) |field_val, index| { |
| 1341 | | const field_ty = ty.structFieldType(index); |
| 1347 | for (field_vals, 0..) |field_val, field_i| { |
| 1348 | if (ty.structFieldIsComptime(field_i)) continue; |
| 1349 | const field_ty = ty.structFieldType(field_i); |
| 1342 | 1350 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1343 | 1351 | |
| 1344 | 1352 | const cast_context = IntCastContext{ .value = .{ .value = field_val } }; |
| ... | ... | @@ -1365,8 +1373,9 @@ pub const DeclGen = struct { |
| 1365 | 1373 | try writer.writeByte('('); |
| 1366 | 1374 | // a << a_off | b << b_off | c << c_off |
| 1367 | 1375 | var empty = true; |
| 1368 | | for (field_vals, 0..) |field_val, index| { |
| 1369 | | const field_ty = ty.structFieldType(index); |
| 1376 | for (field_vals, 0..) |field_val, field_i| { |
| 1377 | if (ty.structFieldIsComptime(field_i)) continue; |
| 1378 | const field_ty = ty.structFieldType(field_i); |
| 1370 | 1379 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1371 | 1380 | |
| 1372 | 1381 | if (!empty) try writer.writeAll(" | "); |
| ... | ... | @@ -1398,9 +1407,9 @@ pub const DeclGen = struct { |
| 1398 | 1407 | try writer.writeByte(')'); |
| 1399 | 1408 | } |
| 1400 | 1409 | |
| 1401 | | const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?; |
| 1402 | | const field_ty = ty.unionFields().values()[index].ty; |
| 1403 | | const field_name = ty.unionFields().keys()[index]; |
| 1410 | const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?; |
| 1411 | const field_ty = ty.unionFields().values()[field_i].ty; |
| 1412 | const field_name = ty.unionFields().keys()[field_i]; |
| 1404 | 1413 | if (ty.containerLayout() == .Packed) { |
| 1405 | 1414 | if (field_ty.hasRuntimeBits()) { |
| 1406 | 1415 | if (field_ty.isPtrAtRuntime()) { |
| ... | ... | @@ -1419,32 +1428,27 @@ pub const DeclGen = struct { |
| 1419 | 1428 | return; |
| 1420 | 1429 | } |
| 1421 | 1430 | |
| 1422 | | var has_payload_init = false; |
| 1423 | 1431 | try writer.writeByte('{'); |
| 1424 | 1432 | if (ty.unionTagTypeSafety()) |tag_ty| { |
| 1425 | 1433 | const layout = ty.unionGetLayout(target); |
| 1426 | 1434 | if (layout.tag_size != 0) { |
| 1427 | | try writer.writeAll(".tag = "); |
| 1435 | try writer.writeAll(" .tag = "); |
| 1428 | 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 | 1442 | if (field_ty.hasRuntimeBits()) { |
| 1439 | | try writer.print(".{ } = ", .{fmtIdent(field_name)}); |
| 1443 | try writer.print(" .{ } = ", .{fmtIdent(field_name)}); |
| 1440 | 1444 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); |
| 1441 | | } else while (it.next()) |field| { |
| 1442 | | if (!field.value_ptr.ty.hasRuntimeBits()) continue; |
| 1443 | | try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)}); |
| 1444 | | try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type); |
| 1445 | try writer.writeByte(' '); |
| 1446 | } else for (ty.unionFields().values()) |field| { |
| 1447 | if (!field.ty.hasRuntimeBits()) continue; |
| 1448 | try dg.renderValue(writer, field.ty, Value.undef, initializer_type); |
| 1445 | 1449 | break; |
| 1446 | 1450 | } |
| 1447 | | if (has_payload_init) try writer.writeByte('}'); |
| 1451 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 1448 | 1452 | try writer.writeByte('}'); |
| 1449 | 1453 | }, |
| 1450 | 1454 | |
| ... | ... | @@ -1585,7 +1589,7 @@ pub const DeclGen = struct { |
| 1585 | 1589 | c_value: struct { |
| 1586 | 1590 | f: *Function, |
| 1587 | 1591 | value: CValue, |
| 1588 | | v: Vectorizer, |
| 1592 | v: Vectorize, |
| 1589 | 1593 | }, |
| 1590 | 1594 | value: struct { |
| 1591 | 1595 | value: Value, |
| ... | ... | @@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 3073 | 3077 | const inst_ty = f.air.typeOfIndex(inst); |
| 3074 | 3078 | const operand = try f.resolveInst(ty_op.operand); |
| 3075 | 3079 | try reap(f, inst, &.{ty_op.operand}); |
| 3080 | |
| 3076 | 3081 | const writer = f.object.writer(); |
| 3077 | 3082 | const local = try f.allocLocal(inst, inst_ty); |
| 3083 | const a = try Assignment.start(f, writer, inst_ty); |
| 3078 | 3084 | try f.writeCValue(writer, local, .Other); |
| 3079 | | try writer.writeAll(" = "); |
| 3085 | try a.assign(f, writer); |
| 3080 | 3086 | if (is_ptr) { |
| 3081 | 3087 | try writer.writeByte('&'); |
| 3082 | 3088 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name }); |
| 3083 | 3089 | } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name }); |
| 3084 | | try writer.writeAll(";\n"); |
| 3090 | try a.end(f, writer); |
| 3085 | 3091 | return local; |
| 3086 | 3092 | } |
| 3087 | 3093 | |
| ... | ... | @@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3097 | 3103 | const index = try f.resolveInst(bin_op.rhs); |
| 3098 | 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 | 3106 | const writer = f.object.writer(); |
| 3105 | | if (is_array) { |
| 3106 | | try writer.writeAll("memcpy("); |
| 3107 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 3108 | | try writer.writeAll(", "); |
| 3109 | | } else { |
| 3110 | | try f.writeCValue(writer, local, .Other); |
| 3111 | | try writer.writeAll(" = "); |
| 3112 | | } |
| 3107 | const local = try f.allocLocal(inst, inst_ty); |
| 3108 | const a = try Assignment.start(f, writer, inst_ty); |
| 3109 | try f.writeCValue(writer, local, .Other); |
| 3110 | try a.assign(f, writer); |
| 3113 | 3111 | try f.writeCValue(writer, ptr, .Other); |
| 3114 | 3112 | try writer.writeByte('['); |
| 3115 | 3113 | try f.writeCValue(writer, index, .Other); |
| 3116 | 3114 | try writer.writeByte(']'); |
| 3117 | | if (is_array) { |
| 3118 | | try writer.writeAll(", sizeof("); |
| 3119 | | try f.renderType(writer, inst_ty); |
| 3120 | | try writer.writeAll("))"); |
| 3121 | | } |
| 3122 | | try writer.writeAll(";\n"); |
| 3115 | try a.end(f, writer); |
| 3123 | 3116 | return local; |
| 3124 | 3117 | } |
| 3125 | 3118 | |
| ... | ... | @@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3129 | 3122 | |
| 3130 | 3123 | const inst_ty = f.air.typeOfIndex(inst); |
| 3131 | 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 | 3128 | const ptr = try f.resolveInst(bin_op.lhs); |
| 3135 | 3129 | const index = try f.resolveInst(bin_op.rhs); |
| 3136 | 3130 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3137 | 3131 | |
| 3138 | 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 | 3135 | try f.writeCValue(writer, local, .Other); |
| 3141 | | try writer.writeAll(" = "); |
| 3142 | | |
| 3143 | | if (!child_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3144 | | try f.writeCValue(writer, ptr, .Initializer); |
| 3145 | | try writer.writeAll(";\n"); |
| 3146 | | return local; |
| 3147 | | } |
| 3148 | | |
| 3136 | try a.assign(f, writer); |
| 3149 | 3137 | try writer.writeByte('('); |
| 3150 | 3138 | try f.renderType(writer, inst_ty); |
| 3151 | | try writer.writeAll(")&("); |
| 3152 | | if (ptr_ty.ptrSize() == .One) { |
| 3139 | try writer.writeByte(')'); |
| 3140 | if (elem_has_bits) try writer.writeByte('&'); |
| 3141 | if (elem_has_bits and ptr_ty.ptrSize() == .One) { |
| 3153 | 3142 | // It's a pointer to an array, so we need to de-reference. |
| 3154 | 3143 | try f.writeCValueDeref(writer, ptr); |
| 3155 | | } else { |
| 3156 | | try f.writeCValue(writer, ptr, .Other); |
| 3144 | } else 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(")["); |
| 3159 | | try f.writeCValue(writer, index, .Other); |
| 3160 | | try writer.writeAll("];\n"); |
| 3150 | try a.end(f, writer); |
| 3161 | 3151 | return local; |
| 3162 | 3152 | } |
| 3163 | 3153 | |
| ... | ... | @@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3173 | 3163 | const index = try f.resolveInst(bin_op.rhs); |
| 3174 | 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 | 3166 | const writer = f.object.writer(); |
| 3181 | | if (is_array) { |
| 3182 | | try writer.writeAll("memcpy("); |
| 3183 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 3184 | | try writer.writeAll(", "); |
| 3185 | | } else { |
| 3186 | | try f.writeCValue(writer, local, .Other); |
| 3187 | | try writer.writeAll(" = "); |
| 3188 | | } |
| 3189 | | try f.writeCValue(writer, slice, .Other); |
| 3190 | | try writer.writeAll(".ptr["); |
| 3167 | const local = try f.allocLocal(inst, inst_ty); |
| 3168 | const a = try Assignment.start(f, writer, inst_ty); |
| 3169 | try f.writeCValue(writer, local, .Other); |
| 3170 | try a.assign(f, writer); |
| 3171 | try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" }); |
| 3172 | try writer.writeByte('['); |
| 3191 | 3173 | try f.writeCValue(writer, index, .Other); |
| 3192 | 3174 | try writer.writeByte(']'); |
| 3193 | | if (is_array) { |
| 3194 | | try writer.writeAll(", sizeof("); |
| 3195 | | try f.renderType(writer, inst_ty); |
| 3196 | | try writer.writeAll("))"); |
| 3197 | | } |
| 3198 | | try writer.writeAll(";\n"); |
| 3175 | try a.end(f, writer); |
| 3199 | 3176 | return local; |
| 3200 | 3177 | } |
| 3201 | 3178 | |
| ... | ... | @@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3203 | 3180 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3204 | 3181 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3205 | 3182 | |
| 3183 | const inst_ty = f.air.typeOfIndex(inst); |
| 3206 | 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 | 3188 | const slice = try f.resolveInst(bin_op.lhs); |
| 3209 | 3189 | const index = try f.resolveInst(bin_op.rhs); |
| 3210 | 3190 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3211 | 3191 | |
| 3212 | 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 | 3195 | try f.writeCValue(writer, local, .Other); |
| 3215 | | try writer.writeAll(" = "); |
| 3216 | | if (child_ty.hasRuntimeBitsIgnoreComptime()) try writer.writeByte('&'); |
| 3217 | | try f.writeCValue(writer, slice, .Other); |
| 3218 | | try writer.writeAll(".ptr"); |
| 3219 | | if (child_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3196 | try a.assign(f, writer); |
| 3197 | if (elem_has_bits) try writer.writeByte('&'); |
| 3198 | try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" }); |
| 3199 | if (elem_has_bits) { |
| 3220 | 3200 | try writer.writeByte('['); |
| 3221 | 3201 | try f.writeCValue(writer, index, .Other); |
| 3222 | 3202 | try writer.writeByte(']'); |
| 3223 | 3203 | } |
| 3224 | | try writer.writeAll(";\n"); |
| 3204 | try a.end(f, writer); |
| 3225 | 3205 | return local; |
| 3226 | 3206 | } |
| 3227 | 3207 | |
| ... | ... | @@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3237 | 3217 | const index = try f.resolveInst(bin_op.rhs); |
| 3238 | 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 | 3220 | const writer = f.object.writer(); |
| 3245 | | if (is_array) { |
| 3246 | | try writer.writeAll("memcpy("); |
| 3247 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 3248 | | try writer.writeAll(", "); |
| 3249 | | } else { |
| 3250 | | try f.writeCValue(writer, local, .Other); |
| 3251 | | try writer.writeAll(" = "); |
| 3252 | | } |
| 3221 | const local = try f.allocLocal(inst, inst_ty); |
| 3222 | const a = try Assignment.start(f, writer, inst_ty); |
| 3223 | try f.writeCValue(writer, local, .Other); |
| 3224 | try a.assign(f, writer); |
| 3253 | 3225 | try f.writeCValue(writer, array, .Other); |
| 3254 | 3226 | try writer.writeByte('['); |
| 3255 | 3227 | try f.writeCValue(writer, index, .Other); |
| 3256 | 3228 | try writer.writeByte(']'); |
| 3257 | | if (is_array) { |
| 3258 | | try writer.writeAll(", sizeof("); |
| 3259 | | try f.renderType(writer, inst_ty); |
| 3260 | | try writer.writeAll("))"); |
| 3261 | | } |
| 3262 | | try writer.writeAll(";\n"); |
| 3229 | try a.end(f, writer); |
| 3263 | 3230 | return local; |
| 3264 | 3231 | } |
| 3265 | 3232 | |
| ... | ... | @@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3343 | 3310 | |
| 3344 | 3311 | const writer = f.object.writer(); |
| 3345 | 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 | 3315 | if (need_memcpy) { |
| 3349 | 3316 | try writer.writeAll("memcpy("); |
| ... | ... | @@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3484 | 3451 | |
| 3485 | 3452 | const writer = f.object.writer(); |
| 3486 | 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 | 3456 | try f.writeCValue(writer, local, .Other); |
| 3489 | 3457 | try v.elem(f, writer); |
| 3490 | | try writer.writeAll(" = "); |
| 3458 | try a.assign(f, writer); |
| 3491 | 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 | 3461 | try v.end(f, inst, writer); |
| 3494 | 3462 | |
| 3495 | 3463 | return local; |
| ... | ... | @@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3513 | 3481 | |
| 3514 | 3482 | const writer = f.object.writer(); |
| 3515 | 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 | 3486 | try f.writeCValue(writer, local, .Other); |
| 3519 | 3487 | try v.elem(f, writer); |
| ... | ... | @@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3597 | 3565 | const writer = f.object.writer(); |
| 3598 | 3566 | const inst_ty = f.air.typeOfIndex(inst); |
| 3599 | 3567 | const local = try f.allocLocal(inst, inst_ty); |
| 3568 | const a = try Assignment.start(f, writer, inst_ty); |
| 3600 | 3569 | try f.writeCValue(writer, local, .Other); |
| 3601 | | try writer.writeAll(" = "); |
| 3570 | try a.assign(f, writer); |
| 3602 | 3571 | try f.writeCValue(writer, operand, .Other); |
| 3603 | | try writer.writeAll(";\n"); |
| 3572 | try a.end(f, writer); |
| 3604 | 3573 | return local; |
| 3605 | 3574 | } |
| 3606 | 3575 | |
| ... | ... | @@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3632 | 3601 | const src_val_is_undefined = |
| 3633 | 3602 | if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; |
| 3634 | 3603 | if (src_val_is_undefined) { |
| 3635 | | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3636 | | return try storeUndefined(f, ptr_info.pointee_type, ptr_val); |
| 3604 | if (ptr_info.host_size == 0) { |
| 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 | 3613 | const target = f.object.dg.module.getTarget(); |
| ... | ... | @@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3646 | 3620 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3647 | 3621 | |
| 3648 | 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 | 3625 | if (need_memcpy) { |
| 3652 | 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 | 3749 | |
| 3776 | 3750 | const w = f.object.writer(); |
| 3777 | 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 | 3753 | try f.writeCValueMember(w, local, .{ .field = 1 }); |
| 3780 | 3754 | try v.elem(f, w); |
| 3781 | 3755 | try w.writeAll(" = zig_"); |
| ... | ... | @@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3811 | 3785 | |
| 3812 | 3786 | const writer = f.object.writer(); |
| 3813 | 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 | 3789 | try f.writeCValue(writer, local, .Other); |
| 3816 | 3790 | try v.elem(f, writer); |
| 3817 | 3791 | try writer.writeAll(" = "); |
| ... | ... | @@ -3846,7 +3820,7 @@ fn airBinOp( |
| 3846 | 3820 | |
| 3847 | 3821 | const writer = f.object.writer(); |
| 3848 | 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 | 3824 | try f.writeCValue(writer, local, .Other); |
| 3851 | 3825 | try v.elem(f, writer); |
| 3852 | 3826 | try writer.writeAll(" = "); |
| ... | ... | @@ -3893,7 +3867,7 @@ fn airCmpOp( |
| 3893 | 3867 | |
| 3894 | 3868 | const writer = f.object.writer(); |
| 3895 | 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 | 3871 | try f.writeCValue(writer, local, .Other); |
| 3898 | 3872 | try v.elem(f, writer); |
| 3899 | 3873 | try writer.writeAll(" = "); |
| ... | ... | @@ -3942,7 +3916,7 @@ fn airEquality( |
| 3942 | 3916 | try f.writeCValue(writer, local, .Other); |
| 3943 | 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 | 3920 | // (A && B) || (C && (A == B)) |
| 3947 | 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 | 3982 | |
| 4009 | 3983 | const local = try f.allocLocal(inst, inst_ty); |
| 4010 | 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 | 3986 | try f.writeCValue(writer, local, .Other); |
| 4013 | 3987 | try v.elem(f, writer); |
| 4014 | 3988 | try writer.writeAll(" = "); |
| ... | ... | @@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4059 | 4033 | |
| 4060 | 4034 | const writer = f.object.writer(); |
| 4061 | 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 | 4037 | try f.writeCValue(writer, local, .Other); |
| 4064 | 4038 | try v.elem(f, writer); |
| 4065 | 4039 | // (lhs <> rhs) ? lhs : rhs |
| ... | ... | @@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4091 | 4065 | const len = try f.resolveInst(bin_op.rhs); |
| 4092 | 4066 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 4093 | 4067 | |
| 4094 | | const writer = f.object.writer(); |
| 4095 | 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 | 4069 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 4100 | | try f.renderType(writer, 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"); |
| 4070 | const ptr_ty = inst_ty.slicePtrFieldType(&buf); |
| 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 | 4091 | return local; |
| 4110 | 4092 | } |
| 4111 | 4093 | |
| ... | ... | @@ -4346,10 +4328,10 @@ fn lowerTry( |
| 4346 | 4328 | operand: Air.Inst.Ref, |
| 4347 | 4329 | body: []const Air.Inst.Index, |
| 4348 | 4330 | err_union_ty: Type, |
| 4349 | | operand_is_ptr: bool, |
| 4331 | is_ptr: bool, |
| 4350 | 4332 | ) !CValue { |
| 4351 | 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 | 4335 | const liveness_condbr = f.liveness.getCondBr(inst); |
| 4354 | 4336 | const writer = f.object.writer(); |
| 4355 | 4337 | const payload_ty = err_union_ty.errorUnionPayload(); |
| ... | ... | @@ -4358,7 +4340,7 @@ fn lowerTry( |
| 4358 | 4340 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 4359 | 4341 | try writer.writeAll("if ("); |
| 4360 | 4342 | if (!payload_has_bits) { |
| 4361 | | if (operand_is_ptr) |
| 4343 | if (is_ptr) |
| 4362 | 4344 | try f.writeCValueDeref(writer, err_union) |
| 4363 | 4345 | else |
| 4364 | 4346 | try f.writeCValue(writer, err_union, .Other); |
| ... | ... | @@ -4367,7 +4349,7 @@ fn lowerTry( |
| 4367 | 4349 | // Remember we must avoid calling reap() twice for the same operand |
| 4368 | 4350 | // in this function. |
| 4369 | 4351 | try reap(f, inst, &.{operand}); |
| 4370 | | if (operand_is_ptr or isByRef(err_union_ty)) |
| 4352 | if (is_ptr) |
| 4371 | 4353 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" }) |
| 4372 | 4354 | else |
| 4373 | 4355 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); |
| ... | ... | @@ -4384,7 +4366,7 @@ fn lowerTry( |
| 4384 | 4366 | } |
| 4385 | 4367 | |
| 4386 | 4368 | if (!payload_has_bits) { |
| 4387 | | if (!operand_is_ptr) { |
| 4369 | if (!is_ptr) { |
| 4388 | 4370 | return .none; |
| 4389 | 4371 | } else { |
| 4390 | 4372 | return err_union; |
| ... | ... | @@ -4397,26 +4379,15 @@ fn lowerTry( |
| 4397 | 4379 | return .none; |
| 4398 | 4380 | } |
| 4399 | 4381 | |
| 4400 | | const target = f.object.dg.module.getTarget(); |
| 4401 | | const is_array = lowersToArray(payload_ty, target); |
| 4402 | | const local = try f.allocLocal(inst, result_ty); |
| 4403 | | if (is_array) { |
| 4404 | | try writer.writeAll("memcpy("); |
| 4405 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 4406 | | try writer.writeAll(", "); |
| 4407 | | try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); |
| 4408 | | try writer.writeAll(", sizeof("); |
| 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 | | } |
| 4382 | const local = try f.allocLocal(inst, inst_ty); |
| 4383 | const a = try Assignment.start(f, writer, inst_ty); |
| 4384 | try f.writeCValue(writer, local, .Other); |
| 4385 | try a.assign(f, writer); |
| 4386 | if (is_ptr) { |
| 4387 | try writer.writeByte('&'); |
| 4388 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" }); |
| 4389 | } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); |
| 4390 | try a.end(f, writer); |
| 4420 | 4391 | return local; |
| 4421 | 4392 | } |
| 4422 | 4393 | |
| ... | ... | @@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4428 | 4399 | |
| 4429 | 4400 | // If result is .none then the value of the block is unused. |
| 4430 | 4401 | if (result != .none) { |
| 4402 | const operand_ty = f.air.typeOf(branch.operand); |
| 4431 | 4403 | const operand = try f.resolveInst(branch.operand); |
| 4432 | 4404 | try reap(f, inst, &.{branch.operand}); |
| 4433 | 4405 | |
| 4434 | | const operand_ty = f.air.typeOf(branch.operand); |
| 4435 | | const target = f.object.dg.module.getTarget(); |
| 4436 | | if (lowersToArray(operand_ty, target)) { |
| 4437 | | try writer.writeAll("memcpy("); |
| 4438 | | try f.writeCValue(writer, result, .FunctionArgument); |
| 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"); |
| 4406 | const a = try Assignment.start(f, writer, operand_ty); |
| 4407 | try f.writeCValue(writer, result, .Other); |
| 4408 | try a.assign(f, writer); |
| 4409 | try f.writeCValue(writer, operand, .Other); |
| 4410 | try a.end(f, writer); |
| 4450 | 4411 | } |
| 4451 | 4412 | |
| 4452 | 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 | 4732 | if (f.wantSafety()) { |
| 4772 | 4733 | try f.writeCValue(writer, local, .Other); |
| 4773 | 4734 | try writer.writeAll(" = "); |
| 4774 | | try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer); |
| 4735 | try f.writeCValue(writer, .{ .undef = inst_ty }, .Other); |
| 4775 | 4736 | try writer.writeAll(";\n"); |
| 4776 | 4737 | } |
| 4777 | 4738 | break :local local; |
| ... | ... | @@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4806 | 4767 | try writer.writeAll("\")"); |
| 4807 | 4768 | if (f.wantSafety()) { |
| 4808 | 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 | 4772 | try writer.writeAll(";\n"); |
| 4812 | 4773 | } |
| ... | ... | @@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4840 | 4801 | try writer.writeAll("\")"); |
| 4841 | 4802 | } |
| 4842 | 4803 | try writer.writeAll(" = "); |
| 4843 | | try f.writeCValue(writer, input_val, .Initializer); |
| 4804 | try f.writeCValue(writer, input_val, .Other); |
| 4844 | 4805 | try writer.writeAll(";\n"); |
| 4845 | 4806 | } |
| 4846 | 4807 | } |
| ... | ... | @@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5072 | 5033 | } |
| 5073 | 5034 | |
| 5074 | 5035 | const inst_ty = f.air.typeOfIndex(inst); |
| 5075 | | const local = try f.allocLocal(inst, inst_ty); |
| 5076 | 5036 | const writer = f.object.writer(); |
| 5037 | const local = try f.allocLocal(inst, inst_ty); |
| 5077 | 5038 | |
| 5078 | 5039 | if (opt_ty.optionalReprIsPayload()) { |
| 5079 | 5040 | try f.writeCValue(writer, local, .Other); |
| ... | ... | @@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5083 | 5044 | return local; |
| 5084 | 5045 | } |
| 5085 | 5046 | |
| 5086 | | const target = f.object.dg.module.getTarget(); |
| 5087 | | const is_array = lowersToArray(inst_ty, target); |
| 5088 | | |
| 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 | | } |
| 5047 | const a = try Assignment.start(f, writer, inst_ty); |
| 5048 | try f.writeCValue(writer, local, .Other); |
| 5049 | try a.assign(f, writer); |
| 5097 | 5050 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5098 | | if (is_array) { |
| 5099 | | try writer.writeAll(", sizeof("); |
| 5100 | | try f.renderType(writer, inst_ty); |
| 5101 | | try writer.writeAll("))"); |
| 5102 | | } |
| 5103 | | try writer.writeAll(";\n"); |
| 5051 | try a.end(f, writer); |
| 5104 | 5052 | return local; |
| 5105 | 5053 | } |
| 5106 | 5054 | |
| ... | ... | @@ -5193,6 +5141,7 @@ fn fieldLocation( |
| 5193 | 5141 | if (container_ty.structFieldIsComptime(next_field_index)) continue; |
| 5194 | 5142 | const field_ty = container_ty.structFieldType(next_field_index); |
| 5195 | 5143 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 5144 | |
| 5196 | 5145 | break .{ .field = if (container_ty.isSimpleTuple()) |
| 5197 | 5146 | .{ .field = next_field_index } |
| 5198 | 5147 | else |
| ... | ... | @@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5437 | 5386 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5438 | 5387 | try writer.writeByte('('); |
| 5439 | 5388 | } |
| 5440 | | try writer.writeAll("zig_shr_"); |
| 5441 | | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5442 | | try writer.writeByte('('); |
| 5389 | if (bit_offset_val_pl.data > 0) { |
| 5390 | try writer.writeAll("zig_shr_"); |
| 5391 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5392 | try writer.writeByte('('); |
| 5393 | } |
| 5443 | 5394 | try f.writeCValue(writer, struct_byval, .Other); |
| 5444 | | try writer.writeAll(", "); |
| 5445 | | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| 5446 | | try writer.writeByte(')'); |
| 5395 | if (bit_offset_val_pl.data > 0) { |
| 5396 | try writer.writeAll(", "); |
| 5397 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| 5398 | try writer.writeByte(')'); |
| 5399 | } |
| 5447 | 5400 | if (cant_cast) try writer.writeByte(')'); |
| 5448 | 5401 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); |
| 5449 | 5402 | try writer.writeAll(");\n"); |
| ... | ... | @@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5473 | 5426 | |
| 5474 | 5427 | const local = try f.allocLocal(inst, inst_ty); |
| 5475 | 5428 | try writer.writeAll("memcpy(&"); |
| 5476 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 5429 | try f.writeCValue(writer, local, .Other); |
| 5477 | 5430 | try writer.writeAll(", &"); |
| 5478 | | try f.writeCValue(writer, operand_lval, .FunctionArgument); |
| 5431 | try f.writeCValue(writer, operand_lval, .Other); |
| 5479 | 5432 | try writer.writeAll(", sizeof("); |
| 5480 | 5433 | try f.renderType(writer, inst_ty); |
| 5481 | 5434 | try writer.writeAll("));\n"); |
| ... | ... | @@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5496 | 5449 | }; |
| 5497 | 5450 | |
| 5498 | 5451 | const local = try f.allocLocal(inst, inst_ty); |
| 5499 | | if (lowersToArray(inst_ty, target)) { |
| 5500 | | try writer.writeAll("memcpy("); |
| 5501 | | try f.writeCValue(writer, local, .FunctionArgument); |
| 5502 | | try writer.writeAll(", "); |
| 5503 | | try f.writeCValueMember(writer, struct_byval, field_name); |
| 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"); |
| 5452 | const a = try Assignment.start(f, writer, inst_ty); |
| 5453 | try f.writeCValue(writer, local, .Other); |
| 5454 | try a.assign(f, writer); |
| 5455 | try f.writeCValueMember(writer, struct_byval, field_name); |
| 5456 | try a.end(f, writer); |
| 5513 | 5457 | return local; |
| 5514 | 5458 | } |
| 5515 | 5459 | |
| ... | ... | @@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 5554 | 5498 | const operand = try f.resolveInst(ty_op.operand); |
| 5555 | 5499 | try reap(f, inst, &.{ty_op.operand}); |
| 5556 | 5500 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 5557 | | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| 5558 | | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5501 | const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty; |
| 5559 | 5502 | |
| 5503 | const writer = f.object.writer(); |
| 5560 | 5504 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { |
| 5561 | 5505 | if (!is_ptr) return .none; |
| 5562 | 5506 | |
| 5563 | | const w = f.object.writer(); |
| 5564 | 5507 | const local = try f.allocLocal(inst, inst_ty); |
| 5565 | | try f.writeCValue(w, local, .Other); |
| 5566 | | try w.writeAll(" = ("); |
| 5567 | | try f.renderType(w, inst_ty); |
| 5568 | | try w.writeByte(')'); |
| 5569 | | try f.writeCValue(w, operand, .Initializer); |
| 5570 | | try w.writeAll(";\n"); |
| 5508 | try f.writeCValue(writer, local, .Other); |
| 5509 | try writer.writeAll(" = ("); |
| 5510 | try f.renderType(writer, inst_ty); |
| 5511 | try writer.writeByte(')'); |
| 5512 | try f.writeCValue(writer, operand, .Initializer); |
| 5513 | try writer.writeAll(";\n"); |
| 5571 | 5514 | return local; |
| 5572 | 5515 | } |
| 5573 | 5516 | |
| 5574 | | const writer = f.object.writer(); |
| 5575 | 5517 | const local = try f.allocLocal(inst, inst_ty); |
| 5518 | const a = try Assignment.start(f, writer, inst_ty); |
| 5576 | 5519 | try f.writeCValue(writer, local, .Other); |
| 5577 | | try writer.writeAll(" = "); |
| 5578 | | if (is_ptr) try writer.writeByte('&'); |
| 5579 | | if (operand_is_ptr) |
| 5580 | | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }) |
| 5581 | | else |
| 5582 | | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5583 | | try writer.writeAll(";\n"); |
| 5520 | try a.assign(f, writer); |
| 5521 | if (is_ptr) { |
| 5522 | try writer.writeByte('&'); |
| 5523 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }); |
| 5524 | } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5525 | try a.end(f, writer); |
| 5584 | 5526 | return local; |
| 5585 | 5527 | } |
| 5586 | 5528 | |
| ... | ... | @@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5588 | 5530 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 5589 | 5531 | |
| 5590 | 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 | 5535 | const payload = try f.resolveInst(ty_op.operand); |
| 5592 | 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 | 5539 | const local = try f.allocLocal(inst, inst_ty); |
| 5609 | | if (!is_array) { |
| 5610 | | try f.writeCValue(writer, local, .Other); |
| 5611 | | try writer.writeAll(".payload = "); |
| 5540 | { |
| 5541 | const a = try Assignment.start(f, writer, payload_ty); |
| 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 | 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); |
| 5616 | | try writer.writeAll(".is_null = false;\n"); |
| 5617 | | if (is_array) { |
| 5618 | | try writer.writeAll("memcpy("); |
| 5619 | | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 5620 | | try writer.writeAll(", "); |
| 5621 | | try f.writeCValue(writer, payload, .FunctionArgument); |
| 5622 | | try writer.writeAll(", sizeof("); |
| 5623 | | try f.renderType(writer, payload_ty); |
| 5624 | | try writer.writeAll("));\n"); |
| 5550 | if (!repr_is_payload) { |
| 5551 | const a = try Assignment.start(f, writer, Type.bool); |
| 5552 | try f.writeCValueMember(writer, local, .{ .identifier = "is_null" }); |
| 5553 | try a.assign(f, writer); |
| 5554 | try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other); |
| 5555 | try a.end(f, writer); |
| 5625 | 5556 | } |
| 5626 | 5557 | return local; |
| 5627 | 5558 | } |
| ... | ... | @@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5629 | 5560 | fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5630 | 5561 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 5631 | 5562 | |
| 5632 | | const writer = f.object.writer(); |
| 5633 | | const operand = try f.resolveInst(ty_op.operand); |
| 5563 | const inst_ty = f.air.typeOfIndex(inst); |
| 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 | 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()) { |
| 5640 | | try f.writeCValue(writer, local, .Other); |
| 5641 | | try writer.writeAll(" = "); |
| 5642 | | try f.writeCValue(writer, operand, .Other); |
| 5643 | | try writer.writeAll(";\n"); |
| 5644 | | return local; |
| 5570 | const writer = f.object.writer(); |
| 5571 | const local = try f.allocLocal(inst, inst_ty); |
| 5572 | if (!repr_is_err) { |
| 5573 | const a = try Assignment.start(f, writer, payload_ty); |
| 5574 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 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 |
| 5649 | | //try f.writeCValue(writer, local, .Other); |
| 5580 | const a = try Assignment.start(f, writer, err_ty); |
| 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 | 5589 | return local; |
| 5656 | 5590 | } |
| 5657 | 5591 | |
| ... | ... | @@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5711 | 5645 | const inst_ty = f.air.typeOfIndex(inst); |
| 5712 | 5646 | const payload_ty = inst_ty.errorUnionPayload(); |
| 5713 | 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 | 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 | 5652 | const writer = f.object.writer(); |
| 5720 | 5653 | const local = try f.allocLocal(inst, inst_ty); |
| 5721 | | if (!is_array) { |
| 5722 | | try f.writeCValue(writer, local, .Other); |
| 5723 | | try writer.writeAll(".payload = "); |
| 5654 | if (!repr_is_err) { |
| 5655 | const a = try Assignment.start(f, writer, payload_ty); |
| 5656 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 5657 | try a.assign(f, writer); |
| 5724 | 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); |
| 5728 | | try writer.writeAll(".error = 0;\n"); |
| 5729 | | if (is_array) { |
| 5730 | | try writer.writeAll("memcpy("); |
| 5731 | | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 5732 | | try writer.writeAll(", "); |
| 5733 | | try f.writeCValue(writer, payload, .FunctionArgument); |
| 5734 | | try writer.writeAll(", sizeof("); |
| 5735 | | try f.renderType(writer, payload_ty); |
| 5736 | | try writer.writeAll("));\n"); |
| 5661 | { |
| 5662 | const a = try Assignment.start(f, writer, err_ty); |
| 5663 | if (repr_is_err) |
| 5664 | try f.writeCValue(writer, local, .Other) |
| 5665 | else |
| 5666 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); |
| 5667 | try a.assign(f, writer); |
| 5668 | try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other); |
| 5669 | try a.end(f, writer); |
| 5737 | 5670 | } |
| 5738 | 5671 | return local; |
| 5739 | 5672 | } |
| ... | ... | @@ -5885,7 +5818,7 @@ fn airUnBuiltinCall( |
| 5885 | 5818 | |
| 5886 | 5819 | const writer = f.object.writer(); |
| 5887 | 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 | 5822 | if (!ref_ret) { |
| 5890 | 5823 | try f.writeCValue(writer, local, .Other); |
| 5891 | 5824 | try v.elem(f, writer); |
| ... | ... | @@ -5934,7 +5867,7 @@ fn airBinBuiltinCall( |
| 5934 | 5867 | const writer = f.object.writer(); |
| 5935 | 5868 | const local = try f.allocLocal(inst, inst_ty); |
| 5936 | 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 | 5871 | if (!ref_ret) { |
| 5939 | 5872 | try f.writeCValue(writer, local, .Other); |
| 5940 | 5873 | try v.elem(f, writer); |
| ... | ... | @@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall( |
| 5982 | 5915 | |
| 5983 | 5916 | const writer = f.object.writer(); |
| 5984 | 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 | 5919 | if (!ref_ret) { |
| 5987 | 5920 | try f.writeCValue(writer, local, .Other); |
| 5988 | 5921 | try v.elem(f, writer); |
| ... | ... | @@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6262 | 6195 | const union_ptr = try f.resolveInst(bin_op.lhs); |
| 6263 | 6196 | const new_tag = try f.resolveInst(bin_op.rhs); |
| 6264 | 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 | 6199 | const target = f.object.dg.module.getTarget(); |
| 6200 | const union_ty = f.air.typeOf(bin_op.lhs).childType(); |
| 6269 | 6201 | const layout = union_ty.unionGetLayout(target); |
| 6270 | 6202 | if (layout.tag_size == 0) return .none; |
| 6203 | const tag_ty = union_ty.unionTagTypeSafety().?; |
| 6271 | 6204 | |
| 6272 | | try writer.writeByte('('); |
| 6273 | | try f.writeCValue(writer, union_ptr, .Other); |
| 6274 | | try writer.writeAll(")->tag = "); |
| 6205 | const writer = f.object.writer(); |
| 6206 | const a = try Assignment.start(f, writer, tag_ty); |
| 6207 | try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" }); |
| 6208 | try a.assign(f, writer); |
| 6275 | 6209 | try f.writeCValue(writer, new_tag, .Other); |
| 6276 | | try writer.writeAll(";\n"); |
| 6277 | | |
| 6210 | try a.end(f, writer); |
| 6278 | 6211 | return .none; |
| 6279 | 6212 | } |
| 6280 | 6213 | |
| ... | ... | @@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6284 | 6217 | const operand = try f.resolveInst(ty_op.operand); |
| 6285 | 6218 | try reap(f, inst, &.{ty_op.operand}); |
| 6286 | 6219 | |
| 6287 | | const un_ty = f.air.typeOf(ty_op.operand); |
| 6288 | | |
| 6220 | const union_ty = f.air.typeOf(ty_op.operand); |
| 6289 | 6221 | const target = f.object.dg.module.getTarget(); |
| 6290 | | const layout = un_ty.unionGetLayout(target); |
| 6222 | const layout = union_ty.unionGetLayout(target); |
| 6291 | 6223 | if (layout.tag_size == 0) return .none; |
| 6292 | 6224 | |
| 6293 | 6225 | const inst_ty = f.air.typeOfIndex(inst); |
| 6294 | 6226 | const writer = f.object.writer(); |
| 6295 | 6227 | const local = try f.allocLocal(inst, inst_ty); |
| 6228 | const a = try Assignment.start(f, writer, inst_ty); |
| 6296 | 6229 | try f.writeCValue(writer, local, .Other); |
| 6297 | | |
| 6298 | | try writer.writeAll(" = "); |
| 6299 | | try f.writeCValue(writer, operand, .Other); |
| 6300 | | try writer.writeAll(".tag;\n"); |
| 6230 | try a.assign(f, writer); |
| 6231 | try f.writeCValueMember(writer, operand, .{ .identifier = "tag" }); |
| 6232 | try a.end(f, writer); |
| 6301 | 6233 | return local; |
| 6302 | 6234 | } |
| 6303 | 6235 | |
| ... | ... | @@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6350 | 6282 | |
| 6351 | 6283 | const writer = f.object.writer(); |
| 6352 | 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 | 6286 | if (need_memcpy) try writer.writeAll("memcpy(&"); |
| 6355 | 6287 | try f.writeCValue(writer, local, .Other); |
| 6356 | 6288 | try v.elem(f, writer); |
| ... | ... | @@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6380 | 6312 | |
| 6381 | 6313 | const writer = f.object.writer(); |
| 6382 | 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 | 6316 | try f.writeCValue(writer, local, .Other); |
| 6385 | 6317 | try v.elem(f, writer); |
| 6386 | 6318 | try writer.writeAll(" = "); |
| ... | ... | @@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6547 | 6479 | }, .Initializer); |
| 6548 | 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 | 6483 | try f.writeCValue(writer, accum, .Other); |
| 6552 | 6484 | switch (op) { |
| 6553 | 6485 | .float_op => |func| { |
| ... | ... | @@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6621 | 6553 | switch (inst_ty.zigTypeTag()) { |
| 6622 | 6554 | .Array, .Vector => { |
| 6623 | 6555 | const elem_ty = inst_ty.childType(); |
| 6624 | | |
| 6625 | | const is_array = lowersToArray(elem_ty, target); |
| 6626 | | const need_memcpy = is_array; |
| 6627 | | if (need_memcpy) { |
| 6628 | | for (resolved_elements, 0..) |element, i| { |
| 6629 | | try writer.writeAll("memcpy("); |
| 6630 | | try f.writeCValue(writer, local, .Other); |
| 6631 | | try writer.print("[{d}]", .{i}); |
| 6632 | | try writer.writeAll(", "); |
| 6633 | | try f.writeCValue(writer, element, .Other); |
| 6634 | | try writer.writeAll(", sizeof("); |
| 6635 | | try f.renderType(writer, elem_ty); |
| 6636 | | try writer.writeAll("))"); |
| 6637 | | try writer.writeAll(";\n"); |
| 6638 | | } |
| 6639 | | assert(inst_ty.sentinel() == null); |
| 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 | | } |
| 6556 | const a = try Assignment.init(f, elem_ty); |
| 6557 | for (resolved_elements, 0..) |element, i| { |
| 6558 | try a.restart(f, writer); |
| 6559 | try f.writeCValue(writer, local, .Other); |
| 6560 | try writer.print("[{d}]", .{i}); |
| 6561 | try a.assign(f, writer); |
| 6562 | try f.writeCValue(writer, element, .Other); |
| 6563 | try a.end(f, writer); |
| 6564 | } |
| 6565 | if (inst_ty.sentinel()) |sentinel| { |
| 6566 | try a.restart(f, writer); |
| 6567 | try f.writeCValue(writer, local, .Other); |
| 6568 | try writer.print("[{d}]", .{resolved_elements.len}); |
| 6569 | try a.assign(f, writer); |
| 6570 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); |
| 6571 | try a.end(f, writer); |
| 6653 | 6572 | } |
| 6654 | 6573 | }, |
| 6655 | 6574 | .Struct => switch (inst_ty.containerLayout()) { |
| 6656 | | .Auto, .Extern => { |
| 6657 | | try f.writeCValue(writer, local, .Other); |
| 6658 | | try writer.writeAll(" = ("); |
| 6659 | | try f.renderType(writer, inst_ty); |
| 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) }; |
| 6575 | .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| { |
| 6576 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| 6577 | const field_ty = inst_ty.structFieldType(field_i); |
| 6578 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6695 | 6579 | |
| 6696 | | try writer.writeAll(";\n"); |
| 6697 | | try writer.writeAll("memcpy("); |
| 6698 | | try f.writeCValueMember(writer, local, field_name); |
| 6699 | | try writer.writeAll(", "); |
| 6700 | | try f.writeCValue(writer, resolved_element, .FunctionArgument); |
| 6701 | | try writer.writeAll(", sizeof("); |
| 6702 | | try f.renderType(writer, element_ty); |
| 6703 | | try writer.writeAll("));\n"); |
| 6704 | | } |
| 6580 | const a = try Assignment.start(f, writer, field_ty); |
| 6581 | try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple()) |
| 6582 | .{ .field = field_i } |
| 6583 | else |
| 6584 | .{ .identifier = inst_ty.structFieldName(field_i) }); |
| 6585 | try a.assign(f, writer); |
| 6586 | try f.writeCValue(writer, element, .Other); |
| 6587 | try a.end(f, writer); |
| 6705 | 6588 | }, |
| 6706 | 6589 | .Packed => { |
| 6707 | 6590 | try f.writeCValue(writer, local, .Other); |
| ... | ... | @@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6718 | 6601 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 6719 | 6602 | |
| 6720 | 6603 | var empty = true; |
| 6721 | | for (0..elements.len) |index| { |
| 6722 | | const field_ty = inst_ty.structFieldType(index); |
| 6604 | for (0..elements.len) |field_i| { |
| 6605 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| 6606 | const field_ty = inst_ty.structFieldType(field_i); |
| 6723 | 6607 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6724 | 6608 | |
| 6725 | 6609 | if (!empty) { |
| ... | ... | @@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6730 | 6614 | empty = false; |
| 6731 | 6615 | } |
| 6732 | 6616 | empty = true; |
| 6733 | | for (resolved_elements, 0..) |element, index| { |
| 6734 | | const field_ty = inst_ty.structFieldType(index); |
| 6617 | for (resolved_elements, 0..) |element, field_i| { |
| 6618 | if (inst_ty.structFieldIsComptime(field_i)) continue; |
| 6619 | const field_ty = inst_ty.structFieldType(field_i); |
| 6735 | 6620 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6736 | 6621 | |
| 6737 | 6622 | if (!empty) try writer.writeAll(", "); |
| ... | ... | @@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6784 | 6669 | const target = f.object.dg.module.getTarget(); |
| 6785 | 6670 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 6786 | 6671 | const field_name = union_obj.fields.keys()[extra.field_index]; |
| 6672 | const payload_ty = f.air.typeOf(extra.init); |
| 6787 | 6673 | const payload = try f.resolveInst(extra.init); |
| 6788 | 6674 | try reap(f, inst, &.{extra.init}); |
| 6789 | 6675 | |
| ... | ... | @@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6811 | 6697 | var int_pl: Value.Payload.U64 = undefined; |
| 6812 | 6698 | const int_val = tag_val.enumToInt(tag_ty, &int_pl); |
| 6813 | 6699 | |
| 6814 | | try f.writeCValue(writer, local, .Other); |
| 6815 | | try writer.print(".tag = {}; ", .{try f.fmtIntLiteral(tag_ty, int_val)}); |
| 6700 | const a = try Assignment.start(f, writer, tag_ty); |
| 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 | 6706 | break :field .{ .payload_identifier = field_name }; |
| 6818 | 6707 | } else .{ .identifier = field_name }; |
| 6819 | 6708 | |
| 6709 | const a = try Assignment.start(f, writer, payload_ty); |
| 6820 | 6710 | try f.writeCValueMember(writer, local, field); |
| 6821 | | try writer.writeAll(" = "); |
| 6711 | try a.assign(f, writer); |
| 6822 | 6712 | try f.writeCValue(writer, payload, .Other); |
| 6823 | | try writer.writeAll(";\n"); |
| 6713 | try a.end(f, writer); |
| 6824 | 6714 | return local; |
| 6825 | 6715 | } |
| 6826 | 6716 | |
| ... | ... | @@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6887 | 6777 | |
| 6888 | 6778 | const writer = f.object.writer(); |
| 6889 | 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 | 6781 | try f.writeCValue(writer, local, .Other); |
| 6892 | 6782 | try v.elem(f, writer); |
| 6893 | 6783 | try writer.writeAll(" = zig_neg_"); |
| ... | ... | @@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal |
| 6912 | 6802 | |
| 6913 | 6803 | const writer = f.object.writer(); |
| 6914 | 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 | 6806 | try f.writeCValue(writer, local, .Other); |
| 6917 | 6807 | try v.elem(f, writer); |
| 6918 | 6808 | try writer.writeAll(" = zig_libc_name_"); |
| ... | ... | @@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa |
| 6940 | 6830 | |
| 6941 | 6831 | const writer = f.object.writer(); |
| 6942 | 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 | 6834 | try f.writeCValue(writer, local, .Other); |
| 6945 | 6835 | try v.elem(f, writer); |
| 6946 | 6836 | try writer.writeAll(" = zig_libc_name_"); |
| ... | ... | @@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6973 | 6863 | |
| 6974 | 6864 | const writer = f.object.writer(); |
| 6975 | 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 | 6867 | try f.writeCValue(writer, local, .Other); |
| 6978 | 6868 | try v.elem(f, writer); |
| 6979 | 6869 | try writer.writeAll(" = zig_libc_name_"); |
| ... | ... | @@ -7480,10 +7370,57 @@ fn formatIntLiteral( |
| 7480 | 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 | 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 | 7424 | return if (ty.zigTypeTag() == .Vector) index: { |
| 7488 | 7425 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; |
| 7489 | 7426 | |
| ... | ... | @@ -7504,7 +7441,7 @@ const Vectorizer = struct { |
| 7504 | 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 | 7445 | if (self.index != .none) { |
| 7509 | 7446 | try writer.writeByte('['); |
| 7510 | 7447 | try f.writeCValue(writer, self.index, .Other); |
| ... | ... | @@ -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 | 7453 | if (self.index != .none) { |
| 7517 | 7454 | f.object.indent_writer.popIndent(); |
| 7518 | 7455 | try writer.writeAll("}\n"); |
| ... | ... | @@ -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 | 7461 | const LowerFnRetTyBuffer = struct { |
| 7530 | 7462 | names: [1][]const u8, |
| 7531 | 7463 | types: [1]Type, |
| ... | ... | @@ -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 | 7492 | fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void { |
| 7584 | 7493 | assert(operands.len <= Liveness.bpi - 1); |
| 7585 | 7494 | var tomb_bits = f.liveness.getTombBits(inst); |