authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-01 21:45:39+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-02 10:48:21+01:00
log0cccd8a88762dde3995702020dd3c39771cf8fd4
treef0d09ce05c32ae4df61337ed401bc1c30ca86128
parent9de30bb065a1562f14bd9473bebfdb7c70792121

x86_64: handle struct_field_ptr for stack_offset mcv


1 files changed, 16 insertions(+), 4 deletions(-)

src/arch/x86_64/CodeGen.zig+16-4
......@@ -1795,7 +1795,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
17951795 return MCValue.dead;
17961796 }
17971797 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();
17991800 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
18001801 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
18011802 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
18041805
18051806 const dst_mcv: MCValue = result: {
18061807 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 },
18071819 .ptr_stack_offset => |off| {
18081820 const ptr_stack_offset = off + @intCast(i32, offset_to_field);
18091821 break :result MCValue{ .ptr_stack_offset = ptr_stack_offset };
18101822 },
18111823 .register => |reg| {
1812 const offset_reg = try self.copyToTmpRegister(Type.usize, .{
1824 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
18131825 .immediate = offset_to_field,
18141826 });
18151827 self.register_manager.freezeRegs(&.{offset_reg});
......@@ -1822,13 +1834,13 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
18221834 } else {
18231835 self.register_manager.freezeRegs(&.{reg});
18241836 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);
18261838 break :blk result_reg;
18271839 }
18281840 };
18291841 defer if (!can_reuse_operand) self.register_manager.unfreezeRegs(&.{reg});
18301842
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 });
18321844 break :result MCValue{ .register = result_reg };
18331845 },
18341846 else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}),