Skip to content

Commit 12aed07

Browse files
MaxGraeydcodeIO
authored andcommitted
Improve f64 to i32 conversion for Math.imul and Math.clz32 (#779)
1 parent a884cc2 commit 12aed07

File tree

7 files changed

+443
-431
lines changed

7 files changed

+443
-431
lines changed

std/assembly/math.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
4242
return p / q;
4343
}
4444

45+
/** @internal */
4546
// @ts-ignore: decorator
4647
@inline
4748
function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
@@ -52,6 +53,27 @@ function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
5253
return NativeMath.exp(x - kln2) * scale * scale;
5354
}
5455

56+
/** @internal */
57+
function dtoi32(x: f64): i32 {
58+
if (ASC_SHRINK_LEVEL > 0) {
59+
const inv32 = 1.0 / 4294967296;
60+
return <i32><i64>(x - 4294967296 * floor(x * inv32));
61+
} else {
62+
let result = 0;
63+
let u = reinterpret<u64>(x);
64+
let e = (u >> 52) & 0x7ff;
65+
if (e <= 1023 + 30) {
66+
result = <i32>x;
67+
} else if (e <= 1023 + 30 + 53) {
68+
let v = (u & ((<u64>1 << 52) - 1)) | (<u64>1 << 52);
69+
v = v << e - 1023 - 52 + 32;
70+
result = <i32>(v >> 32);
71+
result = select<i32>(-result, result, u >> 63);
72+
}
73+
return result;
74+
}
75+
}
76+
5577
// @ts-ignore: decorator
5678
@lazy
5779
var random_seeded = false;
@@ -398,9 +420,7 @@ export namespace NativeMath {
398420
* For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
399421
* our float-point arguments before actual convertion to integers.
400422
*/
401-
return builtin_clz(
402-
<i32><i64>(x - 4294967296 * builtin_floor(x * (1.0 / 4294967296)))
403-
);
423+
return builtin_clz(dtoi32(x));
404424
}
405425

406426
export function cos(x: f64): f64 { // TODO
@@ -599,11 +619,7 @@ export namespace NativeMath {
599619
* our float-point arguments before actual convertion to integers.
600620
*/
601621
if (!isFinite(x + y)) return 0;
602-
const inv32 = 1.0 / 4294967296;
603-
return (
604-
<i32><i64>(x - 4294967296 * builtin_floor(x * inv32)) *
605-
<i32><i64>(y - 4294967296 * builtin_floor(y * inv32))
606-
);
622+
return dtoi32(x) * dtoi32(y);
607623
}
608624

609625
export function log(x: f64): f64 { // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above
@@ -1700,9 +1716,7 @@ export namespace NativeMathf {
17001716

17011717
export function clz32(x: f32): f32 {
17021718
if (!isFinite(x)) return 32;
1703-
return <f32>builtin_clz(
1704-
<i32><i64>(x - 4294967296 * builtin_floor(x * (1.0 / 4294967296)))
1705-
);
1719+
return <f32>builtin_clz(dtoi32(x));
17061720
}
17071721

17081722
export function cos(x: f32): f32 { // see: musl/src/math/cosf.c
@@ -1927,11 +1941,7 @@ export namespace NativeMathf {
19271941
* our float-point arguments before actual convertion to integers.
19281942
*/
19291943
if (!isFinite(x + y)) return 0;
1930-
const inv32 = 1.0 / 4294967296;
1931-
return <f32>(
1932-
<i32><i64>(x - 4294967296 * builtin_floor(x * inv32)) *
1933-
<i32><i64>(y - 4294967296 * builtin_floor(y * inv32))
1934-
);
1944+
return <f32>(dtoi32(x) * dtoi32(y));
19351945
}
19361946

19371947
export function log(x: f32): f32 { // see: musl/src/math/logf.c and SUN COPYRIGHT NOTICE above

tests/compiler/std/array.optimized.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4156,7 +4156,7 @@
41564156
if
41574157
i32.const 0
41584158
i32.const 3160
4159-
i32.const 1020
4159+
i32.const 1036
41604160
i32.const 4
41614161
call $~lib/builtins/abort
41624162
unreachable
@@ -5709,7 +5709,7 @@
57095709
if
57105710
i32.const 3936
57115711
i32.const 3160
5712-
i32.const 1029
5712+
i32.const 1045
57135713
i32.const 24
57145714
call $~lib/builtins/abort
57155715
unreachable

tests/compiler/std/array.untouched.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6534,7 +6534,7 @@
65346534
if
65356535
i32.const 0
65366536
i32.const 3160
6537-
i32.const 1020
6537+
i32.const 1036
65386538
i32.const 4
65396539
call $~lib/builtins/abort
65406540
unreachable
@@ -8842,7 +8842,7 @@
88428842
if
88438843
i32.const 3936
88448844
i32.const 3160
8845-
i32.const 1029
8845+
i32.const 1045
88468846
i32.const 24
88478847
call $~lib/builtins/abort
88488848
unreachable

0 commit comments

Comments
 (0)