| 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 | 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 | 243 | fn getReg(mcv: MCValue) ?Register { |
| 237 | 244 | return switch (mcv) { |
| 238 | 245 | .register => |reg| reg, |
| ... | ... | @@ -4772,10 +4779,21 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4772 | 4779 | } |
| 4773 | 4780 | |
| 4774 | 4781 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4775 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | |
| 4776 | _ = ty_op; | |
| 4777 | return self.fail("TODO implement airFieldParentPtr for {}", .{self.target.cpu.arch}); | |
| 4778 | //return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | |
| 4782 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | |
| 4783 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | |
| 4784 | ||
| 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 | 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 | 1333 | } |
| 1334 | 1334 | |
| 1335 | 1335 | test "fieldParentPtr of a zero-bit field" { |
| 1336 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1337 | 1336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1338 | 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 | 209 | } |
| 210 | 210 | |
| 211 | 211 | test "fieldParentPtr of tuple" { |
| 212 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 213 | 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 214 | 213 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 215 | 214 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -220,7 +219,6 @@ test "fieldParentPtr of tuple" { |
| 220 | 219 | } |
| 221 | 220 | |
| 222 | 221 | test "fieldParentPtr of anon struct" { |
| 223 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 224 | 222 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 225 | 223 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 226 | 224 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |