authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-16 01:55:41+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-16 12:23:47+02:00
log897df18573c951b49fb6421a9e1b711cabfeda67
treee365e821f2c0b7f9e678e767671ce14dee885b54
parent1b5a43fdf71e596247ce0f730206c597b425be3e

stage2: fix @mulAdd on aarch64 Darwin

According to Apple docs, 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. Thus, we need to take this into account when using the compiler intrinsics so that we select the correct function version for FloatMulAdd.

4 files changed, 30 insertions(+), 17 deletions(-)

lib/std/target.zig+10-1
......@@ -1718,8 +1718,17 @@ pub const Target = struct {
17181718 }
17191719 return switch (F) {
17201720 f128 => switch (target.cpu.arch) {
1721 .aarch64 => {
1722 // According to Apple's official guide:
1723 // > The long double type is a double precision IEEE754 binary floating-point type,
1724 // > which makes it identical to the double type. This behavior contrasts to the
1725 // > standard specification, in which a long double is a quad-precision, IEEE754
1726 // > binary, floating-point type.
1727 // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
1728 return !target.isDarwin();
1729 },
1730
17211731 .riscv64,
1722 .aarch64,
17231732 .aarch64_be,
17241733 .aarch64_32,
17251734 .s390x,
src/stage1/target.cpp+9-1
......@@ -1008,8 +1008,16 @@ bool target_long_double_is_f128(const ZigTarget *target) {
10081008 return false;
10091009 }
10101010 switch (target->arch) {
1011 case ZigLLVM_riscv64:
10121011 case ZigLLVM_aarch64:
1012 // According to Apple's official guide:
1013 // > The long double type is a double precision IEEE754 binary floating-point type,
1014 // > which makes it identical to the double type. This behavior contrasts to the
1015 // > standard specification, in which a long double is a quad-precision, IEEE754
1016 // > binary, floating-point type.
1017 // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
1018 return !target_os_is_darwin(target->os);
1019
1020 case ZigLLVM_riscv64:
10131021 case ZigLLVM_aarch64_be:
10141022 case ZigLLVM_aarch64_32:
10151023 case ZigLLVM_systemz:
src/type.zig+1-2
......@@ -6155,7 +6155,6 @@ pub const CType = enum {
61556155 },
61566156
61576157 .linux,
6158 .macos,
61596158 .freebsd,
61606159 .netbsd,
61616160 .dragonfly,
......@@ -6198,7 +6197,7 @@ pub const CType = enum {
61986197 .longlong, .ulonglong, .longdouble => return 64,
61996198 },
62006199
6201 .ios, .tvos, .watchos => switch (self) {
6200 .macos, .ios, .tvos, .watchos => switch (self) {
62026201 .short, .ushort => return 16,
62036202 .int, .uint => return 32,
62046203 .long, .ulong, .longlong, .ulonglong => return 64,
test/behavior/cast.zig+10-13
......@@ -79,19 +79,16 @@ test "comptime_int @intToFloat" {
7979 try expect(result == 1234.0);
8080 }
8181
82 if (!((builtin.zig_backend == .stage2_aarch64 or builtin.zig_backend == .stage2_x86_64) and builtin.os.tag == .macos)) {
83 // TODO investigate why this traps on x86_64-macos and aarch64-macos
84 {
85 const result = @intToFloat(f128, 1234);
86 try expect(@TypeOf(result) == f128);
87 try expect(result == 1234.0);
88 }
89 // big comptime_int (> 64 bits) to f128 conversion
90 {
91 const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
92 try expect(@TypeOf(result) == f128);
93 try expect(result == 0x1_0000_0000_0000_0000.0);
94 }
82 {
83 const result = @intToFloat(f128, 1234);
84 try expect(@TypeOf(result) == f128);
85 try expect(result == 1234.0);
86 }
87 // big comptime_int (> 64 bits) to f128 conversion
88 {
89 const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
90 try expect(@TypeOf(result) == f128);
91 try expect(result == 0x1_0000_0000_0000_0000.0);
9592 }
9693}
9794