mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
improved ABI alignment/size for >= 128-bit integers
* riscv64: adjust alignment and size of 128-bit integers. * take ofmt=c into account for ABI alignment of 128-bit integers and structs. * Type: make packed struct support intInfo * fix f80 alignment for i386-windows-msvc
This commit is contained in:
parent
b975f7a56f
commit
cee82c7ce4
@ -1808,20 +1808,23 @@ pub const Target = struct {
|
||||
// 1. Different machine code instruction when loading into SIMD register.
|
||||
// 2. The C ABI wants 16 for extern structs.
|
||||
// 3. 16-byte cmpxchg needs 16-byte alignment.
|
||||
// Same logic for riscv64, powerpc64, mips64, sparc64.
|
||||
// Same logic for powerpc64, mips64, sparc64.
|
||||
.x86_64,
|
||||
.riscv64,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.sparc64,
|
||||
=> 8,
|
||||
=> return switch (target.ofmt) {
|
||||
.c => 16,
|
||||
else => 8,
|
||||
},
|
||||
|
||||
// Even LLVMABIAlignmentOfType(i128) agrees on these targets.
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.aarch64_32,
|
||||
.riscv64,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.nvptx,
|
||||
|
||||
@ -948,21 +948,29 @@ pub const Struct = struct {
|
||||
|
||||
switch (layout) {
|
||||
.Packed => return 0,
|
||||
.Auto => return field.ty.abiAlignment(target),
|
||||
.Extern => {
|
||||
// This logic is duplicated in Type.abiAlignmentAdvanced.
|
||||
const ty_abi_align = field.ty.abiAlignment(target);
|
||||
|
||||
if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
|
||||
// The C ABI requires 128 bit integer fields of structs
|
||||
// to be 16-bytes aligned.
|
||||
return @maximum(ty_abi_align, 16);
|
||||
.Auto => {
|
||||
if (target.ofmt == .c) {
|
||||
return alignmentExtern(field, target);
|
||||
} else {
|
||||
return field.ty.abiAlignment(target);
|
||||
}
|
||||
|
||||
return ty_abi_align;
|
||||
},
|
||||
.Extern => return alignmentExtern(field, target),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alignmentExtern(field: Field, target: Target) u32 {
|
||||
// This logic is duplicated in Type.abiAlignmentAdvanced.
|
||||
const ty_abi_align = field.ty.abiAlignment(target);
|
||||
|
||||
if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
|
||||
// The C ABI requires 128 bit integer fields of structs
|
||||
// to be 16-bytes aligned.
|
||||
return @maximum(ty_abi_align, 16);
|
||||
}
|
||||
|
||||
return ty_abi_align;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn getFullyQualifiedName(s: *Struct, mod: *Module) ![:0]u8 {
|
||||
|
||||
16
src/type.zig
16
src/type.zig
@ -3019,7 +3019,7 @@ pub const Type = extern union {
|
||||
big_align = @maximum(big_align, field_align);
|
||||
|
||||
// This logic is duplicated in Module.Struct.Field.alignment.
|
||||
if (struct_obj.layout == .Extern) {
|
||||
if (struct_obj.layout == .Extern or target.ofmt == .c) {
|
||||
if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
|
||||
// The C ABI requires 128 bit integer fields of structs
|
||||
// to be 16-bytes aligned.
|
||||
@ -3348,7 +3348,13 @@ pub const Type = extern union {
|
||||
.f128 => return AbiSizeAdvanced{ .scalar = 16 },
|
||||
|
||||
.f80 => switch (target.cpu.arch) {
|
||||
.i386 => return AbiSizeAdvanced{ .scalar = 12 },
|
||||
.i386 => switch (target.os.tag) {
|
||||
.windows => switch (target.abi) {
|
||||
.msvc => return AbiSizeAdvanced{ .scalar = 16 },
|
||||
else => return AbiSizeAdvanced{ .scalar = 12 },
|
||||
},
|
||||
else => return AbiSizeAdvanced{ .scalar = 12 },
|
||||
},
|
||||
.x86_64 => return AbiSizeAdvanced{ .scalar = 16 },
|
||||
else => {
|
||||
var payload: Payload.Bits = .{
|
||||
@ -4559,6 +4565,12 @@ pub const Type = extern union {
|
||||
|
||||
.vector => ty = ty.castTag(.vector).?.data.elem_type,
|
||||
|
||||
.@"struct" => {
|
||||
const struct_obj = ty.castTag(.@"struct").?.data;
|
||||
assert(struct_obj.layout == .Packed);
|
||||
ty = struct_obj.backing_int_ty;
|
||||
},
|
||||
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
@ -100,8 +100,8 @@ test "alignment and size of structs with 128-bit fields" {
|
||||
.a_align = 8,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 8,
|
||||
.b_size = 24,
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 8,
|
||||
.u128_size = 16,
|
||||
@ -114,8 +114,8 @@ test "alignment and size of structs with 128-bit fields" {
|
||||
.a_align = 8,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 8,
|
||||
.b_size = 24,
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 8,
|
||||
.u128_size = 16,
|
||||
@ -126,8 +126,8 @@ test "alignment and size of structs with 128-bit fields" {
|
||||
.a_align = 4,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 4,
|
||||
.b_size = 20,
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 4,
|
||||
.u128_size = 16,
|
||||
@ -140,25 +140,39 @@ test "alignment and size of structs with 128-bit fields" {
|
||||
.mips64el,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.riscv64,
|
||||
.sparc64,
|
||||
.x86_64,
|
||||
=> .{
|
||||
.a_align = 8,
|
||||
.a_size = 16,
|
||||
=> switch (builtin.object_format) {
|
||||
.c => .{
|
||||
.a_align = 16,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 8,
|
||||
.u128_size = 16,
|
||||
.u129_align = 8,
|
||||
.u129_size = 24,
|
||||
.u128_align = 16,
|
||||
.u128_size = 16,
|
||||
.u129_align = 16,
|
||||
.u129_size = 32,
|
||||
},
|
||||
else => .{
|
||||
.a_align = 8,
|
||||
.a_size = 16,
|
||||
|
||||
.b_align = 16,
|
||||
.b_size = 32,
|
||||
|
||||
.u128_align = 8,
|
||||
.u128_size = 16,
|
||||
.u129_align = 8,
|
||||
.u129_size = 24,
|
||||
},
|
||||
},
|
||||
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.aarch64_32,
|
||||
.riscv64,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.nvptx,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user