| author | |
| committer | |
| log | 897df18573c951b49fb6421a9e1b711cabfeda67 |
| tree | e365e821f2c0b7f9e678e767671ce14dee885b54 |
| parent | 1b5a43fdf71e596247ce0f730206c597b425be3e |
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 { |
| 1718 | 1718 | } |
| 1719 | 1719 | return switch (F) { |
| 1720 | 1720 | 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 | ||
| 1721 | 1731 | .riscv64, |
| 1722 | .aarch64, | |
| 1723 | 1732 | .aarch64_be, |
| 1724 | 1733 | .aarch64_32, |
| 1725 | 1734 | .s390x, |
src/stage1/target.cpp+9-1| ... | ... | @@ -1008,8 +1008,16 @@ bool target_long_double_is_f128(const ZigTarget *target) { |
| 1008 | 1008 | return false; |
| 1009 | 1009 | } |
| 1010 | 1010 | switch (target->arch) { |
| 1011 | case ZigLLVM_riscv64: | |
| 1012 | 1011 | 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: | |
| 1013 | 1021 | case ZigLLVM_aarch64_be: |
| 1014 | 1022 | case ZigLLVM_aarch64_32: |
| 1015 | 1023 | case ZigLLVM_systemz: |
src/type.zig+1-2| ... | ... | @@ -6155,7 +6155,6 @@ pub const CType = enum { |
| 6155 | 6155 | }, |
| 6156 | 6156 | |
| 6157 | 6157 | .linux, |
| 6158 | .macos, | |
| 6159 | 6158 | .freebsd, |
| 6160 | 6159 | .netbsd, |
| 6161 | 6160 | .dragonfly, |
| ... | ... | @@ -6198,7 +6197,7 @@ pub const CType = enum { |
| 6198 | 6197 | .longlong, .ulonglong, .longdouble => return 64, |
| 6199 | 6198 | }, |
| 6200 | 6199 | |
| 6201 | .ios, .tvos, .watchos => switch (self) { | |
| 6200 | .macos, .ios, .tvos, .watchos => switch (self) { | |
| 6202 | 6201 | .short, .ushort => return 16, |
| 6203 | 6202 | .int, .uint => return 32, |
| 6204 | 6203 | .long, .ulong, .longlong, .ulonglong => return 64, |
test/behavior/cast.zig+10-13| ... | ... | @@ -79,19 +79,16 @@ test "comptime_int @intToFloat" { |
| 79 | 79 | try expect(result == 1234.0); |
| 80 | 80 | } |
| 81 | 81 | |
| 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); | |
| 95 | 92 | } |
| 96 | 93 | } |
| 97 | 94 |