| ... | ... | @@ -5616,9 +5616,31 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5616 | 5616 | |
| 5617 | 5617 | switch (src_mcv) { |
| 5618 | 5618 | .load_frame => |frame_addr| { |
| 5619 | const field_abi_size: u32 = @intCast(field_ty.abiSize(mod)); |
| 5619 | 5620 | if (field_off % 8 == 0) { |
| 5620 | 5621 | const off_mcv = |
| 5621 | | src_mcv.address().offset(@as(i32, @intCast(@divExact(field_off, 8)))).deref(); |
| 5622 | src_mcv.address().offset(@intCast(@divExact(field_off, 8))).deref(); |
| 5623 | |
| 5624 | if (field_abi_size <= 8) { |
| 5625 | const int_ty = try mod.intType( |
| 5626 | if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, |
| 5627 | @intCast(field_ty.bitSize(mod)), |
| 5628 | ); |
| 5629 | |
| 5630 | const dst_reg = |
| 5631 | try self.register_manager.allocReg(if (field_is_gp) inst else null, gp); |
| 5632 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 5633 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 5634 | defer self.register_manager.unlockReg(dst_lock); |
| 5635 | |
| 5636 | try self.genCopy(int_ty, dst_mcv, off_mcv); |
| 5637 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg); |
| 5638 | break :result if (field_is_gp) |
| 5639 | dst_mcv |
| 5640 | else |
| 5641 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 5642 | } |
| 5643 | |
| 5622 | 5644 | if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv; |
| 5623 | 5645 | |
| 5624 | 5646 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| ... | ... | @@ -5626,7 +5648,6 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5626 | 5648 | break :result dst_mcv; |
| 5627 | 5649 | } |
| 5628 | 5650 | |
| 5629 | | const field_abi_size = @as(u32, @intCast(field_ty.abiSize(mod))); |
| 5630 | 5651 | const limb_abi_size: u32 = @min(field_abi_size, 8); |
| 5631 | 5652 | const limb_abi_bits = limb_abi_size * 8; |
| 5632 | 5653 | const field_byte_off = @as(i32, @intCast(field_off / limb_abi_bits * limb_abi_size)); |