authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-25 03:08:04-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-25 16:23:55-04:00
log0cfc0d0d13bd1e9f1a9119324fac624371aecdd3
tree4872b9bb774328133d4c5ca64cd0742de08ac40e
parentd9ce69dc3949fb11c43520096001b7f06e1a96f3

x86_64: implement struct_field_ptr for packed containers


7 files changed, 15 insertions(+), 19 deletions(-)

src/arch/x86_64/CodeGen.zig+15-12
...@@ -3659,34 +3659,37 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void {...@@ -3659,34 +3659,37 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void {
3659fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {3659fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {
3660 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3660 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3661 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;3661 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
3662 const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index);3662 const result = try self.fieldPtr(inst, extra.struct_operand, extra.field_index);
3663 return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });3663 return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });
3664}3664}
36653665
3666fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {3666fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
3667 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3667 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3668 const result = try self.structFieldPtr(inst, ty_op.operand, index);3668 const result = try self.fieldPtr(inst, ty_op.operand, index);
3669 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3669 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3670}3670}
36713671
3672fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {3672fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
3673 if (self.liveness.isUnused(inst)) {3673 if (self.liveness.isUnused(inst)) {
3674 return MCValue.dead;3674 return MCValue.dead;
3675 }3675 }
36763676
3677 const mcv = try self.resolveInst(operand);3677 const mcv = try self.resolveInst(operand);
3678 const ptr_ty = self.air.typeOf(operand);3678 const ptr_ty = self.air.typeOf(operand);
3679 const struct_ty = ptr_ty.childType();3679 const container_ty = ptr_ty.childType();
3680 if (struct_ty.zigTypeTag() == .Struct and struct_ty.containerLayout() == .Packed) {3680 const field_offset = switch (container_ty.containerLayout()) {
3681 return self.fail("TODO structFieldPtr implement packed structs", .{});3681 .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*)),
3682 }3682 .Packed => if (container_ty.zigTypeTag() == .Struct and ptr_ty.ptrInfo().data.host_size == 0)
3683 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));3683 container_ty.packedStructFieldByteOffset(index, self.target.*)
3684 else
3685 0,
3686 };
36843687
3685 const dst_mcv: MCValue = result: {3688 const dst_mcv: MCValue = result: {
3686 switch (mcv) {3689 switch (mcv) {
3687 .stack_offset => {3690 .stack_offset => {
3688 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{3691 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
3689 .immediate = struct_field_offset,3692 .immediate = field_offset,
3690 });3693 });
3691 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);3694 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
3692 defer self.register_manager.unlockReg(offset_reg_lock);3695 defer self.register_manager.unlockReg(offset_reg_lock);
...@@ -3696,7 +3699,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3696,7 +3699,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
3696 break :result dst_mcv;3699 break :result dst_mcv;
3697 },3700 },
3698 .ptr_stack_offset => |off| {3701 .ptr_stack_offset => |off| {
3699 const ptr_stack_offset = off - @intCast(i32, struct_field_offset);3702 const ptr_stack_offset = off - @intCast(i32, field_offset);
3700 break :result MCValue{ .ptr_stack_offset = ptr_stack_offset };3703 break :result MCValue{ .ptr_stack_offset = ptr_stack_offset };
3701 },3704 },
3702 .register => |reg| {3705 .register => |reg| {
...@@ -3704,7 +3707,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3704,7 +3707,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
3704 defer self.register_manager.unlockReg(reg_lock);3707 defer self.register_manager.unlockReg(reg_lock);
37053708
3706 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{3709 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
3707 .immediate = struct_field_offset,3710 .immediate = field_offset,
3708 });3711 });
3709 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);3712 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
3710 defer self.register_manager.unlockReg(offset_reg_lock);3713 defer self.register_manager.unlockReg(offset_reg_lock);
...@@ -3725,7 +3728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3725,7 +3728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
3725 try self.genBinOpMir(.add, ptr_ty, .{ .register = result_reg }, .{ .register = offset_reg });3728 try self.genBinOpMir(.add, ptr_ty, .{ .register = result_reg }, .{ .register = offset_reg });
3726 break :result MCValue{ .register = result_reg };3729 break :result MCValue{ .register = result_reg };
3727 },3730 },
3728 else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}),3731 else => return self.fail("TODO implement fieldPtr for {}", .{mcv}),
3729 }3732 }
3730 };3733 };
3731 return dst_mcv;3734 return dst_mcv;
test/behavior/bugs/12450.zig-1
...@@ -10,7 +10,6 @@ var buffer: [256]u8 = undefined;...@@ -10,7 +10,6 @@ var buffer: [256]u8 = undefined;
1010
11test {11test {
12 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/bugs/2578.zig-1
...@@ -14,7 +14,6 @@ fn bar(pointer: ?*anyopaque) void {...@@ -14,7 +14,6 @@ fn bar(pointer: ?*anyopaque) void {
14test "fixed" {14test "fixed" {
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1918
20 bar(t);19 bar(t);
test/behavior/bugs/726.zig-2
...@@ -4,7 +4,6 @@ const builtin = @import("builtin");...@@ -4,7 +4,6 @@ const builtin = @import("builtin");
4test "@ptrCast from const to nullable" {4test "@ptrCast from const to nullable" {
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
98
10 const c: u8 = 4;9 const c: u8 = 4;
...@@ -15,7 +14,6 @@ test "@ptrCast from const to nullable" {...@@ -15,7 +14,6 @@ test "@ptrCast from const to nullable" {
15test "@ptrCast from var in empty struct to nullable" {14test "@ptrCast from var in empty struct to nullable" {
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2018
21 const container = struct {19 const container = struct {
test/behavior/fn.zig-1
...@@ -96,7 +96,6 @@ test "discard the result of a function that returns a struct" {...@@ -96,7 +96,6 @@ test "discard the result of a function that returns a struct" {
96}96}
9797
98test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {98test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {
99 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
101 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/packed-struct.zig-1
...@@ -571,7 +571,6 @@ test "packed struct passed to callconv(.C) function" {...@@ -571,7 +571,6 @@ test "packed struct passed to callconv(.C) function" {
571test "overaligned pointer to packed struct" {571test "overaligned pointer to packed struct" {
572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
573 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;573 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
574 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
575574
576 const S = packed struct { a: u32, b: u32 };575 const S = packed struct { a: u32, b: u32 };
577 var foo: S align(4) = .{ .a = 123, .b = 456 };576 var foo: S align(4) = .{ .a = 123, .b = 456 };
test/behavior/struct.zig-1
...@@ -827,7 +827,6 @@ test "non-packed struct with u128 entry in union" {...@@ -827,7 +827,6 @@ test "non-packed struct with u128 entry in union" {
827}827}
828828
829test "packed struct field passed to generic function" {829test "packed struct field passed to generic function" {
830 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
831 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO830 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
832 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO831 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
833 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO832 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO