| ... | ... | @@ -1224,9 +1224,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void { |
| 1224 | 1224 | .pseudo_dbg_enter_block_none, |
| 1225 | 1225 | .pseudo_dbg_leave_block_none, |
| 1226 | 1226 | .pseudo_dbg_end_none, |
| 1227 | | .pseudo_dbg_arg_none, |
| 1228 | 1227 | .pseudo_dbg_var_args_none, |
| 1229 | | .pseudo_dbg_var_none, |
| 1230 | 1228 | .pseudo_dead_none, |
| 1231 | 1229 | => {}, |
| 1232 | 1230 | .pseudo_dbg_line_stmt_line_column, |
| ... | ... | @@ -2318,39 +2316,32 @@ fn genMainBody( |
| 2318 | 2316 | }; |
| 2319 | 2317 | defer zir_param_index += 1; |
| 2320 | 2318 | |
| 2321 | | if (comptime_args.len > 0) switch (comptime_args.get(ip)[zir_param_index]) { |
| 2322 | | .none => {}, |
| 2323 | | else => |comptime_arg| { |
| 2324 | | try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = ip.typeOf(comptime_arg) }); |
| 2325 | | _ = try cg.addInst(.{ |
| 2326 | | .tag = .pseudo, |
| 2327 | | .ops = .pseudo_dbg_arg_val, |
| 2328 | | .data = .{ .ip_index = comptime_arg }, |
| 2329 | | }); |
| 2330 | | continue; |
| 2319 | const arg_ty: Type, const arg_val: ?Value = arg: switch (if (comptime_args.len > 0) |
| 2320 | comptime_args.get(ip)[zir_param_index] |
| 2321 | else |
| 2322 | .none) { |
| 2323 | else => |arg_val| .{ .fromInterned(ip.typeOf(arg_val)), .fromInterned(arg_val) }, |
| 2324 | .none => { |
| 2325 | const arg_ty: Type = .fromInterned(fn_info.param_types.get(ip)[fn_param_index]); |
| 2326 | fn_param_index += 1; |
| 2327 | break :arg .{ arg_ty, try arg_ty.onePossibleValue(pt) }; |
| 2331 | 2328 | }, |
| 2332 | 2329 | }; |
| 2333 | | |
| 2334 | | const arg_ty = fn_info.param_types.get(ip)[fn_param_index]; |
| 2335 | | try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = arg_ty }); |
| 2336 | | fn_param_index += 1; |
| 2337 | | |
| 2338 | | if (air_arg_index == air_args_body.len) { |
| 2339 | | try cg.asmPseudo(.pseudo_dbg_arg_none); |
| 2330 | try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = arg_ty.toIntern() }); |
| 2331 | if (arg_val) |val| { |
| 2332 | _ = try cg.addInst(.{ |
| 2333 | .tag = .pseudo, |
| 2334 | .ops = .pseudo_dbg_arg_val, |
| 2335 | .data = .{ .ip_index = val.toIntern() }, |
| 2336 | }); |
| 2340 | 2337 | continue; |
| 2341 | 2338 | } |
| 2339 | |
| 2342 | 2340 | const air_arg_inst = air_args_body[air_arg_index]; |
| 2343 | 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 | 2342 | air_arg_index += 1; |
| 2349 | | try cg.genLocalDebugInfo( |
| 2350 | | .arg, |
| 2351 | | .fromInterned(arg_ty), |
| 2352 | | cg.getResolvedInstValue(air_arg_inst).short, |
| 2353 | | ); |
| 2343 | assert(air_arg_data.zir_param_index == zir_param_index); |
| 2344 | try cg.genLocalDebugInfo(.arg, arg_ty, cg.getResolvedInstValue(air_arg_inst).short); |
| 2354 | 2345 | } |
| 2355 | 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 | 180614 | fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180624 | 180615 | const pt = self.pt; |
| 180625 | 180616 | const zcu = pt.zcu; |
| 180617 | const ip = &zcu.intern_pool; |
| 180626 | 180618 | const bin_op = self.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 180627 | 180619 | |
| 180628 | 180620 | result: { |
| ... | ... | @@ -180654,29 +180646,32 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180654 | 180646 | |
| 180655 | 180647 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); |
| 180656 | 180648 | |
| 180657 | | if (elem_abi_size == 1) { |
| 180658 | | const dst_ptr: MCValue = switch (dst_ty.ptrSize(zcu)) { |
| 180659 | | .slice => switch (dst) { |
| 180660 | | .register_pair => |dst_regs| .{ .register = dst_regs[0] }, |
| 180661 | | 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] }, |
| 180662 | 180655 | }, |
| 180663 | | .one => dst, |
| 180664 | | .c, .many => unreachable, |
| 180665 | | }; |
| 180666 | | const len: MCValue = switch (dst_ty.ptrSize(zcu)) { |
| 180667 | | .slice => switch (dst) { |
| 180668 | | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| 180669 | | 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 | }, |
| 180670 | 180663 | }, |
| 180671 | | .one => .{ .immediate = dst_ty.childType(zcu).arrayLen(zcu) }, |
| 180672 | | .c, .many => unreachable, |
| 180673 | | }; |
| 180674 | | const len_lock: ?RegisterLock = switch (len) { |
| 180675 | | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 180676 | | else => null, |
| 180677 | | }; |
| 180678 | | 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); |
| 180679 | 180673 | |
| 180674 | if (elem_abi_size == 1) { |
| 180680 | 180675 | try self.genInlineMemset(dst_ptr, src_val, len, .{ .safety = safety }); |
| 180681 | 180676 | break :result; |
| 180682 | 180677 | } |
| ... | ... | @@ -180684,26 +180679,18 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180684 | 180679 | // Store the first element, and then rely on memcpy copying forwards. |
| 180685 | 180680 | // Length zero requires a runtime check - so we handle arrays specially |
| 180686 | 180681 | // here to elide it. |
| 180687 | | switch (dst_ty.ptrSize(zcu)) { |
| 180688 | | .slice => { |
| 180682 | switch (len) { |
| 180683 | else => { |
| 180689 | 180684 | const slice_ptr_ty = dst_ty.slicePtrFieldType(zcu); |
| 180690 | 180685 | |
| 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 | 180686 | // Used to store the number of elements for comparison. |
| 180701 | 180687 | // After comparison, updated to store number of bytes needed to copy. |
| 180702 | 180688 | const len_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 180703 | 180689 | const len_mcv: MCValue = .{ .register = len_reg }; |
| 180704 | | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 180705 | | 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); |
| 180706 | 180692 | |
| 180693 | try self.spillEflagsIfOccupied(); |
| 180707 | 180694 | try self.genSetReg(len_reg, .usize, len, .{}); |
| 180708 | 180695 | try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); |
| 180709 | 180696 | |
| ... | ... | @@ -180733,12 +180720,10 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180733 | 180720 | |
| 180734 | 180721 | self.performReloc(skip_reloc); |
| 180735 | 180722 | }, |
| 180736 | | .one => { |
| 180723 | .immediate => |len_imm| { |
| 180737 | 180724 | const elem_ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 180738 | 180725 | |
| 180739 | | const len = dst_ty.childType(zcu).arrayLen(zcu); |
| 180740 | | |
| 180741 | | assert(len != 0); // prevented by Sema |
| 180726 | assert(len_imm != 0); // prevented by Sema |
| 180742 | 180727 | try self.store(elem_ptr_ty, dst, src_val, .{ .safety = safety }); |
| 180743 | 180728 | |
| 180744 | 180729 | const second_elem_ptr_reg = |
| ... | ... | @@ -180753,10 +180738,9 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 180753 | 180738 | .off = elem_abi_size, |
| 180754 | 180739 | } }, .{}); |
| 180755 | 180740 | |
| 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 | 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 | 180746 | return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | ... | @@ -182779,17 +182763,27 @@ const Temp = struct { |
| 182779 | 182763 | assert(limb_index == 0); |
| 182780 | 182764 | new_temp_index.tracking(cg).* = .init(.{ .lea_nav = nav }); |
| 182781 | 182765 | }, |
| 182782 | | .load_uav => |uav| { |
| 182783 | | const new_reg = |
| 182784 | | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 182785 | | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| 182786 | | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| 182787 | | .base = .{ .uav = uav }, |
| 182788 | | .mod = .{ .rm = .{ |
| 182789 | | .size = .qword, |
| 182790 | | .disp = @as(u31, limb_index) * 8, |
| 182791 | | } }, |
| 182792 | | }); |
| 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 | }))), |
| 182793 | 182787 | }, |
| 182794 | 182788 | .lea_uav => |uav| { |
| 182795 | 182789 | assert(limb_index == 0); |
| ... | ... | @@ -182878,15 +182872,11 @@ const Temp = struct { |
| 182878 | 182872 | fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) InnerError!void { |
| 182879 | 182873 | switch (temp.unwrap(cg)) { |
| 182880 | 182874 | .ref => {}, |
| 182881 | | .temp => |temp_index| { |
| 182875 | .temp => |temp_index| inplace: { |
| 182882 | 182876 | const temp_tracking = temp_index.tracking(cg); |
| 182883 | 182877 | switch (temp_tracking.short) { |
| 182884 | | else => {}, |
| 182885 | | .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => { |
| 182886 | | assert(limb_index == 0); |
| 182887 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182888 | | return; |
| 182889 | | }, |
| 182878 | else => break :inplace, |
| 182879 | .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => assert(limb_index == 0), |
| 182890 | 182880 | .register_pair => |regs| { |
| 182891 | 182881 | switch (temp_tracking.long) { |
| 182892 | 182882 | .none, .reserved_frame => {}, |
| ... | ... | @@ -182896,8 +182886,6 @@ const Temp = struct { |
| 182896 | 182886 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) |
| 182897 | 182887 | cg.register_manager.freeReg(reg); |
| 182898 | 182888 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); |
| 182899 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182900 | | return; |
| 182901 | 182889 | }, |
| 182902 | 182890 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { |
| 182903 | 182891 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); |
| ... | ... | @@ -182905,10 +182893,19 @@ const Temp = struct { |
| 182905 | 182893 | .index = frame_addr.index, |
| 182906 | 182894 | .off = frame_addr.off + @as(u31, limb_index) * 8, |
| 182907 | 182895 | } }); |
| 182908 | | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182909 | | 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 | }))), |
| 182910 | 182905 | }, |
| 182911 | 182906 | } |
| 182907 | cg.temp_type[@backingInt(temp_index)] = limb_ty; |
| 182908 | return; |
| 182912 | 182909 | }, |
| 182913 | 182910 | .err_ret_trace => unreachable, |
| 182914 | 182911 | } |