| author | |
| committer | |
| log | e2b029e2c8ad761c32886d27aa0227655a60eb9e |
| tree | ab421b1e5222e7c887d2abcda490f7b3a5673293 |
| parent | 481bd4761ac9826336d13553e249989f509ba172 |
| signature | Commit is signed but in an unrecognized format. |
2 files changed, 18 insertions(+), 5 deletions(-)
src/arch/arm/CodeGen.zig+18-3| ... | @@ -2681,9 +2681,24 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2681,9 +2681,24 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2681 | 2681 | ||
| 2682 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | 2682 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2683 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 2683 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 2684 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2684 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 2685 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFieldParentPtr", .{}); | 2685 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2686 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 2686 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 2687 | const struct_ty = self.air.getRefType(ty_pl.ty).childType(); | ||
| 2688 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, self.target.*)); | ||
| 2689 | switch (field_ptr) { | ||
| 2690 | .ptr_stack_offset => |off| { | ||
| 2691 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; | ||
| 2692 | }, | ||
| 2693 | else => { | ||
| 2694 | const lhs_bind: ReadArg.Bind = .{ .mcv = field_ptr }; | ||
| 2695 | const rhs_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = struct_field_offset } }; | ||
| 2696 | |||
| 2697 | break :result try self.addSub(.sub, lhs_bind, rhs_bind, Type.usize, Type.usize, null); | ||
| 2698 | }, | ||
| 2699 | } | ||
| 2700 | }; | ||
| 2701 | return self.finishAir(inst, result, .{ extra.field_ptr, .none, .none }); | ||
| 2687 | } | 2702 | } |
| 2688 | 2703 | ||
| 2689 | /// An argument to a Mir instruction which is read (and possibly also | 2704 | /// An argument to a Mir instruction which is read (and possibly also |
test/behavior/field_parent_ptr.zig-2| ... | @@ -2,7 +2,6 @@ const expect = @import("std").testing.expect; | ... | @@ -2,7 +2,6 @@ const expect = @import("std").testing.expect; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | test "@fieldParentPtr non-first field" { | 4 | test "@fieldParentPtr non-first field" { |
| 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| ... | @@ -11,7 +10,6 @@ test "@fieldParentPtr non-first field" { | ... | @@ -11,7 +10,6 @@ test "@fieldParentPtr non-first field" { |
| 11 | } | 10 | } |
| 12 | 11 | ||
| 13 | test "@fieldParentPtr first field" { | 12 | test "@fieldParentPtr first field" { |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 13 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 16 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |