| ... | @@ -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; |
| 2320 | | 2318 | |
| 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 | }; |
| 2333 | | 2330 | 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, |
| 2337 | | 2334 | .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 |
| 180623 | fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { | 180614 | fn 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; |
| 180627 | | 180619 | |
| 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 { |
| 180654 | | 180646 | |
| 180655 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); | 180647 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); |
| 180656 | | 180648 | |
| 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); |
| 180679 | | 180673 | |
| | 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 specially | 180680 | // 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); |
| 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 | // 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); |
| 180706 | | 180692 | |
| | 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); |
| 180709 | | 180696 | |
| ... | @@ -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 { |
| 180733 | | 180720 | |
| 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); |
| 180738 | | 180725 | |
| 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 }); |
| 180743 | | 180728 | |
| 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 | } }, .{}); |
| 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 | 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 | } |