diff --git a/NOTICE b/NOTICE index 3e71e4e7bd..73fe008401 100644 --- a/NOTICE +++ b/NOTICE @@ -48,6 +48,7 @@ under the licensing terms detailed in LICENSE: * Syed Jafri * Peter Hayman * ApsarasX +* 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..8859d4e237 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,11 @@ export namespace BuiltinNames { export const f32_ne = "~lib/builtins/f32.ne"; export const f64_ne = "~lib/builtins/f64.ne"; + 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"; export const i32_load16_s = "~lib/builtins/i32.load16_s"; @@ -815,7 +821,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 +2237,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 +6698,42 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.f64_trunc, builtin_f64_trunc); +// 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_s, builtin_i32_rem_s); + +// 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_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 { checkTypeAbsent(ctx); diff --git a/std/assembly/builtins.ts b/std/assembly/builtins.ts index b476c4cd88..20a7bd9fc3 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,14 @@ export namespace i32 { @builtin export declare function ne(left: i32, right:i32): i32; + // @ts-ignore: decorator + @builtin + 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 export declare function reinterpret_f32(value: f32): i32; @@ -601,6 +613,14 @@ export namespace i64 { @builtin export declare function ne(left: i64, right:i64): i32; + // @ts-ignore: decorator + @builtin + 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 export declare function reinterpret_f64(value: f64): i64; diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index e24d742684..2df1ef5fac 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 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; /** Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages when assigning a value. */ @@ -342,10 +344,15 @@ 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; + /** Computes the signed remainder of two 32-bit integers. */ + export function rem_s(left: i32, right: i32): i32; + /** Computes the unsigned remainder of two 32-bit 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. */ @@ -466,10 +473,15 @@ 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; + /** Computes the signed remainder of two 64-bit integers. */ + export function rem_s(left: i64, right: i64): i64; + /** Computes the unsigned remainder of two 64-bit 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 1a89fb333e..cce4522155 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 @@ -2183,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 @@ -2220,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 @@ -2312,7 +2408,7 @@ if i32.const 0 i32.const 96 - i32.const 393 + i32.const 401 i32.const 1 call $~lib/builtins/abort unreachable @@ -2333,7 +2429,7 @@ if i32.const 0 i32.const 96 - i32.const 394 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -2361,7 +2457,7 @@ if i32.const 0 i32.const 96 - i32.const 395 + i32.const 403 i32.const 1 call $~lib/builtins/abort unreachable @@ -2379,7 +2475,7 @@ if i32.const 0 i32.const 96 - i32.const 396 + i32.const 404 i32.const 1 call $~lib/builtins/abort unreachable @@ -2397,7 +2493,7 @@ if i32.const 0 i32.const 96 - i32.const 397 + i32.const 405 i32.const 1 call $~lib/builtins/abort unreachable @@ -2425,7 +2521,7 @@ if i32.const 0 i32.const 96 - i32.const 398 + i32.const 406 i32.const 1 call $~lib/builtins/abort unreachable @@ -2967,7 +3063,7 @@ if i32.const 0 i32.const 96 - i32.const 580 + i32.const 588 i32.const 1 call $~lib/builtins/abort unreachable @@ -2980,7 +3076,7 @@ if i32.const 0 i32.const 96 - i32.const 581 + i32.const 589 i32.const 1 call $~lib/builtins/abort unreachable @@ -2993,7 +3089,7 @@ if i32.const 0 i32.const 96 - i32.const 582 + i32.const 590 i32.const 1 call $~lib/builtins/abort unreachable @@ -3006,7 +3102,7 @@ if i32.const 0 i32.const 96 - i32.const 583 + i32.const 591 i32.const 1 call $~lib/builtins/abort unreachable @@ -3019,7 +3115,7 @@ if i32.const 0 i32.const 96 - i32.const 584 + i32.const 592 i32.const 1 call $~lib/builtins/abort unreachable @@ -3032,7 +3128,7 @@ if i32.const 0 i32.const 96 - i32.const 585 + i32.const 593 i32.const 1 call $~lib/builtins/abort unreachable @@ -3045,7 +3141,7 @@ if i32.const 0 i32.const 96 - i32.const 586 + i32.const 594 i32.const 1 call $~lib/builtins/abort unreachable @@ -3085,7 +3181,7 @@ if i32.const 304 i32.const 96 - i32.const 596 + i32.const 604 i32.const 3 call $~lib/builtins/abort unreachable @@ -3097,7 +3193,7 @@ if i32.const 0 i32.const 96 - i32.const 597 + i32.const 605 i32.const 3 call $~lib/builtins/abort unreachable @@ -3109,7 +3205,7 @@ if i32.const 0 i32.const 96 - i32.const 598 + i32.const 606 i32.const 3 call $~lib/builtins/abort unreachable @@ -3121,7 +3217,7 @@ if i32.const 0 i32.const 96 - i32.const 599 + i32.const 607 i32.const 3 call $~lib/builtins/abort unreachable @@ -3143,7 +3239,7 @@ if i32.const 0 i32.const 96 - i32.const 603 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -3165,7 +3261,7 @@ if i32.const 0 i32.const 96 - i32.const 604 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -3187,7 +3283,7 @@ if i32.const 0 i32.const 96 - i32.const 605 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -3209,7 +3305,7 @@ if i32.const 0 i32.const 96 - i32.const 606 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -3231,7 +3327,7 @@ if i32.const 0 i32.const 96 - i32.const 607 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -3253,7 +3349,7 @@ if i32.const 0 i32.const 96 - i32.const 608 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -3275,7 +3371,7 @@ if i32.const 0 i32.const 96 - i32.const 609 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -3297,7 +3393,7 @@ if i32.const 0 i32.const 96 - i32.const 610 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -3319,7 +3415,7 @@ if i32.const 0 i32.const 96 - i32.const 611 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -3341,7 +3437,7 @@ if i32.const 0 i32.const 96 - i32.const 612 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -3363,7 +3459,7 @@ if i32.const 0 i32.const 96 - i32.const 613 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -3385,7 +3481,7 @@ if i32.const 0 i32.const 96 - i32.const 614 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -3407,7 +3503,7 @@ if i32.const 0 i32.const 96 - i32.const 615 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -3429,7 +3525,7 @@ if i32.const 0 i32.const 96 - i32.const 616 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -3451,7 +3547,7 @@ if i32.const 0 i32.const 96 - i32.const 617 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -3473,7 +3569,7 @@ if i32.const 0 i32.const 96 - i32.const 618 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable @@ -3495,7 +3591,7 @@ if i32.const 0 i32.const 96 - i32.const 619 + i32.const 627 i32.const 3 call $~lib/builtins/abort unreachable @@ -3517,7 +3613,7 @@ if i32.const 0 i32.const 96 - i32.const 620 + i32.const 628 i32.const 3 call $~lib/builtins/abort unreachable @@ -3539,7 +3635,7 @@ if i32.const 0 i32.const 96 - i32.const 621 + i32.const 629 i32.const 3 call $~lib/builtins/abort unreachable @@ -3561,7 +3657,7 @@ if i32.const 0 i32.const 96 - i32.const 622 + i32.const 630 i32.const 3 call $~lib/builtins/abort unreachable @@ -3642,7 +3738,7 @@ if i32.const 0 i32.const 96 - i32.const 656 + i32.const 664 i32.const 1 call $~lib/builtins/abort unreachable @@ -3657,7 +3753,7 @@ if i32.const 0 i32.const 96 - i32.const 661 + i32.const 669 i32.const 1 call $~lib/builtins/abort unreachable @@ -3672,7 +3768,7 @@ if i32.const 0 i32.const 96 - i32.const 666 + i32.const 674 i32.const 1 call $~lib/builtins/abort unreachable @@ -3687,7 +3783,7 @@ if i32.const 0 i32.const 96 - i32.const 671 + 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 30ac6324d7..cfd0a2d620 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 401 i32.const 1 call $~lib/builtins/abort unreachable @@ -596,7 +604,7 @@ if i32.const 0 i32.const 1120 - i32.const 394 + i32.const 402 i32.const 1 call $~lib/builtins/abort unreachable @@ -618,7 +626,7 @@ if i32.const 0 i32.const 1120 - i32.const 395 + i32.const 403 i32.const 1 call $~lib/builtins/abort unreachable @@ -646,7 +654,7 @@ if i32.const 0 i32.const 1120 - i32.const 398 + i32.const 406 i32.const 1 call $~lib/builtins/abort unreachable @@ -745,7 +753,7 @@ if i32.const 0 i32.const 1120 - i32.const 603 + i32.const 611 i32.const 3 call $~lib/builtins/abort unreachable @@ -764,7 +772,7 @@ if i32.const 0 i32.const 1120 - i32.const 604 + i32.const 612 i32.const 3 call $~lib/builtins/abort unreachable @@ -783,7 +791,7 @@ if i32.const 0 i32.const 1120 - i32.const 605 + i32.const 613 i32.const 3 call $~lib/builtins/abort unreachable @@ -802,7 +810,7 @@ if i32.const 0 i32.const 1120 - i32.const 606 + i32.const 614 i32.const 3 call $~lib/builtins/abort unreachable @@ -821,7 +829,7 @@ if i32.const 0 i32.const 1120 - i32.const 607 + i32.const 615 i32.const 3 call $~lib/builtins/abort unreachable @@ -840,7 +848,7 @@ if i32.const 0 i32.const 1120 - i32.const 608 + i32.const 616 i32.const 3 call $~lib/builtins/abort unreachable @@ -859,7 +867,7 @@ if i32.const 0 i32.const 1120 - i32.const 609 + i32.const 617 i32.const 3 call $~lib/builtins/abort unreachable @@ -878,7 +886,7 @@ if i32.const 0 i32.const 1120 - i32.const 610 + i32.const 618 i32.const 3 call $~lib/builtins/abort unreachable @@ -897,7 +905,7 @@ if i32.const 0 i32.const 1120 - i32.const 611 + i32.const 619 i32.const 3 call $~lib/builtins/abort unreachable @@ -916,7 +924,7 @@ if i32.const 0 i32.const 1120 - i32.const 612 + i32.const 620 i32.const 3 call $~lib/builtins/abort unreachable @@ -935,7 +943,7 @@ if i32.const 0 i32.const 1120 - i32.const 613 + i32.const 621 i32.const 3 call $~lib/builtins/abort unreachable @@ -954,7 +962,7 @@ if i32.const 0 i32.const 1120 - i32.const 614 + i32.const 622 i32.const 3 call $~lib/builtins/abort unreachable @@ -973,7 +981,7 @@ if i32.const 0 i32.const 1120 - i32.const 615 + i32.const 623 i32.const 3 call $~lib/builtins/abort unreachable @@ -992,7 +1000,7 @@ if i32.const 0 i32.const 1120 - i32.const 616 + i32.const 624 i32.const 3 call $~lib/builtins/abort unreachable @@ -1011,7 +1019,7 @@ if i32.const 0 i32.const 1120 - i32.const 617 + i32.const 625 i32.const 3 call $~lib/builtins/abort unreachable @@ -1030,7 +1038,7 @@ if i32.const 0 i32.const 1120 - i32.const 618 + i32.const 626 i32.const 3 call $~lib/builtins/abort unreachable @@ -1049,7 +1057,7 @@ if i32.const 0 i32.const 1120 - i32.const 619 + i32.const 627 i32.const 3 call $~lib/builtins/abort unreachable @@ -1068,7 +1076,7 @@ if i32.const 0 i32.const 1120 - i32.const 620 + i32.const 628 i32.const 3 call $~lib/builtins/abort unreachable @@ -1087,7 +1095,7 @@ if i32.const 0 i32.const 1120 - i32.const 621 + i32.const 629 i32.const 3 call $~lib/builtins/abort unreachable @@ -1106,7 +1114,7 @@ if i32.const 0 i32.const 1120 - i32.const 622 + i32.const 630 i32.const 3 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index 45789fe139..b6411a427a 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 @@ -336,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); @@ -353,6 +359,8 @@ store(8, 1); store(8, 1); // must extend +U = i64.rem_u(15, 4); assert(U == 3); + // reinterpretation reinterpret(1.25);