From a2acee0df5012dfd3e3c6b4b82ad98a75fc45bb0 Mon Sep 17 00:00:00 2001 From: Adrien Zinger Date: Fri, 3 Jun 2022 13:50:07 +0200 Subject: [PATCH 1/3] Add rem builtin (#1310) --- NOTICE | 1 + src/builtins.ts | 78 ++++++++++- std/assembly/builtins.ts | 12 ++ std/assembly/index.d.ts | 14 +- tests/compiler/builtins.debug.wat | 202 ++++++++++++++++++---------- tests/compiler/builtins.release.wat | 56 ++++---- tests/compiler/builtins.ts | 4 + 7 files changed, 269 insertions(+), 98 deletions(-) diff --git a/NOTICE b/NOTICE index 56f50806c1..3080a825f4 100644 --- a/NOTICE +++ b/NOTICE @@ -47,6 +47,7 @@ under the licensing terms detailed in LICENSE: * Yasushi Ando * Syed Jafri * Peter Hayman +* Adrien Zinger Portions of this software are derived from third-party works licensed under the following terms: diff --git a/src/builtins.ts b/src/builtins.ts index 91558c0466..a7acba39ba 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -163,6 +163,7 @@ export namespace BuiltinNames { export const trunc = "~lib/builtins/trunc"; export const eq = "~lib/builtins/eq"; export const ne = "~lib/builtins/ne"; + export const rem = "~lib/builtins/rem"; export const load = "~lib/builtins/load"; export const store = "~lib/builtins/store"; export const atomic_load = "~lib/builtins/atomic.load"; @@ -269,6 +270,9 @@ export namespace BuiltinNames { export const f32_ne = "~lib/builtins/f32.ne"; export const f64_ne = "~lib/builtins/f64.ne"; + export const i32_rem = "~lib/builtins/i32.rem"; + export const i64_rem = "~lib/builtins/i64.rem"; + export const i32_load8_s = "~lib/builtins/i32.load8_s"; export const i32_load8_u = "~lib/builtins/i32.load8_u"; export const i32_load16_s = "~lib/builtins/i32.load16_s"; @@ -815,7 +819,7 @@ function builtin_isString(ctx: BuiltinContext): ExpressionRef { compiler.currentType = Type.bool; if (!type) return module.unreachable(); var classReference = type.getClass(); - return reifyConstantType(ctx, + return reifyConstantType(ctx, module.i32( classReference && classReference.isAssignableTo(compiler.program.stringInstance) ? 1 @@ -2231,6 +2235,60 @@ function builtin_store(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.store, builtin_store); +// rem(left: T, right: T) -> T +function builtin_rem(ctx: BuiltinContext): ExpressionRef { + var compiler = ctx.compiler; + var module = compiler.module; + if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) { + return module.unreachable(); + } + var operands = ctx.operands; + var typeArguments = ctx.typeArguments; + var left = operands[0]; + var arg0 = typeArguments + ? compiler.compileExpression( + left, + typeArguments[0], + Constraints.CONV_IMPLICIT + ) + : compiler.compileExpression(operands[0], Type.auto); + var type = compiler.currentType; + if (type.isIntegerValue) { + let arg1: ExpressionRef; + if (!typeArguments && left.isNumericLiteral) { + // prefer right type + arg1 = compiler.compileExpression( + operands[1], + type + ); + if (compiler.currentType != type) { + arg0 = compiler.compileExpression( + left, + (type = compiler.currentType), + Constraints.CONV_IMPLICIT + ); + } + } else { + arg1 = compiler.compileExpression( + operands[1], + type, + Constraints.CONV_IMPLICIT + ); + } + if (type.isIntegerValue) { + return compiler.makeRem(arg0, arg1, type, ctx.reportNode); + } + } + compiler.error( + DiagnosticCode.Operation_0_cannot_be_applied_to_type_1, + ctx.reportNode.typeArgumentsRange, + "rem", + type.toString() + ); + return module.unreachable(); +} +builtins.set(BuiltinNames.rem, builtin_rem); + // add(left: T, right: T) -> T function builtin_add(ctx: BuiltinContext): ExpressionRef { var compiler = ctx.compiler; @@ -6638,6 +6696,24 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.f64_trunc, builtin_f64_trunc); +// i32.rem -> rem +function builtin_i32_rem(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.i32 ]; + ctx.contextualType = Type.i32; + return builtin_rem(ctx); +} +builtins.set(BuiltinNames.i32_rem, builtin_i32_rem); + +// i64.rem -> rem +function builtin_i64_rem(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.i64 ]; + ctx.contextualType = Type.i64; + return builtin_rem(ctx); +} +builtins.set(BuiltinNames.i64_rem, builtin_i64_rem); + // i32.add -> add function builtin_i32_add(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); diff --git a/std/assembly/builtins.ts b/std/assembly/builtins.ts index b476c4cd88..efd0991be5 100644 --- a/std/assembly/builtins.ts +++ b/std/assembly/builtins.ts @@ -144,6 +144,10 @@ export declare function eq(left: T, right: T): i32; @builtin export declare function ne(left: T, right: T): i32; +// @ts-ignore: decorator +@builtin +export declare function rem(left: T, right: T): T; + // @ts-ignore: decorator @unsafe @builtin export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T; @@ -350,6 +354,10 @@ export namespace i32 { @builtin export declare function ne(left: i32, right:i32): i32; + // @ts-ignore: decorator + @builtin + export declare function rem(left: i32, right: i32): i32; + // @ts-ignore: decorator @builtin export declare function reinterpret_f32(value: f32): i32; @@ -601,6 +609,10 @@ export namespace i64 { @builtin export declare function ne(left: i64, right:i64): i32; + // @ts-ignore: decorator + @builtin + export declare function rem(left: i64, right: i64): i64; + // @ts-ignore: decorator @builtin export declare function reinterpret_f64(value: f64): i64; diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index e24d742684..bf6a86b0a2 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -151,6 +151,8 @@ declare function div(left: T, right: T): T; declare function eq(left: T, right: T): i32; /** Return 0 if two numbers are equal to each other, 1 otherwise. */ declare function ne(left: T, right: T): i32; +/** Computes the rem of two positive integers. */ +declare function rem(left: T, right: T): T; /** Loads a value of the specified type from memory. Equivalent to dereferncing a pointer in other languages. */ declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T; /** Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages when assigning a value. */ @@ -342,10 +344,12 @@ declare namespace i32 { export function div_s(left: i32, right: i32): i32; /** Computes the unsigned quotient of two 32-bit integers. */ export function div_u(left: i32, right: i32): i32; - /** Return 1 two 32-bit inegers are equal to each other, 0 otherwise. */ + /** Return 1 if two 32-bit integers are equal to each other, 0 otherwise. */ export function eq(left: i32, right: i32): i32; - /** Return 0 two 32-bit inegers are equal to each other, 1 otherwise. */ + /** Return 0 if two 32-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i32, right: i32): i32; + /** Compute the remaining between two 32-bit positive integers. */ + export function rem(left: i32, right: i32): i32; /** Atomic 32-bit integer operations. */ export namespace atomic { /** Atomically loads an 8-bit unsigned integer value from memory and returns it as a 32-bit integer. */ @@ -466,10 +470,12 @@ declare namespace i64 { export function div_s(left: i64, right: i64): i64; /** Computes the unsigned quotient of two 64-bit integers. */ export function div_u(left: i64, right: i64): i64; - /** Return 1 two 64-bit inegers are equal to each other, 0 otherwise. */ + /** Return 1 if two 64-bit integers are equal to each other, 0 otherwise. */ export function eq(left: i64, right: i64): i32; - /** Return 0 two 64-bit inegers are equal to each other, 1 otherwise. */ + /** Return 0 if two 64-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i64, right: i64): i32; + /** Compute the remaining between two 64-bit positive integers. */ + export function rem(left: i64, right: i64): i64; /** Atomic 64-bit integer operations. */ export namespace atomic { /** Atomically loads an 8-bit unsigned integer value from memory and returns it as a 64-bit integer. */ diff --git a/tests/compiler/builtins.debug.wat b/tests/compiler/builtins.debug.wat index 1a89fb333e..4d0df3cb98 100644 --- a/tests/compiler/builtins.debug.wat +++ b/tests/compiler/builtins.debug.wat @@ -1044,6 +1044,38 @@ call $~lib/builtins/abort unreachable end + i32.const 1 + i32.const 3 + i32.rem_s + global.set $builtins/i + global.get $builtins/i + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 110 + i32.const 21 + call $~lib/builtins/abort + unreachable + end + i32.const 15 + i32.const 4 + i32.rem_s + global.set $builtins/i + global.get $builtins/i + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 111 + i32.const 22 + call $~lib/builtins/abort + unreachable + end i64.const 1 i64.clz drop @@ -1138,7 +1170,7 @@ if i32.const 0 i32.const 96 - i32.const 135 + i32.const 137 i32.const 20 call $~lib/builtins/abort unreachable @@ -1159,7 +1191,7 @@ if i32.const 0 i32.const 96 - i32.const 136 + i32.const 138 i32.const 21 call $~lib/builtins/abort unreachable @@ -1180,7 +1212,7 @@ if i32.const 0 i32.const 96 - i32.const 137 + i32.const 139 i32.const 21 call $~lib/builtins/abort unreachable @@ -1196,7 +1228,7 @@ if i32.const 0 i32.const 96 - i32.const 138 + i32.const 140 i32.const 21 call $~lib/builtins/abort unreachable @@ -1212,7 +1244,7 @@ if i32.const 0 i32.const 96 - i32.const 139 + i32.const 141 i32.const 21 call $~lib/builtins/abort unreachable @@ -1228,7 +1260,7 @@ if i32.const 0 i32.const 96 - i32.const 140 + i32.const 142 i32.const 21 call $~lib/builtins/abort unreachable @@ -1244,7 +1276,7 @@ if i32.const 0 i32.const 96 - i32.const 141 + i32.const 143 i32.const 21 call $~lib/builtins/abort unreachable @@ -1260,7 +1292,7 @@ if i32.const 0 i32.const 96 - i32.const 142 + i32.const 144 i32.const 20 call $~lib/builtins/abort unreachable @@ -1276,7 +1308,7 @@ if i32.const 0 i32.const 96 - i32.const 143 + i32.const 145 i32.const 20 call $~lib/builtins/abort unreachable @@ -1292,7 +1324,7 @@ if i32.const 0 i32.const 96 - i32.const 144 + i32.const 146 i32.const 20 call $~lib/builtins/abort unreachable @@ -1308,11 +1340,43 @@ if i32.const 0 i32.const 96 - i32.const 145 + i32.const 147 i32.const 20 call $~lib/builtins/abort unreachable end + i64.const 1 + i64.const 3 + i64.rem_s + global.set $builtins/I + global.get $builtins/I + i64.const 1 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 148 + i32.const 21 + call $~lib/builtins/abort + unreachable + end + i64.const 15 + i64.const 4 + i64.rem_s + global.set $builtins/I + global.get $builtins/I + i64.const 3 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 149 + i32.const 22 + call $~lib/builtins/abort + unreachable + end f32.const nan:0x400000 drop f32.const inf @@ -1506,7 +1570,7 @@ if i32.const 0 i32.const 96 - i32.const 197 + i32.const 201 i32.const 25 call $~lib/builtins/abort unreachable @@ -1522,7 +1586,7 @@ if i32.const 0 i32.const 96 - i32.const 198 + i32.const 202 i32.const 25 call $~lib/builtins/abort unreachable @@ -1538,7 +1602,7 @@ if i32.const 0 i32.const 96 - i32.const 199 + i32.const 203 i32.const 25 call $~lib/builtins/abort unreachable @@ -1554,7 +1618,7 @@ if i32.const 0 i32.const 96 - i32.const 200 + i32.const 204 i32.const 25 call $~lib/builtins/abort unreachable @@ -1570,7 +1634,7 @@ if i32.const 0 i32.const 96 - i32.const 201 + i32.const 205 i32.const 26 call $~lib/builtins/abort unreachable @@ -1599,7 +1663,7 @@ if i32.const 0 i32.const 96 - i32.const 206 + i32.const 210 i32.const 24 call $~lib/builtins/abort unreachable @@ -1615,7 +1679,7 @@ if i32.const 0 i32.const 96 - i32.const 207 + i32.const 211 i32.const 24 call $~lib/builtins/abort unreachable @@ -1631,7 +1695,7 @@ if i32.const 0 i32.const 96 - i32.const 208 + i32.const 212 i32.const 24 call $~lib/builtins/abort unreachable @@ -1647,7 +1711,7 @@ if i32.const 0 i32.const 96 - i32.const 209 + i32.const 213 i32.const 24 call $~lib/builtins/abort unreachable @@ -1869,7 +1933,7 @@ if i32.const 0 i32.const 96 - i32.const 265 + i32.const 269 i32.const 25 call $~lib/builtins/abort unreachable @@ -1885,7 +1949,7 @@ if i32.const 0 i32.const 96 - i32.const 266 + i32.const 270 i32.const 25 call $~lib/builtins/abort unreachable @@ -1901,7 +1965,7 @@ if i32.const 0 i32.const 96 - i32.const 267 + i32.const 271 i32.const 25 call $~lib/builtins/abort unreachable @@ -1917,7 +1981,7 @@ if i32.const 0 i32.const 96 - i32.const 268 + i32.const 272 i32.const 25 call $~lib/builtins/abort unreachable @@ -1950,7 +2014,7 @@ if i32.const 0 i32.const 96 - i32.const 274 + i32.const 278 i32.const 24 call $~lib/builtins/abort unreachable @@ -1966,7 +2030,7 @@ if i32.const 0 i32.const 96 - i32.const 275 + i32.const 279 i32.const 24 call $~lib/builtins/abort unreachable @@ -1982,7 +2046,7 @@ if i32.const 0 i32.const 96 - i32.const 276 + i32.const 280 i32.const 24 call $~lib/builtins/abort unreachable @@ -1998,7 +2062,7 @@ if i32.const 0 i32.const 96 - i32.const 277 + i32.const 281 i32.const 24 call $~lib/builtins/abort unreachable @@ -2312,7 +2376,7 @@ if i32.const 0 i32.const 96 - i32.const 393 + i32.const 397 i32.const 1 call $~lib/builtins/abort unreachable @@ -2333,7 +2397,7 @@ if i32.const 0 i32.const 96 - i32.const 394 + i32.const 398 i32.const 1 call $~lib/builtins/abort unreachable @@ -2361,7 +2425,7 @@ if i32.const 0 i32.const 96 - i32.const 395 + i32.const 399 i32.const 1 call $~lib/builtins/abort unreachable @@ -2379,7 +2443,7 @@ if i32.const 0 i32.const 96 - i32.const 396 + i32.const 400 i32.const 1 call $~lib/builtins/abort unreachable @@ -2397,7 +2461,7 @@ if i32.const 0 i32.const 96 - i32.const 397 + i32.const 401 i32.const 1 call $~lib/builtins/abort unreachable @@ -2425,7 +2489,7 @@ if i32.const 0 i32.const 96 - i32.const 398 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -2967,7 +3031,7 @@ if i32.const 0 i32.const 96 - i32.const 580 + i32.const 584 i32.const 1 call $~lib/builtins/abort unreachable @@ -2980,7 +3044,7 @@ if i32.const 0 i32.const 96 - i32.const 581 + i32.const 585 i32.const 1 call $~lib/builtins/abort unreachable @@ -2993,7 +3057,7 @@ if i32.const 0 i32.const 96 - i32.const 582 + i32.const 586 i32.const 1 call $~lib/builtins/abort unreachable @@ -3006,7 +3070,7 @@ if i32.const 0 i32.const 96 - i32.const 583 + i32.const 587 i32.const 1 call $~lib/builtins/abort unreachable @@ -3019,7 +3083,7 @@ if i32.const 0 i32.const 96 - i32.const 584 + i32.const 588 i32.const 1 call $~lib/builtins/abort unreachable @@ -3032,7 +3096,7 @@ if i32.const 0 i32.const 96 - i32.const 585 + i32.const 589 i32.const 1 call $~lib/builtins/abort unreachable @@ -3045,7 +3109,7 @@ if i32.const 0 i32.const 96 - i32.const 586 + i32.const 590 i32.const 1 call $~lib/builtins/abort unreachable @@ -3085,7 +3149,7 @@ if i32.const 304 i32.const 96 - i32.const 596 + i32.const 600 i32.const 3 call $~lib/builtins/abort unreachable @@ -3097,7 +3161,7 @@ if i32.const 0 i32.const 96 - i32.const 597 + i32.const 601 i32.const 3 call $~lib/builtins/abort unreachable @@ -3109,7 +3173,7 @@ if i32.const 0 i32.const 96 - i32.const 598 + i32.const 602 i32.const 3 call $~lib/builtins/abort unreachable @@ -3121,7 +3185,7 @@ if i32.const 0 i32.const 96 - i32.const 599 + i32.const 603 i32.const 3 call $~lib/builtins/abort unreachable @@ -3143,7 +3207,7 @@ if i32.const 0 i32.const 96 - i32.const 603 + i32.const 607 i32.const 3 call $~lib/builtins/abort unreachable @@ -3165,7 +3229,7 @@ if i32.const 0 i32.const 96 - i32.const 604 + i32.const 608 i32.const 3 call $~lib/builtins/abort unreachable @@ -3187,7 +3251,7 @@ if i32.const 0 i32.const 96 - i32.const 605 + i32.const 609 i32.const 3 call $~lib/builtins/abort unreachable @@ -3209,7 +3273,7 @@ if i32.const 0 i32.const 96 - i32.const 606 + i32.const 610 i32.const 3 call $~lib/builtins/abort unreachable @@ -3231,7 +3295,7 @@ if i32.const 0 i32.const 96 - i32.const 607 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -3253,7 +3317,7 @@ if i32.const 0 i32.const 96 - i32.const 608 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -3275,7 +3339,7 @@ if i32.const 0 i32.const 96 - i32.const 609 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -3297,7 +3361,7 @@ if i32.const 0 i32.const 96 - i32.const 610 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -3319,7 +3383,7 @@ if i32.const 0 i32.const 96 - i32.const 611 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -3341,7 +3405,7 @@ if i32.const 0 i32.const 96 - i32.const 612 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -3363,7 +3427,7 @@ if i32.const 0 i32.const 96 - i32.const 613 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -3385,7 +3449,7 @@ if i32.const 0 i32.const 96 - i32.const 614 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -3407,7 +3471,7 @@ if i32.const 0 i32.const 96 - i32.const 615 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -3429,7 +3493,7 @@ if i32.const 0 i32.const 96 - i32.const 616 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -3451,7 +3515,7 @@ if i32.const 0 i32.const 96 - i32.const 617 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -3473,7 +3537,7 @@ if i32.const 0 i32.const 96 - i32.const 618 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -3495,7 +3559,7 @@ if i32.const 0 i32.const 96 - i32.const 619 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -3517,7 +3581,7 @@ if i32.const 0 i32.const 96 - i32.const 620 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -3539,7 +3603,7 @@ if i32.const 0 i32.const 96 - i32.const 621 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -3561,7 +3625,7 @@ if i32.const 0 i32.const 96 - i32.const 622 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable @@ -3642,7 +3706,7 @@ if i32.const 0 i32.const 96 - i32.const 656 + i32.const 660 i32.const 1 call $~lib/builtins/abort unreachable @@ -3657,7 +3721,7 @@ if i32.const 0 i32.const 96 - i32.const 661 + i32.const 665 i32.const 1 call $~lib/builtins/abort unreachable @@ -3672,7 +3736,7 @@ if i32.const 0 i32.const 96 - i32.const 666 + i32.const 670 i32.const 1 call $~lib/builtins/abort unreachable @@ -3687,7 +3751,7 @@ if i32.const 0 i32.const 96 - i32.const 671 + i32.const 675 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.release.wat b/tests/compiler/builtins.release.wat index 30ac6324d7..c991770d8c 100644 --- a/tests/compiler/builtins.release.wat +++ b/tests/compiler/builtins.release.wat @@ -265,6 +265,10 @@ global.set $builtins/i i32.const 1 global.set $builtins/i + i32.const 1 + global.set $builtins/i + i32.const 3 + global.set $builtins/i i64.const 63 global.set $builtins/I i64.const 0 @@ -297,6 +301,10 @@ global.set $builtins/i i32.const 1 global.set $builtins/i + i64.const 1 + global.set $builtins/I + i64.const 3 + global.set $builtins/I f32.const nan:0x400000 global.set $builtins/f f32.const inf @@ -578,7 +586,7 @@ if i32.const 0 i32.const 1120 - i32.const 393 + i32.const 397 i32.const 1 call $~lib/builtins/abort unreachable @@ -596,7 +604,7 @@ if i32.const 0 i32.const 1120 - i32.const 394 + i32.const 398 i32.const 1 call $~lib/builtins/abort unreachable @@ -618,7 +626,7 @@ if i32.const 0 i32.const 1120 - i32.const 395 + i32.const 399 i32.const 1 call $~lib/builtins/abort unreachable @@ -646,7 +654,7 @@ if i32.const 0 i32.const 1120 - i32.const 398 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -745,7 +753,7 @@ if i32.const 0 i32.const 1120 - i32.const 603 + i32.const 607 i32.const 3 call $~lib/builtins/abort unreachable @@ -764,7 +772,7 @@ if i32.const 0 i32.const 1120 - i32.const 604 + i32.const 608 i32.const 3 call $~lib/builtins/abort unreachable @@ -783,7 +791,7 @@ if i32.const 0 i32.const 1120 - i32.const 605 + i32.const 609 i32.const 3 call $~lib/builtins/abort unreachable @@ -802,7 +810,7 @@ if i32.const 0 i32.const 1120 - i32.const 606 + i32.const 610 i32.const 3 call $~lib/builtins/abort unreachable @@ -821,7 +829,7 @@ if i32.const 0 i32.const 1120 - i32.const 607 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -840,7 +848,7 @@ if i32.const 0 i32.const 1120 - i32.const 608 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -859,7 +867,7 @@ if i32.const 0 i32.const 1120 - i32.const 609 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -878,7 +886,7 @@ if i32.const 0 i32.const 1120 - i32.const 610 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -897,7 +905,7 @@ if i32.const 0 i32.const 1120 - i32.const 611 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -916,7 +924,7 @@ if i32.const 0 i32.const 1120 - i32.const 612 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -935,7 +943,7 @@ if i32.const 0 i32.const 1120 - i32.const 613 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -954,7 +962,7 @@ if i32.const 0 i32.const 1120 - i32.const 614 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -973,7 +981,7 @@ if i32.const 0 i32.const 1120 - i32.const 615 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -992,7 +1000,7 @@ if i32.const 0 i32.const 1120 - i32.const 616 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -1011,7 +1019,7 @@ if i32.const 0 i32.const 1120 - i32.const 617 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -1030,7 +1038,7 @@ if i32.const 0 i32.const 1120 - i32.const 618 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -1049,7 +1057,7 @@ if i32.const 0 i32.const 1120 - i32.const 619 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -1068,7 +1076,7 @@ if i32.const 0 i32.const 1120 - i32.const 620 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -1087,7 +1095,7 @@ if i32.const 0 i32.const 1120 - i32.const 621 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -1106,7 +1114,7 @@ if i32.const 0 i32.const 1120 - i32.const 622 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index 45789fe139..345ab6d04d 100644 --- a/tests/compiler/builtins.ts +++ b/tests/compiler/builtins.ts @@ -107,6 +107,8 @@ i = eq(1, 1); assert(i == 1); i = eq(1, 0); assert(i == 0); i = ne(1, 1); assert(i == 0); i = ne(1, 0); assert(i == 1); +i = rem(1, 3); assert(i == 1); +i = rem(15, 4); assert(i == 3); var I: i64; @@ -143,6 +145,8 @@ i = eq(1, 1); assert(i == 1); i = eq(1, 0); assert(i == 0); i = ne(1, 1); assert(i == 0); i = ne(1, 0); assert(i == 1); +I = rem(1, 3); assert(I == 1); +I = rem(15, 4); assert(I == 3); // floats From e275046a8155a3144c6c219f6596542776e338fc Mon Sep 17 00:00:00 2001 From: Adrien Zinger Date: Fri, 3 Jun 2022 16:58:55 +0200 Subject: [PATCH 2/3] Split `rem` builtins into `rem_s` and `rem_u` --- src/builtins.ts | 36 +++++++-- std/assembly/builtins.ts | 12 ++- std/assembly/index.d.ts | 14 +++- tests/compiler/builtins.debug.wat | 114 ++++++++++++++++++---------- tests/compiler/builtins.release.wat | 48 ++++++------ tests/compiler/builtins.ts | 4 + 6 files changed, 149 insertions(+), 79 deletions(-) diff --git a/src/builtins.ts b/src/builtins.ts index a7acba39ba..8859d4e237 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -270,8 +270,10 @@ export namespace BuiltinNames { export const f32_ne = "~lib/builtins/f32.ne"; export const f64_ne = "~lib/builtins/f64.ne"; - export const i32_rem = "~lib/builtins/i32.rem"; - export const i64_rem = "~lib/builtins/i64.rem"; + export const i32_rem_s = "~lib/builtins/i32.rem_s"; + export const i32_rem_u = "~lib/builtins/i32.rem_u"; + export const i64_rem_s = "~lib/builtins/i64.rem_s"; + export const i64_rem_u = "~lib/builtins/i64.rem_u"; export const i32_load8_s = "~lib/builtins/i32.load8_s"; export const i32_load8_u = "~lib/builtins/i32.load8_u"; @@ -6696,23 +6698,41 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.f64_trunc, builtin_f64_trunc); -// i32.rem -> rem -function builtin_i32_rem(ctx: BuiltinContext): ExpressionRef { +// i32.rem_s -> rem +function builtin_i32_rem_s(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.i32 ]; ctx.contextualType = Type.i32; return builtin_rem(ctx); } -builtins.set(BuiltinNames.i32_rem, builtin_i32_rem); +builtins.set(BuiltinNames.i32_rem_s, builtin_i32_rem_s); -// i64.rem -> rem -function builtin_i64_rem(ctx: BuiltinContext): ExpressionRef { +// i32.rem_u -> rem +function builtin_i32_rem_u(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.u32 ]; + ctx.contextualType = Type.u32; + return builtin_rem(ctx); +} +builtins.set(BuiltinNames.i32_rem_u, builtin_i32_rem_u); + +// i64.rem_s -> rem +function builtin_i64_rem_s(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.i64 ]; ctx.contextualType = Type.i64; return builtin_rem(ctx); } -builtins.set(BuiltinNames.i64_rem, builtin_i64_rem); +builtins.set(BuiltinNames.i64_rem_s, builtin_i64_rem_s); + +// i64.rem_u -> rem +function builtin_i64_rem_u(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.u64 ]; + ctx.contextualType = Type.u64; + return builtin_rem(ctx); +} +builtins.set(BuiltinNames.i64_rem_u, builtin_i64_rem_u); // i32.add -> add function builtin_i32_add(ctx: BuiltinContext): ExpressionRef { diff --git a/std/assembly/builtins.ts b/std/assembly/builtins.ts index efd0991be5..20a7bd9fc3 100644 --- a/std/assembly/builtins.ts +++ b/std/assembly/builtins.ts @@ -356,7 +356,11 @@ export namespace i32 { // @ts-ignore: decorator @builtin - export declare function rem(left: i32, right: i32): i32; + export declare function rem_s(left: i32, right: i32): i32; + + // @ts-ignore: decorator + @builtin + export declare function rem_u(left: u32, right: u32): u32; // @ts-ignore: decorator @builtin @@ -611,7 +615,11 @@ export namespace i64 { // @ts-ignore: decorator @builtin - export declare function rem(left: i64, right: i64): i64; + export declare function rem_s(left: i64, right: i64): i64; + + // @ts-ignore: decorator + @builtin + export declare function rem_u(left: u64, right: u64): u64; // @ts-ignore: decorator @builtin diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index bf6a86b0a2..15ca5352f5 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -348,8 +348,11 @@ declare namespace i32 { export function eq(left: i32, right: i32): i32; /** Return 0 if two 32-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i32, right: i32): i32; - /** Compute the remaining between two 32-bit positive integers. */ - export function rem(left: i32, right: i32): i32; + /** Compute the remaining between two 32-bit signed positive integers. */ + export function rem_s(left: i32, right: i32): i32; + /** Compute the remaining between two 32-bit unsigned positive integers. */ + export function rem_u(left: u32, right: u32): u32; + /** Atomic 32-bit integer operations. */ export namespace atomic { /** Atomically loads an 8-bit unsigned integer value from memory and returns it as a 32-bit integer. */ @@ -474,8 +477,11 @@ declare namespace i64 { export function eq(left: i64, right: i64): i32; /** Return 0 if two 64-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i64, right: i64): i32; - /** Compute the remaining between two 64-bit positive integers. */ - export function rem(left: i64, right: i64): i64; + /** Compute the remaining between two 64-bit signed positive integers. */ + export function rem_s(left: i64, right: i64): i64; + /** Compute the remaining between two 64-bit unsigned positive integers. */ + export function rem_u(left: u64, right: u64): u64; + /** Atomic 64-bit integer operations. */ export namespace atomic { /** Atomically loads an 8-bit unsigned integer value from memory and returns it as a 64-bit integer. */ diff --git a/tests/compiler/builtins.debug.wat b/tests/compiler/builtins.debug.wat index 4d0df3cb98..cce4522155 100644 --- a/tests/compiler/builtins.debug.wat +++ b/tests/compiler/builtins.debug.wat @@ -2247,6 +2247,22 @@ i32.const 8 i64.load global.set $builtins/I + i32.const 15 + i32.const 4 + i32.rem_u + global.set $builtins/u + global.get $builtins/u + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 343 + i32.const 23 + call $~lib/builtins/abort + unreachable + end i32.const 8 i64.load8_u global.set $builtins/U @@ -2284,6 +2300,22 @@ i32.const 1 i64.extend_i32_s i64.store + i64.const 15 + i64.const 4 + i64.rem_u + global.set $builtins/U + global.get $builtins/U + i64.const 3 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 362 + i32.const 23 + call $~lib/builtins/abort + unreachable + end f32.const 1.25 i32.reinterpret_f32 drop @@ -2376,7 +2408,7 @@ if i32.const 0 i32.const 96 - i32.const 397 + i32.const 401 i32.const 1 call $~lib/builtins/abort unreachable @@ -2397,7 +2429,7 @@ if i32.const 0 i32.const 96 - i32.const 398 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -2425,7 +2457,7 @@ if i32.const 0 i32.const 96 - i32.const 399 + i32.const 403 i32.const 1 call $~lib/builtins/abort unreachable @@ -2443,7 +2475,7 @@ if i32.const 0 i32.const 96 - i32.const 400 + i32.const 404 i32.const 1 call $~lib/builtins/abort unreachable @@ -2461,7 +2493,7 @@ if i32.const 0 i32.const 96 - i32.const 401 + i32.const 405 i32.const 1 call $~lib/builtins/abort unreachable @@ -2489,7 +2521,7 @@ if i32.const 0 i32.const 96 - i32.const 402 + i32.const 406 i32.const 1 call $~lib/builtins/abort unreachable @@ -3031,7 +3063,7 @@ if i32.const 0 i32.const 96 - i32.const 584 + i32.const 588 i32.const 1 call $~lib/builtins/abort unreachable @@ -3044,7 +3076,7 @@ if i32.const 0 i32.const 96 - i32.const 585 + i32.const 589 i32.const 1 call $~lib/builtins/abort unreachable @@ -3057,7 +3089,7 @@ if i32.const 0 i32.const 96 - i32.const 586 + i32.const 590 i32.const 1 call $~lib/builtins/abort unreachable @@ -3070,7 +3102,7 @@ if i32.const 0 i32.const 96 - i32.const 587 + i32.const 591 i32.const 1 call $~lib/builtins/abort unreachable @@ -3083,7 +3115,7 @@ if i32.const 0 i32.const 96 - i32.const 588 + i32.const 592 i32.const 1 call $~lib/builtins/abort unreachable @@ -3096,7 +3128,7 @@ if i32.const 0 i32.const 96 - i32.const 589 + i32.const 593 i32.const 1 call $~lib/builtins/abort unreachable @@ -3109,7 +3141,7 @@ if i32.const 0 i32.const 96 - i32.const 590 + i32.const 594 i32.const 1 call $~lib/builtins/abort unreachable @@ -3149,7 +3181,7 @@ if i32.const 304 i32.const 96 - i32.const 600 + i32.const 604 i32.const 3 call $~lib/builtins/abort unreachable @@ -3161,7 +3193,7 @@ if i32.const 0 i32.const 96 - i32.const 601 + i32.const 605 i32.const 3 call $~lib/builtins/abort unreachable @@ -3173,7 +3205,7 @@ if i32.const 0 i32.const 96 - i32.const 602 + i32.const 606 i32.const 3 call $~lib/builtins/abort unreachable @@ -3185,7 +3217,7 @@ if i32.const 0 i32.const 96 - i32.const 603 + i32.const 607 i32.const 3 call $~lib/builtins/abort unreachable @@ -3207,7 +3239,7 @@ if i32.const 0 i32.const 96 - i32.const 607 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -3229,7 +3261,7 @@ if i32.const 0 i32.const 96 - i32.const 608 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -3251,7 +3283,7 @@ if i32.const 0 i32.const 96 - i32.const 609 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -3273,7 +3305,7 @@ if i32.const 0 i32.const 96 - i32.const 610 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -3295,7 +3327,7 @@ if i32.const 0 i32.const 96 - i32.const 611 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -3317,7 +3349,7 @@ if i32.const 0 i32.const 96 - i32.const 612 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -3339,7 +3371,7 @@ if i32.const 0 i32.const 96 - i32.const 613 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -3361,7 +3393,7 @@ if i32.const 0 i32.const 96 - i32.const 614 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -3383,7 +3415,7 @@ if i32.const 0 i32.const 96 - i32.const 615 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -3405,7 +3437,7 @@ if i32.const 0 i32.const 96 - i32.const 616 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -3427,7 +3459,7 @@ if i32.const 0 i32.const 96 - i32.const 617 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -3449,7 +3481,7 @@ if i32.const 0 i32.const 96 - i32.const 618 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -3471,7 +3503,7 @@ if i32.const 0 i32.const 96 - i32.const 619 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -3493,7 +3525,7 @@ if i32.const 0 i32.const 96 - i32.const 620 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -3515,7 +3547,7 @@ if i32.const 0 i32.const 96 - i32.const 621 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -3537,7 +3569,7 @@ if i32.const 0 i32.const 96 - i32.const 622 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable @@ -3559,7 +3591,7 @@ if i32.const 0 i32.const 96 - i32.const 623 + i32.const 627 i32.const 3 call $~lib/builtins/abort unreachable @@ -3581,7 +3613,7 @@ if i32.const 0 i32.const 96 - i32.const 624 + i32.const 628 i32.const 3 call $~lib/builtins/abort unreachable @@ -3603,7 +3635,7 @@ if i32.const 0 i32.const 96 - i32.const 625 + i32.const 629 i32.const 3 call $~lib/builtins/abort unreachable @@ -3625,7 +3657,7 @@ if i32.const 0 i32.const 96 - i32.const 626 + i32.const 630 i32.const 3 call $~lib/builtins/abort unreachable @@ -3706,7 +3738,7 @@ if i32.const 0 i32.const 96 - i32.const 660 + i32.const 664 i32.const 1 call $~lib/builtins/abort unreachable @@ -3721,7 +3753,7 @@ if i32.const 0 i32.const 96 - i32.const 665 + i32.const 669 i32.const 1 call $~lib/builtins/abort unreachable @@ -3736,7 +3768,7 @@ if i32.const 0 i32.const 96 - i32.const 670 + i32.const 674 i32.const 1 call $~lib/builtins/abort unreachable @@ -3751,7 +3783,7 @@ if i32.const 0 i32.const 96 - i32.const 675 + i32.const 679 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.release.wat b/tests/compiler/builtins.release.wat index c991770d8c..cfd0a2d620 100644 --- a/tests/compiler/builtins.release.wat +++ b/tests/compiler/builtins.release.wat @@ -586,7 +586,7 @@ if i32.const 0 i32.const 1120 - i32.const 397 + i32.const 401 i32.const 1 call $~lib/builtins/abort unreachable @@ -604,7 +604,7 @@ if i32.const 0 i32.const 1120 - i32.const 398 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -626,7 +626,7 @@ if i32.const 0 i32.const 1120 - i32.const 399 + i32.const 403 i32.const 1 call $~lib/builtins/abort unreachable @@ -654,7 +654,7 @@ if i32.const 0 i32.const 1120 - i32.const 402 + i32.const 406 i32.const 1 call $~lib/builtins/abort unreachable @@ -753,7 +753,7 @@ if i32.const 0 i32.const 1120 - i32.const 607 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -772,7 +772,7 @@ if i32.const 0 i32.const 1120 - i32.const 608 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -791,7 +791,7 @@ if i32.const 0 i32.const 1120 - i32.const 609 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -810,7 +810,7 @@ if i32.const 0 i32.const 1120 - i32.const 610 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -829,7 +829,7 @@ if i32.const 0 i32.const 1120 - i32.const 611 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -848,7 +848,7 @@ if i32.const 0 i32.const 1120 - i32.const 612 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -867,7 +867,7 @@ if i32.const 0 i32.const 1120 - i32.const 613 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -886,7 +886,7 @@ if i32.const 0 i32.const 1120 - i32.const 614 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -905,7 +905,7 @@ if i32.const 0 i32.const 1120 - i32.const 615 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -924,7 +924,7 @@ if i32.const 0 i32.const 1120 - i32.const 616 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -943,7 +943,7 @@ if i32.const 0 i32.const 1120 - i32.const 617 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -962,7 +962,7 @@ if i32.const 0 i32.const 1120 - i32.const 618 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -981,7 +981,7 @@ if i32.const 0 i32.const 1120 - i32.const 619 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -1000,7 +1000,7 @@ if i32.const 0 i32.const 1120 - i32.const 620 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -1019,7 +1019,7 @@ if i32.const 0 i32.const 1120 - i32.const 621 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -1038,7 +1038,7 @@ if i32.const 0 i32.const 1120 - i32.const 622 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable @@ -1057,7 +1057,7 @@ if i32.const 0 i32.const 1120 - i32.const 623 + i32.const 627 i32.const 3 call $~lib/builtins/abort unreachable @@ -1076,7 +1076,7 @@ if i32.const 0 i32.const 1120 - i32.const 624 + i32.const 628 i32.const 3 call $~lib/builtins/abort unreachable @@ -1095,7 +1095,7 @@ if i32.const 0 i32.const 1120 - i32.const 625 + i32.const 629 i32.const 3 call $~lib/builtins/abort unreachable @@ -1114,7 +1114,7 @@ if i32.const 0 i32.const 1120 - i32.const 626 + i32.const 630 i32.const 3 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index 345ab6d04d..b6411a427a 100644 --- a/tests/compiler/builtins.ts +++ b/tests/compiler/builtins.ts @@ -340,6 +340,8 @@ I = load(8); I = load(8); I = load(8); +u = i32.rem_u(15, 4); assert(u == 3); + var U: u64; U = load(8); U = load(8); @@ -357,6 +359,8 @@ store(8, 1); store(8, 1); // must extend +U = i64.rem_u(15, 4); assert(U == 3); + // reinterpretation reinterpret(1.25); From 1130f0aac50bf058c79d91228484c4e872b53771 Mon Sep 17 00:00:00 2001 From: Adrien Zinger Date: Mon, 6 Jun 2022 08:56:46 +0200 Subject: [PATCH 3/3] Fix typo of rem documentation --- std/assembly/index.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index 15ca5352f5..2df1ef5fac 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -151,7 +151,7 @@ declare function div(left: T, right: T): T; declare function eq(left: T, right: T): i32; /** Return 0 if two numbers are equal to each other, 1 otherwise. */ declare function ne(left: T, right: T): i32; -/** Computes the rem of two positive integers. */ +/** Computes the remainder of two integers. */ declare function rem(left: T, right: T): T; /** Loads a value of the specified type from memory. Equivalent to dereferncing a pointer in other languages. */ declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T; @@ -348,9 +348,9 @@ declare namespace i32 { export function eq(left: i32, right: i32): i32; /** Return 0 if two 32-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i32, right: i32): i32; - /** Compute the remaining between two 32-bit signed positive integers. */ + /** Computes the signed remainder of two 32-bit integers. */ export function rem_s(left: i32, right: i32): i32; - /** Compute the remaining between two 32-bit unsigned positive integers. */ + /** Computes the unsigned remainder of two 32-bit integers. */ export function rem_u(left: u32, right: u32): u32; /** Atomic 32-bit integer operations. */ @@ -477,9 +477,9 @@ declare namespace i64 { export function eq(left: i64, right: i64): i32; /** Return 0 if two 64-bit integers are equal to each other, 1 otherwise. */ export function ne(left: i64, right: i64): i32; - /** Compute the remaining between two 64-bit signed positive integers. */ + /** Computes the signed remainder of two 64-bit integers. */ export function rem_s(left: i64, right: i64): i64; - /** Compute the remaining between two 64-bit unsigned positive integers. */ + /** Computes the unsigned remainder of two 64-bit integers. */ export function rem_u(left: u64, right: u64): u64; /** Atomic 64-bit integer operations. */