| ... | @@ -3569,7 +3569,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -3569,7 +3569,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 3569 | return self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }, .{}); | 3569 | return self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }, .{}); |
| 3570 | } | 3570 | } |
| 3571 | | 3571 | |
| 3572 | try self.genInlineMemcpy(dst_mcv, ptr, .{ .immediate = abi_size }, .{}); | 3572 | try self.genInlineMemcpy( |
| | 3573 | .{ .ptr_stack_offset = off }, |
| | 3574 | ptr, |
| | 3575 | .{ .immediate = abi_size }, |
| | 3576 | .{}, |
| | 3577 | ); |
| 3573 | }, | 3578 | }, |
| 3574 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), | 3579 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), |
| 3575 | } | 3580 | } |
| ... | @@ -3745,22 +3750,47 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3745,22 +3750,47 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3745 | -@intCast(i32, overflow_bit_offset), | 3750 | -@intCast(i32, overflow_bit_offset), |
| 3746 | ); | 3751 | ); |
| 3747 | }, | 3752 | }, |
| 3748 | .linker_load, .memory, .stack_offset => if (abi_size <= 8) { | 3753 | .memory, .linker_load => if (abi_size <= 8) { |
| | 3754 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| | 3755 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| | 3756 | defer self.register_manager.unlockReg(tmp_lock); |
| | 3757 | |
| | 3758 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| | 3759 | } else { |
| | 3760 | const addr_reg = try self.register_manager.allocReg(null, gp); |
| | 3761 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| | 3762 | defer self.register_manager.unlockReg(addr_lock); |
| | 3763 | |
| | 3764 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, value); |
| | 3765 | try self.genInlineMemcpy( |
| | 3766 | ptr, |
| | 3767 | .{ .register = addr_reg }, |
| | 3768 | .{ .immediate = abi_size }, |
| | 3769 | .{}, |
| | 3770 | ); |
| | 3771 | }, |
| | 3772 | .stack_offset => |off| if (abi_size <= 8) { |
| 3749 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3773 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| | 3774 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| | 3775 | defer self.register_manager.unlockReg(tmp_lock); |
| | 3776 | |
| 3750 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); | 3777 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| 3751 | } else try self.genInlineMemcpy( | 3778 | } else try self.genInlineMemcpy( |
| 3752 | .{ .stack_offset = 0 }, | 3779 | ptr, |
| 3753 | value, | 3780 | .{ .ptr_stack_offset = off }, |
| 3754 | .{ .immediate = abi_size }, | 3781 | .{ .immediate = abi_size }, |
| 3755 | .{ .source_stack_base = .rbp, .dest_stack_base = reg.to64() }, | 3782 | .{}, |
| 3756 | ), | 3783 | ), |
| 3757 | .ptr_stack_offset => { | 3784 | .ptr_stack_offset => { |
| 3758 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3785 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| | 3786 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| | 3787 | defer self.register_manager.unlockReg(tmp_lock); |
| | 3788 | |
| 3759 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); | 3789 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| 3760 | }, | 3790 | }, |
| 3761 | } | 3791 | } |
| 3762 | }, | 3792 | }, |
| 3763 | .linker_load, .memory => { | 3793 | .memory, .linker_load => { |
| 3764 | const value_lock: ?RegisterLock = switch (value) { | 3794 | const value_lock: ?RegisterLock = switch (value) { |
| 3765 | .register => |reg| self.register_manager.lockReg(reg), | 3795 | .register => |reg| self.register_manager.lockReg(reg), |
| 3766 | else => null, | 3796 | else => null, |
| ... | @@ -5530,14 +5560,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5530,14 +5560,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 5530 | assert(ret_ty.isError()); | 5560 | assert(ret_ty.isError()); |
| 5531 | }, | 5561 | }, |
| 5532 | .stack_offset => { | 5562 | .stack_offset => { |
| 5533 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); | 5563 | try self.store(self.ret_mcv, operand, Type.usize, ret_ty); |
| 5534 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); | | |
| 5535 | defer self.register_manager.unlockReg(reg_lock); | | |
| 5536 | | | |
| 5537 | try self.genSetStack(ret_ty, 0, operand, .{ | | |
| 5538 | .source_stack_base = .rbp, | | |
| 5539 | .dest_stack_base = reg, | | |
| 5540 | }); | | |
| 5541 | }, | 5564 | }, |
| 5542 | else => { | 5565 | else => { |
| 5543 | try self.setRegOrMem(ret_ty, self.ret_mcv, operand); | 5566 | try self.setRegOrMem(ret_ty, self.ret_mcv, operand); |
| ... | @@ -5556,6 +5579,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5556,6 +5579,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 5556 | const ptr = try self.resolveInst(un_op); | 5579 | const ptr = try self.resolveInst(un_op); |
| 5557 | const ptr_ty = self.air.typeOf(un_op); | 5580 | const ptr_ty = self.air.typeOf(un_op); |
| 5558 | const elem_ty = ptr_ty.elemType(); | 5581 | const elem_ty = ptr_ty.elemType(); |
| | 5582 | const abi_size = elem_ty.abiSize(self.target.*); |
| 5559 | switch (self.ret_mcv) { | 5583 | switch (self.ret_mcv) { |
| 5560 | .immediate => { | 5584 | .immediate => { |
| 5561 | assert(elem_ty.isError()); | 5585 | assert(elem_ty.isError()); |
| ... | @@ -5565,10 +5589,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5565,10 +5589,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 5565 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); | 5589 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 5566 | defer self.register_manager.unlockReg(reg_lock); | 5590 | defer self.register_manager.unlockReg(reg_lock); |
| 5567 | | 5591 | |
| 5568 | try self.genInlineMemcpy(.{ .stack_offset = 0 }, ptr, .{ .immediate = elem_ty.abiSize(self.target.*) }, .{ | 5592 | try self.genInlineMemcpy(.{ .register = reg }, ptr, .{ .immediate = abi_size }, .{}); |
| 5569 | .source_stack_base = .rbp, | | |
| 5570 | .dest_stack_base = reg, | | |
| 5571 | }); | | |
| 5572 | }, | 5593 | }, |
| 5573 | else => { | 5594 | else => { |
| 5574 | try self.load(self.ret_mcv, ptr, ptr_ty); | 5595 | try self.load(self.ret_mcv, ptr, ptr_ty); |
| ... | @@ -6838,7 +6859,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -6838,7 +6859,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 6838 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 6859 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 6839 | } | 6860 | } |
| 6840 | try self.genInlineMemset( | 6861 | try self.genInlineMemset( |
| 6841 | .{ .stack_offset = stack_offset }, | 6862 | .{ .ptr_stack_offset = stack_offset }, |
| 6842 | .{ .immediate = 0xaa }, | 6863 | .{ .immediate = 0xaa }, |
| 6843 | .{ .immediate = abi_size }, | 6864 | .{ .immediate = abi_size }, |
| 6844 | .{ .dest_stack_base = .rsp }, | 6865 | .{ .dest_stack_base = .rsp }, |
| ... | @@ -6877,10 +6898,17 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -6877,10 +6898,17 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 6877 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 6898 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 6878 | } | 6899 | } |
| 6879 | | 6900 | |
| 6880 | try self.genInlineMemcpy(.{ .stack_offset = stack_offset }, mcv, .{ .immediate = abi_size }, .{ | 6901 | const addr_reg = try self.register_manager.allocReg(null, gp); |
| 6881 | .source_stack_base = .rbp, | 6902 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6882 | .dest_stack_base = .rsp, | 6903 | defer self.register_manager.unlockReg(addr_lock); |
| 6883 | }); | 6904 | |
| | 6905 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mcv); |
| | 6906 | try self.genInlineMemcpy( |
| | 6907 | .{ .ptr_stack_offset = stack_offset }, |
| | 6908 | .{ .register = addr_reg }, |
| | 6909 | .{ .immediate = abi_size }, |
| | 6910 | .{ .dest_stack_base = .rsp }, |
| | 6911 | ); |
| 6884 | }, | 6912 | }, |
| 6885 | .register => |reg| { | 6913 | .register => |reg| { |
| 6886 | switch (ty.zigTypeTag()) { | 6914 | switch (ty.zigTypeTag()) { |
| ... | @@ -6920,16 +6948,18 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -6920,16 +6948,18 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 6920 | const reg = try self.copyToTmpRegister(ty, mcv); | 6948 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 6921 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 6949 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 6922 | }, | 6950 | }, |
| 6923 | .stack_offset => { | 6951 | .stack_offset => |mcv_off| { |
| 6924 | if (abi_size <= 8) { | 6952 | if (abi_size <= 8) { |
| 6925 | const reg = try self.copyToTmpRegister(ty, mcv); | 6953 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 6926 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 6954 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 6927 | } | 6955 | } |
| 6928 | | 6956 | |
| 6929 | try self.genInlineMemcpy(.{ .stack_offset = stack_offset }, mcv, .{ .immediate = abi_size }, .{ | 6957 | try self.genInlineMemcpy( |
| 6930 | .source_stack_base = .rbp, | 6958 | .{ .ptr_stack_offset = stack_offset }, |
| 6931 | .dest_stack_base = .rsp, | 6959 | .{ .ptr_stack_offset = mcv_off }, |
| 6932 | }); | 6960 | .{ .immediate = abi_size }, |
| | 6961 | .{ .dest_stack_base = .rsp }, |
| | 6962 | ); |
| 6933 | }, | 6963 | }, |
| 6934 | } | 6964 | } |
| 6935 | } | 6965 | } |
| ... | @@ -6963,7 +6993,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -6963,7 +6993,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 6963 | opts, | 6993 | opts, |
| 6964 | ), | 6994 | ), |
| 6965 | else => |x| return self.genInlineMemset( | 6995 | else => |x| return self.genInlineMemset( |
| 6966 | .{ .stack_offset = stack_offset }, | 6996 | .{ .ptr_stack_offset = stack_offset }, |
| 6967 | .{ .immediate = 0xaa }, | 6997 | .{ .immediate = 0xaa }, |
| 6968 | .{ .immediate = x }, | 6998 | .{ .immediate = x }, |
| 6969 | opts, | 6999 | opts, |
| ... | @@ -7072,22 +7102,40 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7072,22 +7102,40 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7072 | }, | 7102 | }, |
| 7073 | } | 7103 | } |
| 7074 | }, | 7104 | }, |
| 7075 | .memory, .linker_load, .stack_offset, .ptr_stack_offset => { | 7105 | .memory, .linker_load => if (abi_size <= 8) { |
| 7076 | switch (mcv) { | 7106 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7077 | else => unreachable, | 7107 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); |
| 7078 | .memory, .linker_load, .ptr_stack_offset => {}, | 7108 | } else { |
| 7079 | .stack_offset => |src_off| if (stack_offset == src_off) { | 7109 | const addr_reg = try self.register_manager.allocReg(null, gp); |
| 7080 | // Copy stack variable to itself; nothing to do. | 7110 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7081 | return; | 7111 | defer self.register_manager.unlockReg(addr_lock); |
| 7082 | }, | | |
| 7083 | } | | |
| 7084 | | 7112 | |
| 7085 | if (abi_size <= 8) { | 7113 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mcv); |
| 7086 | const reg = try self.copyToTmpRegister(ty, mcv); | 7114 | try self.genInlineMemcpy( |
| 7087 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); | 7115 | .{ .ptr_stack_offset = stack_offset }, |
| 7088 | } | 7116 | .{ .register = addr_reg }, |
| | 7117 | .{ .immediate = abi_size }, |
| | 7118 | .{}, |
| | 7119 | ); |
| | 7120 | }, |
| | 7121 | .stack_offset => |off| if (abi_size <= 8) { |
| | 7122 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| | 7123 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| | 7124 | defer self.register_manager.unlockReg(tmp_lock); |
| 7089 | | 7125 | |
| 7090 | try self.genInlineMemcpy(.{ .stack_offset = stack_offset }, mcv, .{ .immediate = abi_size }, opts); | 7126 | try self.genSetStack(ty, stack_offset, .{ .register = tmp_reg }, opts); |
| | 7127 | } else try self.genInlineMemcpy( |
| | 7128 | .{ .ptr_stack_offset = stack_offset }, |
| | 7129 | .{ .ptr_stack_offset = off }, |
| | 7130 | .{ .immediate = abi_size }, |
| | 7131 | .{}, |
| | 7132 | ), |
| | 7133 | .ptr_stack_offset => { |
| | 7134 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| | 7135 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| | 7136 | defer self.register_manager.unlockReg(tmp_lock); |
| | 7137 | |
| | 7138 | try self.genSetStack(ty, stack_offset, .{ .register = tmp_reg }, opts); |
| 7091 | }, | 7139 | }, |
| 7092 | } | 7140 | } |
| 7093 | } | 7141 | } |
| ... | @@ -7134,10 +7182,14 @@ fn genInlineMemcpyRegisterRegister( | ... | @@ -7134,10 +7182,14 @@ fn genInlineMemcpyRegisterRegister( |
| 7134 | next_offset -= nearest_power_of_two; | 7182 | next_offset -= nearest_power_of_two; |
| 7135 | } | 7183 | } |
| 7136 | } else { | 7184 | } else { |
| 7137 | try self.asmMemoryRegister(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 7185 | try self.asmMemoryRegister( |
| 7138 | .base = dst_reg, | 7186 | switch (src_reg.class()) { |
| 7139 | .disp = -offset, | 7187 | .general_purpose, .segment => .mov, |
| 7140 | }), registerAlias(src_reg, abi_size)); | 7188 | .floating_point => .movss, |
| | 7189 | }, |
| | 7190 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = dst_reg, .disp = -offset }), |
| | 7191 | registerAlias(src_reg, abi_size), |
| | 7192 | ); |
| 7141 | } | 7193 | } |
| 7142 | } | 7194 | } |
| 7143 | | 7195 | |
| ... | @@ -7170,9 +7222,15 @@ fn genInlineMemcpy( | ... | @@ -7170,9 +7222,15 @@ fn genInlineMemcpy( |
| 7170 | switch (dst_ptr) { | 7222 | switch (dst_ptr) { |
| 7171 | .memory, .linker_load => { | 7223 | .memory, .linker_load => { |
| 7172 | try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); | 7224 | try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); |
| | 7225 | // Load the pointer, which is stored in memory |
| | 7226 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7173 | }, | 7227 | }, |
| 7174 | .ptr_stack_offset, .stack_offset => |off| { | 7228 | .stack_offset, .ptr_stack_offset => |off| { |
| 7175 | try self.asmRegisterMemory(.lea, .rdi, Memory.sib(.qword, .{ | 7229 | try self.asmRegisterMemory(switch (dst_ptr) { |
| | 7230 | .stack_offset => .mov, |
| | 7231 | .ptr_stack_offset => .lea, |
| | 7232 | else => unreachable, |
| | 7233 | }, .rdi, Memory.sib(.qword, .{ |
| 7176 | .base = opts.dest_stack_base orelse .rbp, | 7234 | .base = opts.dest_stack_base orelse .rbp, |
| 7177 | .disp = -off, | 7235 | .disp = -off, |
| 7178 | })); | 7236 | })); |
| ... | @@ -7192,9 +7250,15 @@ fn genInlineMemcpy( | ... | @@ -7192,9 +7250,15 @@ fn genInlineMemcpy( |
| 7192 | switch (src_ptr) { | 7250 | switch (src_ptr) { |
| 7193 | .memory, .linker_load => { | 7251 | .memory, .linker_load => { |
| 7194 | try self.loadMemPtrIntoRegister(.rsi, Type.usize, src_ptr); | 7252 | try self.loadMemPtrIntoRegister(.rsi, Type.usize, src_ptr); |
| | 7253 | // Load the pointer, which is stored in memory |
| | 7254 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); |
| 7195 | }, | 7255 | }, |
| 7196 | .ptr_stack_offset, .stack_offset => |off| { | 7256 | .stack_offset, .ptr_stack_offset => |off| { |
| 7197 | try self.asmRegisterMemory(.lea, .rsi, Memory.sib(.qword, .{ | 7257 | try self.asmRegisterMemory(switch (src_ptr) { |
| | 7258 | .stack_offset => .mov, |
| | 7259 | .ptr_stack_offset => .lea, |
| | 7260 | else => unreachable, |
| | 7261 | }, .rsi, Memory.sib(.qword, .{ |
| 7198 | .base = opts.source_stack_base orelse .rbp, | 7262 | .base = opts.source_stack_base orelse .rbp, |
| 7199 | .disp = -off, | 7263 | .disp = -off, |
| 7200 | })); | 7264 | })); |
| ... | @@ -7237,9 +7301,15 @@ fn genInlineMemset( | ... | @@ -7237,9 +7301,15 @@ fn genInlineMemset( |
| 7237 | switch (dst_ptr) { | 7301 | switch (dst_ptr) { |
| 7238 | .memory, .linker_load => { | 7302 | .memory, .linker_load => { |
| 7239 | try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); | 7303 | try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); |
| | 7304 | // Load the pointer, which is stored in memory |
| | 7305 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7240 | }, | 7306 | }, |
| 7241 | .ptr_stack_offset, .stack_offset => |off| { | 7307 | .stack_offset, .ptr_stack_offset => |off| { |
| 7242 | try self.asmRegisterMemory(.lea, .rdi, Memory.sib(.qword, .{ | 7308 | try self.asmRegisterMemory(switch (dst_ptr) { |
| | 7309 | .stack_offset => .mov, |
| | 7310 | .ptr_stack_offset => .lea, |
| | 7311 | else => unreachable, |
| | 7312 | }, .rdi, Memory.sib(.qword, .{ |
| 7243 | .base = opts.dest_stack_base orelse .rbp, | 7313 | .base = opts.dest_stack_base orelse .rbp, |
| 7244 | .disp = -off, | 7314 | .disp = -off, |
| 7245 | })); | 7315 | })); |
| ... | @@ -7979,7 +8049,6 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7979,7 +8049,6 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 7979 | }; | 8049 | }; |
| 7980 | defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock); | 8050 | defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 7981 | | 8051 | |
| 7982 | const src_ty = self.air.typeOf(extra.lhs); | | |
| 7983 | const src_ptr = try self.resolveInst(extra.lhs); | 8052 | const src_ptr = try self.resolveInst(extra.lhs); |
| 7984 | const src_ptr_lock: ?RegisterLock = switch (src_ptr) { | 8053 | const src_ptr_lock: ?RegisterLock = switch (src_ptr) { |
| 7985 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 8054 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| ... | @@ -7994,25 +8063,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7994,25 +8063,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 7994 | }; | 8063 | }; |
| 7995 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); | 8064 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); |
| 7996 | | 8065 | |
| 7997 | // TODO Is this the only condition for pointer dereference for memcpy? | 8066 | try self.genInlineMemcpy(dst_ptr, src_ptr, len, .{}); |
| 7998 | const src: MCValue = blk: { | | |
| 7999 | switch (src_ptr) { | | |
| 8000 | .linker_load, .memory => { | | |
| 8001 | const reg = try self.register_manager.allocReg(null, gp); | | |
| 8002 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); | | |
| 8003 | try self.asmRegisterMemory(.mov, reg, Memory.sib(.qword, .{ .base = reg })); | | |
| 8004 | break :blk MCValue{ .register = reg }; | | |
| 8005 | }, | | |
| 8006 | else => break :blk src_ptr, | | |
| 8007 | } | | |
| 8008 | }; | | |
| 8009 | const src_lock: ?RegisterLock = switch (src) { | | |
| 8010 | .register => |reg| self.register_manager.lockReg(reg), | | |
| 8011 | else => null, | | |
| 8012 | }; | | |
| 8013 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 8014 | | | |
| 8015 | try self.genInlineMemcpy(dst_ptr, src, len, .{}); | | |
| 8016 | | 8067 | |
| 8017 | return self.finishAir(inst, .none, .{ pl_op.operand, extra.lhs, extra.rhs }); | 8068 | return self.finishAir(inst, .none, .{ pl_op.operand, extra.lhs, extra.rhs }); |
| 8018 | } | 8069 | } |
| ... | @@ -8156,11 +8207,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8156,11 +8207,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8156 | switch (result_ty.zigTypeTag()) { | 8207 | switch (result_ty.zigTypeTag()) { |
| 8157 | .Struct => { | 8208 | .Struct => { |
| 8158 | const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); | 8209 | const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); |
| 8159 | const dst_mcv = MCValue{ .stack_offset = stack_offset }; | | |
| 8160 | if (result_ty.containerLayout() == .Packed) { | 8210 | if (result_ty.containerLayout() == .Packed) { |
| 8161 | const struct_obj = result_ty.castTag(.@"struct").?.data; | 8211 | const struct_obj = result_ty.castTag(.@"struct").?.data; |
| 8162 | try self.genInlineMemset( | 8212 | try self.genInlineMemset( |
| 8163 | dst_mcv, | 8213 | .{ .ptr_stack_offset = stack_offset }, |
| 8164 | .{ .immediate = 0 }, | 8214 | .{ .immediate = 0 }, |
| 8165 | .{ .immediate = abi_size }, | 8215 | .{ .immediate = abi_size }, |
| 8166 | .{}, | 8216 | .{}, |
| ... | @@ -8236,7 +8286,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8236,7 +8286,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8236 | const elem_mcv = try self.resolveInst(elem); | 8286 | const elem_mcv = try self.resolveInst(elem); |
| 8237 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); | 8287 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); |
| 8238 | } | 8288 | } |
| 8239 | break :res dst_mcv; | 8289 | break :res .{ .stack_offset = stack_offset }; |
| 8240 | }, | 8290 | }, |
| 8241 | .Array => { | 8291 | .Array => { |
| 8242 | const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); | 8292 | const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); |