| ... | ... | @@ -180614,6 +180614,7 @@ fn airAtomicStore(self: *CodeGen, inst: Air.Inst.Index, order: std.lang.AtomicOr |
| 180614 | 180614 | fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180615 | 180615 | const pt = self.pt; |
| 180616 | 180616 | const zcu = pt.zcu; |
| 180617 | const ip = &zcu.intern_pool; |
| 180617 | 180618 | const bin_op = self.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 180618 | 180619 | |
| 180619 | 180620 | result: { |
| ... | ... | @@ -180645,29 +180646,32 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180645 | 180646 | |
| 180646 | 180647 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); |
| 180647 | 180648 | |
| 180648 | | if (elem_abi_size == 1) { |
| 180649 | | const dst_ptr: MCValue = switch (dst_ty.ptrSize(zcu)) { |
| 180650 | | .slice => switch (dst) { |
| 180651 | | .register_pair => |dst_regs| .{ .register = dst_regs[0] }, |
| 180652 | | else => dst, |
| 180649 | const dst_ptr: MCValue, const len: MCValue = switch (dst_ty.ptrSize(zcu)) { |
| 180650 | .slice => switch (dst) { |
| 180651 | else => .{ dst, dst.address().offset(8).deref() }, |
| 180652 | .register_pair => |dst_regs| .{ |
| 180653 | .{ .register = dst_regs[0] }, |
| 180654 | .{ .register = dst_regs[1] }, |
| 180653 | 180655 | }, |
| 180654 | | .one => dst, |
| 180655 | | .c, .many => unreachable, |
| 180656 | | }; |
| 180657 | | const len: MCValue = switch (dst_ty.ptrSize(zcu)) { |
| 180658 | | .slice => switch (dst) { |
| 180659 | | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| 180660 | | else => dst.address().offset(8).deref(), |
| 180656 | .load_uav => |uav| switch (ip.indexToKey(uav.val)) { |
| 180657 | else => unreachable, |
| 180658 | .undef => .{ .undef, .undef }, |
| 180659 | .slice => |slice| .{ |
| 180660 | try self.lowerValue(.fromInterned(slice.ptr)), |
| 180661 | try self.lowerValue(.fromInterned(slice.len)), |
| 180662 | }, |
| 180661 | 180663 | }, |
| 180662 | | .one => .{ .immediate = dst_ty.childType(zcu).arrayLen(zcu) }, |
| 180663 | | .c, .many => unreachable, |
| 180664 | | }; |
| 180665 | | const len_lock: ?RegisterLock = switch (len) { |
| 180666 | | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 180667 | | else => null, |
| 180668 | | }; |
| 180669 | | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); |
| 180664 | }, |
| 180665 | .one => .{ dst, .{ .immediate = dst_ty.childType(zcu).arrayLen(zcu) } }, |
| 180666 | .c, .many => unreachable, |
| 180667 | }; |
| 180668 | const len_lock: ?RegisterLock = switch (len) { |
| 180669 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 180670 | else => null, |
| 180671 | }; |
| 180672 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); |
| 180670 | 180673 | |
| 180674 | if (elem_abi_size == 1) { |
| 180671 | 180675 | try self.genInlineMemset(dst_ptr, src_val, len, .{ .safety = safety }); |
| 180672 | 180676 | break :result; |
| 180673 | 180677 | } |
| ... | ... | @@ -180675,25 +180679,16 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180675 | 180679 | // Store the first element, and then rely on memcpy copying forwards. |
| 180676 | 180680 | // Length zero requires a runtime check - so we handle arrays specially |
| 180677 | 180681 | // here to elide it. |
| 180678 | | switch (dst_ty.ptrSize(zcu)) { |
| 180679 | | .slice => { |
| 180682 | switch (len) { |
| 180683 | else => { |
| 180680 | 180684 | const slice_ptr_ty = dst_ty.slicePtrFieldType(zcu); |
| 180681 | 180685 | |
| 180682 | | const dst_ptr: MCValue = switch (dst) { |
| 180683 | | .register_pair => |dst_regs| .{ .register = dst_regs[0] }, |
| 180684 | | else => dst, |
| 180685 | | }; |
| 180686 | | const len: MCValue = switch (dst) { |
| 180687 | | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| 180688 | | else => dst.address().offset(8).deref(), |
| 180689 | | }; |
| 180690 | | |
| 180691 | 180686 | // Used to store the number of elements for comparison. |
| 180692 | 180687 | // After comparison, updated to store number of bytes needed to copy. |
| 180693 | 180688 | const len_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 180694 | 180689 | const len_mcv: MCValue = .{ .register = len_reg }; |
| 180695 | | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 180696 | | defer self.register_manager.unlockReg(len_lock); |
| 180690 | const len_reg_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 180691 | defer self.register_manager.unlockReg(len_reg_lock); |
| 180697 | 180692 | |
| 180698 | 180693 | try self.spillEflagsIfOccupied(); |
| 180699 | 180694 | try self.genSetReg(len_reg, .usize, len, .{}); |
| ... | ... | @@ -180725,12 +180720,10 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180725 | 180720 | |
| 180726 | 180721 | self.performReloc(skip_reloc); |
| 180727 | 180722 | }, |
| 180728 | | .one => { |
| 180723 | .immediate => |len_imm| { |
| 180729 | 180724 | const elem_ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 180730 | 180725 | |
| 180731 | | const len = dst_ty.childType(zcu).arrayLen(zcu); |
| 180732 | | |
| 180733 | | assert(len != 0); // prevented by Sema |
| 180726 | assert(len_imm != 0); // prevented by Sema |
| 180734 | 180727 | try self.store(elem_ptr_ty, dst, src_val, .{ .safety = safety }); |
| 180735 | 180728 | |
| 180736 | 180729 | const second_elem_ptr_reg = |
| ... | ... | @@ -180745,10 +180738,9 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180745 | 180738 | .off = elem_abi_size, |
| 180746 | 180739 | } }, .{}); |
| 180747 | 180740 | |
| 180748 | | const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) }; |
| 180741 | const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len_imm - 1) }; |
| 180749 | 180742 | try self.genInlineMemcpy(second_elem_ptr_mcv, dst, bytes_to_copy, .{ .no_alias = false }); |
| 180750 | 180743 | }, |
| 180751 | | .c, .many => unreachable, |
| 180752 | 180744 | } |
| 180753 | 180745 | } |
| 180754 | 180746 | return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | ... | @@ -182771,17 +182763,27 @@ const Temp = struct { |
| 182771 | 182763 | assert(limb_index == 0); |
| 182772 | 182764 | new_temp_index.tracking(cg).* = .init(.{ .lea_nav = nav }); |
| 182773 | 182765 | }, |
| 182774 | | .load_uav => |uav| { |
| 182775 | | const new_reg = |
| 182776 | | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 182777 | | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| 182778 | | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| 182779 | | .base = .{ .uav = uav }, |
| 182780 | | .mod = .{ .rm = .{ |
| 182781 | | .size = .qword, |
| 182782 | | .disp = @as(u31, limb_index) * 8, |
| 182783 | | } }, |
| 182784 | | }); |
| 182766 | .load_uav => |uav| switch (cg.pt.zcu.intern_pool.indexToKey(uav.val)) { |
| 182767 | else => { |
| 182768 | const new_reg = try cg.register_manager.allocReg( |
| 182769 | new_temp_index.toIndex(), |
| 182770 | abi.RegisterClass.gp, |
| 182771 | ); |
| 182772 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| 182773 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| 182774 | .base = .{ .uav = uav }, |
| 182775 | .mod = .{ .rm = .{ |
| 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 | }))), |
| 182785 | 182787 | }, |
| 182786 | 182788 | .lea_uav => |uav| { |
| 182787 | 182789 | assert(limb_index == 0); |
| ... | ... | @@ -182870,15 +182872,11 @@ const Temp = struct { |
| 182870 | 182872 | fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) InnerError!void { |
| 182871 | 182873 | switch (temp.unwrap(cg)) { |
| 182872 | 182874 | .ref => {}, |
| 182873 | | .temp => |temp_index| { |
| 182875 | .temp => |temp_index| inplace: { |
| 182874 | 182876 | const temp_tracking = temp_index.tracking(cg); |
| 182875 | 182877 | switch (temp_tracking.short) { |
| 182876 | | else => {}, |
| 182877 | | .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => { |
| 182878 | | assert(limb_index == 0); |
| 182879 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182880 | | return; |
| 182881 | | }, |
| 182878 | else => break :inplace, |
| 182879 | .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => assert(limb_index == 0), |
| 182882 | 182880 | .register_pair => |regs| { |
| 182883 | 182881 | switch (temp_tracking.long) { |
| 182884 | 182882 | .none, .reserved_frame => {}, |
| ... | ... | @@ -182888,8 +182886,6 @@ const Temp = struct { |
| 182888 | 182886 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) |
| 182889 | 182887 | cg.register_manager.freeReg(reg); |
| 182890 | 182888 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); |
| 182891 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182892 | | return; |
| 182893 | 182889 | }, |
| 182894 | 182890 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { |
| 182895 | 182891 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); |
| ... | ... | @@ -182897,10 +182893,19 @@ const Temp = struct { |
| 182897 | 182893 | .index = frame_addr.index, |
| 182898 | 182894 | .off = frame_addr.off + @as(u31, limb_index) * 8, |
| 182899 | 182895 | } }); |
| 182900 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182901 | | return; |
| 182896 | }, |
| 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 | }))), |
| 182902 | 182905 | }, |
| 182903 | 182906 | } |
| 182907 | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182908 | return; |
| 182904 | 182909 | }, |
| 182905 | 182910 | .err_ret_trace => unreachable, |
| 182906 | 182911 | } |