| author | |
| committer | |
| log | 3a30b827414926dceccf606d6557e00f1cc6458d |
| tree | 7c824b5d6d1e09f3ae2becd3a3e2db6596528e68 |
| parent | 3f5592c114ffbc28e7ffb9e9e411870b31d81dd8 |
3 files changed, 22 insertions(+), 7 deletions(-)
src/arch/x86_64/CodeGen.zig+22-4| ... | @@ -233,6 +233,13 @@ pub const MCValue = union(enum) { | ... | @@ -233,6 +233,13 @@ pub const MCValue = union(enum) { |
| 233 | }; | 233 | }; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | fn isRegisterOffset(mcv: MCValue) bool { | ||
| 237 | return switch (mcv) { | ||
| 238 | .register, .register_offset => true, | ||
| 239 | else => false, | ||
| 240 | }; | ||
| 241 | } | ||
| 242 | |||
| 236 | fn getReg(mcv: MCValue) ?Register { | 243 | fn getReg(mcv: MCValue) ?Register { |
| 237 | return switch (mcv) { | 244 | return switch (mcv) { |
| 238 | .register => |reg| reg, | 245 | .register => |reg| reg, |
| ... | @@ -4772,10 +4779,21 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4772,10 +4779,21 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4772 | } | 4779 | } |
| 4773 | 4780 | ||
| 4774 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | 4781 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4775 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4782 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 4776 | _ = ty_op; | 4783 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 4777 | return self.fail("TODO implement airFieldParentPtr for {}", .{self.target.cpu.arch}); | 4784 | |
| 4778 | //return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4785 | const inst_ty = self.air.typeOfIndex(inst); |
| 4786 | const parent_ty = inst_ty.childType(); | ||
| 4787 | const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, self.target.*)); | ||
| 4788 | |||
| 4789 | const src_mcv = try self.resolveInst(extra.field_ptr); | ||
| 4790 | const dst_mcv = if (src_mcv.isRegisterOffset() and | ||
| 4791 | self.reuseOperand(inst, extra.field_ptr, 0, src_mcv)) | ||
| 4792 | src_mcv | ||
| 4793 | else | ||
| 4794 | try self.copyToRegisterWithInstTracking(inst, inst_ty, src_mcv); | ||
| 4795 | const result = dst_mcv.offset(-field_offset); | ||
| 4796 | return self.finishAir(inst, result, .{ extra.field_ptr, .none, .none }); | ||
| 4779 | } | 4797 | } |
| 4780 | 4798 | ||
| 4781 | fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { | 4799 | fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { |
test/behavior/struct.zig-1| ... | @@ -1333,7 +1333,6 @@ test "under-aligned struct field" { | ... | @@ -1333,7 +1333,6 @@ test "under-aligned struct field" { |
| 1333 | } | 1333 | } |
| 1334 | 1334 | ||
| 1335 | test "fieldParentPtr of a zero-bit field" { | 1335 | test "fieldParentPtr of a zero-bit field" { |
| 1336 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1337 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1338 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1337 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1339 | 1338 |
test/behavior/tuple.zig-2| ... | @@ -209,7 +209,6 @@ test "initializing anon struct with explicit type" { | ... | @@ -209,7 +209,6 @@ test "initializing anon struct with explicit type" { |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | test "fieldParentPtr of tuple" { | 211 | test "fieldParentPtr of tuple" { |
| 212 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 213 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 214 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 213 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 214 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -220,7 +219,6 @@ test "fieldParentPtr of tuple" { | ... | @@ -220,7 +219,6 @@ test "fieldParentPtr of tuple" { |
| 220 | } | 219 | } |
| 221 | 220 | ||
| 222 | test "fieldParentPtr of anon struct" { | 221 | test "fieldParentPtr of anon struct" { |
| 223 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 224 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 222 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 225 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 223 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 226 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 224 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |