| ... | @@ -882,14 +882,14 @@ pub const DeclGen = struct { | ... | @@ -882,14 +882,14 @@ pub const DeclGen = struct { |
| 882 | var literal = stringLiteral(writer); | 882 | var literal = stringLiteral(writer); |
| 883 | try literal.start(); | 883 | try literal.start(); |
| 884 | const c_len = ty.arrayLenIncludingSentinel(); | 884 | const c_len = ty.arrayLenIncludingSentinel(); |
| 885 | var index: usize = 0; | 885 | var index: u64 = 0; |
| 886 | while (index < c_len) : (index += 1) | 886 | while (index < c_len) : (index += 1) |
| 887 | try literal.writeChar(0xaa); | 887 | try literal.writeChar(0xaa); |
| 888 | return literal.end(); | 888 | return literal.end(); |
| 889 | } else { | 889 | } else { |
| 890 | try writer.writeByte('{'); | 890 | try writer.writeByte('{'); |
| 891 | const c_len = ty.arrayLenIncludingSentinel(); | 891 | const c_len = ty.arrayLenIncludingSentinel(); |
| 892 | var index: usize = 0; | 892 | var index: u64 = 0; |
| 893 | while (index < c_len) : (index += 1) { | 893 | while (index < c_len) : (index += 1) { |
| 894 | if (index > 0) try writer.writeAll(", "); | 894 | if (index > 0) try writer.writeAll(", "); |
| 895 | try dg.renderValue(writer, ty.childType(), val, initializer_type); | 895 | try dg.renderValue(writer, ty.childType(), val, initializer_type); |
| ... | @@ -1089,8 +1089,8 @@ pub const DeclGen = struct { | ... | @@ -1089,8 +1089,8 @@ pub const DeclGen = struct { |
| 1089 | // First try specific tag representations for more efficiency. | 1089 | // First try specific tag representations for more efficiency. |
| 1090 | switch (val.tag()) { | 1090 | switch (val.tag()) { |
| 1091 | .undef, .empty_struct_value, .empty_array => { | 1091 | .undef, .empty_struct_value, .empty_array => { |
| 1092 | try writer.writeByte('{'); | | |
| 1093 | const ai = ty.arrayInfo(); | 1092 | const ai = ty.arrayInfo(); |
| | 1093 | try writer.writeByte('{'); |
| 1094 | if (ai.sentinel) |s| { | 1094 | if (ai.sentinel) |s| { |
| 1095 | try dg.renderValue(writer, ai.elem_type, s, initializer_type); | 1095 | try dg.renderValue(writer, ai.elem_type, s, initializer_type); |
| 1096 | } else { | 1096 | } else { |
| ... | @@ -1098,13 +1098,19 @@ pub const DeclGen = struct { | ... | @@ -1098,13 +1098,19 @@ pub const DeclGen = struct { |
| 1098 | } | 1098 | } |
| 1099 | try writer.writeByte('}'); | 1099 | try writer.writeByte('}'); |
| 1100 | }, | 1100 | }, |
| 1101 | .bytes => { | 1101 | .bytes, .str_lit => |t| { |
| 1102 | try writer.print("{s}", .{fmtStringLiteral(val.castTag(.bytes).?.data)}); | 1102 | const bytes = switch (t) { |
| 1103 | }, | 1103 | .bytes => val.castTag(.bytes).?.data, |
| 1104 | .str_lit => { | 1104 | .str_lit => bytes: { |
| 1105 | const str_lit = val.castTag(.str_lit).?.data; | 1105 | const str_lit = val.castTag(.str_lit).?.data; |
| 1106 | const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; | 1106 | break :bytes dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; |
| 1107 | try writer.print("{s}", .{fmtStringLiteral(bytes)}); | 1107 | }, |
| | 1108 | else => unreachable, |
| | 1109 | }; |
| | 1110 | const sentinel = if (ty.sentinel()) |sentinel| @intCast(u8, sentinel.toUnsignedInt(target)) else null; |
| | 1111 | try writer.print("{s}", .{ |
| | 1112 | fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel), |
| | 1113 | }); |
| 1108 | }, | 1114 | }, |
| 1109 | else => { | 1115 | else => { |
| 1110 | // Fall back to generic implementation. | 1116 | // Fall back to generic implementation. |
| ... | @@ -1128,7 +1134,7 @@ pub const DeclGen = struct { | ... | @@ -1128,7 +1134,7 @@ pub const DeclGen = struct { |
| 1128 | } | 1134 | } |
| 1129 | if (ai.sentinel) |s| { | 1135 | if (ai.sentinel) |s| { |
| 1130 | const s_u8 = @intCast(u8, s.toUnsignedInt(target)); | 1136 | const s_u8 = @intCast(u8, s.toUnsignedInt(target)); |
| 1131 | try literal.writeChar(s_u8); | 1137 | if (s_u8 != 0) try literal.writeChar(s_u8); |
| 1132 | } | 1138 | } |
| 1133 | try literal.end(); | 1139 | try literal.end(); |
| 1134 | } else { | 1140 | } else { |
| ... | @@ -1638,6 +1644,11 @@ pub const DeclGen = struct { | ... | @@ -1638,6 +1644,11 @@ pub const DeclGen = struct { |
| 1638 | try context.writeValue(dg, w, src_ty, location); | 1644 | try context.writeValue(dg, w, src_ty, location); |
| 1639 | } else if (dest_bits <= 64 and src_bits > 64) { | 1645 | } else if (dest_bits <= 64 and src_bits > 64) { |
| 1640 | assert(!src_is_ptr); | 1646 | assert(!src_is_ptr); |
| | 1647 | if (dest_bits < 64) { |
| | 1648 | try w.writeByte('('); |
| | 1649 | try dg.renderType(w, dest_ty); |
| | 1650 | try w.writeByte(')'); |
| | 1651 | } |
| 1641 | try w.writeAll("zig_lo_"); | 1652 | try w.writeAll("zig_lo_"); |
| 1642 | try dg.renderTypeForBuiltinFnName(w, src_eff_ty); | 1653 | try dg.renderTypeForBuiltinFnName(w, src_eff_ty); |
| 1643 | try w.writeByte('('); | 1654 | try w.writeByte('('); |
| ... | @@ -2380,9 +2391,7 @@ pub fn genTypeDecl( | ... | @@ -2380,9 +2391,7 @@ pub fn genTypeDecl( |
| 2380 | | 2391 | |
| 2381 | pub fn genGlobalAsm(mod: *Module, writer: anytype) !void { | 2392 | pub fn genGlobalAsm(mod: *Module, writer: anytype) !void { |
| 2382 | var it = mod.global_assembly.valueIterator(); | 2393 | var it = mod.global_assembly.valueIterator(); |
| 2383 | while (it.next()) |asm_source| { | 2394 | while (it.next()) |asm_source| try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source.*, null)}); |
| 2384 | try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source.*)}); | | |
| 2385 | } | | |
| 2386 | } | 2395 | } |
| 2387 | | 2396 | |
| 2388 | pub fn genErrDecls(o: *Object) !void { | 2397 | pub fn genErrDecls(o: *Object) !void { |
| ... | @@ -2400,22 +2409,20 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2400,22 +2409,20 @@ pub fn genErrDecls(o: *Object) !void { |
| 2400 | o.indent_writer.popIndent(); | 2409 | o.indent_writer.popIndent(); |
| 2401 | try writer.writeAll("};\n"); | 2410 | try writer.writeAll("};\n"); |
| 2402 | | 2411 | |
| 2403 | const name_prefix = "zig_errorName"; | 2412 | const array_identifier = "zig_errorName"; |
| 2404 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1); | 2413 | const name_prefix = array_identifier ++ "_"; |
| | 2414 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len); |
| 2405 | defer o.dg.gpa.free(name_buf); | 2415 | defer o.dg.gpa.free(name_buf); |
| 2406 | | 2416 | |
| 2407 | std.mem.copy(u8, name_buf, name_prefix ++ "_"); | 2417 | std.mem.copy(u8, name_buf, name_prefix); |
| 2408 | for (o.dg.module.error_name_list.items) |name| { | 2418 | for (o.dg.module.error_name_list.items) |name| { |
| 2409 | std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name); | 2419 | std.mem.copy(u8, name_buf[name_prefix.len..], name); |
| 2410 | name_buf[name_prefix.len + "_".len + name.len] = 0; | 2420 | const identifier = name_buf[0 .. name_prefix.len + name.len]; |
| 2411 | | | |
| 2412 | const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0]; | | |
| 2413 | const name_z = identifier[name_prefix.len + "_".len ..]; | | |
| 2414 | | 2421 | |
| 2415 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; | 2422 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| 2416 | const name_ty = Type.initPayload(&name_ty_pl.base); | 2423 | const name_ty = Type.initPayload(&name_ty_pl.base); |
| 2417 | | 2424 | |
| 2418 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z }; | 2425 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name }; |
| 2419 | const name_val = Value.initPayload(&name_pl.base); | 2426 | const name_val = Value.initPayload(&name_pl.base); |
| 2420 | | 2427 | |
| 2421 | try writer.writeAll("static "); | 2428 | try writer.writeAll("static "); |
| ... | @@ -2432,7 +2439,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2432,7 +2439,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2432 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); | 2439 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); |
| 2433 | | 2440 | |
| 2434 | try writer.writeAll("static "); | 2441 | try writer.writeAll("static "); |
| 2435 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, Const, 0, .complete); | 2442 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete); |
| 2436 | try writer.writeAll(" = {"); | 2443 | try writer.writeAll(" = {"); |
| 2437 | for (o.dg.module.error_name_list.items, 0..) |name, value| { | 2444 | for (o.dg.module.error_name_list.items, 0..) |name, value| { |
| 2438 | if (value != 0) try writer.writeByte(','); | 2445 | if (value != 0) try writer.writeByte(','); |
| ... | @@ -2440,7 +2447,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2440,7 +2447,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2440 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; | 2447 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| 2441 | const len_val = Value.initPayload(&len_pl.base); | 2448 | const len_val = Value.initPayload(&len_pl.base); |
| 2442 | | 2449 | |
| 2443 | try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{ | 2450 | try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ |
| 2444 | fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val), | 2451 | fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val), |
| 2445 | }); | 2452 | }); |
| 2446 | } | 2453 | } |
| ... | @@ -2457,8 +2464,8 @@ fn genExports(o: *Object) !void { | ... | @@ -2457,8 +2464,8 @@ fn genExports(o: *Object) !void { |
| 2457 | try fwd_decl_writer.writeAll("zig_export("); | 2464 | try fwd_decl_writer.writeAll("zig_export("); |
| 2458 | try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) }); | 2465 | try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) }); |
| 2459 | try fwd_decl_writer.print(", {s}, {s});\n", .{ | 2466 | try fwd_decl_writer.print(", {s}, {s});\n", .{ |
| 2460 | fmtStringLiteral(exports.items[0].options.name), | 2467 | fmtStringLiteral(exports.items[0].options.name, null), |
| 2461 | fmtStringLiteral(@"export".options.name), | 2468 | fmtStringLiteral(@"export".options.name, null), |
| 2462 | }); | 2469 | }); |
| 2463 | } | 2470 | } |
| 2464 | } | 2471 | } |
| ... | @@ -2483,10 +2490,6 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { | ... | @@ -2483,10 +2490,6 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2483 | try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete); | 2490 | try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete); |
| 2484 | try w.writeAll(") {\n switch (tag) {\n"); | 2491 | try w.writeAll(") {\n switch (tag) {\n"); |
| 2485 | for (enum_ty.enumFields().keys(), 0..) |name, index| { | 2492 | for (enum_ty.enumFields().keys(), 0..) |name, index| { |
| 2486 | const name_z = try o.dg.gpa.dupeZ(u8, name); | | |
| 2487 | defer o.dg.gpa.free(name_z); | | |
| 2488 | const name_bytes = name_z[0 .. name_z.len + 1]; | | |
| 2489 | | | |
| 2490 | var tag_pl: Value.Payload.U32 = .{ | 2493 | var tag_pl: Value.Payload.U32 = .{ |
| 2491 | .base = .{ .tag = .enum_field_index }, | 2494 | .base = .{ .tag = .enum_field_index }, |
| 2492 | .data = @intCast(u32, index), | 2495 | .data = @intCast(u32, index), |
| ... | @@ -2499,7 +2502,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { | ... | @@ -2499,7 +2502,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2499 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; | 2502 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| 2500 | const name_ty = Type.initPayload(&name_ty_pl.base); | 2503 | const name_ty = Type.initPayload(&name_ty_pl.base); |
| 2501 | | 2504 | |
| 2502 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes }; | 2505 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name }; |
| 2503 | const name_val = Value.initPayload(&name_pl.base); | 2506 | const name_val = Value.initPayload(&name_pl.base); |
| 2504 | | 2507 | |
| 2505 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; | 2508 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| ... | @@ -3459,15 +3462,17 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3459,15 +3462,17 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3459 | try f.writeCValue(writer, local, .Other); | 3462 | try f.writeCValue(writer, local, .Other); |
| 3460 | try writer.writeAll(" = "); | 3463 | try writer.writeAll(" = "); |
| 3461 | | 3464 | |
| | 3465 | if (dest_c_bits < 64) { |
| | 3466 | try writer.writeByte('('); |
| | 3467 | try f.renderType(writer, inst_ty); |
| | 3468 | try writer.writeByte(')'); |
| | 3469 | } |
| | 3470 | |
| 3462 | const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64; | 3471 | const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64; |
| 3463 | if (needs_lo) { | 3472 | if (needs_lo) { |
| 3464 | try writer.writeAll("zig_lo_"); | 3473 | try writer.writeAll("zig_lo_"); |
| 3465 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | 3474 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); |
| 3466 | try writer.writeByte('('); | 3475 | try writer.writeByte('('); |
| 3467 | } else if (dest_c_bits <= 64) { | | |
| 3468 | try writer.writeByte('('); | | |
| 3469 | try f.renderType(writer, inst_ty); | | |
| 3470 | try writer.writeByte(')'); | | |
| 3471 | } | 3476 | } |
| 3472 | | 3477 | |
| 3473 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { | 3478 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { |
| ... | @@ -4228,8 +4233,9 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4228,8 +4233,9 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4228 | | 4233 | |
| 4229 | try genBodyInner(f, body); | 4234 | try genBodyInner(f, body); |
| 4230 | try f.object.indent_writer.insertNewline(); | 4235 | try f.object.indent_writer.insertNewline(); |
| | 4236 | // label might be unused, add a dummy goto |
| 4231 | // label must be followed by an expression, add an empty one. | 4237 | // label must be followed by an expression, add an empty one. |
| 4232 | try writer.print("zig_block_{d}:;\n", .{block_id}); | 4238 | try writer.print("goto zig_block_{d};\nzig_block_{d}: (void)0;\n", .{ block_id, block_id }); |
| 4233 | return result; | 4239 | return result; |
| 4234 | } | 4240 | } |
| 4235 | | 4241 | |
| ... | @@ -4608,8 +4614,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4608,8 +4614,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4608 | const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0); | 4614 | const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0); |
| 4609 | | 4615 | |
| 4610 | var extra_index: usize = switch_br.end; | 4616 | var extra_index: usize = switch_br.end; |
| 4611 | var case_i: u32 = 0; | 4617 | for (0..switch_br.data.cases_len) |case_i| { |
| 4612 | while (case_i < switch_br.data.cases_len) : (case_i += 1) { | | |
| 4613 | const case = f.air.extraData(Air.SwitchBr.Case, extra_index); | 4618 | const case = f.air.extraData(Air.SwitchBr.Case, extra_index); |
| 4614 | const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]); | 4619 | const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]); |
| 4615 | const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len]; | 4620 | const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len]; |
| ... | @@ -4789,14 +4794,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4789,14 +4794,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4789 | try writer.writeAll(";\n"); | 4794 | try writer.writeAll(";\n"); |
| 4790 | } | 4795 | } |
| 4791 | } | 4796 | } |
| 4792 | { | 4797 | for (0..clobbers_len) |_| { |
| 4793 | var clobber_i: u32 = 0; | 4798 | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4794 | while (clobber_i < clobbers_len) : (clobber_i += 1) { | 4799 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4795 | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | 4800 | // for the string, we still use the next u32 for the null terminator. |
| 4796 | // This equation accounts for the fact that even if we have exactly 4 bytes | 4801 | extra_i += clobber.len / 4 + 1; |
| 4797 | // for the string, we still use the next u32 for the null terminator. | | |
| 4798 | extra_i += clobber.len / 4 + 1; | | |
| 4799 | } | | |
| 4800 | } | 4802 | } |
| 4801 | | 4803 | |
| 4802 | { | 4804 | { |
| ... | @@ -4851,7 +4853,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4851,7 +4853,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4851 | | 4853 | |
| 4852 | try writer.writeAll("__asm"); | 4854 | try writer.writeAll("__asm"); |
| 4853 | if (is_volatile) try writer.writeAll(" volatile"); | 4855 | if (is_volatile) try writer.writeAll(" volatile"); |
| 4854 | try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i])}); | 4856 | try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)}); |
| 4855 | } | 4857 | } |
| 4856 | | 4858 | |
| 4857 | extra_i = constraints_extra_begin; | 4859 | extra_i = constraints_extra_begin; |
| ... | @@ -4869,7 +4871,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4869,7 +4871,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4869 | try writer.writeByte(' '); | 4871 | try writer.writeByte(' '); |
| 4870 | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); | 4872 | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); |
| 4871 | const is_reg = constraint[1] == '{'; | 4873 | const is_reg = constraint[1] == '{'; |
| 4872 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint)}); | 4874 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)}); |
| 4873 | if (is_reg) { | 4875 | if (is_reg) { |
| 4874 | try f.writeCValue(writer, .{ .local = locals_index }, .Other); | 4876 | try f.writeCValue(writer, .{ .local = locals_index }, .Other); |
| 4875 | locals_index += 1; | 4877 | locals_index += 1; |
| ... | @@ -4895,7 +4897,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4895,7 +4897,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4895 | | 4897 | |
| 4896 | const is_reg = constraint[0] == '{'; | 4898 | const is_reg = constraint[0] == '{'; |
| 4897 | const input_val = try f.resolveInst(input); | 4899 | const input_val = try f.resolveInst(input); |
| 4898 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint)}); | 4900 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)}); |
| 4899 | try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: { | 4901 | try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: { |
| 4900 | const input_local = CValue{ .local = locals_index }; | 4902 | const input_local = CValue{ .local = locals_index }; |
| 4901 | locals_index += 1; | 4903 | locals_index += 1; |
| ... | @@ -4904,19 +4906,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4904,19 +4906,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4904 | try writer.writeByte(')'); | 4906 | try writer.writeByte(')'); |
| 4905 | } | 4907 | } |
| 4906 | try writer.writeByte(':'); | 4908 | try writer.writeByte(':'); |
| 4907 | { | 4909 | for (0..clobbers_len) |clobber_i| { |
| 4908 | var clobber_i: u32 = 0; | 4910 | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4909 | while (clobber_i < clobbers_len) : (clobber_i += 1) { | 4911 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4910 | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | 4912 | // for the string, we still use the next u32 for the null terminator. |
| 4911 | // This equation accounts for the fact that even if we have exactly 4 bytes | 4913 | extra_i += clobber.len / 4 + 1; |
| 4912 | // for the string, we still use the next u32 for the null terminator. | | |
| 4913 | extra_i += clobber.len / 4 + 1; | | |
| 4914 | | 4914 | |
| 4915 | if (clobber.len == 0) continue; | 4915 | if (clobber.len == 0) continue; |
| 4916 | | 4916 | |
| 4917 | if (clobber_i > 0) try writer.writeByte(','); | 4917 | if (clobber_i > 0) try writer.writeByte(','); |
| 4918 | try writer.print(" {s}", .{fmtStringLiteral(clobber)}); | 4918 | try writer.print(" {s}", .{fmtStringLiteral(clobber, null)}); |
| 4919 | } | | |
| 4920 | } | 4919 | } |
| 4921 | try writer.writeAll(");\n"); | 4920 | try writer.writeAll(");\n"); |
| 4922 | | 4921 | |
| ... | @@ -5340,8 +5339,9 @@ fn fieldPtr( | ... | @@ -5340,8 +5339,9 @@ fn fieldPtr( |
| 5340 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); | 5339 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| 5341 | }, | 5340 | }, |
| 5342 | .end => { | 5341 | .end => { |
| | 5342 | try writer.writeByte('('); |
| 5343 | try f.writeCValue(writer, container_ptr_val, .Other); | 5343 | try f.writeCValue(writer, container_ptr_val, .Other); |
| 5344 | try writer.print(" + {}", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | 5344 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, Value.one)}); |
| 5345 | }, | 5345 | }, |
| 5346 | } | 5346 | } |
| 5347 | | 5347 | |
| ... | @@ -6448,10 +6448,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6448,10 +6448,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6448 | // | 6448 | // |
| 6449 | // Equivalent to: | 6449 | // Equivalent to: |
| 6450 | // reduce: { | 6450 | // reduce: { |
| 6451 | // var i: usize = 0; | | |
| 6452 | // var accum: T = init; | 6451 | // var accum: T = init; |
| 6453 | // while (i < vec.len) : (i += 1) { | 6452 | // for (vec) : (elem) { |
| 6454 | // accum = func(accum, vec[i]); | 6453 | // accum = func(accum, elem); |
| 6455 | // } | 6454 | // } |
| 6456 | // break :reduce accum; | 6455 | // break :reduce accum; |
| 6457 | // } | 6456 | // } |
| ... | @@ -7162,8 +7161,9 @@ fn stringLiteral(child_stream: anytype) StringLiteral(@TypeOf(child_stream)) { | ... | @@ -7162,8 +7161,9 @@ fn stringLiteral(child_stream: anytype) StringLiteral(@TypeOf(child_stream)) { |
| 7162 | return .{ .counting_writer = std.io.countingWriter(child_stream) }; | 7161 | return .{ .counting_writer = std.io.countingWriter(child_stream) }; |
| 7163 | } | 7162 | } |
| 7164 | | 7163 | |
| | 7164 | const FormatStringContext = struct { str: []const u8, sentinel: ?u8 }; |
| 7165 | fn formatStringLiteral( | 7165 | fn formatStringLiteral( |
| 7166 | str: []const u8, | 7166 | data: FormatStringContext, |
| 7167 | comptime fmt: []const u8, | 7167 | comptime fmt: []const u8, |
| 7168 | _: std.fmt.FormatOptions, | 7168 | _: std.fmt.FormatOptions, |
| 7169 | writer: anytype, | 7169 | writer: anytype, |
| ... | @@ -7172,13 +7172,13 @@ fn formatStringLiteral( | ... | @@ -7172,13 +7172,13 @@ fn formatStringLiteral( |
| 7172 | | 7172 | |
| 7173 | var literal = stringLiteral(writer); | 7173 | var literal = stringLiteral(writer); |
| 7174 | try literal.start(); | 7174 | try literal.start(); |
| 7175 | for (str) |c| | 7175 | for (data.str) |c| try literal.writeChar(c); |
| 7176 | try literal.writeChar(c); | 7176 | if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel); |
| 7177 | try literal.end(); | 7177 | try literal.end(); |
| 7178 | } | 7178 | } |
| 7179 | | 7179 | |
| 7180 | fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) { | 7180 | fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Formatter(formatStringLiteral) { |
| 7181 | return .{ .data = str }; | 7181 | return .{ .data = .{ .str = str, .sentinel = sentinel } }; |
| 7182 | } | 7182 | } |
| 7183 | | 7183 | |
| 7184 | fn undefPattern(comptime IntType: type) IntType { | 7184 | fn undefPattern(comptime IntType: type) IntType { |