| author | |
| committer | |
| log | 4411f9c019f8f41baeacd39be01af9f961df4e4e |
| tree | 1e811c386b03682fbe32f7ce61214d6fb3027073 |
| parent | f8b204bb189125e85a7f14f08c4bab60a462e76e |
6 files changed, 114 insertions(+), 2 deletions(-)
src/stage1/softfloat.hpp+1-1| ... | ... | @@ -57,7 +57,7 @@ static inline bool zig_f128_isNaN(float128_t *aPtr) { |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | static inline bool zig_extF80_isNaN(extFloat80_t *aPtr) { |
| 60 | return aPtr->signExp & 0x7FFF && aPtr->signif; | |
| 60 | return (aPtr->signExp & 0x7FFF) == 0x7FFF && aPtr->signif & UINT64_C(0x7FFFFFFFFFFFFFFF); | |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | #endif |
test/behavior/floatop_stage1.zig+81| ... | ... | @@ -4,6 +4,7 @@ const math = std.math; |
| 4 | 4 | const pi = std.math.pi; |
| 5 | 5 | const e = std.math.e; |
| 6 | 6 | const Vector = std.meta.Vector; |
| 7 | const has_f80_rt = @import("builtin").cpu.arch == .x86_64; | |
| 7 | 8 | |
| 8 | 9 | const epsilon = 0.000001; |
| 9 | 10 | |
| ... | ... | @@ -27,6 +28,10 @@ fn testSqrt() !void { |
| 27 | 28 | var a: f64 = 25; |
| 28 | 29 | try expect(@sqrt(a) == 5); |
| 29 | 30 | } |
| 31 | if (has_f80_rt) { | |
| 32 | var a: f80 = 25; | |
| 33 | try expect(@sqrt(a) == 5); | |
| 34 | } | |
| 30 | 35 | { |
| 31 | 36 | const a: comptime_float = 25.0; |
| 32 | 37 | try expect(@sqrt(a) == 5.0); |
| ... | ... | @@ -86,6 +91,10 @@ fn testSin() !void { |
| 86 | 91 | var a: f64 = 0; |
| 87 | 92 | try expect(@sin(a) == 0); |
| 88 | 93 | } |
| 94 | // { | |
| 95 | // var a: f80 = 0; | |
| 96 | // try expect(@sin(a) == 0); | |
| 97 | // } | |
| 89 | 98 | { |
| 90 | 99 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; |
| 91 | 100 | var result = @sin(v); |
| ... | ... | @@ -116,6 +125,10 @@ fn testCos() !void { |
| 116 | 125 | var a: f64 = 0; |
| 117 | 126 | try expect(@cos(a) == 1); |
| 118 | 127 | } |
| 128 | // { | |
| 129 | // var a: f80 = 0; | |
| 130 | // try expect(@cos(a) == 1); | |
| 131 | // } | |
| 119 | 132 | { |
| 120 | 133 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; |
| 121 | 134 | var result = @cos(v); |
| ... | ... | @@ -146,6 +159,10 @@ fn testExp() !void { |
| 146 | 159 | var a: f64 = 0; |
| 147 | 160 | try expect(@exp(a) == 1); |
| 148 | 161 | } |
| 162 | // { | |
| 163 | // var a: f80 = 0; | |
| 164 | // try expect(@exp(a) == 1); | |
| 165 | // } | |
| 149 | 166 | { |
| 150 | 167 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| 151 | 168 | var result = @exp(v); |
| ... | ... | @@ -176,6 +193,10 @@ fn testExp2() !void { |
| 176 | 193 | var a: f64 = 2; |
| 177 | 194 | try expect(@exp2(a) == 4); |
| 178 | 195 | } |
| 196 | // { | |
| 197 | // var a: f80 = 2; | |
| 198 | // try expect(@exp2(a) == 4); | |
| 199 | // } | |
| 179 | 200 | { |
| 180 | 201 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| 181 | 202 | var result = @exp2(v); |
| ... | ... | @@ -208,6 +229,10 @@ fn testLog() !void { |
| 208 | 229 | var a: f64 = e; |
| 209 | 230 | try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000))); |
| 210 | 231 | } |
| 232 | // { | |
| 233 | // var a: f80 = e; | |
| 234 | // try expect(@log(a) == 1); | |
| 235 | // } | |
| 211 | 236 | { |
| 212 | 237 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| 213 | 238 | var result = @log(v); |
| ... | ... | @@ -238,6 +263,10 @@ fn testLog2() !void { |
| 238 | 263 | var a: f64 = 4; |
| 239 | 264 | try expect(@log2(a) == 2); |
| 240 | 265 | } |
| 266 | // { | |
| 267 | // var a: f80 = 4; | |
| 268 | // try expect(@log2(a) == 2); | |
| 269 | // } | |
| 241 | 270 | { |
| 242 | 271 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| 243 | 272 | var result = @log2(v); |
| ... | ... | @@ -268,6 +297,10 @@ fn testLog10() !void { |
| 268 | 297 | var a: f64 = 1000; |
| 269 | 298 | try expect(@log10(a) == 3); |
| 270 | 299 | } |
| 300 | // { | |
| 301 | // var a: f80 = 1000; | |
| 302 | // try expect(@log10(a) == 3); | |
| 303 | // } | |
| 271 | 304 | { |
| 272 | 305 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| 273 | 306 | var result = @log10(v); |
| ... | ... | @@ -304,6 +337,12 @@ fn testFabs() !void { |
| 304 | 337 | try expect(@fabs(a) == 2.5); |
| 305 | 338 | try expect(@fabs(b) == 2.5); |
| 306 | 339 | } |
| 340 | // { | |
| 341 | // var a: f80 = -2.5; | |
| 342 | // var b: f80 = 2.5; | |
| 343 | // try expect(@fabs(a) == 2.5); | |
| 344 | // try expect(@fabs(b) == 2.5); | |
| 345 | // } | |
| 307 | 346 | { |
| 308 | 347 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; |
| 309 | 348 | var result = @fabs(v); |
| ... | ... | @@ -334,6 +373,10 @@ fn testFloor() !void { |
| 334 | 373 | var a: f64 = 3.5; |
| 335 | 374 | try expect(@floor(a) == 3); |
| 336 | 375 | } |
| 376 | // { | |
| 377 | // var a: f80 = 3.5; | |
| 378 | // try expect(@floor(a) == 3); | |
| 379 | // } | |
| 337 | 380 | { |
| 338 | 381 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; |
| 339 | 382 | var result = @floor(v); |
| ... | ... | @@ -364,6 +407,10 @@ fn testCeil() !void { |
| 364 | 407 | var a: f64 = 3.5; |
| 365 | 408 | try expect(@ceil(a) == 4); |
| 366 | 409 | } |
| 410 | // { | |
| 411 | // var a: f80 = 3.5; | |
| 412 | // try expect(@ceil(a) == 4); | |
| 413 | // } | |
| 367 | 414 | { |
| 368 | 415 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; |
| 369 | 416 | var result = @ceil(v); |
| ... | ... | @@ -394,6 +441,10 @@ fn testTrunc() !void { |
| 394 | 441 | var a: f64 = -3.5; |
| 395 | 442 | try expect(@trunc(a) == -3); |
| 396 | 443 | } |
| 444 | // { | |
| 445 | // var a: f80 = -3.5; | |
| 446 | // try expect(@trunc(a) == -3); | |
| 447 | // } | |
| 397 | 448 | { |
| 398 | 449 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; |
| 399 | 450 | var result = @trunc(v); |
| ... | ... | @@ -403,3 +454,33 @@ fn testTrunc() !void { |
| 403 | 454 | try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); |
| 404 | 455 | } |
| 405 | 456 | } |
| 457 | ||
| 458 | test "floating point comparisons" { | |
| 459 | if (has_f80_rt) try testFloatComparisons(); | |
| 460 | comptime try testFloatComparisons(); | |
| 461 | } | |
| 462 | ||
| 463 | fn testFloatComparisons() !void { | |
| 464 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |ty| { | |
| 465 | // No decimal part | |
| 466 | { | |
| 467 | const x: ty = 1.0; | |
| 468 | try expect(x == 1); | |
| 469 | try expect(x != 0); | |
| 470 | try expect(x > 0); | |
| 471 | try expect(x < 2); | |
| 472 | try expect(x >= 1); | |
| 473 | try expect(x <= 1); | |
| 474 | } | |
| 475 | // Non-zero decimal part | |
| 476 | { | |
| 477 | const x: ty = 1.5; | |
| 478 | try expect(x != 1); | |
| 479 | try expect(x != 2); | |
| 480 | try expect(x > 1); | |
| 481 | try expect(x < 2); | |
| 482 | try expect(x >= 1); | |
| 483 | try expect(x <= 2); | |
| 484 | } | |
| 485 | } | |
| 486 | } |
test/behavior/math_stage1.zig+19| ... | ... | @@ -5,6 +5,7 @@ const expectEqualSlices = std.testing.expectEqualSlices; |
| 5 | 5 | const maxInt = std.math.maxInt; |
| 6 | 6 | const minInt = std.math.minInt; |
| 7 | 7 | const mem = std.mem; |
| 8 | const has_f80_rt = @import("builtin").cpu.arch == .x86_64; | |
| 8 | 9 | |
| 9 | 10 | test "allow signed integer division/remainder when values are comptime known and positive or exact" { |
| 10 | 11 | try expect(5 / 3 == 1); |
| ... | ... | @@ -194,6 +195,8 @@ fn testSqrt(comptime T: type, x: T) !void { |
| 194 | 195 | test "@fabs" { |
| 195 | 196 | try testFabs(f128, 12.0); |
| 196 | 197 | comptime try testFabs(f128, 12.0); |
| 198 | if (has_f80_rt) try testFabs(f80, 12.0); | |
| 199 | // comptime try testFabs(f80, 12.0); | |
| 197 | 200 | try testFabs(f64, 12.0); |
| 198 | 201 | comptime try testFabs(f64, 12.0); |
| 199 | 202 | try testFabs(f32, 12.0); |
| ... | ... | @@ -217,6 +220,8 @@ test "@floor" { |
| 217 | 220 | // FIXME: Generates a floorl function call |
| 218 | 221 | // testFloor(f128, 12.0); |
| 219 | 222 | comptime try testFloor(f128, 12.0); |
| 223 | // try testFloor(f80, 12.0); | |
| 224 | comptime try testFloor(f80, 12.0); | |
| 220 | 225 | try testFloor(f64, 12.0); |
| 221 | 226 | comptime try testFloor(f64, 12.0); |
| 222 | 227 | try testFloor(f32, 12.0); |
| ... | ... | @@ -240,6 +245,8 @@ test "@ceil" { |
| 240 | 245 | // FIXME: Generates a ceill function call |
| 241 | 246 | //testCeil(f128, 12.0); |
| 242 | 247 | comptime try testCeil(f128, 12.0); |
| 248 | // try testCeil(f80, 12.0); | |
| 249 | comptime try testCeil(f80, 12.0); | |
| 243 | 250 | try testCeil(f64, 12.0); |
| 244 | 251 | comptime try testCeil(f64, 12.0); |
| 245 | 252 | try testCeil(f32, 12.0); |
| ... | ... | @@ -263,6 +270,14 @@ test "@trunc" { |
| 263 | 270 | // FIXME: Generates a truncl function call |
| 264 | 271 | //testTrunc(f128, 12.0); |
| 265 | 272 | comptime try testTrunc(f128, 12.0); |
| 273 | // try testTrunc(f80, 12.0); | |
| 274 | // comptime try testTrunc(f80, 12.0); | |
| 275 | comptime { | |
| 276 | const x: f80 = 12.0; | |
| 277 | const y = x + 0.8; | |
| 278 | const z = @trunc(y); | |
| 279 | try expectEqual(x, z); | |
| 280 | } | |
| 266 | 281 | try testTrunc(f64, 12.0); |
| 267 | 282 | comptime try testTrunc(f64, 12.0); |
| 268 | 283 | try testTrunc(f32, 12.0); |
| ... | ... | @@ -294,6 +309,8 @@ test "@round" { |
| 294 | 309 | // FIXME: Generates a roundl function call |
| 295 | 310 | //testRound(f128, 12.0); |
| 296 | 311 | comptime try testRound(f128, 12.0); |
| 312 | // try testRound(f80, 12.0); | |
| 313 | comptime try testRound(f80, 12.0); | |
| 297 | 314 | try testRound(f64, 12.0); |
| 298 | 315 | comptime try testRound(f64, 12.0); |
| 299 | 316 | try testRound(f32, 12.0); |
| ... | ... | @@ -333,10 +350,12 @@ test "NaN comparison" { |
| 333 | 350 | try testNanEqNan(f32); |
| 334 | 351 | try testNanEqNan(f64); |
| 335 | 352 | try testNanEqNan(f128); |
| 353 | if (has_f80_rt) try testNanEqNan(f80); | |
| 336 | 354 | comptime try testNanEqNan(f16); |
| 337 | 355 | comptime try testNanEqNan(f32); |
| 338 | 356 | comptime try testNanEqNan(f64); |
| 339 | 357 | comptime try testNanEqNan(f128); |
| 358 | // comptime try testNanEqNan(f80); | |
| 340 | 359 | } |
| 341 | 360 | |
| 342 | 361 | fn testNanEqNan(comptime F: type) !void { |
test/behavior/muladd.zig+6| ... | ... | @@ -25,6 +25,12 @@ fn testMulAdd() !void { |
| 25 | 25 | var c: f64 = 6.25; |
| 26 | 26 | try expect(@mulAdd(f64, a, b, c) == 20); |
| 27 | 27 | } |
| 28 | // { | |
| 29 | // var a: f16 = 5.5; | |
| 30 | // var b: f80 = 2.5; | |
| 31 | // var c: f80 = 6.25; | |
| 32 | // try expect(@mulAdd(f80, a, b, c) == 20); | |
| 33 | // } | |
| 28 | 34 | if (builtin.os.tag == .macos and builtin.cpu.arch == .aarch64) { |
| 29 | 35 | // https://github.com/ziglang/zig/issues/9900 |
| 30 | 36 | return error.SkipZigTest; |
test/behavior/type_stage1.zig+2-1| ... | ... | @@ -13,8 +13,9 @@ test "Type.Float" { |
| 13 | 13 | try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } })); |
| 14 | 14 | try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); |
| 15 | 15 | try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); |
| 16 | try testing.expect(f80 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 80 } })); | |
| 16 | 17 | try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); |
| 17 | try testTypes(&[_]type{ f16, f32, f64, f128 }); | |
| 18 | try testTypes(&[_]type{ f16, f32, f64, f80, f128 }); | |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | 21 | test "Type.Array" { |
test/behavior/widening.zig+5| ... | ... | @@ -2,6 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const expect = std.testing.expect; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | const builtin = @import("builtin"); |
| 5 | const has_f80_rt = @import("builtin").cpu.arch == .x86_64; | |
| 5 | 6 | |
| 6 | 7 | test "integer widening" { |
| 7 | 8 | var a: u8 = 250; |
| ... | ... | @@ -27,6 +28,10 @@ test "float widening" { |
| 27 | 28 | try expect(a == b); |
| 28 | 29 | try expect(b == c); |
| 29 | 30 | try expect(c == d); |
| 31 | if (has_f80_rt) { | |
| 32 | var e: f80 = c; | |
| 33 | try expect(c == e); | |
| 34 | } | |
| 30 | 35 | } |
| 31 | 36 | |
| 32 | 37 | test "float widening f16 to f128" { |