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 {
17611761 }
17621762
17631763 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)) {
17651765 return F == f64;
17661766 }
17671767 return switch (F) {
src/type.zig+47-7
......@@ -2892,12 +2892,30 @@ pub const Type = extern union {
28922892 .c_uint => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
28932893 .c_long => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
28942894 .c_ulong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2895 .c_longlong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2896 .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
2895 .c_longlong => switch (target.cpu.arch) {
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
28982910 .f16 => return AbiAlignmentAdvanced{ .scalar = 2 },
28992911 .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 },
29012919 .f128 => return AbiAlignmentAdvanced{ .scalar = 16 },
29022920
29032921 .f80 => switch (target.cpu.arch) {
......@@ -2916,7 +2934,10 @@ pub const Type = extern union {
29162934 16 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f16, target) },
29172935 32 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f32, target) },
29182936 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) },
29202941 128 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f128, target) },
29212942 else => unreachable,
29222943 },
......@@ -6637,7 +6658,11 @@ pub const CType = enum {
66376658 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
66386659 .longlong, .ulonglong => return 64,
66396660 .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
66426667 .riscv64,
66436668 .aarch64,
......@@ -6687,7 +6712,11 @@ pub const CType = enum {
66876712 .long, .ulong => return target.cpu.arch.ptrBitWidth(),
66886713 .longlong, .ulonglong => return 64,
66896714 .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
66926721 .riscv64,
66936722 .aarch64,
......@@ -6715,7 +6744,18 @@ pub const CType = enum {
67156744 .windows, .uefi => switch (self) {
67166745 .short, .ushort => return 16,
67176746 .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 },
67196759 },
67206760
67216761 .macos, .ios, .tvos, .watchos => switch (self) {
test/standalone.zig+3
......@@ -53,6 +53,9 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
5353 if (builtin.cpu.arch.isAARCH64() and builtin.zig_backend == .stage2_llvm) {
5454 cases.addBuildFile("test/c_abi/build.zig", .{});
5555 }
56 if (builtin.cpu.arch == .i386 and builtin.zig_backend == .stage2_llvm) {
57 cases.addBuildFile("test/c_abi/build.zig", .{});
58 }
5659 // C ABI tests only pass for the Wasm target when using stage2
5760 cases.addBuildFile("test/c_abi/build_wasm.zig", .{
5861 .requires_stage2 = true,