| ... | @@ -5133,74 +5133,114 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5133,74 +5133,114 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5133 | const mod = self.bin_file.options.module.?; | 5133 | const mod = self.bin_file.options.module.?; |
| 5134 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5134 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5135 | | 5135 | |
| 5136 | const array_ty = self.typeOf(bin_op.lhs); | 5136 | const result: MCValue = result: { |
| 5137 | const array = try self.resolveInst(bin_op.lhs); | 5137 | const array_ty = self.typeOf(bin_op.lhs); |
| 5138 | const array_lock: ?RegisterLock = switch (array) { | 5138 | const elem_ty = array_ty.childType(mod); |
| 5139 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | | |
| 5140 | else => null, | | |
| 5141 | }; | | |
| 5142 | defer if (array_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 5143 | | 5139 | |
| 5144 | const elem_ty = array_ty.childType(mod); | 5140 | const array_mcv = try self.resolveInst(bin_op.lhs); |
| 5145 | const elem_abi_size = elem_ty.abiSize(mod); | 5141 | const array_lock: ?RegisterLock = switch (array_mcv) { |
| | 5142 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| | 5143 | else => null, |
| | 5144 | }; |
| | 5145 | defer if (array_lock) |lock| self.register_manager.unlockReg(lock); |
| 5146 | | 5146 | |
| 5147 | const index_ty = self.typeOf(bin_op.rhs); | 5147 | const index_ty = self.typeOf(bin_op.rhs); |
| 5148 | const index = try self.resolveInst(bin_op.rhs); | 5148 | const index_mcv = try self.resolveInst(bin_op.rhs); |
| 5149 | const index_lock: ?RegisterLock = switch (index) { | 5149 | const index_lock: ?RegisterLock = switch (index_mcv) { |
| 5150 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 5150 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 5151 | else => null, | 5151 | else => null, |
| 5152 | }; | 5152 | }; |
| 5153 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); | 5153 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); |
| 5154 | | 5154 | |
| 5155 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 5155 | try self.spillEflagsIfOccupied(); |
| 5156 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 5156 | if (array_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) { |
| 5157 | defer self.register_manager.unlockReg(addr_lock); | 5157 | const index_reg = switch (index_mcv) { |
| | 5158 | .register => |reg| reg, |
| | 5159 | else => try self.copyToTmpRegister(index_ty, index_mcv), |
| | 5160 | }; |
| | 5161 | switch (array_mcv) { |
| | 5162 | .register => |array_reg| try self.asmRegisterRegister( |
| | 5163 | .{ ._, .bt }, |
| | 5164 | array_reg.to64(), |
| | 5165 | index_reg.to64(), |
| | 5166 | ), |
| | 5167 | .load_frame => try self.asmMemoryRegister( |
| | 5168 | .{ ._, .bt }, |
| | 5169 | try array_mcv.mem(self, .qword), |
| | 5170 | index_reg.to64(), |
| | 5171 | ), |
| | 5172 | .memory, .load_symbol, .load_direct, .load_got, .load_tlv => try self.asmMemoryRegister( |
| | 5173 | .{ ._, .bt }, |
| | 5174 | .{ |
| | 5175 | .base = .{ |
| | 5176 | .reg = try self.copyToTmpRegister(Type.usize, array_mcv.address()), |
| | 5177 | }, |
| | 5178 | .mod = .{ .rm = .{ .size = .qword } }, |
| | 5179 | }, |
| | 5180 | index_reg.to64(), |
| | 5181 | ), |
| | 5182 | else => return self.fail("TODO airArrayElemVal for {s} of {}", .{ |
| | 5183 | @tagName(array_mcv), array_ty.fmt(mod), |
| | 5184 | }), |
| | 5185 | } |
| 5158 | | 5186 | |
| 5159 | switch (array) { | 5187 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); |
| 5160 | .register => { | 5188 | try self.asmSetccRegister(.c, dst_reg.to8()); |
| 5161 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); | 5189 | break :result .{ .register = dst_reg }; |
| 5162 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array); | 5190 | } |
| 5163 | try self.asmRegisterMemory( | 5191 | |
| | 5192 | const elem_abi_size = elem_ty.abiSize(mod); |
| | 5193 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| | 5194 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| | 5195 | defer self.register_manager.unlockReg(addr_lock); |
| | 5196 | |
| | 5197 | switch (array_mcv) { |
| | 5198 | .register => { |
| | 5199 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); |
| | 5200 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); |
| | 5201 | try self.asmRegisterMemory( |
| | 5202 | .{ ._, .lea }, |
| | 5203 | addr_reg, |
| | 5204 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| | 5205 | ); |
| | 5206 | }, |
| | 5207 | .load_frame => |frame_addr| try self.asmRegisterMemory( |
| 5164 | .{ ._, .lea }, | 5208 | .{ ._, .lea }, |
| 5165 | addr_reg, | 5209 | addr_reg, |
| 5166 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, | 5210 | .{ |
| 5167 | ); | 5211 | .base = .{ .frame = frame_addr.index }, |
| 5168 | }, | 5212 | .mod = .{ .rm = .{ .size = .qword, .disp = frame_addr.off } }, |
| 5169 | .load_frame => |frame_addr| try self.asmRegisterMemory( | 5213 | }, |
| 5170 | .{ ._, .lea }, | 5214 | ), |
| 5171 | addr_reg, | 5215 | .memory, |
| 5172 | .{ | 5216 | .load_symbol, |
| 5173 | .base = .{ .frame = frame_addr.index }, | 5217 | .load_direct, |
| 5174 | .mod = .{ .rm = .{ .size = .qword, .disp = frame_addr.off } }, | 5218 | .load_got, |
| 5175 | }, | 5219 | .load_tlv, |
| 5176 | ), | 5220 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address()), |
| 5177 | .memory, | 5221 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, |
| 5178 | .load_symbol, | 5222 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ |
| 5179 | .load_direct, | 5223 | @tagName(array_mcv), array_ty.fmt(mod), |
| 5180 | .load_got, | 5224 | }), |
| 5181 | .load_tlv, | 5225 | } |
| 5182 | => try self.genSetReg(addr_reg, Type.usize, array.address()), | | |
| 5183 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, | | |
| 5184 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), | | |
| 5185 | } | | |
| 5186 | | | |
| 5187 | const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); | | |
| 5188 | const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | | |
| 5189 | defer self.register_manager.unlockReg(offset_lock); | | |
| 5190 | | 5226 | |
| 5191 | // TODO we could allocate register here, but need to expect addr register and potentially | 5227 | const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); |
| 5192 | // offset register. | 5228 | const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 5193 | try self.spillEflagsIfOccupied(); | 5229 | defer self.register_manager.unlockReg(offset_lock); |
| 5194 | const dst_mcv = try self.allocRegOrMem(inst, false); | | |
| 5195 | try self.genBinOpMir( | | |
| 5196 | .{ ._, .add }, | | |
| 5197 | Type.usize, | | |
| 5198 | .{ .register = addr_reg }, | | |
| 5199 | .{ .register = offset_reg }, | | |
| 5200 | ); | | |
| 5201 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); | | |
| 5202 | | 5230 | |
| 5203 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); | 5231 | // TODO we could allocate register here, but need to expect addr register and potentially |
| | 5232 | // offset register. |
| | 5233 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| | 5234 | try self.genBinOpMir( |
| | 5235 | .{ ._, .add }, |
| | 5236 | Type.usize, |
| | 5237 | .{ .register = addr_reg }, |
| | 5238 | .{ .register = offset_reg }, |
| | 5239 | ); |
| | 5240 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); |
| | 5241 | break :result dst_mcv; |
| | 5242 | }; |
| | 5243 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5204 | } | 5244 | } |
| 5205 | | 5245 | |
| 5206 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | 5246 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -5258,32 +5298,44 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5258,32 +5298,44 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5258 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5298 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5259 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 5299 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 5260 | | 5300 | |
| 5261 | const ptr_ty = self.typeOf(extra.lhs); | 5301 | const result = result: { |
| 5262 | const ptr = try self.resolveInst(extra.lhs); | 5302 | const elem_ptr_ty = self.typeOfIndex(inst); |
| 5263 | const ptr_lock: ?RegisterLock = switch (ptr) { | 5303 | const base_ptr_ty = self.typeOf(extra.lhs); |
| 5264 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | | |
| 5265 | else => null, | | |
| 5266 | }; | | |
| 5267 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 5268 | | 5304 | |
| 5269 | const elem_ty = ptr_ty.elemType2(mod); | 5305 | const base_ptr_mcv = try self.resolveInst(extra.lhs); |
| 5270 | const elem_abi_size = elem_ty.abiSize(mod); | 5306 | const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) { |
| 5271 | const index_ty = self.typeOf(extra.rhs); | 5307 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 5272 | const index = try self.resolveInst(extra.rhs); | 5308 | else => null, |
| 5273 | const index_lock: ?RegisterLock = switch (index) { | 5309 | }; |
| 5274 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 5310 | defer if (base_ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 5275 | else => null, | | |
| 5276 | }; | | |
| 5277 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 5278 | | 5311 | |
| 5279 | const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); | 5312 | if (elem_ptr_ty.ptrInfo(mod).flags.vector_index != .none) { |
| 5280 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | 5313 | break :result if (self.reuseOperand(inst, extra.lhs, 0, base_ptr_mcv)) |
| 5281 | defer self.register_manager.unlockReg(offset_reg_lock); | 5314 | base_ptr_mcv |
| | 5315 | else |
| | 5316 | try self.copyToRegisterWithInstTracking(inst, elem_ptr_ty, base_ptr_mcv); |
| | 5317 | } |
| 5282 | | 5318 | |
| 5283 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); | 5319 | const elem_ty = base_ptr_ty.elemType2(mod); |
| 5284 | try self.genBinOpMir(.{ ._, .add }, ptr_ty, dst_mcv, .{ .register = offset_reg }); | 5320 | const elem_abi_size = elem_ty.abiSize(mod); |
| | 5321 | const index_ty = self.typeOf(extra.rhs); |
| | 5322 | const index_mcv = try self.resolveInst(extra.rhs); |
| | 5323 | const index_lock: ?RegisterLock = switch (index_mcv) { |
| | 5324 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| | 5325 | else => null, |
| | 5326 | }; |
| | 5327 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); |
| 5285 | | 5328 | |
| 5286 | return self.finishAir(inst, dst_mcv, .{ extra.lhs, extra.rhs, .none }); | 5329 | const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); |
| | 5330 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| | 5331 | defer self.register_manager.unlockReg(offset_reg_lock); |
| | 5332 | |
| | 5333 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, elem_ptr_ty, base_ptr_mcv); |
| | 5334 | try self.genBinOpMir(.{ ._, .add }, elem_ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| | 5335 | |
| | 5336 | break :result dst_mcv; |
| | 5337 | }; |
| | 5338 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 5287 | } | 5339 | } |
| 5288 | | 5340 | |
| 5289 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | 5341 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -6712,19 +6764,20 @@ fn reuseOperandAdvanced( | ... | @@ -6712,19 +6764,20 @@ fn reuseOperandAdvanced( |
| 6712 | | 6764 | |
| 6713 | fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { | 6765 | fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| 6714 | const mod = self.bin_file.options.module.?; | 6766 | const mod = self.bin_file.options.module.?; |
| 6715 | const ptr_info = ptr_ty.ptrInfo(mod); | | |
| 6716 | | 6767 | |
| | 6768 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 6717 | const val_ty = Type.fromInterned(ptr_info.child); | 6769 | const val_ty = Type.fromInterned(ptr_info.child); |
| 6718 | if (!val_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 6770 | if (!val_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| 6719 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); | 6771 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); |
| 6720 | | 6772 | |
| 6721 | if (ptr_info.packed_offset.bit_offset % 8 == 0) { | 6773 | const val_bit_size: u32 = @intCast(val_ty.bitSize(mod)); |
| 6722 | try self.load( | 6774 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 6723 | dst_mcv, | 6775 | .none => 0, |
| 6724 | ptr_ty, | 6776 | .runtime => unreachable, |
| 6725 | ptr_mcv.offset(@intCast(@divExact(ptr_info.packed_offset.bit_offset, 8))), | 6777 | else => |vector_index| @intFromEnum(vector_index) * val_bit_size, |
| 6726 | ); | 6778 | }; |
| 6727 | const val_bit_size: u32 = @intCast(val_ty.bitSize(mod)); | 6779 | if (ptr_bit_off % 8 == 0) { |
| | 6780 | try self.load(dst_mcv, ptr_ty, ptr_mcv.offset(@intCast(@divExact(ptr_bit_off, 8)))); |
| 6728 | if (val_abi_size * 8 > val_bit_size) { | 6781 | if (val_abi_size * 8 > val_bit_size) { |
| 6729 | if (dst_mcv.isRegister()) { | 6782 | if (dst_mcv.isRegister()) { |
| 6730 | try self.truncateRegister(val_ty, dst_mcv.getReg().?); | 6783 | try self.truncateRegister(val_ty, dst_mcv.getReg().?); |
| ... | @@ -6746,9 +6799,8 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -6746,9 +6799,8 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 6746 | | 6799 | |
| 6747 | const limb_abi_size: u32 = @min(val_abi_size, 8); | 6800 | const limb_abi_size: u32 = @min(val_abi_size, 8); |
| 6748 | const limb_abi_bits = limb_abi_size * 8; | 6801 | const limb_abi_bits = limb_abi_size * 8; |
| 6749 | const val_byte_off: i32 = | 6802 | const val_byte_off: i32 = @intCast(ptr_bit_off / limb_abi_bits * limb_abi_size); |
| 6750 | @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size); | 6803 | const val_bit_off = ptr_bit_off % limb_abi_bits; |
| 6751 | const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits; | | |
| 6752 | const val_extra_bits = self.regExtraBits(val_ty); | 6804 | const val_extra_bits = self.regExtraBits(val_ty); |
| 6753 | | 6805 | |
| 6754 | const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv); | 6806 | const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv); |
| ... | @@ -6875,7 +6927,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6875,7 +6927,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 6875 | else | 6927 | else |
| 6876 | try self.allocRegOrMem(inst, true); | 6928 | try self.allocRegOrMem(inst, true); |
| 6877 | | 6929 | |
| 6878 | if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) { | 6930 | const ptr_info = ptr_ty.ptrInfo(mod); |
| | 6931 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { |
| 6879 | try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv); | 6932 | try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv); |
| 6880 | } else { | 6933 | } else { |
| 6881 | try self.load(dst_mcv, ptr_ty, ptr_mcv); | 6934 | try self.load(dst_mcv, ptr_ty, ptr_mcv); |
| ... | @@ -6909,7 +6962,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6909,7 +6962,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 6909 | fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 6962 | fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 6910 | const mod = self.bin_file.options.module.?; | 6963 | const mod = self.bin_file.options.module.?; |
| 6911 | const ptr_info = ptr_ty.ptrInfo(mod); | 6964 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 6912 | const src_ty = ptr_ty.childType(mod); | 6965 | const src_ty = Type.fromInterned(ptr_info.child); |
| 6913 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 6966 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| 6914 | | 6967 | |
| 6915 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); | 6968 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); |
| ... | @@ -6917,8 +6970,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -6917,8 +6970,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 6917 | const limb_ty = try mod.intType(.unsigned, limb_abi_bits); | 6970 | const limb_ty = try mod.intType(.unsigned, limb_abi_bits); |
| 6918 | | 6971 | |
| 6919 | const src_bit_size = src_ty.bitSize(mod); | 6972 | const src_bit_size = src_ty.bitSize(mod); |
| 6920 | const src_byte_off: i32 = @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size); | 6973 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 6921 | const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits; | 6974 | .none => 0, |
| | 6975 | .runtime => unreachable, |
| | 6976 | else => |vector_index| @intFromEnum(vector_index) * src_bit_size, |
| | 6977 | }; |
| | 6978 | const src_byte_off: i32 = @intCast(ptr_bit_off / limb_abi_bits * limb_abi_size); |
| | 6979 | const src_bit_off = ptr_bit_off % limb_abi_bits; |
| 6922 | | 6980 | |
| 6923 | const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv); | 6981 | const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv); |
| 6924 | const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg); | 6982 | const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg); |
| ... | @@ -7055,11 +7113,14 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -7055,11 +7113,14 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 7055 | const ptr_mcv = try self.resolveInst(bin_op.lhs); | 7113 | const ptr_mcv = try self.resolveInst(bin_op.lhs); |
| 7056 | const ptr_ty = self.typeOf(bin_op.lhs); | 7114 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 7057 | const src_mcv = try self.resolveInst(bin_op.rhs); | 7115 | const src_mcv = try self.resolveInst(bin_op.rhs); |
| 7058 | if (ptr_ty.ptrInfo(mod).packed_offset.host_size > 0) { | 7116 | |
| | 7117 | const ptr_info = ptr_ty.ptrInfo(mod); |
| | 7118 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { |
| 7059 | try self.packedStore(ptr_ty, ptr_mcv, src_mcv); | 7119 | try self.packedStore(ptr_ty, ptr_mcv, src_mcv); |
| 7060 | } else { | 7120 | } else { |
| 7061 | try self.store(ptr_ty, ptr_mcv, src_mcv); | 7121 | try self.store(ptr_ty, ptr_mcv, src_mcv); |
| 7062 | } | 7122 | } |
| | 7123 | |
| 7063 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 7124 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 7064 | } | 7125 | } |
| 7065 | | 7126 | |
| ... | @@ -12777,7 +12838,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo | ... | @@ -12777,7 +12838,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 12777 | else => { | 12838 | else => { |
| 12778 | const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none); | 12839 | const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none); |
| 12779 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ | 12840 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ |
| 12780 | .integer, .sse, .float, .float_combine, | 12841 | .integer, .sse, .memory, .float, .float_combine, |
| 12781 | }) == null); | 12842 | }) == null); |
| 12782 | const abi_size = ty.abiSize(mod); | 12843 | const abi_size = ty.abiSize(mod); |
| 12783 | if (abi_size < 4 or | 12844 | if (abi_size < 4 or |