diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-01 21:30:38 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-02 10:48:21 +0100 |
| commit | 9de30bb065a1562f14bd9473bebfdb7c70792121 (patch) | |
| tree | f3d870ce07f012b22ba39feb8ff2a5cd1deedc8a /src | |
| parent | 09e69c8c776d21be5441a0b15f13a3ce9608ab87 (diff) | |
| download | zig-9de30bb065a1562f14bd9473bebfdb7c70792121.tar.gz zig-9de30bb065a1562f14bd9473bebfdb7c70792121.zip | |
x86_64: handle struct_field_ptr for register mcv
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 48 | ||||
| -rw-r--r-- | src/link/Elf.zig | 1 |
2 files changed, 39 insertions, 10 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 3a439ed71d..3ee5ec200f 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -812,7 +812,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void const stack_mcv = try self.allocRegOrMem(inst, false); log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv }); const reg_mcv = self.getResolvedInstValue(inst); - assert(reg == reg_mcv.register.to64()); + assert(reg.to64() == reg_mcv.register.to64()); const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; try branch.inst_table.put(self.gpa, inst, stack_mcv); 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 { } fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { - return if (self.liveness.isUnused(inst)) .dead else result: { - const mcv = try self.resolveInst(operand); - const struct_ty = self.air.typeOf(operand).childType(); - const struct_size = @intCast(i32, struct_ty.abiSize(self.target.*)); - const struct_field_offset = @intCast(i32, struct_ty.structFieldOffset(index, self.target.*)); - const struct_field_ty = struct_ty.structFieldType(index); - const struct_field_size = @intCast(i32, struct_field_ty.abiSize(self.target.*)); - + if (self.liveness.isUnused(inst)) { + return MCValue.dead; + } + const mcv = try self.resolveInst(operand); + const struct_ty = self.air.typeOf(operand).childType(); + const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); + const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); + const struct_field_ty = struct_ty.structFieldType(index); + const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); + const offset_to_field = struct_size - struct_field_offset - struct_field_size; + + const dst_mcv: MCValue = result: { switch (mcv) { .ptr_stack_offset => |off| { - const ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size; + const ptr_stack_offset = off + @intCast(i32, offset_to_field); break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; }, + .register => |reg| { + const offset_reg = try self.copyToTmpRegister(Type.usize, .{ + .immediate = offset_to_field, + }); + self.register_manager.freezeRegs(&.{offset_reg}); + defer self.register_manager.unfreezeRegs(&.{offset_reg}); + + const can_reuse_operand = self.reuseOperand(inst, operand, 0, mcv); + const result_reg = blk: { + if (can_reuse_operand) { + break :blk reg; + } else { + self.register_manager.freezeRegs(&.{reg}); + const result_reg = try self.register_manager.allocReg(inst, &.{}); + try self.genSetReg(Type.usize, result_reg, mcv); + break :blk result_reg; + } + }; + defer if (!can_reuse_operand) self.register_manager.unfreezeRegs(&.{reg}); + + try self.genBinMathOpMir(.add, Type.usize, .{ .register = result_reg }, .{ .register = offset_reg }); + break :result MCValue{ .register = result_reg }; + }, else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), } }; + return dst_mcv; } fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 71956cd5b3..d0773c44c8 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2367,6 +2367,7 @@ fn deinitRelocs(gpa: Allocator, table: *File.DbgInfoTypeRelocsTable) void { } fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym { + log.debug("updateDeclCode {s}{*}", .{ mem.sliceTo(decl.name, 0), decl }); const required_alignment = decl.ty.abiAlignment(self.base.options.target); const block_list = self.getDeclBlockList(decl); |
