From 614c8077027767063f399d3dbb5d478deebf37c3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 24 Jun 2023 22:51:29 -0400 Subject: x86_64: fix packed store crash --- test/behavior/struct.zig | 1 - 1 file changed, 1 deletion(-) (limited to 'test/behavior/struct.zig') diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 95b2718efd..3210e0c112 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -530,7 +530,6 @@ test "packed struct fields are ordered from LSB to MSB" { test "implicit cast packed struct field to const ptr" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; -- cgit v1.2.3 From 5b742785100bb2662f6fc0ee11ac84b2fed9be9e Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 25 Jun 2023 00:43:18 -0400 Subject: x86_64: fix global pointers to packed struct fields --- src/codegen.zig | 20 ++++++++++++++++---- test/behavior/packed-struct.zig | 2 -- test/behavior/struct.zig | 1 - 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'test/behavior/struct.zig') diff --git a/src/codegen.zig b/src/codegen.zig index 9e5ae11a63..1718201e6c 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -684,10 +684,22 @@ fn lowerParentPtr( .struct_type, .anon_struct_type, .union_type, - => @as(u32, @intCast(base_type.toType().structFieldOffset( - @as(u32, @intCast(field.index)), - mod, - ))), + => switch (base_type.toType().containerLayout(mod)) { + .Auto, .Extern => @intCast(base_type.toType().structFieldOffset( + @intCast(field.index), + mod, + )), + .Packed => if (mod.typeToStruct(base_type.toType())) |struct_obj| + math.divExact(u16, struct_obj.packedFieldBitOffset( + mod, + @intCast(field.index), + ), 8) catch |err| switch (err) { + error.UnexpectedRemainder => 0, + error.DivisionByZero => unreachable, + } + else + 0, + }, else => unreachable, }), ); diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 12cc027ef4..e2970c3603 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -376,7 +376,6 @@ test "load pointer from packed struct" { } test "@intFromPtr on a packed struct field" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -608,7 +607,6 @@ test "pointer to container level packed struct field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 3210e0c112..b3160cb2d3 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1077,7 +1077,6 @@ test "packed struct with undefined initializers" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; -- cgit v1.2.3 From b4b1ad475be4d4b6331ae56481c3b99d60cf0039 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 24 Jun 2023 23:32:55 -0400 Subject: x86_64: truncate packed field value --- src/arch/x86_64/CodeGen.zig | 25 +++++++++++++++++++++++-- test/behavior/struct.zig | 1 - 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'test/behavior/struct.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7b5f47a777..48de9f6363 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5616,9 +5616,31 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { switch (src_mcv) { .load_frame => |frame_addr| { + const field_abi_size: u32 = @intCast(field_ty.abiSize(mod)); if (field_off % 8 == 0) { const off_mcv = - src_mcv.address().offset(@as(i32, @intCast(@divExact(field_off, 8)))).deref(); + src_mcv.address().offset(@intCast(@divExact(field_off, 8))).deref(); + + if (field_abi_size <= 8) { + const int_ty = try mod.intType( + if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, + @intCast(field_ty.bitSize(mod)), + ); + + const dst_reg = + try self.register_manager.allocReg(if (field_is_gp) inst else null, gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + try self.genCopy(int_ty, dst_mcv, off_mcv); + if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg); + break :result if (field_is_gp) + dst_mcv + else + try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); + } + if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv; const dst_mcv = try self.allocRegOrMem(inst, true); @@ -5626,7 +5648,6 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { break :result dst_mcv; } - const field_abi_size = @as(u32, @intCast(field_ty.abiSize(mod))); const limb_abi_size: u32 = @min(field_abi_size, 8); const limb_abi_bits = limb_abi_size * 8; const field_byte_off = @as(i32, @intCast(field_off / limb_abi_bits * limb_abi_size)); diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index b3160cb2d3..76a99fa0ec 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -426,7 +426,6 @@ test "packed struct 24bits" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO -- cgit v1.2.3