aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-06-07 22:47:08 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-06-07 22:47:08 -0700
commit53c86febcbeee858e9c6536c54adf99ee644147e (patch)
tree4d2ab07845f46e98dce59c6fea920f02444d339b /src
parent3e30ba3f20dce2d406253de3fc0eb86934a3eaa7 (diff)
downloadzig-53c86febcbeee858e9c6536c54adf99ee644147e.tar.gz
zig-53c86febcbeee858e9c6536c54adf99ee644147e.zip
stage2: packed struct fixes for big-endian targets
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig11
-rw-r--r--src/type.zig7
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;
}