authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2022-10-06 15:29:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-14 15:22:00-04:00
loge4e1c21e1fa599c1f243cad9236c88676023f6a8
tree76bfda7044428f77ad0758f9d1765158676b9581
parentc8da03a0e18661375ad72b66fbcfe6a84e303205

i386 ABI: Fix some sizes and alignments

This makes the following changes for i386: long long and unsigned long long have 4 byte alignment on non-Windows f64 (double) has 4-byte alignment on non-Windows long double is 80 bits and has 4 byte alignment on mingw long double on android is 64 bits, not 80: https://www.uclibc.org/docs/psABI-i386.pdf Fixes #12453 Fixes #12987

3 files changed, 51 insertions(+), 8 deletions(-)

lib/std/target.zig+1-1
...@@ -1761,7 +1761,7 @@ pub const Target = struct {...@@ -1761,7 +1761,7 @@ pub const Target = struct {
1761 }1761 }
17621762
1763 pub inline fn longDoubleIs(target: Target, comptime F: type) bool {1763 pub inline fn longDoubleIs(target: Target, comptime F: type) bool {
1764 if (target.abi == .msvc) {1764 if (target.abi == .msvc or (target.abi == .android and target.cpu.arch == .i386)) {
1765 return F == f64;1765 return F == f64;
1766 }1766 }
1767 return switch (F) {1767 return switch (F) {
src/type.zig+47-7
...@@ -2892,12 +2892,30 @@ pub const Type = extern union {...@@ -2892,12 +2892,30 @@ pub const Type = extern union {
2892 .c_uint => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },2892 .c_uint => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
2893 .c_long => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },2893 .c_long => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
2894 .c_ulong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },2894 .c_ulong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2895 .c_longlong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },2895 .c_longlong => switch (target.cpu.arch) {
2896 .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },2896 .i386 => switch (target.os.tag) {
2897 .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
2898 else => return AbiAlignmentAdvanced{ .scalar = 4 },
2899 },
2900 else => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2901 },
2902 .c_ulonglong => switch (target.cpu.arch) {
2903 .i386 => switch (target.os.tag) {
2904 .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
2905 else => return AbiAlignmentAdvanced{ .scalar = 4 },
2906 },
2907 else => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
2908 },
28972909
2898 .f16 => return AbiAlignmentAdvanced{ .scalar = 2 },2910 .f16 => return AbiAlignmentAdvanced{ .scalar = 2 },
2899 .f32 => return AbiAlignmentAdvanced{ .scalar = 4 },2911 .f32 => return AbiAlignmentAdvanced{ .scalar = 4 },
2900 .f64 => return AbiAlignmentAdvanced{ .scalar = 8 },2912 .f64 => switch (target.cpu.arch) {
2913 .i386 => switch (target.os.tag) {
2914 .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
2915 else => return AbiAlignmentAdvanced{ .scalar = 4 },
2916 },
2917 else => return AbiAlignmentAdvanced{ .scalar = 8 },
2918 },
2901 .f128 => return AbiAlignmentAdvanced{ .scalar = 16 },2919 .f128 => return AbiAlignmentAdvanced{ .scalar = 16 },
29022920
2903 .f80 => switch (target.cpu.arch) {2921 .f80 => switch (target.cpu.arch) {
...@@ -2916,7 +2934,10 @@ pub const Type = extern union {...@@ -2916,7 +2934,10 @@ pub const Type = extern union {
2916 16 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f16, target) },2934 16 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f16, target) },
2917 32 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f32, target) },2935 32 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f32, target) },
2918 64 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f64, target) },2936 64 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f64, target) },
2919 80 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f80, target) },2937 80 => if (target.cpu.arch == .i386 and target.isMinGW())
2938 return AbiAlignmentAdvanced{ .scalar = 4 }
2939 else
2940 return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f80, target) },
2920 128 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f128, target) },2941 128 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f128, target) },
2921 else => unreachable,2942 else => unreachable,
2922 },2943 },
...@@ -6637,7 +6658,11 @@ pub const CType = enum {...@@ -6637,7 +6658,11 @@ pub const CType = enum {
6637 .long, .ulong => return target.cpu.arch.ptrBitWidth(),6658 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
6638 .longlong, .ulonglong => return 64,6659 .longlong, .ulonglong => return 64,
6639 .longdouble => switch (target.cpu.arch) {6660 .longdouble => switch (target.cpu.arch) {
6640 .i386, .x86_64 => return 80,6661 .i386 => switch (target.abi) {
6662 .android => return 64,
6663 else => return 80,
6664 },
6665 .x86_64 => return 80,
66416666
6642 .riscv64,6667 .riscv64,
6643 .aarch64,6668 .aarch64,
...@@ -6687,7 +6712,11 @@ pub const CType = enum {...@@ -6687,7 +6712,11 @@ pub const CType = enum {
6687 .long, .ulong => return target.cpu.arch.ptrBitWidth(),6712 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
6688 .longlong, .ulonglong => return 64,6713 .longlong, .ulonglong => return 64,
6689 .longdouble => switch (target.cpu.arch) {6714 .longdouble => switch (target.cpu.arch) {
6690 .i386, .x86_64 => return 80,6715 .i386 => switch (target.abi) {
6716 .android => return 64,
6717 else => return 80,
6718 },
6719 .x86_64 => return 80,
66916720
6692 .riscv64,6721 .riscv64,
6693 .aarch64,6722 .aarch64,
...@@ -6715,7 +6744,18 @@ pub const CType = enum {...@@ -6715,7 +6744,18 @@ pub const CType = enum {
6715 .windows, .uefi => switch (self) {6744 .windows, .uefi => switch (self) {
6716 .short, .ushort => return 16,6745 .short, .ushort => return 16,
6717 .int, .uint, .long, .ulong => return 32,6746 .int, .uint, .long, .ulong => return 32,
6718 .longlong, .ulonglong, .longdouble => return 64,6747 .longlong, .ulonglong => return 64,
6748 .longdouble => switch (target.cpu.arch) {
6749 .i386 => switch (target.abi) {
6750 .gnu => return 80,
6751 else => return 64,
6752 },
6753 .x86_64 => switch (target.abi) {
6754 .gnu => return 80,
6755 else => return 64,
6756 },
6757 else => return 64,
6758 },
6719 },6759 },
67206760
6721 .macos, .ios, .tvos, .watchos => switch (self) {6761 .macos, .ios, .tvos, .watchos => switch (self) {
test/standalone.zig+3
...@@ -53,6 +53,9 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -53,6 +53,9 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
53 if (builtin.cpu.arch.isAARCH64() and builtin.zig_backend == .stage2_llvm) {53 if (builtin.cpu.arch.isAARCH64() and builtin.zig_backend == .stage2_llvm) {
54 cases.addBuildFile("test/c_abi/build.zig", .{});54 cases.addBuildFile("test/c_abi/build.zig", .{});
55 }55 }
56 if (builtin.cpu.arch == .i386 and builtin.zig_backend == .stage2_llvm) {
57 cases.addBuildFile("test/c_abi/build.zig", .{});
58 }
56 // C ABI tests only pass for the Wasm target when using stage259 // C ABI tests only pass for the Wasm target when using stage2
57 cases.addBuildFile("test/c_abi/build_wasm.zig", .{60 cases.addBuildFile("test/c_abi/build_wasm.zig", .{
58 .requires_stage2 = true,61 .requires_stage2 = true,