| author | |
| committer | |
| log | 8f385e77caae676ad675ca13baea51751230f200 |
| tree | 9f38a6d1a62a72d990021765520f631e85a97a99 |
| parent | 0cfc0d0d13bd1e9f1a9119324fac624371aecdd3 |
6 files changed, 26 insertions(+), 33 deletions(-)
src/arch/x86_64/CodeGen.zig+26-21| ... | ... | @@ -3745,18 +3745,22 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3745 | 3745 | } |
| 3746 | 3746 | |
| 3747 | 3747 | const mcv = try self.resolveInst(operand); |
| 3748 | const struct_ty = self.air.typeOf(operand); | |
| 3749 | if (struct_ty.zigTypeTag() == .Struct and struct_ty.containerLayout() == .Packed) { | |
| 3750 | return self.fail("TODO airStructFieldVal implement packed structs", .{}); | |
| 3751 | } | |
| 3752 | const struct_field_offset = struct_ty.structFieldOffset(index, self.target.*); | |
| 3753 | const struct_field_ty = struct_ty.structFieldType(index); | |
| 3748 | const container_ty = self.air.typeOf(operand); | |
| 3749 | const field_ty = container_ty.structFieldType(index); | |
| 3750 | const field_bit_offset = switch (container_ty.containerLayout()) { | |
| 3751 | .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*) * 8), | |
| 3752 | .Packed => if (container_ty.castTag(.@"struct")) |struct_obj| | |
| 3753 | struct_obj.data.packedFieldBitOffset(self.target.*, index) | |
| 3754 | else | |
| 3755 | 0, | |
| 3756 | }; | |
| 3754 | 3757 | |
| 3755 | 3758 | const result: MCValue = result: { |
| 3756 | 3759 | switch (mcv) { |
| 3757 | 3760 | .stack_offset => |off| { |
| 3758 | const stack_offset = off - @intCast(i32, struct_field_offset); | |
| 3759 | break :result MCValue{ .stack_offset = stack_offset }; | |
| 3761 | const byte_offset = std.math.divExact(u32, field_bit_offset, 8) catch | |
| 3762 | return self.fail("TODO implement struct_field_val for a packed struct", .{}); | |
| 3763 | break :result MCValue{ .stack_offset = off - @intCast(i32, byte_offset) }; | |
| 3760 | 3764 | }, |
| 3761 | 3765 | .register => |reg| { |
| 3762 | 3766 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| ... | ... | @@ -3779,27 +3783,28 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3779 | 3783 | defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); |
| 3780 | 3784 | |
| 3781 | 3785 | // Shift by struct_field_offset. |
| 3782 | const shift = @intCast(u8, struct_field_offset * 8); | |
| 3783 | try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift }); | |
| 3786 | try self.genShiftBinOpMir( | |
| 3787 | .shr, | |
| 3788 | Type.usize, | |
| 3789 | dst_mcv.register, | |
| 3790 | .{ .immediate = field_bit_offset }, | |
| 3791 | ); | |
| 3784 | 3792 | |
| 3785 | // Mask with reg.bitSize() - struct_field_size | |
| 3786 | const max_reg_bit_width = Register.rax.bitSize(); | |
| 3787 | const mask_shift = @intCast(u6, (max_reg_bit_width - struct_field_ty.bitSize(self.target.*))); | |
| 3788 | const mask = (~@as(u64, 0)) >> mask_shift; | |
| 3793 | // Mask to field_bit_size bits | |
| 3794 | const field_bit_size = field_ty.bitSize(self.target.*); | |
| 3795 | const mask = ~@as(u64, 0) >> @intCast(u6, 64 - field_bit_size); | |
| 3789 | 3796 | |
| 3790 | 3797 | const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); |
| 3791 | 3798 | try self.genBinOpMir(.@"and", Type.usize, dst_mcv, .{ .register = tmp_reg }); |
| 3792 | 3799 | |
| 3793 | const signedness: std.builtin.Signedness = blk: { | |
| 3794 | if (struct_field_ty.zigTypeTag() != .Int) break :blk .unsigned; | |
| 3795 | break :blk struct_field_ty.intInfo(self.target.*).signedness; | |
| 3796 | }; | |
| 3797 | const field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); | |
| 3798 | if (signedness == .signed and field_size < 8) { | |
| 3800 | const signedness = | |
| 3801 | if (field_ty.isAbiInt()) field_ty.intInfo(self.target.*).signedness else .unsigned; | |
| 3802 | const field_byte_size = @intCast(u32, field_ty.abiSize(self.target.*)); | |
| 3803 | if (signedness == .signed and field_byte_size < 8) { | |
| 3799 | 3804 | try self.asmRegisterRegister( |
| 3800 | 3805 | .movsx, |
| 3801 | 3806 | dst_mcv.register, |
| 3802 | registerAlias(dst_mcv.register, field_size), | |
| 3807 | registerAlias(dst_mcv.register, field_byte_size), | |
| 3803 | 3808 | ); |
| 3804 | 3809 | } |
| 3805 | 3810 |
test/behavior/bitcast.zig-2| ... | ... | @@ -157,7 +157,6 @@ test "bitcast generates a temporary value" { |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | test "@bitCast packed structs at runtime and comptime" { |
| 160 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 161 | 160 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 162 | 161 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 163 | 162 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -215,7 +214,6 @@ test "@bitCast extern structs at runtime and comptime" { |
| 215 | 214 | } |
| 216 | 215 | |
| 217 | 216 | test "bitcast packed struct to integer and back" { |
| 218 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 219 | 217 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 220 | 218 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 221 | 219 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/bugs/9584.zig-1| ... | ... | @@ -44,7 +44,6 @@ pub fn b(x: *X) !void { |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | test { |
| 47 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 48 | 47 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 49 | 48 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 50 | 49 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/packed-struct.zig-4| ... | ... | @@ -254,7 +254,6 @@ test "regular in irregular packed struct" { |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | 256 | test "byte-aligned field pointer offsets" { |
| 257 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 258 | 257 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 259 | 258 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 260 | 259 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -397,7 +396,6 @@ test "@ptrToInt on a packed struct field" { |
| 397 | 396 | } |
| 398 | 397 | |
| 399 | 398 | test "optional pointer in packed struct" { |
| 400 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 401 | 399 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 402 | 400 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 403 | 401 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -530,7 +528,6 @@ test "nested packed struct field access test" { |
| 530 | 528 | test "runtime init of unnamed packed struct type" { |
| 531 | 529 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 532 | 530 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 533 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 534 | 531 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 535 | 532 | |
| 536 | 533 | var z: u8 = 123; |
| ... | ... | @@ -545,7 +542,6 @@ test "runtime init of unnamed packed struct type" { |
| 545 | 542 | test "packed struct passed to callconv(.C) function" { |
| 546 | 543 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 547 | 544 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 548 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 549 | 545 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 550 | 546 | |
| 551 | 547 | const S = struct { |
test/behavior/struct.zig-3| ... | ... | @@ -387,7 +387,6 @@ const APackedStruct = packed struct { |
| 387 | 387 | test "packed struct" { |
| 388 | 388 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 389 | 389 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 390 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 391 | 390 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 392 | 391 | |
| 393 | 392 | var foo = APackedStruct{ |
| ... | ... | @@ -496,7 +495,6 @@ const Bitfields = packed struct { |
| 496 | 495 | test "packed struct fields are ordered from LSB to MSB" { |
| 497 | 496 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 498 | 497 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 499 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 500 | 498 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 501 | 499 | |
| 502 | 500 | var all: u64 = 0x7765443322221111; |
| ... | ... | @@ -632,7 +630,6 @@ test "default struct initialization fields" { |
| 632 | 630 | } |
| 633 | 631 | |
| 634 | 632 | test "packed array 24bits" { |
| 635 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 636 | 633 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 637 | 634 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 638 | 635 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/union.zig-2| ... | ... | @@ -1408,7 +1408,6 @@ test "union field ptr - zero sized field" { |
| 1408 | 1408 | } |
| 1409 | 1409 | |
| 1410 | 1410 | test "packed union in packed struct" { |
| 1411 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1412 | 1411 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1413 | 1412 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1414 | 1413 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1494,7 +1493,6 @@ test "union reassignment can use previous value" { |
| 1494 | 1493 | } |
| 1495 | 1494 | |
| 1496 | 1495 | test "packed union with zero-bit field" { |
| 1497 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1498 | 1496 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1499 | 1497 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1500 | 1498 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |