aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-02-01 21:30:38 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-02-02 10:48:21 +0100
commit9de30bb065a1562f14bd9473bebfdb7c70792121 (patch)
treef3d870ce07f012b22ba39feb8ff2a5cd1deedc8a /src
parent09e69c8c776d21be5441a0b15f13a3ce9608ab87 (diff)
downloadzig-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.zig48
-rw-r--r--src/link/Elf.zig1
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);