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