diff --git a/src/compiler.ts b/src/compiler.ts index ada299256e..af14b57934 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -7794,19 +7794,23 @@ export class Compiler extends DiagnosticEmitter { case LiteralKind.INTEGER: { let expr = expression; let type = this.resolver.determineIntegerLiteralType(expr, implicitlyNegate, contextualType); - - let intValue = implicitlyNegate - ? i64_neg(expr.value) - : expr.value; - this.currentType = type; + let intValue = expr.value; + let sign = 1.0; // should multiply for float literals + if (implicitlyNegate) { + if (type.isFloatValue) { + sign = -1.0; + } else { + intValue = i64_neg(intValue); + } + } switch (type.kind) { case TypeKind.ISIZE: if (!this.options.isWasm64) return module.i32(i64_low(intValue)); case TypeKind.I64: return module.i64(i64_low(intValue), i64_high(intValue)); case TypeKind.USIZE: if (!this.options.isWasm64) return module.i32(i64_low(intValue)); case TypeKind.U64: return module.i64(i64_low(intValue), i64_high(intValue)); - case TypeKind.F32: return module.f32(i64_to_f32(intValue)); - case TypeKind.F64: return module.f64(i64_to_f64(intValue)); + case TypeKind.F32: return module.f32(sign * i64_to_f32(intValue)); + case TypeKind.F64: return module.f64(sign * i64_to_f64(intValue)); default: return module.i32(i64_low(intValue)); } } diff --git a/src/resolver.ts b/src/resolver.ts index 7f57fe3d81..9297041b2a 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1603,6 +1603,16 @@ export class Resolver extends DiagnosticEmitter { DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types, range, range.source.text.substring(range.start - 1, range.end) ); + } else if (i64_eq(intValue, i64_zero)) { + // Special handling for -0 + if (ctxType.isFloatValue) { + return ctxType.kind == TypeKind.F32 + ? Type.f32 + : Type.f64; + } else if (!ctxType.isIntegerValue) { + // If it's unknown just always assume this is f64 + return Type.f64; + } } intValue = i64_neg(intValue); } diff --git a/tests/compiler/literals.debug.wat b/tests/compiler/literals.debug.wat index 238ac11537..667d61348b 100644 --- a/tests/compiler/literals.debug.wat +++ b/tests/compiler/literals.debug.wat @@ -105,6 +105,16 @@ drop i64.const -9223372036854775808 drop + i32.const 0 + drop + i64.const 0 + drop + f64.const -0 + drop + f32.const -0 + drop + f64.const -0 + drop ) (func $~start call $start:literals diff --git a/tests/compiler/literals.ts b/tests/compiler/literals.ts index 417e1a3773..a754e2eecd 100644 --- a/tests/compiler/literals.ts +++ b/tests/compiler/literals.ts @@ -47,3 +47,9 @@ false; -0x8000000000000000; 0o1000000000000000000000; -0o1000000000000000000000; + +-0; // i32.const 0 +-0; // i64.const 0 +-0; // f64.const -0. +f32(-0); // f32.const -0. +-0; // f64.const -0. diff --git a/tests/compiler/std/hash.debug.wat b/tests/compiler/std/hash.debug.wat index 645af94e50..aa13fb2d46 100644 --- a/tests/compiler/std/hash.debug.wat +++ b/tests/compiler/std/hash.debug.wat @@ -826,7 +826,7 @@ call $~lib/util/hash/HASH call $std/hash/check drop - f32.const 0 + f32.const -0 call $~lib/util/hash/HASH call $std/hash/check drop @@ -850,7 +850,7 @@ call $~lib/util/hash/HASH call $std/hash/check drop - f64.const 0 + f64.const -0 call $~lib/util/hash/HASH call $std/hash/check drop diff --git a/tests/compiler/std/hash.ts b/tests/compiler/std/hash.ts index 155caebe09..e253bb6f5a 100644 --- a/tests/compiler/std/hash.ts +++ b/tests/compiler/std/hash.ts @@ -19,13 +19,13 @@ check(HASH("abcdefghi")); check(HASH(0.0)); check(HASH(1.0)); check(HASH(1.1)); -check(HASH(-0)); +check(HASH(-0.0)); check(HASH(Infinity)); check(HASH(NaN)); check(HASH(0.0)); check(HASH(1.0)); check(HASH(1.1)); -check(HASH(-0)); +check(HASH(-0.0)); check(HASH(Infinity)); check(HASH(NaN)); diff --git a/tests/compiler/std/math.debug.wat b/tests/compiler/std/math.debug.wat index ea4744da8b..51d3e84d49 100644 --- a/tests/compiler/std/math.debug.wat +++ b/tests/compiler/std/math.debug.wat @@ -29598,7 +29598,7 @@ call $~lib/builtins/abort unreachable end - f64.const 0 + f64.const -0 i64.const 4607182418800017408 f64.reinterpret_i64 f64.const 0 diff --git a/tests/compiler/std/math.release.wat b/tests/compiler/std/math.release.wat index af1efd82fd..591eb72158 100644 --- a/tests/compiler/std/math.release.wat +++ b/tests/compiler/std/math.release.wat @@ -27420,7 +27420,7 @@ call $~lib/builtins/abort unreachable end - f64.const 0 + f64.const -0 f64.const 1 f64.const 0 call $std/math/test_exp2 diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index 7ed266d6f5..7bad7a7291 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -1558,31 +1558,31 @@ assert(test_exp2(reinterpret(0x3FE8C5DB097F7442), reinterpret(0x3FFB5C assert(test_exp2(reinterpret(0xBFE5B86EA8118A0E), reinterpret(0x3FE3FD8BA33216B9), reinterpret(0xBFD3F71A00000000), INEXACT)); // special -assert(test_exp2( 0, reinterpret(0x3FF0000000000000), 0, 0)); -assert(test_exp2( -0, reinterpret(0x3FF0000000000000), 0, 0)); -assert(test_exp2( 1, reinterpret(0x4000000000000000), 0, 0)); -assert(test_exp2( -1, reinterpret(0x3FE0000000000000), 0, 0)); +assert(test_exp2( 0.0, reinterpret(0x3FF0000000000000), 0, 0)); +assert(test_exp2( -0.0, reinterpret(0x3FF0000000000000), 0, 0)); +assert(test_exp2( 1.0, reinterpret(0x4000000000000000), 0, 0)); +assert(test_exp2( -1.0, reinterpret(0x3FE0000000000000), 0, 0)); assert(test_exp2( Infinity, Infinity, 0, 0)); assert(test_exp2( -Infinity, 0, 0, 0)); assert(test_exp2( NaN, NaN, 0, 0)); assert(test_exp2(reinterpret(0x3FFFF80000000000), reinterpret(0x400FF4EACA4391B6), reinterpret(0x3FC2E60C60000000), INEXACT)); -assert(test_exp2(reinterpret(0xC08FEF3333333333), reinterpret(0x1125FBEE2506B0), reinterpret(0xBFCC612EC0000000), INEXACT)); -assert(test_exp2(reinterpret(0xC08FF00000000000), reinterpret(0x10000000000000), 0, 0)); -assert(test_exp2(reinterpret(0xC08FF0CCCCCCCCCD), reinterpret(0xEEDB4008BD547), reinterpret(0x3FC966DFC0000000), INEXACT | UNDERFLOW)); -assert(test_exp2(reinterpret(0xC08FF80000000000), reinterpret(0x8000000000000), 0, 0)); +assert(test_exp2(reinterpret(0xC08FEF3333333333), reinterpret(0x001125FBEE2506B0), reinterpret(0xBFCC612EC0000000), INEXACT)); +assert(test_exp2(reinterpret(0xC08FF00000000000), reinterpret(0x0010000000000000), 0, 0)); +assert(test_exp2(reinterpret(0xC08FF0CCCCCCCCCD), reinterpret(0x000EEDB4008BD547), reinterpret(0x3FC966DFC0000000), INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC08FF80000000000), reinterpret(0x0008000000000000), 0, 0)); assert(test_exp2(reinterpret(0x408FFF3333333333), reinterpret(0x7FEDDB680117AA8E), reinterpret(0x3FD966DFC0000000), INEXACT)); assert(test_exp2(reinterpret(0x4090000000000000), Infinity, 0, INEXACT | UNDERFLOW)); assert(test_exp2(reinterpret(0x4090006666666666), Infinity, 0, INEXACT | UNDERFLOW)); assert(test_exp2(reinterpret(0x40091EB851EB851F), reinterpret(0x4021A167423FC31C), reinterpret(0x3FD9287B80000000), INEXACT)); -assert(test_exp2(reinterpret(0xC08FF40000000000), reinterpret(0xB504F333F9DE6), reinterpret(0xBFD2116600000000), INEXACT | UNDERFLOW)); -assert(test_exp2(reinterpret(0xC08FF80000000000), reinterpret(0x8000000000000), 0, 0)); -assert(test_exp2(reinterpret(0xC08FFC0000000000), reinterpret(0x5A827999FCEF3), reinterpret(0xBFC2116600000000), INEXACT | UNDERFLOW)); -assert(test_exp2(reinterpret(0xC090000000000000), reinterpret(0x4000000000000), 0, 0)); -assert(test_exp2(reinterpret(0xC090040000000000), reinterpret(0x2000000000000), 0, 0)); -assert(test_exp2(reinterpret(0xC090C80000000000), reinterpret(0x1), 0, 0)); -assert(test_exp2(reinterpret(0xC090CA0000000000), reinterpret(0x1), reinterpret(0x3FD2BEC340000000), INEXACT | UNDERFLOW)); -assert(test_exp2(reinterpret(0xC090CC0000000000), 0, reinterpret(0xBFE0000000000000), INEXACT | UNDERFLOW)); -assert(test_exp2(reinterpret(0xC0A0000000000000), 0, 0, INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC08FF40000000000), reinterpret(0x000B504F333F9DE6), reinterpret(0xBFD2116600000000), INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC08FF80000000000), reinterpret(0x0008000000000000), 0, 0)); +assert(test_exp2(reinterpret(0xC08FFC0000000000), reinterpret(0x0005A827999FCEF3), reinterpret(0xBFC2116600000000), INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC090000000000000), reinterpret(0x0004000000000000), 0, 0)); +assert(test_exp2(reinterpret(0xC090040000000000), reinterpret(0x0002000000000000), 0, 0)); +assert(test_exp2(reinterpret(0xC090C80000000000), reinterpret(1), 0, 0)); +assert(test_exp2(reinterpret(0xC090CA0000000000), reinterpret(1), reinterpret(0x3FD2BEC340000000), INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC090CC0000000000), 0, reinterpret(0xBFE0000000000000), INEXACT | UNDERFLOW)); +assert(test_exp2(reinterpret(0xC0A0000000000000), 0, 0, INEXACT | UNDERFLOW)); //////////////////////////////////////////////////////////////////////////////////////////////////// // Mathf.exp2 diff --git a/tests/compiler/std/object.debug.wat b/tests/compiler/std/object.debug.wat index 937c1b7b9e..22b6400dbb 100644 --- a/tests/compiler/std/object.debug.wat +++ b/tests/compiler/std/object.debug.wat @@ -705,24 +705,6 @@ call $~lib/builtins/abort unreachable end - f64.const 0 - f64.const 0.1 - f64.const -1e-308 - f64.mul - call $~lib/object/Object.is - i32.const 0 - i32.ne - i32.const 0 - i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 34 - i32.const 1 - call $~lib/builtins/abort - unreachable - end f64.const -0 f64.const 0.1 f64.const -1e-308 @@ -736,7 +718,7 @@ if i32.const 0 i32.const 32 - i32.const 35 + i32.const 34 i32.const 1 call $~lib/builtins/abort unreachable @@ -752,7 +734,7 @@ if i32.const 0 i32.const 32 - i32.const 36 + i32.const 35 i32.const 1 call $~lib/builtins/abort unreachable @@ -766,7 +748,7 @@ if i32.const 0 i32.const 32 - i32.const 38 + i32.const 37 i32.const 1 call $~lib/builtins/abort unreachable @@ -780,7 +762,7 @@ if i32.const 0 i32.const 32 - i32.const 39 + i32.const 38 i32.const 1 call $~lib/builtins/abort unreachable @@ -794,7 +776,7 @@ if i32.const 0 i32.const 32 - i32.const 41 + i32.const 40 i32.const 1 call $~lib/builtins/abort unreachable @@ -808,7 +790,7 @@ if i32.const 0 i32.const 32 - i32.const 42 + i32.const 41 i32.const 1 call $~lib/builtins/abort unreachable @@ -822,7 +804,7 @@ if i32.const 0 i32.const 32 - i32.const 43 + i32.const 42 i32.const 1 call $~lib/builtins/abort unreachable @@ -846,7 +828,7 @@ if i32.const 0 i32.const 32 - i32.const 45 + i32.const 44 i32.const 1 call $~lib/builtins/abort unreachable @@ -870,7 +852,7 @@ if i32.const 0 i32.const 32 - i32.const 46 + i32.const 45 i32.const 1 call $~lib/builtins/abort unreachable @@ -894,7 +876,7 @@ if i32.const 0 i32.const 32 - i32.const 47 + i32.const 46 i32.const 1 call $~lib/builtins/abort unreachable @@ -908,7 +890,7 @@ if i32.const 0 i32.const 32 - i32.const 49 + i32.const 48 i32.const 1 call $~lib/builtins/abort unreachable @@ -927,7 +909,7 @@ if i32.const 0 i32.const 32 - i32.const 50 + i32.const 49 i32.const 1 call $~lib/builtins/abort unreachable @@ -946,7 +928,7 @@ if i32.const 0 i32.const 32 - i32.const 51 + i32.const 50 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/object.release.wat b/tests/compiler/std/object.release.wat index 43a22872a7..52bd0c90c9 100644 --- a/tests/compiler/std/object.release.wat +++ b/tests/compiler/std/object.release.wat @@ -169,7 +169,7 @@ if i32.const 0 i32.const 1056 - i32.const 45 + i32.const 44 i32.const 1 call $~lib/builtins/abort unreachable @@ -187,7 +187,7 @@ if i32.const 0 i32.const 1056 - i32.const 46 + i32.const 45 i32.const 1 call $~lib/builtins/abort unreachable @@ -205,7 +205,7 @@ if i32.const 0 i32.const 1056 - i32.const 47 + i32.const 46 i32.const 1 call $~lib/builtins/abort unreachable @@ -218,7 +218,7 @@ if i32.const 0 i32.const 1056 - i32.const 49 + i32.const 48 i32.const 1 call $~lib/builtins/abort unreachable @@ -232,7 +232,7 @@ if i32.const 0 i32.const 1056 - i32.const 50 + i32.const 49 i32.const 1 call $~lib/builtins/abort unreachable @@ -246,7 +246,7 @@ if i32.const 0 i32.const 1056 - i32.const 51 + i32.const 50 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/object.ts b/tests/compiler/std/object.ts index b9b22e4e51..efcfe3a718 100644 --- a/tests/compiler/std/object.ts +++ b/tests/compiler/std/object.ts @@ -31,7 +31,6 @@ assert(Object.is(+Infinity, NaN) == false); assert(Object.is(NaN, Infinity) == false); assert(Object.is(NaN, NaN) == true); -assert(Object.is(-0, 1e-1 * (-1e-308)) == false); assert(Object.is(-0.0, 1e-1 * (-1e-308)) == false); assert(Object.is(0, 0.0) == true);