| ... | ... | @@ -8175,7 +8175,15 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8175 | 8175 | }; |
| 8176 | 8176 | defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock); |
| 8177 | 8177 | |
| 8178 | | if (elem_ty.abiSize(self.target.*) == 1) { |
| 8178 | const elem_abi_size = @intCast(u31, elem_ty.abiSize(self.target.*)); |
| 8179 | |
| 8180 | if (elem_abi_size == 1) { |
| 8181 | const ptr = switch (dst_ptr_ty.ptrSize()) { |
| 8182 | // TODO: this only handles slices stored in the stack |
| 8183 | .Slice => @as(MCValue, .{ .stack_offset = dst_ptr.stack_offset - 0 }), |
| 8184 | .One => dst_ptr, |
| 8185 | .C, .Many => unreachable, |
| 8186 | }; |
| 8179 | 8187 | const len = switch (dst_ptr_ty.ptrSize()) { |
| 8180 | 8188 | // TODO: this only handles slices stored in the stack |
| 8181 | 8189 | .Slice => @as(MCValue, .{ .stack_offset = dst_ptr.stack_offset - 8 }), |
| ... | ... | @@ -8188,8 +8196,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8188 | 8196 | }; |
| 8189 | 8197 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); |
| 8190 | 8198 | |
| 8191 | | // TODO: dst_ptr could be a slice rather than raw pointer |
| 8192 | | try self.genInlineMemset(dst_ptr, src_val, len, .{}); |
| 8199 | try self.genInlineMemset(ptr, src_val, len, .{}); |
| 8193 | 8200 | return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 8194 | 8201 | } |
| 8195 | 8202 | |
| ... | ... | @@ -8198,12 +8205,47 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8198 | 8205 | // here to elide it. |
| 8199 | 8206 | switch (dst_ptr_ty.ptrSize()) { |
| 8200 | 8207 | .Slice => { |
| 8208 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 8209 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf); |
| 8210 | |
| 8201 | 8211 | // TODO: this only handles slices stored in the stack |
| 8202 | 8212 | const ptr = @as(MCValue, .{ .stack_offset = dst_ptr.stack_offset - 0 }); |
| 8203 | 8213 | const len = @as(MCValue, .{ .stack_offset = dst_ptr.stack_offset - 8 }); |
| 8204 | | _ = ptr; |
| 8205 | | _ = len; |
| 8206 | | return self.fail("TODO implement airMemset for x86_64 with ABI size > 1 using a slice", .{}); |
| 8214 | |
| 8215 | // Used to store the number of elements for comparison. |
| 8216 | // After comparison, updated to store number of bytes needed to copy. |
| 8217 | const len_reg = try self.register_manager.allocReg(null, gp); |
| 8218 | const len_mcv: MCValue = .{ .register = len_reg }; |
| 8219 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 8220 | defer self.register_manager.unlockReg(len_lock); |
| 8221 | |
| 8222 | try self.asmRegisterMemory(.mov, len_reg, Memory.sib(.qword, .{ |
| 8223 | .base = .rbp, |
| 8224 | .disp = -len.stack_offset, |
| 8225 | })); |
| 8226 | |
| 8227 | const skip_reloc = try self.asmJccReloc(undefined, .z); |
| 8228 | try self.store(ptr, src_val, slice_ptr_ty, elem_ty); |
| 8229 | |
| 8230 | const second_elem_ptr_reg = try self.register_manager.allocReg(null, gp); |
| 8231 | const second_elem_ptr_mcv: MCValue = .{ .register = second_elem_ptr_reg }; |
| 8232 | const second_elem_ptr_lock = self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); |
| 8233 | defer self.register_manager.unlockReg(second_elem_ptr_lock); |
| 8234 | |
| 8235 | try self.asmRegisterMemory( |
| 8236 | .lea, |
| 8237 | second_elem_ptr_reg, |
| 8238 | Memory.sib(.qword, .{ |
| 8239 | .base = try self.copyToTmpRegister(Type.usize, ptr), |
| 8240 | .disp = elem_abi_size, |
| 8241 | }), |
| 8242 | ); |
| 8243 | |
| 8244 | try self.genBinOpMir(.sub, Type.usize, len_mcv, .{ .immediate = 1 }); |
| 8245 | try self.asmRegisterRegisterImmediate(.imul, len_reg, len_reg, Immediate.u(elem_abi_size)); |
| 8246 | try self.genInlineMemcpy(second_elem_ptr_mcv, ptr, len_mcv, .{}); |
| 8247 | |
| 8248 | try self.performReloc(skip_reloc); |
| 8207 | 8249 | }, |
| 8208 | 8250 | .One => { |
| 8209 | 8251 | const len = dst_ptr_ty.childType().arrayLen(); |
| ... | ... | @@ -8215,8 +8257,6 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8215 | 8257 | const second_elem_ptr_lock = self.register_manager.lockRegAssumeUnused(second_elem_ptr_reg); |
| 8216 | 8258 | defer self.register_manager.unlockReg(second_elem_ptr_lock); |
| 8217 | 8259 | |
| 8218 | | const elem_abi_size = @intCast(u31, elem_ty.abiSize(self.target.*)); |
| 8219 | | |
| 8220 | 8260 | try self.asmRegisterMemory( |
| 8221 | 8261 | .lea, |
| 8222 | 8262 | second_elem_ptr_reg, |