diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-06-07 22:47:08 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-06-07 22:47:08 -0700 |
| commit | 53c86febcbeee858e9c6536c54adf99ee644147e (patch) | |
| tree | 4d2ab07845f46e98dce59c6fea920f02444d339b /src | |
| parent | 3e30ba3f20dce2d406253de3fc0eb86934a3eaa7 (diff) | |
| download | zig-53c86febcbeee858e9c6536c54adf99ee644147e.tar.gz zig-53c86febcbeee858e9c6536c54adf99ee644147e.zip | |
stage2: packed struct fixes for big-endian targets
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 11 | ||||
| -rw-r--r-- | src/type.zig | 7 |
2 files changed, 13 insertions, 5 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 0cf449991d..8ce9226bd4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -18708,11 +18708,18 @@ fn structFieldPtrByIndex( // If the field happens to be byte-aligned, simplify the pointer type. // The pointee type bit size must match its ABI byte size so that loads and stores // do not interfere with the surrounding packed bits. - if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0) { - const byte_offset = ptr_ty_data.bit_offset / 8; + // We do not attempt this with big-endian targets yet because of nested + // structs and floats. I need to double-check the desired behavior for big endian + // targets before adding the necessary complications to this code. This will not + // cause miscompilations; it only means the field pointer uses bit masking when it + // might not be strictly necessary. + if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and + target.cpu.arch.endian() == .Little) + { const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(target); const elem_size_bits = ptr_ty_data.pointee_type.bitSize(target); if (elem_size_bytes * 8 == elem_size_bits) { + const byte_offset = ptr_ty_data.bit_offset / 8; const new_align = @as(u32, 1) << @intCast(u5, @ctz(u64, byte_offset | parent_align)); ptr_ty_data.bit_offset = 0; ptr_ty_data.host_size = 0; diff --git a/src/type.zig b/src/type.zig index 8e5eaf0ec7..b6f8db4ca1 100644 --- a/src/type.zig +++ b/src/type.zig @@ -5597,17 +5597,18 @@ pub const Type = extern union { comptime assert(Type.packed_struct_layout_version == 2); var bit_offset: u16 = undefined; + var elem_size_bits: u16 = undefined; var running_bits: u16 = 0; for (struct_obj.fields.values()) |f, i| { if (!f.ty.hasRuntimeBits()) continue; + const field_bits = @intCast(u16, f.ty.bitSize(target)); if (i == field_index) { bit_offset = running_bits; + elem_size_bits = field_bits; } - running_bits += @intCast(u16, f.ty.bitSize(target)); + running_bits += field_bits; } - const host_size = (running_bits + 7) / 8; - _ = host_size; // TODO big-endian const byte_offset = bit_offset / 8; return byte_offset; } |
