diff --git a/src/stage1/softfloat.hpp b/src/stage1/softfloat.hpp index ec0315d684..a0d270d55f 100644 --- a/src/stage1/softfloat.hpp +++ b/src/stage1/softfloat.hpp @@ -57,7 +57,7 @@ static inline bool zig_f128_isNaN(float128_t *aPtr) { } static inline bool zig_extF80_isNaN(extFloat80_t *aPtr) { - return aPtr->signExp & 0x7FFF && aPtr->signif; + return (aPtr->signExp & 0x7FFF) == 0x7FFF && aPtr->signif & UINT64_C(0x7FFFFFFFFFFFFFFF); } #endif diff --git a/test/behavior/floatop_stage1.zig b/test/behavior/floatop_stage1.zig index b1b7eb2b92..303288a118 100644 --- a/test/behavior/floatop_stage1.zig +++ b/test/behavior/floatop_stage1.zig @@ -4,6 +4,7 @@ const math = std.math; const pi = std.math.pi; const e = std.math.e; const Vector = std.meta.Vector; +const has_f80_rt = @import("builtin").cpu.arch == .x86_64; const epsilon = 0.000001; @@ -27,6 +28,10 @@ fn testSqrt() !void { var a: f64 = 25; try expect(@sqrt(a) == 5); } + if (has_f80_rt) { + var a: f80 = 25; + try expect(@sqrt(a) == 5); + } { const a: comptime_float = 25.0; try expect(@sqrt(a) == 5.0); @@ -86,6 +91,10 @@ fn testSin() !void { var a: f64 = 0; try expect(@sin(a) == 0); } + // { + // var a: f80 = 0; + // try expect(@sin(a) == 0); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; var result = @sin(v); @@ -116,6 +125,10 @@ fn testCos() !void { var a: f64 = 0; try expect(@cos(a) == 1); } + // { + // var a: f80 = 0; + // try expect(@cos(a) == 1); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; var result = @cos(v); @@ -146,6 +159,10 @@ fn testExp() !void { var a: f64 = 0; try expect(@exp(a) == 1); } + // { + // var a: f80 = 0; + // try expect(@exp(a) == 1); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var result = @exp(v); @@ -176,6 +193,10 @@ fn testExp2() !void { var a: f64 = 2; try expect(@exp2(a) == 4); } + // { + // var a: f80 = 2; + // try expect(@exp2(a) == 4); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var result = @exp2(v); @@ -208,6 +229,10 @@ fn testLog() !void { var a: f64 = e; try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000))); } + // { + // var a: f80 = e; + // try expect(@log(a) == 1); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var result = @log(v); @@ -238,6 +263,10 @@ fn testLog2() !void { var a: f64 = 4; try expect(@log2(a) == 2); } + // { + // var a: f80 = 4; + // try expect(@log2(a) == 2); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var result = @log2(v); @@ -268,6 +297,10 @@ fn testLog10() !void { var a: f64 = 1000; try expect(@log10(a) == 3); } + // { + // var a: f80 = 1000; + // try expect(@log10(a) == 3); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var result = @log10(v); @@ -304,6 +337,12 @@ fn testFabs() !void { try expect(@fabs(a) == 2.5); try expect(@fabs(b) == 2.5); } + // { + // var a: f80 = -2.5; + // var b: f80 = 2.5; + // try expect(@fabs(a) == 2.5); + // try expect(@fabs(b) == 2.5); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var result = @fabs(v); @@ -334,6 +373,10 @@ fn testFloor() !void { var a: f64 = 3.5; try expect(@floor(a) == 3); } + // { + // var a: f80 = 3.5; + // try expect(@floor(a) == 3); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var result = @floor(v); @@ -364,6 +407,10 @@ fn testCeil() !void { var a: f64 = 3.5; try expect(@ceil(a) == 4); } + // { + // var a: f80 = 3.5; + // try expect(@ceil(a) == 4); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var result = @ceil(v); @@ -394,6 +441,10 @@ fn testTrunc() !void { var a: f64 = -3.5; try expect(@trunc(a) == -3); } + // { + // var a: f80 = -3.5; + // try expect(@trunc(a) == -3); + // } { var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var result = @trunc(v); @@ -403,3 +454,33 @@ fn testTrunc() !void { try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); } } + +test "floating point comparisons" { + if (has_f80_rt) try testFloatComparisons(); + comptime try testFloatComparisons(); +} + +fn testFloatComparisons() !void { + inline for ([_]type{ f16, f32, f64, f80, f128 }) |ty| { + // No decimal part + { + const x: ty = 1.0; + try expect(x == 1); + try expect(x != 0); + try expect(x > 0); + try expect(x < 2); + try expect(x >= 1); + try expect(x <= 1); + } + // Non-zero decimal part + { + const x: ty = 1.5; + try expect(x != 1); + try expect(x != 2); + try expect(x > 1); + try expect(x < 2); + try expect(x >= 1); + try expect(x <= 2); + } + } +} diff --git a/test/behavior/math_stage1.zig b/test/behavior/math_stage1.zig index 72824348dd..298f2ffc85 100644 --- a/test/behavior/math_stage1.zig +++ b/test/behavior/math_stage1.zig @@ -5,6 +5,7 @@ const expectEqualSlices = std.testing.expectEqualSlices; const maxInt = std.math.maxInt; const minInt = std.math.minInt; const mem = std.mem; +const has_f80_rt = @import("builtin").cpu.arch == .x86_64; test "allow signed integer division/remainder when values are comptime known and positive or exact" { try expect(5 / 3 == 1); @@ -194,6 +195,8 @@ fn testSqrt(comptime T: type, x: T) !void { test "@fabs" { try testFabs(f128, 12.0); comptime try testFabs(f128, 12.0); + if (has_f80_rt) try testFabs(f80, 12.0); + // comptime try testFabs(f80, 12.0); try testFabs(f64, 12.0); comptime try testFabs(f64, 12.0); try testFabs(f32, 12.0); @@ -217,6 +220,8 @@ test "@floor" { // FIXME: Generates a floorl function call // testFloor(f128, 12.0); comptime try testFloor(f128, 12.0); + // try testFloor(f80, 12.0); + comptime try testFloor(f80, 12.0); try testFloor(f64, 12.0); comptime try testFloor(f64, 12.0); try testFloor(f32, 12.0); @@ -240,6 +245,8 @@ test "@ceil" { // FIXME: Generates a ceill function call //testCeil(f128, 12.0); comptime try testCeil(f128, 12.0); + // try testCeil(f80, 12.0); + comptime try testCeil(f80, 12.0); try testCeil(f64, 12.0); comptime try testCeil(f64, 12.0); try testCeil(f32, 12.0); @@ -263,6 +270,14 @@ test "@trunc" { // FIXME: Generates a truncl function call //testTrunc(f128, 12.0); comptime try testTrunc(f128, 12.0); + // try testTrunc(f80, 12.0); + // comptime try testTrunc(f80, 12.0); + comptime { + const x: f80 = 12.0; + const y = x + 0.8; + const z = @trunc(y); + try expectEqual(x, z); + } try testTrunc(f64, 12.0); comptime try testTrunc(f64, 12.0); try testTrunc(f32, 12.0); @@ -294,6 +309,8 @@ test "@round" { // FIXME: Generates a roundl function call //testRound(f128, 12.0); comptime try testRound(f128, 12.0); + // try testRound(f80, 12.0); + comptime try testRound(f80, 12.0); try testRound(f64, 12.0); comptime try testRound(f64, 12.0); try testRound(f32, 12.0); @@ -333,10 +350,12 @@ test "NaN comparison" { try testNanEqNan(f32); try testNanEqNan(f64); try testNanEqNan(f128); + if (has_f80_rt) try testNanEqNan(f80); comptime try testNanEqNan(f16); comptime try testNanEqNan(f32); comptime try testNanEqNan(f64); comptime try testNanEqNan(f128); + // comptime try testNanEqNan(f80); } fn testNanEqNan(comptime F: type) !void { diff --git a/test/behavior/muladd.zig b/test/behavior/muladd.zig index cff7b5e2ad..46e938e1a9 100644 --- a/test/behavior/muladd.zig +++ b/test/behavior/muladd.zig @@ -25,6 +25,12 @@ fn testMulAdd() !void { var c: f64 = 6.25; try expect(@mulAdd(f64, a, b, c) == 20); } + // { + // var a: f16 = 5.5; + // var b: f80 = 2.5; + // var c: f80 = 6.25; + // try expect(@mulAdd(f80, a, b, c) == 20); + // } if (builtin.os.tag == .macos and builtin.cpu.arch == .aarch64) { // https://github.com/ziglang/zig/issues/9900 return error.SkipZigTest; diff --git a/test/behavior/type_stage1.zig b/test/behavior/type_stage1.zig index a87cba08d4..911e6963c9 100644 --- a/test/behavior/type_stage1.zig +++ b/test/behavior/type_stage1.zig @@ -13,8 +13,9 @@ test "Type.Float" { try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } })); try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); + try testing.expect(f80 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 80 } })); try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); - try testTypes(&[_]type{ f16, f32, f64, f128 }); + try testTypes(&[_]type{ f16, f32, f64, f80, f128 }); } test "Type.Array" { diff --git a/test/behavior/widening.zig b/test/behavior/widening.zig index afca1ae143..035d4fa4f9 100644 --- a/test/behavior/widening.zig +++ b/test/behavior/widening.zig @@ -2,6 +2,7 @@ const std = @import("std"); const expect = std.testing.expect; const mem = std.mem; const builtin = @import("builtin"); +const has_f80_rt = @import("builtin").cpu.arch == .x86_64; test "integer widening" { var a: u8 = 250; @@ -27,6 +28,10 @@ test "float widening" { try expect(a == b); try expect(b == c); try expect(c == d); + if (has_f80_rt) { + var e: f80 = c; + try expect(c == e); + } } test "float widening f16 to f128" {