authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-18 22:04:34+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-18 22:04:34+02:00
log806624169a70301f37b6fe4dbdc5b6827cfd1ab1
tree2d2b700a60ad21c1a3ea5650c80ac5d122745675
parent3f9fe9e28f83119f8ecf2fdafcd12967417634e9
parentcc9447c103a540ae21582385ef33581c9719324e

Merge pull request 'x86_64: fixes' (#36860) from jacobly/x86_64-opv-arg into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36860 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

7 files changed, 168 insertions(+), 110 deletions(-)

src/codegen/x86_64/CodeGen.zig+86-89
...@@ -1224,9 +1224,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {...@@ -1224,9 +1224,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {
1224 .pseudo_dbg_enter_block_none,1224 .pseudo_dbg_enter_block_none,
1225 .pseudo_dbg_leave_block_none,1225 .pseudo_dbg_leave_block_none,
1226 .pseudo_dbg_end_none,1226 .pseudo_dbg_end_none,
1227 .pseudo_dbg_arg_none,
1228 .pseudo_dbg_var_args_none,1227 .pseudo_dbg_var_args_none,
1229 .pseudo_dbg_var_none,
1230 .pseudo_dead_none,1228 .pseudo_dead_none,
1231 => {},1229 => {},
1232 .pseudo_dbg_line_stmt_line_column,1230 .pseudo_dbg_line_stmt_line_column,
...@@ -2318,39 +2316,32 @@ fn genMainBody(...@@ -2318,39 +2316,32 @@ fn genMainBody(
2318 };2316 };
2319 defer zir_param_index += 1;2317 defer zir_param_index += 1;
23202318
2321 if (comptime_args.len > 0) switch (comptime_args.get(ip)[zir_param_index]) {2319 const arg_ty: Type, const arg_val: ?Value = arg: switch (if (comptime_args.len > 0)
2322 .none => {},2320 comptime_args.get(ip)[zir_param_index]
2323 else => |comptime_arg| {2321 else
2324 try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = ip.typeOf(comptime_arg) });2322 .none) {
2325 _ = try cg.addInst(.{2323 else => |arg_val| .{ .fromInterned(ip.typeOf(arg_val)), .fromInterned(arg_val) },
2326 .tag = .pseudo,2324 .none => {
2327 .ops = .pseudo_dbg_arg_val,2325 const arg_ty: Type = .fromInterned(fn_info.param_types.get(ip)[fn_param_index]);
2328 .data = .{ .ip_index = comptime_arg },2326 fn_param_index += 1;
2329 });2327 break :arg .{ arg_ty, try arg_ty.onePossibleValue(pt) };
2330 continue;
2331 },2328 },
2332 };2329 };
23332330 try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = arg_ty.toIntern() });
2334 const arg_ty = fn_info.param_types.get(ip)[fn_param_index];2331 if (arg_val) |val| {
2335 try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = arg_ty });2332 _ = try cg.addInst(.{
2336 fn_param_index += 1;2333 .tag = .pseudo,
23372334 .ops = .pseudo_dbg_arg_val,
2338 if (air_arg_index == air_args_body.len) {2335 .data = .{ .ip_index = val.toIntern() },
2339 try cg.asmPseudo(.pseudo_dbg_arg_none);2336 });
2340 continue;2337 continue;
2341 }2338 }
2339
2342 const air_arg_inst = air_args_body[air_arg_index];2340 const air_arg_inst = air_args_body[air_arg_index];
2343 const air_arg_data = cg.air.instructions.items(.data)[air_arg_index].arg;2341 const air_arg_data = cg.air.instructions.items(.data)[air_arg_index].arg;
2344 if (air_arg_data.zir_param_index != zir_param_index) {
2345 try cg.asmPseudo(.pseudo_dbg_arg_none);
2346 continue;
2347 }
2348 air_arg_index += 1;2342 air_arg_index += 1;
2349 try cg.genLocalDebugInfo(2343 assert(air_arg_data.zir_param_index == zir_param_index);
2350 .arg,2344 try cg.genLocalDebugInfo(.arg, arg_ty, cg.getResolvedInstValue(air_arg_inst).short);
2351 .fromInterned(arg_ty),
2352 cg.getResolvedInstValue(air_arg_inst).short,
2353 );
2354 }2345 }
2355 if (fn_info.is_var_args) try cg.asmPseudo(.pseudo_dbg_var_args_none);2346 if (fn_info.is_var_args) try cg.asmPseudo(.pseudo_dbg_var_args_none);
2356 }2347 }
...@@ -180623,6 +180614,7 @@ fn airAtomicStore(self: *CodeGen, inst: Air.Inst.Index, order: std.lang.AtomicOr...@@ -180623,6 +180614,7 @@ fn airAtomicStore(self: *CodeGen, inst: Air.Inst.Index, order: std.lang.AtomicOr
180623fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {180614fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
180624 const pt = self.pt;180615 const pt = self.pt;
180625 const zcu = pt.zcu;180616 const zcu = pt.zcu;
180617 const ip = &zcu.intern_pool;
180626 const bin_op = self.air.instructions.items(.data)[@backingInt(inst)].bin_op;180618 const bin_op = self.air.instructions.items(.data)[@backingInt(inst)].bin_op;
180627180619
180628 result: {180620 result: {
...@@ -180654,29 +180646,32 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -180654,29 +180646,32 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
180654180646
180655 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu));180647 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu));
180656180648
180657 if (elem_abi_size == 1) {180649 const dst_ptr: MCValue, const len: MCValue = switch (dst_ty.ptrSize(zcu)) {
180658 const dst_ptr: MCValue = switch (dst_ty.ptrSize(zcu)) {180650 .slice => switch (dst) {
180659 .slice => switch (dst) {180651 else => .{ dst, dst.address().offset(8).deref() },
180660 .register_pair => |dst_regs| .{ .register = dst_regs[0] },180652 .register_pair => |dst_regs| .{
180661 else => dst,180653 .{ .register = dst_regs[0] },
180654 .{ .register = dst_regs[1] },
180662 },180655 },
180663 .one => dst,180656 .load_uav => |uav| switch (ip.indexToKey(uav.val)) {
180664 .c, .many => unreachable,180657 else => unreachable,
180665 };180658 .undef => .{ .undef, .undef },
180666 const len: MCValue = switch (dst_ty.ptrSize(zcu)) {180659 .slice => |slice| .{
180667 .slice => switch (dst) {180660 try self.lowerValue(.fromInterned(slice.ptr)),
180668 .register_pair => |dst_regs| .{ .register = dst_regs[1] },180661 try self.lowerValue(.fromInterned(slice.len)),
180669 else => dst.address().offset(8).deref(),180662 },
180670 },180663 },
180671 .one => .{ .immediate = dst_ty.childType(zcu).arrayLen(zcu) },180664 },
180672 .c, .many => unreachable,180665 .one => .{ dst, .{ .immediate = dst_ty.childType(zcu).arrayLen(zcu) } },
180673 };180666 .c, .many => unreachable,
180674 const len_lock: ?RegisterLock = switch (len) {180667 };
180675 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),180668 const len_lock: ?RegisterLock = switch (len) {
180676 else => null,180669 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
180677 };180670 else => null,
180678 defer if (len_lock) |lock| self.register_manager.unlockReg(lock);180671 };
180672 defer if (len_lock) |lock| self.register_manager.unlockReg(lock);
180679180673
180674 if (elem_abi_size == 1) {
180680 try self.genInlineMemset(dst_ptr, src_val, len, .{ .safety = safety });180675 try self.genInlineMemset(dst_ptr, src_val, len, .{ .safety = safety });
180681 break :result;180676 break :result;
180682 }180677 }
...@@ -180684,26 +180679,18 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -180684,26 +180679,18 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
180684 // Store the first element, and then rely on memcpy copying forwards.180679 // Store the first element, and then rely on memcpy copying forwards.
180685 // Length zero requires a runtime check - so we handle arrays specially180680 // Length zero requires a runtime check - so we handle arrays specially
180686 // here to elide it.180681 // here to elide it.
180687 switch (dst_ty.ptrSize(zcu)) {180682 switch (len) {
180688 .slice => {180683 else => {
180689 const slice_ptr_ty = dst_ty.slicePtrFieldType(zcu);180684 const slice_ptr_ty = dst_ty.slicePtrFieldType(zcu);
180690180685
180691 const dst_ptr: MCValue = switch (dst) {
180692 .register_pair => |dst_regs| .{ .register = dst_regs[0] },
180693 else => dst,
180694 };
180695 const len: MCValue = switch (dst) {
180696 .register_pair => |dst_regs| .{ .register = dst_regs[1] },
180697 else => dst.address().offset(8).deref(),
180698 };
180699
180700 // Used to store the number of elements for comparison.180686 // Used to store the number of elements for comparison.
180701 // After comparison, updated to store number of bytes needed to copy.180687 // After comparison, updated to store number of bytes needed to copy.
180702 const len_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);180688 const len_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
180703 const len_mcv: MCValue = .{ .register = len_reg };180689 const len_mcv: MCValue = .{ .register = len_reg };
180704 const len_lock = self.register_manager.lockRegAssumeUnused(len_reg);180690 const len_reg_lock = self.register_manager.lockRegAssumeUnused(len_reg);
180705 defer self.register_manager.unlockReg(len_lock);180691 defer self.register_manager.unlockReg(len_reg_lock);
180706180692
180693 try self.spillEflagsIfOccupied();
180707 try self.genSetReg(len_reg, .usize, len, .{});180694 try self.genSetReg(len_reg, .usize, len, .{});
180708 try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg);180695 try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg);
180709180696
...@@ -180733,12 +180720,10 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -180733,12 +180720,10 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
180733180720
180734 self.performReloc(skip_reloc);180721 self.performReloc(skip_reloc);
180735 },180722 },
180736 .one => {180723 .immediate => |len_imm| {
180737 const elem_ptr_ty = try pt.singleMutPtrType(elem_ty);180724 const elem_ptr_ty = try pt.singleMutPtrType(elem_ty);
180738180725
180739 const len = dst_ty.childType(zcu).arrayLen(zcu);180726 assert(len_imm != 0); // prevented by Sema
180740
180741 assert(len != 0); // prevented by Sema
180742 try self.store(elem_ptr_ty, dst, src_val, .{ .safety = safety });180727 try self.store(elem_ptr_ty, dst, src_val, .{ .safety = safety });
180743180728
180744 const second_elem_ptr_reg =180729 const second_elem_ptr_reg =
...@@ -180753,10 +180738,9 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -180753,10 +180738,9 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
180753 .off = elem_abi_size,180738 .off = elem_abi_size,
180754 } }, .{});180739 } }, .{});
180755180740
180756 const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) };180741 const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len_imm - 1) };
180757 try self.genInlineMemcpy(second_elem_ptr_mcv, dst, bytes_to_copy, .{ .no_alias = false });180742 try self.genInlineMemcpy(second_elem_ptr_mcv, dst, bytes_to_copy, .{ .no_alias = false });
180758 },180743 },
180759 .c, .many => unreachable,
180760 }180744 }
180761 }180745 }
180762 return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none });180746 return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -182779,17 +182763,27 @@ const Temp = struct {...@@ -182779,17 +182763,27 @@ const Temp = struct {
182779 assert(limb_index == 0);182763 assert(limb_index == 0);
182780 new_temp_index.tracking(cg).* = .init(.{ .lea_nav = nav });182764 new_temp_index.tracking(cg).* = .init(.{ .lea_nav = nav });
182781 },182765 },
182782 .load_uav => |uav| {182766 .load_uav => |uav| switch (cg.pt.zcu.intern_pool.indexToKey(uav.val)) {
182783 const new_reg =182767 else => {
182784 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);182768 const new_reg = try cg.register_manager.allocReg(
182785 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });182769 new_temp_index.toIndex(),
182786 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{182770 abi.RegisterClass.gp,
182787 .base = .{ .uav = uav },182771 );
182788 .mod = .{ .rm = .{182772 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182789 .size = .qword,182773 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182790 .disp = @as(u31, limb_index) * 8,182774 .base = .{ .uav = uav },
182791 } },182775 .mod = .{ .rm = .{
182792 });182776 .size = .qword,
182777 .disp = @as(u31, limb_index) * 8,
182778 } },
182779 });
182780 },
182781 .slice => |slice| new_temp_index.tracking(cg).* =
182782 .init(try cg.lowerValue(.fromInterned(switch (limb_index) {
182783 else => unreachable,
182784 0 => slice.ptr,
182785 1 => slice.len,
182786 }))),
182793 },182787 },
182794 .lea_uav => |uav| {182788 .lea_uav => |uav| {
182795 assert(limb_index == 0);182789 assert(limb_index == 0);
...@@ -182878,15 +182872,11 @@ const Temp = struct {...@@ -182878,15 +182872,11 @@ const Temp = struct {
182878 fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) InnerError!void {182872 fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) InnerError!void {
182879 switch (temp.unwrap(cg)) {182873 switch (temp.unwrap(cg)) {
182880 .ref => {},182874 .ref => {},
182881 .temp => |temp_index| {182875 .temp => |temp_index| inplace: {
182882 const temp_tracking = temp_index.tracking(cg);182876 const temp_tracking = temp_index.tracking(cg);
182883 switch (temp_tracking.short) {182877 switch (temp_tracking.short) {
182884 else => {},182878 else => break :inplace,
182885 .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => {182879 .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => assert(limb_index == 0),
182886 assert(limb_index == 0);
182887 cg.temp_type[@backingInt(temp_index)] = limb_ty;
182888 return;
182889 },
182890 .register_pair => |regs| {182880 .register_pair => |regs| {
182891 switch (temp_tracking.long) {182881 switch (temp_tracking.long) {
182892 .none, .reserved_frame => {},182882 .none, .reserved_frame => {},
...@@ -182896,8 +182886,6 @@ const Temp = struct {...@@ -182896,8 +182886,6 @@ const Temp = struct {
182896 for (regs, 0..) |reg, reg_index| if (reg_index != limb_index)182886 for (regs, 0..) |reg, reg_index| if (reg_index != limb_index)
182897 cg.register_manager.freeReg(reg);182887 cg.register_manager.freeReg(reg);
182898 temp_tracking.* = .init(.{ .register = regs[limb_index] });182888 temp_tracking.* = .init(.{ .register = regs[limb_index] });
182899 cg.temp_type[@backingInt(temp_index)] = limb_ty;
182900 return;
182901 },182889 },
182902 .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) {182890 .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) {
182903 assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr));182891 assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr));
...@@ -182905,10 +182893,19 @@ const Temp = struct {...@@ -182905,10 +182893,19 @@ const Temp = struct {
182905 .index = frame_addr.index,182893 .index = frame_addr.index,
182906 .off = frame_addr.off + @as(u31, limb_index) * 8,182894 .off = frame_addr.off + @as(u31, limb_index) * 8,
182907 } });182895 } });
182908 cg.temp_type[@backingInt(temp_index)] = limb_ty;182896 },
182909 return;182897 .load_uav => |uav| switch (cg.pt.zcu.intern_pool.indexToKey(uav.val)) {
182898 else => break :inplace,
182899 .slice => |slice| temp_tracking.* =
182900 .init(try cg.lowerValue(.fromInterned(switch (limb_index) {
182901 else => unreachable,
182902 0 => slice.ptr,
182903 1 => slice.len,
182904 }))),
182910 },182905 },
182911 }182906 }
182907 cg.temp_type[@backingInt(temp_index)] = limb_ty;
182908 return;
182912 },182909 },
182913 .err_ret_trace => unreachable,182910 .err_ret_trace => unreachable,
182914 }182911 }
src/codegen/x86_64/Emit.zig-7
...@@ -536,14 +536,12 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -536,14 +536,12 @@ pub fn emitMir(emit: *Emit) Error!void {
536 .column = emit.prev_di_loc.column,536 .column = emit.prev_di_loc.column,
537 .end = true,537 .end = true,
538 }),538 }),
539 .pseudo_dbg_arg_none,
540 .pseudo_dbg_arg_i_s,539 .pseudo_dbg_arg_i_s,
541 .pseudo_dbg_arg_i_u,540 .pseudo_dbg_arg_i_u,
542 .pseudo_dbg_arg_i_64,541 .pseudo_dbg_arg_i_64,
543 .pseudo_dbg_arg_ro,542 .pseudo_dbg_arg_ro,
544 .pseudo_dbg_arg_fa,543 .pseudo_dbg_arg_fa,
545 .pseudo_dbg_arg_m,544 .pseudo_dbg_arg_m,
546 .pseudo_dbg_var_none,
547 .pseudo_dbg_var_i_s,545 .pseudo_dbg_var_i_s,
548 .pseudo_dbg_var_i_u,546 .pseudo_dbg_var_i_u,
549 .pseudo_dbg_var_i_64,547 .pseudo_dbg_var_i_64,
...@@ -560,7 +558,6 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -560,7 +558,6 @@ pub fn emitMir(emit: *Emit) Error!void {
560 var loc_buf: [2]DwarfLoc = undefined;558 var loc_buf: [2]DwarfLoc = undefined;
561 const loc: DwarfLoc = loc: switch (mir_inst.ops) {559 const loc: DwarfLoc = loc: switch (mir_inst.ops) {
562 else => unreachable,560 else => unreachable,
563 .pseudo_dbg_arg_none, .pseudo_dbg_var_none => .empty,
564 .pseudo_dbg_arg_i_s,561 .pseudo_dbg_arg_i_s,
565 .pseudo_dbg_arg_i_u,562 .pseudo_dbg_arg_i_u,
566 .pseudo_dbg_var_i_s,563 .pseudo_dbg_var_i_s,
...@@ -632,23 +629,19 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -632,23 +629,19 @@ pub fn emitMir(emit: *Emit) Error!void {
632 try dwarf.genLocalVarDebugInfo(629 try dwarf.genLocalVarDebugInfo(
633 switch (mir_inst.ops) {630 switch (mir_inst.ops) {
634 else => unreachable,631 else => unreachable,
635 .pseudo_dbg_arg_none,
636 .pseudo_dbg_arg_i_s,632 .pseudo_dbg_arg_i_s,
637 .pseudo_dbg_arg_i_u,633 .pseudo_dbg_arg_i_u,
638 .pseudo_dbg_arg_i_64,634 .pseudo_dbg_arg_i_64,
639 .pseudo_dbg_arg_ro,635 .pseudo_dbg_arg_ro,
640 .pseudo_dbg_arg_fa,636 .pseudo_dbg_arg_fa,
641 .pseudo_dbg_arg_m,637 .pseudo_dbg_arg_m,
642 .pseudo_dbg_arg_val,
643 => .arg,638 => .arg,
644 .pseudo_dbg_var_none,
645 .pseudo_dbg_var_i_s,639 .pseudo_dbg_var_i_s,
646 .pseudo_dbg_var_i_u,640 .pseudo_dbg_var_i_u,
647 .pseudo_dbg_var_i_64,641 .pseudo_dbg_var_i_64,
648 .pseudo_dbg_var_ro,642 .pseudo_dbg_var_ro,
649 .pseudo_dbg_var_fa,643 .pseudo_dbg_var_fa,
650 .pseudo_dbg_var_m,644 .pseudo_dbg_var_m,
651 .pseudo_dbg_var_val,
652 => .local_var,645 => .local_var,
653 },646 },
654 local.name.toSlice(&emit.lower.mir),647 local.name.toSlice(&emit.lower.mir),
src/codegen/x86_64/Lower.zig-2
...@@ -320,7 +320,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -320,7 +320,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
320 .pseudo_dbg_enter_inline_func,320 .pseudo_dbg_enter_inline_func,
321 .pseudo_dbg_leave_inline_func,321 .pseudo_dbg_leave_inline_func,
322 .pseudo_dbg_end_none,322 .pseudo_dbg_end_none,
323 .pseudo_dbg_arg_none,
324 .pseudo_dbg_arg_i_s,323 .pseudo_dbg_arg_i_s,
325 .pseudo_dbg_arg_i_u,324 .pseudo_dbg_arg_i_u,
326 .pseudo_dbg_arg_i_64,325 .pseudo_dbg_arg_i_64,
...@@ -329,7 +328,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -329,7 +328,6 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
329 .pseudo_dbg_arg_m,328 .pseudo_dbg_arg_m,
330 .pseudo_dbg_arg_val,329 .pseudo_dbg_arg_val,
331 .pseudo_dbg_var_args_none,330 .pseudo_dbg_var_args_none,
332 .pseudo_dbg_var_none,
333 .pseudo_dbg_var_i_s,331 .pseudo_dbg_var_i_s,
334 .pseudo_dbg_var_i_u,332 .pseudo_dbg_var_i_u,
335 .pseudo_dbg_var_i_64,333 .pseudo_dbg_var_i_64,
src/codegen/x86_64/Mir.zig-6
...@@ -1547,9 +1547,6 @@ pub const Inst = struct {...@@ -1547,9 +1547,6 @@ pub const Inst = struct {
1547 /// Uses `none` payload.1547 /// Uses `none` payload.
1548 pseudo_dbg_end_none,1548 pseudo_dbg_end_none,
1549 /// Local argument.1549 /// Local argument.
1550 /// Uses `none` payload.
1551 pseudo_dbg_arg_none,
1552 /// Local argument.
1553 /// Uses `i` payload.1550 /// Uses `i` payload.
1554 pseudo_dbg_arg_i_s,1551 pseudo_dbg_arg_i_s,
1555 /// Local argument.1552 /// Local argument.
...@@ -1573,9 +1570,6 @@ pub const Inst = struct {...@@ -1573,9 +1570,6 @@ pub const Inst = struct {
1573 /// Remaining arguments are varargs.1570 /// Remaining arguments are varargs.
1574 pseudo_dbg_var_args_none,1571 pseudo_dbg_var_args_none,
1575 /// Local variable.1572 /// Local variable.
1576 /// Uses `none` payload.
1577 pseudo_dbg_var_none,
1578 /// Local variable.
1579 /// Uses `i` payload.1573 /// Uses `i` payload.
1580 pseudo_dbg_var_i_s,1574 pseudo_dbg_var_i_s,
1581 /// Local variable.1575 /// Local variable.
test/behavior/memcpy.zig+29
...@@ -180,3 +180,32 @@ test "@memcpy no sentinel source into sentinel destination" {...@@ -180,3 +180,32 @@ test "@memcpy no sentinel source into sentinel destination" {
180 S.doTheTest();180 S.doTheTest();
181 comptime S.doTheTest();181 comptime S.doTheTest();
182}182}
183
184test "@memcpy a global array" {
185 const S = struct {
186 var array_u8: [1]u8 = .{1};
187 const slice_u8: []u8 = &array_u8;
188 var array_u32: [1]u32 = .{10};
189 const slice_u32: []u32 = &array_u32;
190 };
191
192 try expect(S.array_u8[0] == 1);
193 @memcpy(&S.array_u8, &[1]u8{2});
194 try expect(S.array_u8[0] == 2);
195 @memcpy(&S.array_u8, &[1]u8{S.array_u8[0] + 1});
196 try expect(S.array_u8[0] == 3);
197 @memcpy(S.slice_u8, &[1]u8{4});
198 try expect(S.array_u8[0] == 4);
199 @memcpy(S.slice_u8, &[1]u8{S.array_u8[0] + 1});
200 try expect(S.array_u8[0] == 5);
201
202 try expect(S.array_u32[0] == 10);
203 @memcpy(&S.array_u32, &[1]u32{20});
204 try expect(S.array_u32[0] == 20);
205 @memcpy(&S.array_u32, &[1]u32{S.array_u32[0] + 10});
206 try expect(S.array_u32[0] == 30);
207 @memcpy(S.slice_u32, &[1]u32{40});
208 try expect(S.array_u32[0] == 40);
209 @memcpy(S.slice_u32, &[1]u32{S.array_u32[0] + 10});
210 try expect(S.array_u32[0] == 50);
211}
test/behavior/memmove.zig+29
...@@ -170,3 +170,32 @@ comptime {...@@ -170,3 +170,32 @@ comptime {
170 s.set("hello");170 s.set("hello");
171 if (!std.mem.eql(u8, s.buffer[0..8], "hehelloo")) @compileError("bad");171 if (!std.mem.eql(u8, s.buffer[0..8], "hehelloo")) @compileError("bad");
172}172}
173
174test "@memmove a global array" {
175 const S = struct {
176 var array_u8: [1]u8 = .{1};
177 const slice_u8: []u8 = &array_u8;
178 var array_u32: [1]u32 = .{10};
179 const slice_u32: []u32 = &array_u32;
180 };
181
182 try expect(S.array_u8[0] == 1);
183 @memmove(&S.array_u8, &[1]u8{2});
184 try expect(S.array_u8[0] == 2);
185 @memmove(&S.array_u8, &[1]u8{S.array_u8[0] + 1});
186 try expect(S.array_u8[0] == 3);
187 @memmove(S.slice_u8, &[1]u8{4});
188 try expect(S.array_u8[0] == 4);
189 @memmove(S.slice_u8, &[1]u8{S.array_u8[0] + 1});
190 try expect(S.array_u8[0] == 5);
191
192 try expect(S.array_u32[0] == 10);
193 @memmove(&S.array_u32, &[1]u32{20});
194 try expect(S.array_u32[0] == 20);
195 @memmove(&S.array_u32, &[1]u32{S.array_u32[0] + 10});
196 try expect(S.array_u32[0] == 30);
197 @memmove(S.slice_u32, &[1]u32{40});
198 try expect(S.array_u32[0] == 40);
199 @memmove(S.slice_u32, &[1]u32{S.array_u32[0] + 10});
200 try expect(S.array_u32[0] == 50);
201}
test/behavior/memset.zig+24-6
...@@ -204,13 +204,31 @@ test "@memset a global array" {...@@ -204,13 +204,31 @@ test "@memset a global array" {
204 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;204 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
205205
206 const S = struct {206 const S = struct {
207 var buf: [1]u32 = .{123};207 var array_u8: [1]u8 = .{1};
208 const slice_u8: []u8 = &array_u8;
209 var array_u32: [1]u32 = .{10};
210 const slice_u32: []u32 = &array_u32;
208 };211 };
209 try expect(S.buf[0] == 123);212
210 @memset(&S.buf, 456);213 try expect(S.array_u8[0] == 1);
211 try expect(S.buf[0] == 456);214 @memset(&S.array_u8, 2);
212 @memset(&S.buf, S.buf[0] + 333);215 try expect(S.array_u8[0] == 2);
213 try expect(S.buf[0] == 789);216 @memset(&S.array_u8, S.array_u8[0] + 1);
217 try expect(S.array_u8[0] == 3);
218 @memset(S.slice_u8, 4);
219 try expect(S.array_u8[0] == 4);
220 @memset(S.slice_u8, S.array_u8[0] + 1);
221 try expect(S.array_u8[0] == 5);
222
223 try expect(S.array_u32[0] == 10);
224 @memset(&S.array_u32, 20);
225 try expect(S.array_u32[0] == 20);
226 @memset(&S.array_u32, S.array_u32[0] + 10);
227 try expect(S.array_u32[0] == 30);
228 @memset(S.slice_u32, 40);
229 try expect(S.array_u32[0] == 40);
230 @memset(S.slice_u32, S.array_u32[0] + 10);
231 try expect(S.array_u32[0] == 50);
214}232}
215233
216test "@memset array of booleans" {234test "@memset array of booleans" {