mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +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.
|
// 1. Different machine code instruction when loading into SIMD register.
|
||||||
// 2. The C ABI wants 16 for extern structs.
|
// 2. The C ABI wants 16 for extern structs.
|
||||||
// 3. 16-byte cmpxchg needs 16-byte alignment.
|
// 3. 16-byte cmpxchg needs 16-byte alignment.
|
||||||
// Same logic for riscv64, powerpc64, mips64, sparc64.
|
// Same logic for powerpc64, mips64, sparc64.
|
||||||
.x86_64,
|
.x86_64,
|
||||||
.riscv64,
|
|
||||||
.powerpc64,
|
.powerpc64,
|
||||||
.powerpc64le,
|
.powerpc64le,
|
||||||
.mips64,
|
.mips64,
|
||||||
.mips64el,
|
.mips64el,
|
||||||
.sparc64,
|
.sparc64,
|
||||||
=> 8,
|
=> return switch (target.ofmt) {
|
||||||
|
.c => 16,
|
||||||
|
else => 8,
|
||||||
|
},
|
||||||
|
|
||||||
// Even LLVMABIAlignmentOfType(i128) agrees on these targets.
|
// Even LLVMABIAlignmentOfType(i128) agrees on these targets.
|
||||||
.aarch64,
|
.aarch64,
|
||||||
.aarch64_be,
|
.aarch64_be,
|
||||||
.aarch64_32,
|
.aarch64_32,
|
||||||
|
.riscv64,
|
||||||
.bpfel,
|
.bpfel,
|
||||||
.bpfeb,
|
.bpfeb,
|
||||||
.nvptx,
|
.nvptx,
|
||||||
|
|||||||
@ -948,8 +948,18 @@ pub const Struct = struct {
|
|||||||
|
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
.Packed => return 0,
|
.Packed => return 0,
|
||||||
.Auto => return field.ty.abiAlignment(target),
|
.Auto => {
|
||||||
.Extern => {
|
if (target.ofmt == .c) {
|
||||||
|
return alignmentExtern(field, target);
|
||||||
|
} else {
|
||||||
|
return field.ty.abiAlignment(target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.Extern => return alignmentExtern(field, target),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alignmentExtern(field: Field, target: Target) u32 {
|
||||||
// This logic is duplicated in Type.abiAlignmentAdvanced.
|
// This logic is duplicated in Type.abiAlignmentAdvanced.
|
||||||
const ty_abi_align = field.ty.abiAlignment(target);
|
const ty_abi_align = field.ty.abiAlignment(target);
|
||||||
|
|
||||||
@ -960,8 +970,6 @@ pub const Struct = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ty_abi_align;
|
return ty_abi_align;
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
16
src/type.zig
16
src/type.zig
@ -3019,7 +3019,7 @@ pub const Type = extern union {
|
|||||||
big_align = @maximum(big_align, field_align);
|
big_align = @maximum(big_align, field_align);
|
||||||
|
|
||||||
// This logic is duplicated in Module.Struct.Field.alignment.
|
// 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) {
|
if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
|
||||||
// The C ABI requires 128 bit integer fields of structs
|
// The C ABI requires 128 bit integer fields of structs
|
||||||
// to be 16-bytes aligned.
|
// to be 16-bytes aligned.
|
||||||
@ -3348,7 +3348,13 @@ pub const Type = extern union {
|
|||||||
.f128 => return AbiSizeAdvanced{ .scalar = 16 },
|
.f128 => return AbiSizeAdvanced{ .scalar = 16 },
|
||||||
|
|
||||||
.f80 => switch (target.cpu.arch) {
|
.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 },
|
.x86_64 => return AbiSizeAdvanced{ .scalar = 16 },
|
||||||
else => {
|
else => {
|
||||||
var payload: Payload.Bits = .{
|
var payload: Payload.Bits = .{
|
||||||
@ -4559,6 +4565,12 @@ pub const Type = extern union {
|
|||||||
|
|
||||||
.vector => ty = ty.castTag(.vector).?.data.elem_type,
|
.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,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,8 +100,8 @@ test "alignment and size of structs with 128-bit fields" {
|
|||||||
.a_align = 8,
|
.a_align = 8,
|
||||||
.a_size = 16,
|
.a_size = 16,
|
||||||
|
|
||||||
.b_align = 8,
|
.b_align = 16,
|
||||||
.b_size = 24,
|
.b_size = 32,
|
||||||
|
|
||||||
.u128_align = 8,
|
.u128_align = 8,
|
||||||
.u128_size = 16,
|
.u128_size = 16,
|
||||||
@ -114,8 +114,8 @@ test "alignment and size of structs with 128-bit fields" {
|
|||||||
.a_align = 8,
|
.a_align = 8,
|
||||||
.a_size = 16,
|
.a_size = 16,
|
||||||
|
|
||||||
.b_align = 8,
|
.b_align = 16,
|
||||||
.b_size = 24,
|
.b_size = 32,
|
||||||
|
|
||||||
.u128_align = 8,
|
.u128_align = 8,
|
||||||
.u128_size = 16,
|
.u128_size = 16,
|
||||||
@ -126,8 +126,8 @@ test "alignment and size of structs with 128-bit fields" {
|
|||||||
.a_align = 4,
|
.a_align = 4,
|
||||||
.a_size = 16,
|
.a_size = 16,
|
||||||
|
|
||||||
.b_align = 4,
|
.b_align = 16,
|
||||||
.b_size = 20,
|
.b_size = 32,
|
||||||
|
|
||||||
.u128_align = 4,
|
.u128_align = 4,
|
||||||
.u128_size = 16,
|
.u128_size = 16,
|
||||||
@ -140,10 +140,22 @@ test "alignment and size of structs with 128-bit fields" {
|
|||||||
.mips64el,
|
.mips64el,
|
||||||
.powerpc64,
|
.powerpc64,
|
||||||
.powerpc64le,
|
.powerpc64le,
|
||||||
.riscv64,
|
|
||||||
.sparc64,
|
.sparc64,
|
||||||
.x86_64,
|
.x86_64,
|
||||||
=> .{
|
=> switch (builtin.object_format) {
|
||||||
|
.c => .{
|
||||||
|
.a_align = 16,
|
||||||
|
.a_size = 16,
|
||||||
|
|
||||||
|
.b_align = 16,
|
||||||
|
.b_size = 32,
|
||||||
|
|
||||||
|
.u128_align = 16,
|
||||||
|
.u128_size = 16,
|
||||||
|
.u129_align = 16,
|
||||||
|
.u129_size = 32,
|
||||||
|
},
|
||||||
|
else => .{
|
||||||
.a_align = 8,
|
.a_align = 8,
|
||||||
.a_size = 16,
|
.a_size = 16,
|
||||||
|
|
||||||
@ -155,10 +167,12 @@ test "alignment and size of structs with 128-bit fields" {
|
|||||||
.u129_align = 8,
|
.u129_align = 8,
|
||||||
.u129_size = 24,
|
.u129_size = 24,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
.aarch64,
|
.aarch64,
|
||||||
.aarch64_be,
|
.aarch64_be,
|
||||||
.aarch64_32,
|
.aarch64_32,
|
||||||
|
.riscv64,
|
||||||
.bpfel,
|
.bpfel,
|
||||||
.bpfeb,
|
.bpfeb,
|
||||||
.nvptx,
|
.nvptx,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user