| ... | ... | @@ -1795,7 +1795,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 1795 | 1795 | return MCValue.dead; |
| 1796 | 1796 | } |
| 1797 | 1797 | const mcv = try self.resolveInst(operand); |
| 1798 | | const struct_ty = self.air.typeOf(operand).childType(); |
| 1798 | const ptr_ty = self.air.typeOf(operand); |
| 1799 | const struct_ty = ptr_ty.childType(); |
| 1799 | 1800 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| 1800 | 1801 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| 1801 | 1802 | const struct_field_ty = struct_ty.structFieldType(index); |
| ... | ... | @@ -1804,12 +1805,23 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 1804 | 1805 | |
| 1805 | 1806 | const dst_mcv: MCValue = result: { |
| 1806 | 1807 | switch (mcv) { |
| 1808 | .stack_offset => { |
| 1809 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 1810 | .immediate = offset_to_field, |
| 1811 | }); |
| 1812 | self.register_manager.freezeRegs(&.{offset_reg}); |
| 1813 | defer self.register_manager.unfreezeRegs(&.{offset_reg}); |
| 1814 | |
| 1815 | const dst_mcv = try self.copyToNewRegister(inst, ptr_ty, mcv); |
| 1816 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| 1817 | break :result dst_mcv; |
| 1818 | }, |
| 1807 | 1819 | .ptr_stack_offset => |off| { |
| 1808 | 1820 | const ptr_stack_offset = off + @intCast(i32, offset_to_field); |
| 1809 | 1821 | break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; |
| 1810 | 1822 | }, |
| 1811 | 1823 | .register => |reg| { |
| 1812 | | const offset_reg = try self.copyToTmpRegister(Type.usize, .{ |
| 1824 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 1813 | 1825 | .immediate = offset_to_field, |
| 1814 | 1826 | }); |
| 1815 | 1827 | self.register_manager.freezeRegs(&.{offset_reg}); |
| ... | ... | @@ -1822,13 +1834,13 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 1822 | 1834 | } else { |
| 1823 | 1835 | self.register_manager.freezeRegs(&.{reg}); |
| 1824 | 1836 | const result_reg = try self.register_manager.allocReg(inst, &.{}); |
| 1825 | | try self.genSetReg(Type.usize, result_reg, mcv); |
| 1837 | try self.genSetReg(ptr_ty, result_reg, mcv); |
| 1826 | 1838 | break :blk result_reg; |
| 1827 | 1839 | } |
| 1828 | 1840 | }; |
| 1829 | 1841 | defer if (!can_reuse_operand) self.register_manager.unfreezeRegs(&.{reg}); |
| 1830 | 1842 | |
| 1831 | | try self.genBinMathOpMir(.add, Type.usize, .{ .register = result_reg }, .{ .register = offset_reg }); |
| 1843 | try self.genBinMathOpMir(.add, ptr_ty, .{ .register = result_reg }, .{ .register = offset_reg }); |
| 1832 | 1844 | break :result MCValue{ .register = result_reg }; |
| 1833 | 1845 | }, |
| 1834 | 1846 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), |