authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-01 21:30:38+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-02 10:48:21+01:00
log9de30bb065a1562f14bd9473bebfdb7c70792121
treef3d870ce07f012b22ba39feb8ff2a5cd1deedc8a
parent09e69c8c776d21be5441a0b15f13a3ce9608ab87

x86_64: handle struct_field_ptr for register mcv


2 files changed, 39 insertions(+), 10 deletions(-)

src/arch/x86_64/CodeGen.zig+38-10
...@@ -812,7 +812,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -812,7 +812,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
812 const stack_mcv = try self.allocRegOrMem(inst, false);812 const stack_mcv = try self.allocRegOrMem(inst, false);
813 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });813 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });
814 const reg_mcv = self.getResolvedInstValue(inst);814 const reg_mcv = self.getResolvedInstValue(inst);
815 assert(reg == reg_mcv.register.to64());815 assert(reg.to64() == reg_mcv.register.to64());
816 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];816 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
817 try branch.inst_table.put(self.gpa, inst, stack_mcv);817 try branch.inst_table.put(self.gpa, inst, stack_mcv);
818 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);818 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
...@@ -1791,22 +1791,50 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -1791,22 +1791,50 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
1791}1791}
17921792
1793fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {1793fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
1794 return if (self.liveness.isUnused(inst)) .dead else result: {1794 if (self.liveness.isUnused(inst)) {
1795 const mcv = try self.resolveInst(operand);1795 return MCValue.dead;
1796 const struct_ty = self.air.typeOf(operand).childType();1796 }
1797 const struct_size = @intCast(i32, struct_ty.abiSize(self.target.*));1797 const mcv = try self.resolveInst(operand);
1798 const struct_field_offset = @intCast(i32, struct_ty.structFieldOffset(index, self.target.*));1798 const struct_ty = self.air.typeOf(operand).childType();
1799 const struct_field_ty = struct_ty.structFieldType(index);1799 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
1800 const struct_field_size = @intCast(i32, struct_field_ty.abiSize(self.target.*));1800 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
18011801 const struct_field_ty = struct_ty.structFieldType(index);
1802 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
1803 const offset_to_field = struct_size - struct_field_offset - struct_field_size;
1804
1805 const dst_mcv: MCValue = result: {
1802 switch (mcv) {1806 switch (mcv) {
1803 .ptr_stack_offset => |off| {1807 .ptr_stack_offset => |off| {
1804 const ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size;1808 const ptr_stack_offset = off + @intCast(i32, offset_to_field);
1805 break :result MCValue{ .ptr_stack_offset = ptr_stack_offset };1809 break :result MCValue{ .ptr_stack_offset = ptr_stack_offset };
1806 },1810 },
1811 .register => |reg| {
1812 const offset_reg = try self.copyToTmpRegister(Type.usize, .{
1813 .immediate = offset_to_field,
1814 });
1815 self.register_manager.freezeRegs(&.{offset_reg});
1816 defer self.register_manager.unfreezeRegs(&.{offset_reg});
1817
1818 const can_reuse_operand = self.reuseOperand(inst, operand, 0, mcv);
1819 const result_reg = blk: {
1820 if (can_reuse_operand) {
1821 break :blk reg;
1822 } else {
1823 self.register_manager.freezeRegs(&.{reg});
1824 const result_reg = try self.register_manager.allocReg(inst, &.{});
1825 try self.genSetReg(Type.usize, result_reg, mcv);
1826 break :blk result_reg;
1827 }
1828 };
1829 defer if (!can_reuse_operand) self.register_manager.unfreezeRegs(&.{reg});
1830
1831 try self.genBinMathOpMir(.add, Type.usize, .{ .register = result_reg }, .{ .register = offset_reg });
1832 break :result MCValue{ .register = result_reg };
1833 },
1807 else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}),1834 else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}),
1808 }1835 }
1809 };1836 };
1837 return dst_mcv;
1810}1838}
18111839
1812fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {1840fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
src/link/Elf.zig+1
...@@ -2367,6 +2367,7 @@ fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void {...@@ -2367,6 +2367,7 @@ fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void {
2367}2367}
23682368
2369fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym {2369fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym {
2370 log.debug("updateDeclCode {s}{*}", .{ mem.sliceTo(decl.name, 0), decl });
2370 const required_alignment = decl.ty.abiAlignment(self.base.options.target);2371 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
23712372
2372 const block_list = self.getDeclBlockList(decl);2373 const block_list = self.getDeclBlockList(decl);