| ... | @@ -5325,8 +5325,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5325,8 +5325,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5325 | const index = extra.field_index; | 5325 | const index = extra.field_index; |
| 5326 | | 5326 | |
| 5327 | const container_ty = self.air.typeOf(operand); | 5327 | const container_ty = self.air.typeOf(operand); |
| | 5328 | const container_rc = regClassForType(container_ty); |
| 5328 | const field_ty = container_ty.structFieldType(index); | 5329 | const field_ty = container_ty.structFieldType(index); |
| 5329 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; | 5330 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; |
| | 5331 | const field_rc = regClassForType(field_ty); |
| 5330 | | 5332 | |
| 5331 | const src_mcv = try self.resolveInst(operand); | 5333 | const src_mcv = try self.resolveInst(operand); |
| 5332 | const field_off = switch (container_ty.containerLayout()) { | 5334 | const field_off = switch (container_ty.containerLayout()) { |
| ... | @@ -5410,30 +5412,23 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5410,30 +5412,23 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5410 | if (field_extra_bits > 0) try self.truncateRegister(field_ty, dst_reg); | 5412 | if (field_extra_bits > 0) try self.truncateRegister(field_ty, dst_reg); |
| 5411 | | 5413 | |
| 5412 | const dst_mcv = MCValue{ .register = dst_reg }; | 5414 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 5413 | const dst_rc = regClassForType(field_ty); | 5415 | break :result if (field_rc.supersetOf(gp)) |
| 5414 | if (dst_rc.eql(gp)) break :result dst_mcv; | 5416 | dst_mcv |
| 5415 | | 5417 | else |
| 5416 | const result_reg = try self.register_manager.allocReg(inst, dst_rc); | 5418 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 5417 | try self.genSetReg(result_reg, field_ty, dst_mcv); | | |
| 5418 | break :result .{ .register = result_reg }; | | |
| 5419 | }, | 5419 | }, |
| 5420 | .register => |reg| { | 5420 | .register => |reg| { |
| 5421 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); | 5421 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 5422 | defer self.register_manager.unlockReg(reg_lock); | 5422 | defer self.register_manager.unlockReg(reg_lock); |
| 5423 | | 5423 | |
| 5424 | const dst_mcv = if (self.reuseOperand(inst, operand, 0, src_mcv)) | 5424 | const dst_reg = if (src_mcv.isRegister() and field_rc.supersetOf(container_rc) and |
| 5425 | src_mcv | 5425 | self.reuseOperand(inst, operand, 0, src_mcv)) |
| | 5426 | src_mcv.getReg().? |
| 5426 | else | 5427 | else |
| 5427 | try self.copyToRegisterWithInstTracking( | 5428 | try self.copyToTmpRegister(Type.usize, .{ .register = reg.to64() }); |
| 5428 | inst, | 5429 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 5429 | Type.usize, | 5430 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5430 | .{ .register = reg.to64() }, | 5431 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5431 | ); | | |
| 5432 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { | | |
| 5433 | .register => |a_reg| self.register_manager.lockReg(a_reg), | | |
| 5434 | else => null, | | |
| 5435 | }; | | |
| 5436 | defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 5437 | | 5432 | |
| 5438 | // Shift by struct_field_offset. | 5433 | // Shift by struct_field_offset. |
| 5439 | try self.genShiftBinOpMir( | 5434 | try self.genShiftBinOpMir( |
| ... | @@ -5460,7 +5455,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5460,7 +5455,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5460 | registerAlias(dst_mcv.register, field_byte_size), | 5455 | registerAlias(dst_mcv.register, field_byte_size), |
| 5461 | ); | 5456 | ); |
| 5462 | } | 5457 | } |
| 5463 | break :result dst_mcv; | 5458 | |
| | 5459 | break :result if (field_rc.supersetOf(gp)) |
| | 5460 | dst_mcv |
| | 5461 | else |
| | 5462 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 5464 | }, | 5463 | }, |
| 5465 | .register_overflow => |ro| { | 5464 | .register_overflow => |ro| { |
| 5466 | switch (index) { | 5465 | switch (index) { |