Commit ddbdb83c86
Changed files (2)
lib
std
src
lib/std/target.zig
@@ -1781,68 +1781,89 @@ pub const Target = struct {
}
pub inline fn longDoubleIs(target: Target, comptime F: type) bool {
- if (target.abi == .msvc or (target.abi == .android and target.cpu.arch == .i386)) {
- return F == f64;
- }
- return switch (F) {
- f128 => switch (target.cpu.arch) {
- .aarch64 => {
- // According to Apple's official guide:
- // > The long double type is a double precision IEEE754 binary floating-point type,
- // > which makes it identical to the double type. This behavior contrasts to the
- // > standard specification, in which a long double is a quad-precision, IEEE754
- // > binary, floating-point type.
- // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
- return !target.isDarwin();
+ switch (target.os.tag) {
+ .windows, .uefi => switch (target.abi) {
+ .gnu, .gnuilp32, .cygnus => switch (target.cpu.arch) {
+ .i386 => return F == f80,
+ .x86_64 => return F == f128,
+ else => return F == f64,
},
+ else => return F == f64,
+ },
+ else => {},
+ }
- .riscv64,
- .aarch64_be,
- .aarch64_32,
- .s390x,
- .mips64,
- .mips64el,
- .sparc,
- .sparc64,
- .sparcel,
- .powerpc,
- .powerpcle,
- .powerpc64,
- .powerpc64le,
- .wasm32,
- .wasm64,
- => true,
+ if (target.abi == .android and target.cpu.arch == .i386)
+ return F == f64;
- else => false,
+ switch (target.cpu.arch) {
+ .aarch64,
+ .aarch64_be,
+ .aarch64_32,
+ => switch (target.os.tag) {
+ // According to Apple's official guide:
+ // > The long double type is a double precision IEEE754 binary floating-point type,
+ // > which makes it identical to the double type. This behavior contrasts to the
+ // > standard specification, in which a long double is a quad-precision, IEEE754
+ // > binary, floating-point type.
+ // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
+ .ios, .macos, .watchos, .tvos => return F == f64,
+ .windows, .uefi => return F == f64,
+ else => return F == f128,
},
- f80 => switch (target.cpu.arch) {
- .x86_64, .i386 => true,
- else => false,
+
+ .i386 => return F == f80,
+ .x86_64 => return F == f80,
+
+ .mips64,
+ .mips64el,
+ => switch (target.os.tag) {
+ .freebsd => return F == f64,
+ else => return F == f128,
},
- f64 => switch (target.cpu.arch) {
- .aarch64 => target.isDarwin(),
- .x86_64,
- .i386,
- .riscv64,
- .aarch64_be,
- .aarch64_32,
- .s390x,
- .mips64,
- .mips64el,
- .sparc,
- .sparc64,
- .sparcel,
- .powerpc,
- .powerpcle,
- .powerpc64,
- .powerpc64le,
- => false,
+ .powerpc,
+ .powerpcle,
+ => switch (target.abi) {
+ .musl,
+ .musleabi,
+ .musleabihf,
+ .muslx32,
+ => return F == f64,
+ else => switch (target.os.tag) {
+ .freebsd, .netbsd, .openbsd => return F == f64,
+ else => return F == f128,
+ },
+ },
- else => true,
+ .powerpc64,
+ .powerpc64le,
+ => switch (target.abi) {
+ .musl,
+ .musleabi,
+ .musleabihf,
+ .muslx32,
+ => return F == f64,
+ else => switch (target.os.tag) {
+ .freebsd, .openbsd => return F == f64,
+ else => return F == f128,
+ },
},
- else => false,
- };
+
+ .riscv32,
+ .riscv64,
+ .s390x,
+ .sparc,
+ .sparc64,
+ .sparcel,
+ .wasm32,
+ .wasm64,
+ => return F == f128,
+
+ .avr, .tce, .tcele => return F == f32,
+
+ else => return F == f64,
+ }
}
pub inline fn maxIntAlignment(target: Target) u16 {
@@ -1872,7 +1893,7 @@ pub const Target = struct {
=> 8,
.i386 => return switch (target.os.tag) {
- .windows => 8,
+ .windows, .uefi => 8,
else => 4,
},
src/type.zig
@@ -2892,41 +2892,24 @@ pub const Type = extern union {
.anyframe_T,
=> return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
- .c_short => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
- .c_ushort => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
- .c_int => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
- .c_uint => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
- .c_long => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
- .c_ulong => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
- .c_longlong => switch (target.cpu.arch) {
- .i386 => switch (target.os.tag) {
- .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
- else => return AbiAlignmentAdvanced{ .scalar = 4 },
- },
- else => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
- },
- .c_ulonglong => switch (target.cpu.arch) {
- .i386 => switch (target.os.tag) {
- .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
- else => return AbiAlignmentAdvanced{ .scalar = 4 },
- },
- else => return AbiAlignmentAdvanced{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
- },
+ .c_short => return AbiAlignmentAdvanced{ .scalar = CType.short.alignment(target) },
+ .c_ushort => return AbiAlignmentAdvanced{ .scalar = CType.ushort.alignment(target) },
+ .c_int => return AbiAlignmentAdvanced{ .scalar = CType.int.alignment(target) },
+ .c_uint => return AbiAlignmentAdvanced{ .scalar = CType.uint.alignment(target) },
+ .c_long => return AbiAlignmentAdvanced{ .scalar = CType.long.alignment(target) },
+ .c_ulong => return AbiAlignmentAdvanced{ .scalar = CType.ulong.alignment(target) },
+ .c_longlong => return AbiAlignmentAdvanced{ .scalar = CType.longlong.alignment(target) },
+ .c_ulonglong => return AbiAlignmentAdvanced{ .scalar = CType.ulonglong.alignment(target) },
+ .c_longdouble => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
.f16 => return AbiAlignmentAdvanced{ .scalar = 2 },
- .f32 => return AbiAlignmentAdvanced{ .scalar = 4 },
- .f64 => switch (target.cpu.arch) {
- .i386 => switch (target.os.tag) {
- .windows, .uefi => return AbiAlignmentAdvanced{ .scalar = 8 },
- else => return AbiAlignmentAdvanced{ .scalar = 4 },
- },
+ .f32 => return AbiAlignmentAdvanced{ .scalar = CType.float.alignment(target) },
+ .f64 => switch (CType.double.sizeInBits(target)) {
+ 64 => return AbiAlignmentAdvanced{ .scalar = CType.double.alignment(target) },
else => return AbiAlignmentAdvanced{ .scalar = 8 },
},
- .f128 => return AbiAlignmentAdvanced{ .scalar = 16 },
-
- .f80 => switch (target.cpu.arch) {
- .i386 => return AbiAlignmentAdvanced{ .scalar = 4 },
- .x86_64 => return AbiAlignmentAdvanced{ .scalar = 16 },
+ .f80 => switch (CType.longdouble.sizeInBits(target)) {
+ 80 => return AbiAlignmentAdvanced{ .scalar = CType.longdouble.alignment(target) },
else => {
var payload: Payload.Bits = .{
.base = .{ .tag = .int_unsigned },
@@ -2936,17 +2919,7 @@ pub const Type = extern union {
return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, target) };
},
},
- .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
- 16 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f16, target) },
- 32 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f32, target) },
- 64 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f64, target) },
- 80 => if (target.cpu.arch == .i386 and target.isMinGW())
- return AbiAlignmentAdvanced{ .scalar = 4 }
- else
- return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f80, target) },
- 128 => return AbiAlignmentAdvanced{ .scalar = abiAlignment(Type.f128, target) },
- else => unreachable,
- },
+ .f128 => return AbiAlignmentAdvanced{ .scalar = 16 },
// TODO revisit this when we have the concept of the error tag type
.anyerror_void_error_union,
@@ -3411,16 +3384,8 @@ pub const Type = extern union {
.f32 => return AbiSizeAdvanced{ .scalar = 4 },
.f64 => return AbiSizeAdvanced{ .scalar = 8 },
.f128 => return AbiSizeAdvanced{ .scalar = 16 },
-
- .f80 => switch (target.cpu.arch) {
- .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 },
+ .f80 => switch (CType.longdouble.sizeInBits(target)) {
+ 80 => return AbiSizeAdvanced{ .scalar = std.mem.alignForward(10, CType.longdouble.alignment(target)) },
else => {
var payload: Payload.Bits = .{
.base = .{ .tag = .int_unsigned },
@@ -6654,45 +6619,80 @@ pub const CType = enum {
ulonglong,
longdouble,
+ // We don't have a `c_float`/`c_double` type in Zig, but these
+ // are useful for querying target-correct alignment and checking
+ // whether C's double is f64 or f32
+ float,
+ double,
+
pub fn sizeInBits(self: CType, target: Target) u16 {
switch (target.os.tag) {
.freestanding, .other => switch (target.cpu.arch) {
.msp430 => switch (self) {
.short, .ushort, .int, .uint => return 16,
- .long, .ulong => return 32,
- .longlong, .ulonglong, .longdouble => return 64,
+ .float, .long, .ulong => return 32,
+ .longlong, .ulonglong, .double, .longdouble => return 64,
},
.avr => switch (self) {
.short, .ushort, .int, .uint => return 16,
- .long, .ulong, .longdouble => return 32,
+ .long, .ulong, .float, .double, .longdouble => return 32,
.longlong, .ulonglong => return 64,
},
+ .tce, .tcele => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
+ .float, .double, .longdouble => return 32,
+ },
+ .mips64, .mips64el => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => return 128,
+ },
+ .x86_64 => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => switch (target.abi) {
+ .gnux32, .muslx32 => return 32,
+ else => return 64,
+ },
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => return 80,
+ },
else => switch (self) {
.short, .ushort => return 16,
- .int, .uint => return 32,
+ .int, .uint, .float => return 32,
.long, .ulong => return target.cpu.arch.ptrBitWidth(),
- .longlong, .ulonglong => return 64,
+ .longlong, .ulonglong, .double => return 64,
.longdouble => switch (target.cpu.arch) {
.i386 => switch (target.abi) {
.android => return 64,
else => return 80,
},
- .x86_64 => return 80,
+ .powerpc,
+ .powerpcle,
+ .powerpc64,
+ .powerpc64le,
+ => switch (target.abi) {
+ .musl,
+ .musleabi,
+ .musleabihf,
+ .muslx32,
+ => return 64,
+ else => return 128,
+ },
+
+ .riscv32,
.riscv64,
.aarch64,
.aarch64_be,
.aarch64_32,
.s390x,
- .mips64,
- .mips64el,
.sparc,
.sparc64,
.sparcel,
- .powerpc,
- .powerpcle,
- .powerpc64,
- .powerpc64le,
.wasm32,
.wasm64,
=> return 128,
@@ -6716,23 +6716,78 @@ pub const CType = enum {
.fuchsia,
.minix,
=> switch (target.cpu.arch) {
+ .msp430 => switch (self) {
+ .short, .ushort, .int, .uint => return 16,
+ .long, .ulong, .float => return 32,
+ .longlong, .ulonglong, .double, .longdouble => return 64,
+ },
.avr => switch (self) {
.short, .ushort, .int, .uint => return 16,
- .long, .ulong, .longdouble => return 32,
+ .long, .ulong, .float, .double, .longdouble => return 32,
.longlong, .ulonglong => return 64,
},
+ .tce, .tcele => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
+ .float, .double, .longdouble => return 32,
+ },
+ .mips64, .mips64el => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
+ },
+ .x86_64 => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => switch (target.abi) {
+ .gnux32, .muslx32 => return 32,
+ else => return 64,
+ },
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => return 80,
+ },
else => switch (self) {
.short, .ushort => return 16,
- .int, .uint => return 32,
+ .int, .uint, .float => return 32,
.long, .ulong => return target.cpu.arch.ptrBitWidth(),
- .longlong, .ulonglong => return 64,
+ .longlong, .ulonglong, .double => return 64,
.longdouble => switch (target.cpu.arch) {
.i386 => switch (target.abi) {
.android => return 64,
else => return 80,
},
- .x86_64 => return 80,
+ .powerpc,
+ .powerpcle,
+ => switch (target.abi) {
+ .musl,
+ .musleabi,
+ .musleabihf,
+ .muslx32,
+ => return 64,
+ else => switch (target.os.tag) {
+ .freebsd, .netbsd, .openbsd => return 64,
+ else => return 128,
+ },
+ },
+
+ .powerpc64,
+ .powerpc64le,
+ => switch (target.abi) {
+ .musl,
+ .musleabi,
+ .musleabihf,
+ .muslx32,
+ => return 64,
+ else => switch (target.os.tag) {
+ .freebsd, .openbsd => return 64,
+ else => return 128,
+ },
+ },
+
+ .riscv32,
.riscv64,
.aarch64,
.aarch64_be,
@@ -6743,10 +6798,6 @@ pub const CType = enum {
.sparc,
.sparc64,
.sparcel,
- .powerpc,
- .powerpcle,
- .powerpc64,
- .powerpc64le,
.wasm32,
.wasm64,
=> return 128,
@@ -6756,37 +6807,65 @@ pub const CType = enum {
},
},
- .windows, .uefi => switch (self) {
- .short, .ushort => return 16,
- .int, .uint, .long, .ulong => return 32,
- .longlong, .ulonglong => return 64,
- .longdouble => switch (target.cpu.arch) {
- .i386 => switch (target.abi) {
- .gnu => return 80,
+ .windows, .uefi => switch (target.cpu.arch) {
+ .i386 => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => return 32,
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => switch (target.abi) {
+ .gnu, .gnuilp32, .cygnus => return 80,
else => return 64,
},
- .x86_64 => switch (target.abi) {
- .gnu => return 80,
+ },
+ .x86_64 => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => switch (target.abi) {
+ .cygnus => return 64,
+ else => return 32,
+ },
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => switch (target.abi) {
+ .gnu, .gnuilp32, .cygnus => return 128,
else => return 64,
},
- else => return 64,
+ },
+ else => switch (self) {
+ .short, .ushort => return 16,
+ .int, .uint, .float => return 32,
+ .long, .ulong => return 32,
+ .longlong, .ulonglong, .double => return 64,
+ .longdouble => return 64,
},
},
.macos, .ios, .tvos, .watchos => switch (self) {
.short, .ushort => return 16,
- .int, .uint => return 32,
- .long, .ulong, .longlong, .ulonglong => return 64,
+ .int, .uint, .float => return 32,
+ .long, .ulong => switch (target.cpu.arch) {
+ .i386, .arm, .aarch64_32 => return 32,
+ .x86_64 => switch (target.abi) {
+ .gnux32, .muslx32 => return 32,
+ else => return 64,
+ },
+ else => return 64,
+ },
+ .longlong, .ulonglong, .double => return 64,
.longdouble => switch (target.cpu.arch) {
- .i386, .x86_64 => return 80,
+ .i386 => switch (target.abi) {
+ .android => return 64,
+ else => return 80,
+ },
+ .x86_64 => return 80,
else => return 64,
},
},
.amdhsa, .amdpal => switch (self) {
.short, .ushort => return 16,
- .int, .uint => return 32,
- .long, .ulong, .longlong, .ulonglong => return 64,
+ .int, .uint, .float => return 32,
+ .long, .ulong, .longlong, .ulonglong, .double => return 64,
.longdouble => return 128,
},
@@ -6814,4 +6893,114 @@ pub const CType = enum {
=> @panic("TODO specify the C integer and float type sizes for this OS"),
}
}
+
+ pub fn alignment(self: CType, target: Target) u16 {
+
+ // Overrides for unusual alignments
+ switch (target.cpu.arch) {
+ .avr => switch (self) {
+ .short, .ushort => return 2,
+ else => return 1,
+ },
+ .i386 => switch (target.os.tag) {
+ .windows, .uefi => switch (self) {
+ .longlong, .ulonglong, .double => return 8,
+ .longdouble => switch (target.abi) {
+ .gnu, .gnuilp32, .cygnus => return 4,
+ else => return 8,
+ },
+ else => {},
+ },
+ else => {},
+ },
+ else => {},
+ }
+
+ // Self-aligned, up to a maximum.
+ return @min(
+ std.math.ceilPowerOfTwoAssert(u16, (self.sizeInBits(target) + 7) / 8),
+ switch (target.cpu.arch) {
+ .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
+ .netbsd => switch (target.abi) {
+ .gnueabi,
+ .gnueabihf,
+ .eabi,
+ .eabihf,
+ .android,
+ .musleabi,
+ .musleabihf,
+ => 8,
+
+ else => @as(u16, 4),
+ },
+ .ios, .tvos, .watchos => 4,
+ else => 8,
+ },
+
+ .msp430,
+ .avr,
+ => 2,
+
+ .arc,
+ .csky,
+ .i386,
+ .xcore,
+ .dxil,
+ .loongarch32,
+ .tce,
+ .tcele,
+ .le32,
+ .amdil,
+ .hsail,
+ .spir,
+ .spirv32,
+ .kalimba,
+ .shave,
+ .renderscript32,
+ .ve,
+ .spu_2,
+ => 4,
+
+ .aarch64_32,
+ .amdgcn,
+ .amdil64,
+ .bpfel,
+ .bpfeb,
+ .hexagon,
+ .hsail64,
+ .loongarch64,
+ .m68k,
+ .mips,
+ .mipsel,
+ .sparc,
+ .sparcel,
+ .sparc64,
+ .lanai,
+ .le64,
+ .nvptx,
+ .nvptx64,
+ .r600,
+ .s390x,
+ .spir64,
+ .spirv64,
+ .renderscript64,
+ => 8,
+
+ .aarch64,
+ .aarch64_be,
+ .mips64,
+ .mips64el,
+ .powerpc,
+ .powerpcle,
+ .powerpc64,
+ .powerpc64le,
+ .riscv32,
+ .riscv64,
+ .x86_64,
+ .wasm32,
+ .wasm64,
+ => 16,
+ },
+ );
+ }
};