From e2b029e2c8ad761c32886d27aa0227655a60eb9e Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Fri, 26 Aug 2022 22:19:27 +0200 Subject: [PATCH] stage2 ARM: implement field_parent_ptr --- src/arch/arm/CodeGen.zig | 21 ++++++++++++++++++--- test/behavior/field_parent_ptr.zig | 2 -- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index bf378e24ce..c0a28f1f94 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -2681,9 +2681,24 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFieldParentPtr", .{}); - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); + const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const field_ptr = try self.resolveInst(extra.field_ptr); + const struct_ty = self.air.getRefType(ty_pl.ty).childType(); + const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, self.target.*)); + switch (field_ptr) { + .ptr_stack_offset => |off| { + break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; + }, + else => { + const lhs_bind: ReadArg.Bind = .{ .mcv = field_ptr }; + const rhs_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = struct_field_offset } }; + + break :result try self.addSub(.sub, lhs_bind, rhs_bind, Type.usize, Type.usize, null); + }, + } + }; + return self.finishAir(inst, result, .{ extra.field_ptr, .none, .none }); } /// An argument to a Mir instruction which is read (and possibly also diff --git a/test/behavior/field_parent_ptr.zig b/test/behavior/field_parent_ptr.zig index 3aefb0ef47..570a1f9522 100644 --- a/test/behavior/field_parent_ptr.zig +++ b/test/behavior/field_parent_ptr.zig @@ -2,7 +2,6 @@ const expect = @import("std").testing.expect; const builtin = @import("builtin"); test "@fieldParentPtr non-first field" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -11,7 +10,6 @@ test "@fieldParentPtr non-first field" { } test "@fieldParentPtr first field" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;