diff --git a/std/assembly/math.ts b/std/assembly/math.ts index e399d81c..5131fa42 100644 --- a/std/assembly/math.ts +++ b/std/assembly/math.ts @@ -550,7 +550,18 @@ export namespace NativeMath { } export function imul(x: f64, y: f64): f64 { - return (x * y); + /* + * Wasm (MVP) and JS have different approachas for double->int conversions. + * + * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT + * our float-point arguments before actual convertion to integers. + */ + if (!isFinite(x + y)) return 0; + const inv32 = 1.0 / 4294967296; + return ( + (x - 4294967296 * builtin_floor(x * inv32)) * + (y - 4294967296 * builtin_floor(y * inv32)) + ); } export function log(x: f64): f64 { // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above diff --git a/tests/compiler/std/array.optimized.wat b/tests/compiler/std/array.optimized.wat index 2d7b389f..a0c559ce 100644 --- a/tests/compiler/std/array.optimized.wat +++ b/tests/compiler/std/array.optimized.wat @@ -3813,7 +3813,7 @@ if i32.const 0 i32.const 2816 - i32.const 959 + i32.const 970 i32.const 4 call $~lib/env/abort unreachable @@ -5479,7 +5479,7 @@ if i32.const 0 i32.const 2816 - i32.const 968 + i32.const 979 i32.const 24 call $~lib/env/abort unreachable diff --git a/tests/compiler/std/array.untouched.wat b/tests/compiler/std/array.untouched.wat index 8fb97a4e..19d89fac 100644 --- a/tests/compiler/std/array.untouched.wat +++ b/tests/compiler/std/array.untouched.wat @@ -5225,7 +5225,7 @@ if i32.const 0 i32.const 2816 - i32.const 959 + i32.const 970 i32.const 4 call $~lib/env/abort unreachable @@ -8241,7 +8241,7 @@ if i32.const 0 i32.const 2816 - i32.const 968 + i32.const 979 i32.const 24 call $~lib/env/abort unreachable diff --git a/tests/compiler/std/libm.optimized.wat b/tests/compiler/std/libm.optimized.wat index 71f6e154..f78ccf24 100644 --- a/tests/compiler/std/libm.optimized.wat +++ b/tests/compiler/std/libm.optimized.wat @@ -2347,19 +2347,53 @@ get_local $1 call $~lib/math/NativeMath.hypot ) - (func $std/libm/imul (; 34 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $~lib/math/NativeMath.imul (; 34 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (local $2 f64) get_local $0 - i32.trunc_s/f64 get_local $1 - i32.trunc_s/f64 + f64.add + tee_local $2 + get_local $2 + f64.sub + f64.const 0 + f64.ne + if + f64.const 0 + return + end + get_local $0 + f64.const 4294967296 + get_local $0 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + get_local $1 + f64.const 4294967296 + get_local $1 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 i32.mul f64.convert_s/i32 ) - (func $std/libm/log (; 35 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/imul (; 35 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + get_local $0 + get_local $1 + call $~lib/math/NativeMath.imul + ) + (func $std/libm/log (; 36 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log ) - (func $~lib/math/NativeMath.log10 (; 36 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.log10 (; 37 ;) (type $FF) (param $0 f64) (result f64) (local $1 f64) (local $2 i32) (local $3 i32) @@ -2571,15 +2605,15 @@ get_local $0 f64.add ) - (func $std/libm/log10 (; 37 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log10 (; 38 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log10 ) - (func $std/libm/log1p (; 38 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log1p (; 39 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log1p ) - (func $~lib/math/NativeMath.log2 (; 39 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.log2 (; 40 ;) (type $FF) (param $0 f64) (result f64) (local $1 f64) (local $2 i32) (local $3 i32) @@ -2785,21 +2819,21 @@ get_local $0 f64.add ) - (func $std/libm/log2 (; 40 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log2 (; 41 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log2 ) - (func $std/libm/max (; 41 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/max (; 42 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 f64.max ) - (func $std/libm/min (; 42 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/min (; 43 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 f64.min ) - (func $~lib/math/NativeMath.pow (; 43 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $~lib/math/NativeMath.pow (; 44 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) (local $2 f64) (local $3 f64) (local $4 i32) @@ -3749,12 +3783,12 @@ f64.const 1e-300 f64.mul ) - (func $std/libm/pow (; 44 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/pow (; 45 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 call $~lib/math/NativeMath.pow ) - (func $std/libm/round (; 45 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/round (; 46 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.const 0.5 f64.add @@ -3762,7 +3796,7 @@ get_local $0 f64.copysign ) - (func $std/libm/sign (; 46 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sign (; 47 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.const 0 f64.gt @@ -3780,7 +3814,7 @@ end get_local $0 ) - (func $~lib/math/NativeMath.sinh (; 47 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.sinh (; 48 ;) (type $FF) (param $0 f64) (result f64) (local $1 f64) (local $2 f64) (local $3 i32) @@ -3857,15 +3891,15 @@ f64.mul f64.mul ) - (func $std/libm/sinh (; 48 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sinh (; 49 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.sinh ) - (func $std/libm/sqrt (; 49 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sqrt (; 50 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.sqrt ) - (func $~lib/math/NativeMath.tanh (; 50 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.tanh (; 51 ;) (type $FF) (param $0 f64) (result f64) (local $1 f64) (local $2 i32) (local $3 i64) @@ -3944,15 +3978,15 @@ get_local $0 f64.copysign ) - (func $std/libm/tanh (; 51 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/tanh (; 52 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.tanh ) - (func $std/libm/trunc (; 52 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/trunc (; 53 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.trunc ) - (func $null (; 53 ;) (type $v) + (func $null (; 54 ;) (type $v) nop ) ) diff --git a/tests/compiler/std/libm.untouched.wat b/tests/compiler/std/libm.untouched.wat index 3e85fe99..844d3712 100644 --- a/tests/compiler/std/libm.untouched.wat +++ b/tests/compiler/std/libm.untouched.wat @@ -2825,24 +2825,56 @@ get_local $1 call $~lib/math/NativeMath.hypot ) - (func $~lib/math/NativeMath.imul (; 36 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $~lib/builtins/isFinite (; 36 ;) (type $Fi) (param $0 f64) (result i32) + get_local $0 + get_local $0 + f64.sub + f64.const 0 + f64.eq + ) + (func $~lib/math/NativeMath.imul (; 37 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 - i32.trunc_s/f64 get_local $1 - i32.trunc_s/f64 + f64.add + call $~lib/builtins/isFinite + i32.eqz + if + f64.const 0 + return + end + get_local $0 + f64.const 4294967296 + get_local $0 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + get_local $1 + f64.const 4294967296 + get_local $1 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 i32.mul f64.convert_s/i32 ) - (func $std/libm/imul (; 37 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/imul (; 38 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 call $~lib/math/NativeMath.imul ) - (func $std/libm/log (; 38 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log (; 39 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log ) - (func $~lib/math/NativeMath.log10 (; 39 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.log10 (; 40 ;) (type $FF) (param $0 f64) (result f64) (local $1 i64) (local $2 i32) (local $3 i32) @@ -3105,15 +3137,15 @@ get_local $9 f64.add ) - (func $std/libm/log10 (; 40 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log10 (; 41 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log10 ) - (func $std/libm/log1p (; 41 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log1p (; 42 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log1p ) - (func $~lib/math/NativeMath.log2 (; 42 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.log2 (; 43 ;) (type $FF) (param $0 f64) (result f64) (local $1 i64) (local $2 i32) (local $3 i32) @@ -3369,21 +3401,21 @@ get_local $15 f64.add ) - (func $std/libm/log2 (; 43 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/log2 (; 44 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.log2 ) - (func $std/libm/max (; 44 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/max (; 45 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 f64.max ) - (func $std/libm/min (; 45 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/min (; 46 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 f64.min ) - (func $~lib/math/NativeMath.pow (; 46 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $~lib/math/NativeMath.pow (; 47 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) (local $2 i64) (local $3 i32) (local $4 i32) @@ -4470,12 +4502,12 @@ get_local $15 f64.mul ) - (func $std/libm/pow (; 47 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (func $std/libm/pow (; 48 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) get_local $0 get_local $1 call $~lib/math/NativeMath.pow ) - (func $std/libm/round (; 48 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/round (; 49 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.const 0.5 f64.add @@ -4483,7 +4515,7 @@ get_local $0 f64.copysign ) - (func $std/libm/sign (; 49 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sign (; 50 ;) (type $FF) (param $0 f64) (result f64) block $~lib/math/NativeMath.sign|inlined.0 (result f64) get_local $0 f64.const 0 @@ -4503,15 +4535,15 @@ br $~lib/math/NativeMath.sign|inlined.0 end ) - (func $~lib/math/NativeMath.sin (; 50 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.sin (; 51 ;) (type $FF) (param $0 f64) (result f64) unreachable f64.const 0 ) - (func $std/libm/sin (; 51 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sin (; 52 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.sin ) - (func $~lib/math/NativeMath.sinh (; 52 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.sinh (; 53 ;) (type $FF) (param $0 f64) (result f64) (local $1 i64) (local $2 f64) (local $3 i32) @@ -4612,23 +4644,23 @@ set_local $4 get_local $4 ) - (func $std/libm/sinh (; 53 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sinh (; 54 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.sinh ) - (func $std/libm/sqrt (; 54 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/sqrt (; 55 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.sqrt ) - (func $~lib/math/NativeMath.tan (; 55 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.tan (; 56 ;) (type $FF) (param $0 f64) (result f64) unreachable f64.const 0 ) - (func $std/libm/tan (; 56 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/tan (; 57 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.tan ) - (func $~lib/math/NativeMath.tanh (; 57 ;) (type $FF) (param $0 f64) (result f64) + (func $~lib/math/NativeMath.tanh (; 58 ;) (type $FF) (param $0 f64) (result f64) (local $1 i64) (local $2 f64) (local $3 i32) @@ -4720,14 +4752,14 @@ get_local $0 f64.copysign ) - (func $std/libm/tanh (; 58 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/tanh (; 59 ;) (type $FF) (param $0 f64) (result f64) get_local $0 call $~lib/math/NativeMath.tanh ) - (func $std/libm/trunc (; 59 ;) (type $FF) (param $0 f64) (result f64) + (func $std/libm/trunc (; 60 ;) (type $FF) (param $0 f64) (result f64) get_local $0 f64.trunc ) - (func $null (; 60 ;) (type $v) + (func $null (; 61 ;) (type $v) ) ) diff --git a/tests/compiler/std/math.optimized.wat b/tests/compiler/std/math.optimized.wat index 228c54ea..146505f9 100644 --- a/tests/compiler/std/math.optimized.wat +++ b/tests/compiler/std/math.optimized.wat @@ -8002,7 +8002,7 @@ if i32.const 0 i32.const 40 - i32.const 959 + i32.const 970 i32.const 4 call $~lib/env/abort unreachable @@ -8068,7 +8068,7 @@ if i32.const 0 i32.const 40 - i32.const 968 + i32.const 979 i32.const 24 call $~lib/env/abort unreachable @@ -8115,7 +8115,7 @@ if i32.const 0 i32.const 40 - i32.const 2029 + i32.const 2040 i32.const 24 call $~lib/env/abort unreachable @@ -9183,7 +9183,44 @@ f32.const 0 call $std/math/check ) - (func $~lib/math/ipow64 (; 145 ;) (type $IiI) (param $0 i64) (param $1 i32) (result i64) + (func $~lib/math/NativeMath.imul (; 145 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + (local $2 f64) + get_local $0 + get_local $1 + f64.add + tee_local $2 + get_local $2 + f64.sub + f64.const 0 + f64.ne + if + f64.const 0 + return + end + get_local $0 + f64.const 4294967296 + get_local $0 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + get_local $1 + f64.const 4294967296 + get_local $1 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + i32.mul + f64.convert_s/i32 + ) + (func $~lib/math/ipow64 (; 146 ;) (type $IiI) (param $0 i64) (param $1 i32) (result i64) (local $2 i64) (local $3 i32) i64.const 1 @@ -9379,7 +9416,7 @@ end get_local $2 ) - (func $start (; 146 ;) (type $v) + (func $start (; 147 ;) (type $v) (local $0 i32) (local $1 i32) (local $2 f64) @@ -37563,11 +37600,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const 2 + f64.const 4 + call $~lib/math/NativeMath.imul + f64.const 8 + f64.ne if i32.const 0 i32.const 8 @@ -37576,11 +37613,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 1 - call $~lib/math/ipow64 - i64.const 0 - i64.ne + f64.const -1 + f64.const 8 + call $~lib/math/NativeMath.imul + f64.const -8 + f64.ne if i32.const 0 i32.const 8 @@ -37589,11 +37626,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 2 - call $~lib/math/ipow64 - i64.const 0 - i64.ne + f64.const -2 + f64.const -2 + call $~lib/math/NativeMath.imul + f64.const 4 + f64.ne if i32.const 0 i32.const 8 @@ -37602,11 +37639,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 3 - call $~lib/math/ipow64 - i64.const 0 - i64.ne + f64.const 4294967295 + f64.const 5 + call $~lib/math/NativeMath.imul + f64.const -5 + f64.ne if i32.const 0 i32.const 8 @@ -37615,11 +37652,24 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const 4294967294 + f64.const 5 + call $~lib/math/NativeMath.imul + f64.const -10 + f64.ne + if + i32.const 0 + i32.const 8 + i32.const 3278 + i32.const 0 + call $~lib/env/abort + unreachable + end + f64.const 1.e+60 + f64.const 1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne if i32.const 0 i32.const 8 @@ -37628,11 +37678,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 1 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const 1.e+60 + f64.const -1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne if i32.const 0 i32.const 8 @@ -37641,11 +37691,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 2 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const -1.e+60 + f64.const -1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne if i32.const 0 i32.const 8 @@ -37654,11 +37704,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 3 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const 1.e+24 + f64.const 100 + call $~lib/math/NativeMath.imul + f64.const -2147483648 + f64.ne if i32.const 0 i32.const 8 @@ -37667,11 +37717,24 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.ne + f64.const nan:0x8000000000000 + f64.const 1 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne + if + i32.const 0 + i32.const 8 + i32.const 3283 + i32.const 0 + call $~lib/env/abort + unreachable + end + f64.const 1 + f64.const inf + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne if i32.const 0 i32.const 8 @@ -37680,11 +37743,11 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 1 - call $~lib/math/ipow64 - i64.const 2 - i64.ne + f64.const 1797693134862315708145274e284 + f64.const 1797693134862315708145274e284 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.ne if i32.const 0 i32.const 8 @@ -37693,33 +37756,7 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 2 - call $~lib/math/ipow64 - i64.const 4 - i64.ne - if - i32.const 0 - i32.const 8 - i32.const 3286 - i32.const 0 - call $~lib/env/abort - unreachable - end - i64.const 2 - i32.const 3 - call $~lib/math/ipow64 - i64.const 8 - i64.ne - if - i32.const 0 - i32.const 8 - i32.const 3287 - i32.const 0 - call $~lib/env/abort - unreachable - end - i64.const -1 + i64.const 0 i32.const 0 call $~lib/math/ipow64 i64.const 1 @@ -37732,10 +37769,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 1 call $~lib/math/ipow64 - i64.const -1 + i64.const 0 i64.ne if i32.const 0 @@ -37745,10 +37782,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 2 call $~lib/math/ipow64 - i64.const 1 + i64.const 0 i64.ne if i32.const 0 @@ -37758,10 +37795,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 3 call $~lib/math/ipow64 - i64.const -1 + i64.const 0 i64.ne if i32.const 0 @@ -37771,7 +37808,7 @@ call $~lib/env/abort unreachable end - i64.const -2 + i64.const 1 i32.const 0 call $~lib/math/ipow64 i64.const 1 @@ -37784,6 +37821,162 @@ call $~lib/env/abort unreachable end + i64.const 1 + i32.const 1 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3295 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 1 + i32.const 2 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3296 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 1 + i32.const 3 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3297 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3299 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 1 + call $~lib/math/ipow64 + i64.const 2 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3300 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 2 + call $~lib/math/ipow64 + i64.const 4 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3301 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 3 + call $~lib/math/ipow64 + i64.const 8 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3302 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3304 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 1 + call $~lib/math/ipow64 + i64.const -1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3305 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 2 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3306 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 3 + call $~lib/math/ipow64 + i64.const -1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3307 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -2 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 8 + i32.const 3309 + i32.const 0 + call $~lib/env/abort + unreachable + end i64.const -2 i32.const 1 call $~lib/math/ipow64 @@ -37792,7 +37985,7 @@ if i32.const 0 i32.const 8 - i32.const 3295 + i32.const 3310 i32.const 0 call $~lib/env/abort unreachable @@ -37805,7 +37998,7 @@ if i32.const 0 i32.const 8 - i32.const 3296 + i32.const 3311 i32.const 0 call $~lib/env/abort unreachable @@ -37818,7 +38011,7 @@ if i32.const 0 i32.const 8 - i32.const 3297 + i32.const 3312 i32.const 0 call $~lib/env/abort unreachable @@ -37831,7 +38024,7 @@ if i32.const 0 i32.const 8 - i32.const 3299 + i32.const 3314 i32.const 0 call $~lib/env/abort unreachable @@ -37844,7 +38037,7 @@ if i32.const 0 i32.const 8 - i32.const 3300 + i32.const 3315 i32.const 0 call $~lib/env/abort unreachable @@ -37857,7 +38050,7 @@ if i32.const 0 i32.const 8 - i32.const 3301 + i32.const 3316 i32.const 0 call $~lib/env/abort unreachable @@ -37870,7 +38063,7 @@ if i32.const 0 i32.const 8 - i32.const 3302 + i32.const 3317 i32.const 0 call $~lib/env/abort unreachable @@ -37883,7 +38076,7 @@ if i32.const 0 i32.const 8 - i32.const 3303 + i32.const 3318 i32.const 0 call $~lib/env/abort unreachable @@ -37896,7 +38089,7 @@ if i32.const 0 i32.const 8 - i32.const 3304 + i32.const 3319 i32.const 0 call $~lib/env/abort unreachable @@ -37909,7 +38102,7 @@ if i32.const 0 i32.const 8 - i32.const 3305 + i32.const 3320 i32.const 0 call $~lib/env/abort unreachable @@ -37926,13 +38119,13 @@ if i32.const 0 i32.const 8 - i32.const 3307 + i32.const 3322 i32.const 0 call $~lib/env/abort unreachable end ) - (func $null (; 147 ;) (type $v) + (func $null (; 148 ;) (type $v) nop ) ) diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index 0a68c7dd..83dfc216 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -3269,6 +3269,21 @@ assert(test_truncf(-0.9999923706, -0.0, 0.0, INEXACT)); assert(test_truncf(7.888609052e-31, 0.0, 0.0, INEXACT)); assert(test_truncf(-7.888609052e-31, -0.0, 0.0, INEXACT)); +// Math.imul ////////////////////////////////////////////////////////////////////////////////// + +assert(NativeMath.imul(2, 4) == 8); +assert(NativeMath.imul(-1, 8) == -8); +assert(NativeMath.imul(-2, -2) == 4); +assert(NativeMath.imul(0xffffffff, 5) == -5); +assert(NativeMath.imul(0xfffffffe, 5) == -10); +assert(NativeMath.imul(1e+60, 1e+60) == 0); +assert(NativeMath.imul(1e+60,-1e+60) == 0); +assert(NativeMath.imul(-1e+60,-1e+60) == 0); +assert(NativeMath.imul(1e+24, 1e2) == -2147483648); +assert(NativeMath.imul(NaN, 1) == 0); +assert(NativeMath.imul(1, Infinity) == 0); +assert(NativeMath.imul(f64.MAX_VALUE, f64.MAX_VALUE) == 0); + // ipow64 ///////////////////////////////////////////////////////////////////////////////////// assert(ipow64(0, 0) == 1); diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index 8eeaaf96..a2c93e4b 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -94,6 +94,7 @@ (global $~lib/math/random_state0_32 (mut i32) (i32.const 0)) (global $~lib/math/random_state1_32 (mut i32) (i32.const 0)) (global $ASC_SHRINK_LEVEL i32 (i32.const 0)) + (global $~lib/builtins/f64.MAX_VALUE f64 (f64.const 1797693134862315708145274e284)) (global $HEAP_BASE i32 (i32.const 68)) (export "memory" (memory $0)) (export "table" (table $0)) @@ -9713,7 +9714,7 @@ if i32.const 0 i32.const 40 - i32.const 959 + i32.const 970 i32.const 4 call $~lib/env/abort unreachable @@ -9745,7 +9746,7 @@ if i32.const 0 i32.const 40 - i32.const 968 + i32.const 979 i32.const 24 call $~lib/env/abort unreachable @@ -9802,7 +9803,7 @@ if i32.const 0 i32.const 40 - i32.const 2029 + i32.const 2040 i32.const 24 call $~lib/env/abort unreachable @@ -11122,7 +11123,40 @@ get_local $3 call $std/math/check ) - (func $~lib/math/ipow64 (; 153 ;) (type $IiI) (param $0 i64) (param $1 i32) (result i64) + (func $~lib/math/NativeMath.imul (; 153 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64) + get_local $0 + get_local $1 + f64.add + call $~lib/builtins/isFinite + i32.eqz + if + f64.const 0 + return + end + get_local $0 + f64.const 4294967296 + get_local $0 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + get_local $1 + f64.const 4294967296 + get_local $1 + f64.const 2.3283064365386963e-10 + f64.mul + f64.floor + f64.mul + f64.sub + i64.trunc_s/f64 + i32.wrap/i64 + i32.mul + f64.convert_s/i32 + ) + (func $~lib/math/ipow64 (; 154 ;) (type $IiI) (param $0 i64) (param $1 i32) (result i64) (local $2 i64) (local $3 i32) (local $4 i32) @@ -11354,7 +11388,7 @@ end get_local $2 ) - (func $start (; 154 ;) (type $v) + (func $start (; 155 ;) (type $v) (local $0 i32) (local $1 f64) (local $2 i32) @@ -41725,11 +41759,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const 2 + f64.const 4 + call $~lib/math/NativeMath.imul + f64.const 8 + f64.eq i32.eqz if i32.const 0 @@ -41739,11 +41773,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 1 - call $~lib/math/ipow64 - i64.const 0 - i64.eq + f64.const -1 + f64.const 8 + call $~lib/math/NativeMath.imul + f64.const -8 + f64.eq i32.eqz if i32.const 0 @@ -41753,11 +41787,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 2 - call $~lib/math/ipow64 - i64.const 0 - i64.eq + f64.const -2 + f64.const -2 + call $~lib/math/NativeMath.imul + f64.const 4 + f64.eq i32.eqz if i32.const 0 @@ -41767,11 +41801,11 @@ call $~lib/env/abort unreachable end - i64.const 0 - i32.const 3 - call $~lib/math/ipow64 - i64.const 0 - i64.eq + f64.const 4294967295 + f64.const 5 + call $~lib/math/NativeMath.imul + f64.const -5 + f64.eq i32.eqz if i32.const 0 @@ -41781,11 +41815,25 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const 4294967294 + f64.const 5 + call $~lib/math/NativeMath.imul + f64.const -10 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3278 + i32.const 0 + call $~lib/env/abort + unreachable + end + f64.const 1.e+60 + f64.const 1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq i32.eqz if i32.const 0 @@ -41795,11 +41843,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 1 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const 1.e+60 + f64.const -1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq i32.eqz if i32.const 0 @@ -41809,11 +41857,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 2 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const -1.e+60 + f64.const -1.e+60 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq i32.eqz if i32.const 0 @@ -41823,11 +41871,11 @@ call $~lib/env/abort unreachable end - i64.const 1 - i32.const 3 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const 1.e+24 + f64.const 100 + call $~lib/math/NativeMath.imul + f64.const -2147483648 + f64.eq i32.eqz if i32.const 0 @@ -41837,11 +41885,25 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.eq + f64.const nan:0x8000000000000 + f64.const 1 + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3283 + i32.const 0 + call $~lib/env/abort + unreachable + end + f64.const 1 + f64.const inf + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq i32.eqz if i32.const 0 @@ -41851,11 +41913,11 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 1 - call $~lib/math/ipow64 - i64.const 2 - i64.eq + get_global $~lib/builtins/f64.MAX_VALUE + get_global $~lib/builtins/f64.MAX_VALUE + call $~lib/math/NativeMath.imul + f64.const 0 + f64.eq i32.eqz if i32.const 0 @@ -41865,35 +41927,7 @@ call $~lib/env/abort unreachable end - i64.const 2 - i32.const 2 - call $~lib/math/ipow64 - i64.const 4 - i64.eq - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 3286 - i32.const 0 - call $~lib/env/abort - unreachable - end - i64.const 2 - i32.const 3 - call $~lib/math/ipow64 - i64.const 8 - i64.eq - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 3287 - i32.const 0 - call $~lib/env/abort - unreachable - end - i64.const -1 + i64.const 0 i32.const 0 call $~lib/math/ipow64 i64.const 1 @@ -41907,10 +41941,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 1 call $~lib/math/ipow64 - i64.const -1 + i64.const 0 i64.eq i32.eqz if @@ -41921,10 +41955,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 2 call $~lib/math/ipow64 - i64.const 1 + i64.const 0 i64.eq i32.eqz if @@ -41935,10 +41969,10 @@ call $~lib/env/abort unreachable end - i64.const -1 + i64.const 0 i32.const 3 call $~lib/math/ipow64 - i64.const -1 + i64.const 0 i64.eq i32.eqz if @@ -41949,7 +41983,7 @@ call $~lib/env/abort unreachable end - i64.const -2 + i64.const 1 i32.const 0 call $~lib/math/ipow64 i64.const 1 @@ -41963,6 +41997,174 @@ call $~lib/env/abort unreachable end + i64.const 1 + i32.const 1 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3295 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 1 + i32.const 2 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3296 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 1 + i32.const 3 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3297 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3299 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 1 + call $~lib/math/ipow64 + i64.const 2 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3300 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 2 + call $~lib/math/ipow64 + i64.const 4 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3301 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const 2 + i32.const 3 + call $~lib/math/ipow64 + i64.const 8 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3302 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3304 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 1 + call $~lib/math/ipow64 + i64.const -1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3305 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 2 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3306 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -1 + i32.const 3 + call $~lib/math/ipow64 + i64.const -1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3307 + i32.const 0 + call $~lib/env/abort + unreachable + end + i64.const -2 + i32.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 3309 + i32.const 0 + call $~lib/env/abort + unreachable + end i64.const -2 i32.const 1 call $~lib/math/ipow64 @@ -41972,7 +42174,7 @@ if i32.const 0 i32.const 8 - i32.const 3295 + i32.const 3310 i32.const 0 call $~lib/env/abort unreachable @@ -41986,7 +42188,7 @@ if i32.const 0 i32.const 8 - i32.const 3296 + i32.const 3311 i32.const 0 call $~lib/env/abort unreachable @@ -42000,7 +42202,7 @@ if i32.const 0 i32.const 8 - i32.const 3297 + i32.const 3312 i32.const 0 call $~lib/env/abort unreachable @@ -42014,7 +42216,7 @@ if i32.const 0 i32.const 8 - i32.const 3299 + i32.const 3314 i32.const 0 call $~lib/env/abort unreachable @@ -42028,7 +42230,7 @@ if i32.const 0 i32.const 8 - i32.const 3300 + i32.const 3315 i32.const 0 call $~lib/env/abort unreachable @@ -42042,7 +42244,7 @@ if i32.const 0 i32.const 8 - i32.const 3301 + i32.const 3316 i32.const 0 call $~lib/env/abort unreachable @@ -42056,7 +42258,7 @@ if i32.const 0 i32.const 8 - i32.const 3302 + i32.const 3317 i32.const 0 call $~lib/env/abort unreachable @@ -42070,7 +42272,7 @@ if i32.const 0 i32.const 8 - i32.const 3303 + i32.const 3318 i32.const 0 call $~lib/env/abort unreachable @@ -42084,7 +42286,7 @@ if i32.const 0 i32.const 8 - i32.const 3304 + i32.const 3319 i32.const 0 call $~lib/env/abort unreachable @@ -42098,7 +42300,7 @@ if i32.const 0 i32.const 8 - i32.const 3305 + i32.const 3320 i32.const 0 call $~lib/env/abort unreachable @@ -42116,12 +42318,12 @@ if i32.const 0 i32.const 8 - i32.const 3307 + i32.const 3322 i32.const 0 call $~lib/env/abort unreachable end ) - (func $null (; 155 ;) (type $v) + (func $null (; 156 ;) (type $v) ) )