diff --git a/src/builtins.ts b/src/builtins.ts index eb995b8c88..396cb9da5b 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -144,6 +144,7 @@ export namespace BuiltinNames { export const add = "~lib/builtins/add"; export const sub = "~lib/builtins/sub"; export const mul = "~lib/builtins/mul"; + export const div = "~lib/builtins/div"; export const clz = "~lib/builtins/clz"; export const ctz = "~lib/builtins/ctz"; export const popcnt = "~lib/builtins/popcnt"; @@ -249,6 +250,12 @@ export namespace BuiltinNames { export const i64_mul = "~lib/builtins/i64.mul"; export const f32_mul = "~lib/builtins/f32.mul"; export const f64_mul = "~lib/builtins/f64.mul"; + export const i32_div_s = "~lib/builtins/i32.div_s"; + export const i32_div_u = "~lib/builtins/i32.div_u"; + export const i64_div_s = "~lib/builtins/i64.div_s"; + export const i64_div_u = "~lib/builtins/i64.div_u"; + export const f32_div = "~lib/builtins/f32.div"; + export const f64_div = "~lib/builtins/f64.div"; export const i32_load8_s = "~lib/builtins/i32.load8_s"; export const i32_load8_u = "~lib/builtins/i32.load8_u"; @@ -2293,6 +2300,60 @@ function builtin_mul(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.mul, builtin_mul); +// div(left: T, right: T) -> T +function builtin_div(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.isValue) { + 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.isNumericValue) { + return compiler.makeDiv(arg0, arg1, type); + } + } + compiler.error( + DiagnosticCode.Operation_0_cannot_be_applied_to_type_1, + ctx.reportNode.typeArgumentsRange, + "div", + type.toString() + ); + return module.unreachable(); +} +builtins.set(BuiltinNames.div, builtin_div); + // === Atomics ================================================================================ // atomic.load(offset: usize, immOffset?: usize) -> T* @@ -5822,6 +5883,24 @@ function builtin_i64_add(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.i64_add, builtin_i64_add); +// f32.add -> add +function builtin_f32_add(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.f32 ]; + ctx.contextualType = Type.f32; + return builtin_add(ctx); +} +builtins.set(BuiltinNames.f32_add, builtin_f32_add); + +// f64.add -> add +function builtin_f64_add(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.f64 ]; + ctx.contextualType = Type.f64; + return builtin_add(ctx); +} +builtins.set(BuiltinNames.f64_add, builtin_f64_add); + // i32.sub -> sub function builtin_i32_sub(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); @@ -5840,6 +5919,24 @@ function builtin_i64_sub(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.i64_sub, builtin_i64_sub); +// f32.sub -> sub +function builtin_f32_sub(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.f32 ]; + ctx.contextualType = Type.f32; + return builtin_sub(ctx); +} +builtins.set(BuiltinNames.f32_sub, builtin_f32_sub); + +// f64.sub -> sub +function builtin_f64_sub(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.f64 ]; + ctx.contextualType = Type.f64; + return builtin_sub(ctx); +} +builtins.set(BuiltinNames.f64_sub, builtin_f64_sub); + // i32.mul -> mul function builtin_i32_mul(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); @@ -5858,59 +5955,77 @@ function builtin_i64_mul(ctx: BuiltinContext): ExpressionRef { } builtins.set(BuiltinNames.i64_mul, builtin_i64_mul); -// f32.add -> add -function builtin_f32_add(ctx: BuiltinContext): ExpressionRef { +// f32.mul -> mul +function builtin_f32_mul(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.f32 ]; ctx.contextualType = Type.f32; - return builtin_add(ctx); + return builtin_mul(ctx); } -builtins.set(BuiltinNames.f32_add, builtin_f32_add); +builtins.set(BuiltinNames.f32_mul, builtin_f32_mul); -// f64.add -> add -function builtin_f64_add(ctx: BuiltinContext): ExpressionRef { +// f64.mul -> mul +function builtin_f64_mul(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.f64 ]; ctx.contextualType = Type.f64; - return builtin_add(ctx); + return builtin_mul(ctx); } -builtins.set(BuiltinNames.f64_add, builtin_f64_add); +builtins.set(BuiltinNames.f64_mul, builtin_f64_mul); -// f32.sub -> sub -function builtin_f32_sub(ctx: BuiltinContext): ExpressionRef { +// i32.div_s -> div +function builtin_i32_div_s(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); - ctx.typeArguments = [ Type.f32 ]; - ctx.contextualType = Type.f32; - return builtin_sub(ctx); + ctx.typeArguments = [ Type.i32 ]; + ctx.contextualType = Type.i32; + return builtin_div(ctx); } -builtins.set(BuiltinNames.f32_sub, builtin_f32_sub); +builtins.set(BuiltinNames.i32_div_s, builtin_i32_div_s); -// f64.sub -> sub -function builtin_f64_sub(ctx: BuiltinContext): ExpressionRef { +// i32.div_u -> div +function builtin_i32_div_u(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); - ctx.typeArguments = [ Type.f64 ]; - ctx.contextualType = Type.f64; - return builtin_sub(ctx); + ctx.typeArguments = [ Type.u32 ]; + ctx.contextualType = Type.u32; + return builtin_div(ctx); } -builtins.set(BuiltinNames.f64_sub, builtin_f64_sub); +builtins.set(BuiltinNames.i32_div_u, builtin_i32_div_u); -// f32.mul -> mul -function builtin_f32_mul(ctx: BuiltinContext): ExpressionRef { +// i64.div_s -> div_s +function builtin_i64_div_s(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.i64 ]; + ctx.contextualType = Type.i64; + return builtin_div(ctx); +} +builtins.set(BuiltinNames.i64_div_s, builtin_i64_div_s); + +// i64.div_u -> div_u +function builtin_i64_div_u(ctx: BuiltinContext): ExpressionRef { + checkTypeAbsent(ctx); + ctx.typeArguments = [ Type.u64 ]; + ctx.contextualType = Type.u64; + return builtin_div(ctx); +} +builtins.set(BuiltinNames.i64_div_u, builtin_i64_div_u); + +// f32.div -> div +function builtin_f32_div(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.f32 ]; ctx.contextualType = Type.f32; - return builtin_mul(ctx); + return builtin_div(ctx); } -builtins.set(BuiltinNames.f32_mul, builtin_f32_mul); +builtins.set(BuiltinNames.f32_div, builtin_f32_div); -// f64.mul -> mul -function builtin_f64_mul(ctx: BuiltinContext): ExpressionRef { +// f64.div -> div +function builtin_f64_div(ctx: BuiltinContext): ExpressionRef { checkTypeAbsent(ctx); ctx.typeArguments = [ Type.f64 ]; ctx.contextualType = Type.f64; - return builtin_mul(ctx); + return builtin_div(ctx); } -builtins.set(BuiltinNames.f64_mul, builtin_f64_mul); +builtins.set(BuiltinNames.f64_div, builtin_f64_div); // i32.load8_s -> load function builtin_i32_load8_s(ctx: BuiltinContext): ExpressionRef { diff --git a/std/assembly/builtins.ts b/std/assembly/builtins.ts index 0638f842cb..da8c88c33f 100644 --- a/std/assembly/builtins.ts +++ b/std/assembly/builtins.ts @@ -132,6 +132,10 @@ export declare function sub(left: T, right: T): T; @builtin export declare function mul(left: T, right: T): T; +// @ts-ignore: decorator +@builtin +export declare function div(left: T, right: T): T; + // @ts-ignore: decorator @unsafe @builtin export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T; @@ -314,6 +318,14 @@ export namespace i32 { @builtin export declare function mul(left: i32, right:i32): i32; + // @ts-ignore: decorator + @builtin + export declare function div_s(left: i32, right:i32): i32; + + // @ts-ignore: decorator + @builtin + export declare function div_u(left: i32, right:i32): i32; + // @ts-ignore: decorator @builtin export declare function rotl(value: i32, shift: i32): i32; @@ -515,7 +527,15 @@ export namespace i64 { // @ts-ignore: decorator @builtin - export declare function mul(left: i64, right:i64): i64; + export declare function mul(left: i64, right:i64): i64; + + // @ts-ignore: decorator + @builtin + export declare function div_s(left: i64, right:i64): i64; + + // @ts-ignore: decorator + @builtin + export declare function div_u(left: i64, right:i64): i64; // @ts-ignore: decorator @builtin @@ -952,7 +972,11 @@ export namespace f32 { // @ts-ignore: decorator @builtin - export declare function mul(left: f32, right: f32): f32; + export declare function mul(left: f32, right: f32): f32; + + // @ts-ignore: decorator + @builtin + export declare function div(left: f32, right: f32): f32; } // @ts-ignore: decorator @@ -1055,7 +1079,11 @@ export namespace f64 { // @ts-ignore: decorator @builtin - export declare function mul(left: f64, right: f64): f64; + export declare function mul(left: f64, right: f64): f64; + + // @ts-ignore: decorator + @builtin + export declare function div(left: f64, right: f64): f64; } // @ts-ignore: decorator diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index 3b7ed7f76a..d5e1c48da6 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -119,12 +119,14 @@ declare function select(ifTrue: T, ifFalse: T, condition: bool): T; declare function sqrt(value: T): T; /** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */ declare function trunc(value: T): T; -/** Computes sum of two integers or floats. */ +/** Computes the sum of two integers or floats. */ declare function add(left: T, right: T): T; -/** Computes difference of two integers or floats. */ +/** Computes the difference of two integers or floats. */ declare function sub(left: T, right: T): T; -/** Computes product of two integers or floats. */ +/** Computes the product of two integers or floats. */ declare function mul(left: T, right: T): T; +/** Computes the quotient of two integers or floats. */ +declare function div(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. */ @@ -282,12 +284,28 @@ declare namespace i32 { export function store16(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void; /** Stores a 32-bit integer value to memory. */ export function store(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void; - /** Computes sum of two 32-bit integers */ + /** Performs the sign-agnostic count leading zero bits operation on a 32-bit integer. All zero bits are considered leading if the value is zero. */ + export function clz(value: i32): i32; + /** Performs the sign-agnostic count tailing zero bits operation on a 32-bit integer. All zero bits are considered trailing if the value is zero. */ + export function ctz(value: i32): i32; + /** Performs the sign-agnostic count number of one bits operation on a 32-bit integer. */ + export function popcnt(value: i32): i32; + /** Performs the sign-agnostic rotate left operation on a 32-bit integer. */ + export function rotl(value: i32, shift: i32): i32; + /** Performs the sign-agnostic rotate right operation on a 32-bit integer. */ + export function rotr(value: i32, shift: i32): i32; + /** Reinterprets the bits of the specified 32-bit float as a 32-bit integer. */ + export function reinterpret_f32(value: f32): i32; + /** Computes the sum of two 32-bit integers. */ export function add(left: i32, right: i32): i32; - /** Computes difference of two 32-bit integers */ + /** Computes the difference of two 32-bit integers. */ export function sub(left: i32, right: i32): i32; - /** Computes product of two 32-bit integers */ - export function mul(left: i32, right: i32): i32; + /** Computes the product of two 32-bit integers. */ + export function mul(left: i32, right: i32): i32; + /** Computes the signed quotient of two 32-bit integers. */ + 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; /** 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. */ @@ -386,12 +404,28 @@ declare namespace i64 { export function store32(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void; /** Stores a 64-bit integer value to memory. */ export function store(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void; - /** Computes sum of two 64-bit integers */ + /** Performs the sign-agnostic count leading zero bits operation on a 64-bit integer. All zero bits are considered leading if the value is zero. */ + export function clz(value: i64): i64; + /** Performs the sign-agnostic count tailing zero bits operation on a 64-bit integer. All zero bits are considered trailing if the value is zero. */ + export function ctz(value: i64): i64; + /** Performs the sign-agnostic count number of one bits operation on a 64-bit integer. */ + export function popcnt(value: i64): i64; + /** Performs the sign-agnostic rotate left operation on a 64-bit integer. */ + export function rotl(value: i64, shift: i64): i64; + /** Performs the sign-agnostic rotate right operation on a 64-bit integer. */ + export function rotr(value: i64, shift: i64): i64; + /** Reinterprets the bits of the specified 64-bit float as a 64-bit integer. */ + export function reinterpret_f64(value: f64): i64; + /** Computes the sum of two 64-bit integers. */ export function add(left: i64, right: i64): i64; - /** Computes difference of two 64-bit integers */ + /** Computes the difference of two 64-bit integers. */ export function sub(left: i64, right: i64): i64; - /** Computes product of two 64-bit integers */ - export function mul(left: i64, right: i64): i64; + /** Computes the product of two 64-bit integers. */ + export function mul(left: i64, right: i64): i64; + /** Computes the signed quotient of two 64-bit integers. */ + 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; /** 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. */ @@ -551,12 +585,34 @@ declare namespace f32 { export function load(ptr: usize, immOffset?: usize, immAlign?: usize): f32; /** Stores a 32-bit float to memory. */ export function store(ptr: usize, value: f32, immOffset?: usize, immAlign?: usize): void; - /** Computes sum of two 32-bit floats */ + /** Computes the sum of two 32-bit floats. */ export function add(left: f32, right: f32): f32; - /** Computes difference of two 32-bit floats */ + /** Computes the difference of two 32-bit floats. */ export function sub(left: f32, right: f32): f32; - /** Computes product of two 32-bit floats */ - export function mul(left: f32, right: f32): f32; + /** Computes the product of two 32-bit floats. */ + export function mul(left: f32, right: f32): f32; + /** Computes the quotient of two 32-bit floats. */ + export function div(left: f32, right: f32): f32; + /** Computes the absolute value of a 32-bit float. */ + export function abs(value: f32): f32; + /** Determines the maximum of two 32-bit floats. If either operand is `NaN`, returns `NaN`. */ + export function max(left: f32, right: f32): f32; + /** Determines the minimum of two 32-bit floats. If either operand is `NaN`, returns `NaN`. */ + export function min(left: f32, right: f32): f32; + /** Performs the ceiling operation on a 32-bit float. */ + export function ceil(value: f32): f32; + /** Composes a 32-bit float from the magnitude of `x` and the sign of `y`. */ + export function copysign(x: f32, y: f32): f32; + /** Performs the floor operation on a 32-bit float. */ + export function floor(value: f32): f32; + /** Rounds to the nearest integer tied to even of a 32-bit float. */ + export function nearest(value: f32): f32; + /** Reinterprets the bits of the specified 32-bit integer as a 32-bit float. */ + export function reinterpret_i32(value: i32): f32; + /** Calculates the square root of a 32-bit float. */ + export function sqrt(value: f32): f32; + /** Rounds to the nearest integer towards zero of a 32-bit float. */ + export function trunc(value: f32): f32; } /** Converts any other numeric value to a 64-bit float. */ declare function f64(value: any): f64; @@ -583,12 +639,34 @@ declare namespace f64 { export function load(ptr: usize, immOffset?: usize, immAlign?: usize): f64; /** Stores a 64-bit float to memory. */ export function store(ptr: usize, value: f64, immOffset?: usize, immAlign?: usize): void; - /** Computes sum of two 64-bit floats */ + /** Computes the sum of two 64-bit floats. */ export function add(left: f64, right: f64): f64; - /** Computes difference of two 64-bit floats */ + /** Computes the difference of two 64-bit floats. */ export function sub(left: f64, right: f64): f64; - /** Computes product of two 64-bit floats */ - export function mul(left: f64, right: f64): f64; + /** Computes the product of two 64-bit floats. */ + export function mul(left: f64, right: f64): f64; + /** Computes the quotient of two 64-bit floats. */ + export function div(left: f64, right: f64): f64; + /** Computes the absolute value of a 64-bit float. */ + export function abs(value: f64): f64; + /** Determines the maximum of two 64-bit floats. If either operand is `NaN`, returns `NaN`. */ + export function max(left: f64, right: f64): f64; + /** Determines the minimum of two 64-bit floats. If either operand is `NaN`, returns `NaN`. */ + export function min(left: f64, right: f64): f64; + /** Performs the ceiling operation on a 64-bit float. */ + export function ceil(value: f64): f64; + /** Composes a 64-bit float from the magnitude of `x` and the sign of `y`. */ + export function copysign(x: f64, y: f64): f64; + /** Performs the floor operation on a 64-bit float. */ + export function floor(value: f64): f64; + /** Rounds to the nearest integer tied to even of a 64-bit float. */ + export function nearest(value: f64): f64; + /** Reinterprets the bits of the specified 64-bit integer as a 64-bit float. */ + export function reinterpret_i64(value: i64): f64; + /** Calculates the square root of a 64-bit float. */ + export function sqrt(value: f64): f64; + /** Rounds to the nearest integer towards zero of a 64-bit float. */ + export function trunc(value: f64): f64; } /** Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants. */ declare function v128(a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8): v128; diff --git a/tests/compiler/builtins.optimized.wat b/tests/compiler/builtins.optimized.wat index 3f853f3ef8..aa4581c088 100644 --- a/tests/compiler/builtins.optimized.wat +++ b/tests/compiler/builtins.optimized.wat @@ -209,6 +209,8 @@ global.set $builtins/i i32.const 6 global.set $builtins/i + i32.const 3 + global.set $builtins/i i64.const 63 global.set $builtins/I i64.const 0 @@ -231,6 +233,8 @@ global.set $builtins/I i64.const 6 global.set $builtins/I + i64.const 3 + global.set $builtins/I f32.const nan:0x400000 global.set $builtins/f f32.const inf @@ -249,6 +253,8 @@ global.set $builtins/f f32.const 3 global.set $builtins/f + f32.const 3 + global.set $builtins/f f32.const 2.5 global.set $builtins/f f32.const 1.25 @@ -277,6 +283,8 @@ global.set $builtins/F f64.const 3 global.set $builtins/F + f64.const 3 + global.set $builtins/F f64.const 2.5 global.set $builtins/F f64.const 1.25 @@ -303,6 +311,10 @@ global.set $builtins/F f32.const 2 global.set $builtins/f + f64.const 2 + global.set $builtins/F + f32.const 1 + global.set $builtins/f i32.const 8 i32.load global.set $builtins/i @@ -503,7 +515,7 @@ if i32.const 0 i32.const 1088 - i32.const 298 + i32.const 307 i32.const 1 call $~lib/builtins/abort unreachable @@ -518,7 +530,7 @@ if i32.const 0 i32.const 1088 - i32.const 299 + i32.const 308 i32.const 1 call $~lib/builtins/abort unreachable @@ -530,7 +542,7 @@ if i32.const 0 i32.const 1088 - i32.const 300 + i32.const 309 i32.const 1 call $~lib/builtins/abort unreachable @@ -542,7 +554,7 @@ if i32.const 0 i32.const 1088 - i32.const 303 + i32.const 312 i32.const 1 call $~lib/builtins/abort unreachable @@ -621,7 +633,7 @@ if i32.const 0 i32.const 1088 - i32.const 479 + i32.const 494 i32.const 1 call $~lib/builtins/abort unreachable @@ -633,7 +645,7 @@ if i32.const 0 i32.const 1088 - i32.const 480 + i32.const 495 i32.const 1 call $~lib/builtins/abort unreachable @@ -645,7 +657,7 @@ if i32.const 0 i32.const 1088 - i32.const 481 + i32.const 496 i32.const 1 call $~lib/builtins/abort unreachable @@ -655,7 +667,7 @@ if i32.const 0 i32.const 1088 - i32.const 482 + i32.const 497 i32.const 1 call $~lib/builtins/abort unreachable @@ -667,7 +679,7 @@ if i32.const 0 i32.const 1088 - i32.const 483 + i32.const 498 i32.const 1 call $~lib/builtins/abort unreachable @@ -677,7 +689,7 @@ if i32.const 0 i32.const 1088 - i32.const 484 + i32.const 499 i32.const 1 call $~lib/builtins/abort unreachable @@ -687,7 +699,7 @@ if i32.const 0 i32.const 1088 - i32.const 485 + i32.const 500 i32.const 1 call $~lib/builtins/abort unreachable @@ -707,7 +719,7 @@ if i32.const 0 i32.const 1088 - i32.const 502 + i32.const 517 i32.const 3 call $~lib/builtins/abort unreachable @@ -719,7 +731,7 @@ if i32.const 0 i32.const 1088 - i32.const 503 + i32.const 518 i32.const 3 call $~lib/builtins/abort unreachable @@ -731,7 +743,7 @@ if i32.const 0 i32.const 1088 - i32.const 504 + i32.const 519 i32.const 3 call $~lib/builtins/abort unreachable @@ -743,7 +755,7 @@ if i32.const 0 i32.const 1088 - i32.const 505 + i32.const 520 i32.const 3 call $~lib/builtins/abort unreachable @@ -755,7 +767,7 @@ if i32.const 0 i32.const 1088 - i32.const 506 + i32.const 521 i32.const 3 call $~lib/builtins/abort unreachable @@ -767,7 +779,7 @@ if i32.const 0 i32.const 1088 - i32.const 507 + i32.const 522 i32.const 3 call $~lib/builtins/abort unreachable @@ -779,7 +791,7 @@ if i32.const 0 i32.const 1088 - i32.const 508 + i32.const 523 i32.const 3 call $~lib/builtins/abort unreachable @@ -791,7 +803,7 @@ if i32.const 0 i32.const 1088 - i32.const 509 + i32.const 524 i32.const 3 call $~lib/builtins/abort unreachable @@ -803,7 +815,7 @@ if i32.const 0 i32.const 1088 - i32.const 510 + i32.const 525 i32.const 3 call $~lib/builtins/abort unreachable @@ -815,7 +827,7 @@ if i32.const 0 i32.const 1088 - i32.const 511 + i32.const 526 i32.const 3 call $~lib/builtins/abort unreachable @@ -827,7 +839,7 @@ if i32.const 0 i32.const 1088 - i32.const 512 + i32.const 527 i32.const 3 call $~lib/builtins/abort unreachable @@ -839,7 +851,7 @@ if i32.const 0 i32.const 1088 - i32.const 513 + i32.const 528 i32.const 3 call $~lib/builtins/abort unreachable @@ -851,7 +863,7 @@ if i32.const 0 i32.const 1088 - i32.const 514 + i32.const 529 i32.const 3 call $~lib/builtins/abort unreachable @@ -863,7 +875,7 @@ if i32.const 0 i32.const 1088 - i32.const 515 + i32.const 530 i32.const 3 call $~lib/builtins/abort unreachable @@ -875,7 +887,7 @@ if i32.const 0 i32.const 1088 - i32.const 516 + i32.const 531 i32.const 3 call $~lib/builtins/abort unreachable @@ -887,7 +899,7 @@ if i32.const 0 i32.const 1088 - i32.const 517 + i32.const 532 i32.const 3 call $~lib/builtins/abort unreachable @@ -899,7 +911,7 @@ if i32.const 0 i32.const 1088 - i32.const 518 + i32.const 533 i32.const 3 call $~lib/builtins/abort unreachable @@ -911,7 +923,7 @@ if i32.const 0 i32.const 1088 - i32.const 519 + i32.const 534 i32.const 3 call $~lib/builtins/abort unreachable @@ -923,7 +935,7 @@ if i32.const 0 i32.const 1088 - i32.const 520 + i32.const 535 i32.const 3 call $~lib/builtins/abort unreachable @@ -935,7 +947,7 @@ if i32.const 0 i32.const 1088 - i32.const 521 + i32.const 536 i32.const 3 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index 8288498b94..f7b5442565 100644 --- a/tests/compiler/builtins.ts +++ b/tests/compiler/builtins.ts @@ -51,6 +51,7 @@ var l: i8; l = add(1, 2); assert(l == 3); l = sub(2, 1); assert(l == 1); l = mul(1, 2); assert(l == 2); +l = div(6, 2); assert(l == 3); var v: u8; v = rotl(0b10001111, 3); assert(v == 0b01111100); @@ -71,6 +72,7 @@ min(1, 2); add(1, 2); sub(2, 1); mul(1, 2); +div(6, 2); i = clz(1); i = ctz(1); @@ -83,6 +85,7 @@ i = min(1, 2); assert(i == 1); i = add(1, 2); assert(i == 3); i = sub(2, 1); assert(i == 1); i = mul(2, 3); assert(i == 6); +i = div(6, 2); assert(i == 3); var I: i64; clz(1); @@ -103,6 +106,7 @@ I = min(1, 2); assert(I == 1); I = add(1, 2); assert(I == 3); I = sub(2, 1); assert(I == 1); I = mul(2, 3); assert(I == 6); +I = div(6, 2); assert(I == 3); // floats @@ -135,6 +139,7 @@ f = floor(1.25); f = add(1.5, 2.5); assert(f == 4.0); f = sub(2.5, 1.5); assert(f == 1.0); f = mul(1.5, 2.0); assert(f == 3.0); +f = div(1.5, 0.5); assert(f == 3.0); f = max(1.25, 2.5); assert(f == 2.5); f = min(1.25, 2.5); f = nearest(1.25); @@ -156,6 +161,7 @@ floor(1.25); add(1.5, 2.5); sub(2.5, 1.5); mul(1.5, 2.0); +div(1.5, 0.5); max(1.25, 2.5); min(1.25, 2.5); nearest(1.25); @@ -177,6 +183,7 @@ F = floor(1.25); F = add(1.5, 2.5); assert(F == 4.0); F = sub(2.5, 1.5); assert(F == 1.0); F = mul(1.5, 2.0); assert(F == 3.0); +F = div(1.5, 0.5); assert(F == 3.0); F = max(1.25, 2.5); F = min(1.25, 2.5); F = nearest(1.25); @@ -195,6 +202,8 @@ F = sub(2, 1.0); f = sub(2, f); F = mul(2, 1.0); f = mul(2, f); +F = div(2, 1.0); +f = div(2, f); // load and store @@ -418,8 +427,12 @@ i32.add(1, 2); i64.add(1, 2); i32.sub(2, 1); i64.sub(2, 1); -i32.mul(2, 1); -i64.mul(2, 1); +i32.mul(3, 1); +i64.mul(3, 1); +i32.div_s(4, 1); +i32.div_u(4, 1); +i64.div_s(5, 1); +i64.div_u(5, 1); i32.load8_s(8); i32.load8_u(8); @@ -442,6 +455,8 @@ f32.sub(2.0, 1.0); f64.sub(2.0, 1.0); f32.mul(1.0, 2.0); f64.mul(1.0, 2.0); +f32.div(1.5, 0.5); +f64.div(1.5, 0.5); f32.max(1.0, 2.0); f64.max(1.0, 2.0); diff --git a/tests/compiler/builtins.untouched.wat b/tests/compiler/builtins.untouched.wat index 94fb8b047d..ec84ec9289 100644 --- a/tests/compiler/builtins.untouched.wat +++ b/tests/compiler/builtins.untouched.wat @@ -501,6 +501,26 @@ call $~lib/builtins/abort unreachable end + i32.const 6 + i32.const 2 + i32.div_s + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + global.set $builtins/l + global.get $builtins/l + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 80 + i32.const 54 + i32.const 20 + call $~lib/builtins/abort + unreachable + end i32.const 143 local.tee $0 i32.const 3 @@ -526,7 +546,7 @@ if i32.const 0 i32.const 80 - i32.const 56 + i32.const 57 i32.const 34 call $~lib/builtins/abort unreachable @@ -556,7 +576,7 @@ if i32.const 0 i32.const 80 - i32.const 57 + i32.const 58 i32.const 34 call $~lib/builtins/abort unreachable @@ -618,6 +638,10 @@ i32.const 2 i32.mul drop + i32.const 6 + i32.const 2 + i32.div_s + drop i32.const 1 i32.clz global.set $builtins/i @@ -652,7 +676,7 @@ if i32.const 0 i32.const 80 - i32.const 80 + i32.const 82 i32.const 20 call $~lib/builtins/abort unreachable @@ -673,7 +697,7 @@ if i32.const 0 i32.const 80 - i32.const 81 + i32.const 83 i32.const 21 call $~lib/builtins/abort unreachable @@ -694,7 +718,7 @@ if i32.const 0 i32.const 80 - i32.const 82 + i32.const 84 i32.const 21 call $~lib/builtins/abort unreachable @@ -710,7 +734,7 @@ if i32.const 0 i32.const 80 - i32.const 83 + i32.const 85 i32.const 21 call $~lib/builtins/abort unreachable @@ -726,7 +750,7 @@ if i32.const 0 i32.const 80 - i32.const 84 + i32.const 86 i32.const 21 call $~lib/builtins/abort unreachable @@ -742,7 +766,23 @@ if i32.const 0 i32.const 80 - i32.const 85 + i32.const 87 + i32.const 21 + call $~lib/builtins/abort + unreachable + end + i32.const 6 + i32.const 2 + i32.div_s + global.set $builtins/i + global.get $builtins/i + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 80 + i32.const 88 i32.const 21 call $~lib/builtins/abort unreachable @@ -808,7 +848,7 @@ if i32.const 0 i32.const 80 - i32.const 100 + i32.const 103 i32.const 20 call $~lib/builtins/abort unreachable @@ -829,7 +869,7 @@ if i32.const 0 i32.const 80 - i32.const 101 + i32.const 104 i32.const 21 call $~lib/builtins/abort unreachable @@ -850,7 +890,7 @@ if i32.const 0 i32.const 80 - i32.const 102 + i32.const 105 i32.const 21 call $~lib/builtins/abort unreachable @@ -866,7 +906,7 @@ if i32.const 0 i32.const 80 - i32.const 103 + i32.const 106 i32.const 21 call $~lib/builtins/abort unreachable @@ -882,7 +922,7 @@ if i32.const 0 i32.const 80 - i32.const 104 + i32.const 107 i32.const 21 call $~lib/builtins/abort unreachable @@ -898,7 +938,23 @@ if i32.const 0 i32.const 80 - i32.const 105 + i32.const 108 + i32.const 21 + call $~lib/builtins/abort + unreachable + end + i64.const 6 + i64.const 2 + i64.div_s + global.set $builtins/I + global.get $builtins/I + i64.const 3 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 80 + i32.const 109 i32.const 21 call $~lib/builtins/abort unreachable @@ -1016,7 +1072,7 @@ if i32.const 0 i32.const 80 - i32.const 135 + i32.const 139 i32.const 25 call $~lib/builtins/abort unreachable @@ -1032,7 +1088,7 @@ if i32.const 0 i32.const 80 - i32.const 136 + i32.const 140 i32.const 25 call $~lib/builtins/abort unreachable @@ -1048,7 +1104,23 @@ if i32.const 0 i32.const 80 - i32.const 137 + i32.const 141 + i32.const 25 + call $~lib/builtins/abort + unreachable + end + f32.const 1.5 + f32.const 0.5 + f32.div + global.set $builtins/f + global.get $builtins/f + f32.const 3 + f32.eq + i32.eqz + if + i32.const 0 + i32.const 80 + i32.const 142 i32.const 25 call $~lib/builtins/abort unreachable @@ -1064,7 +1136,7 @@ if i32.const 0 i32.const 80 - i32.const 138 + i32.const 143 i32.const 26 call $~lib/builtins/abort unreachable @@ -1127,6 +1199,10 @@ f64.const 2 f64.mul drop + f64.const 1.5 + f64.const 0.5 + f64.div + drop f64.const 1.25 f64.const 2.5 f64.max @@ -1223,7 +1299,7 @@ if i32.const 0 i32.const 80 - i32.const 177 + i32.const 183 i32.const 25 call $~lib/builtins/abort unreachable @@ -1239,7 +1315,7 @@ if i32.const 0 i32.const 80 - i32.const 178 + i32.const 184 i32.const 25 call $~lib/builtins/abort unreachable @@ -1255,7 +1331,23 @@ if i32.const 0 i32.const 80 - i32.const 179 + i32.const 185 + i32.const 25 + call $~lib/builtins/abort + unreachable + end + f64.const 1.5 + f64.const 0.5 + f64.div + global.set $builtins/F + global.get $builtins/F + f64.const 3 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 80 + i32.const 186 i32.const 25 call $~lib/builtins/abort unreachable @@ -1321,6 +1413,14 @@ global.get $builtins/f f32.mul global.set $builtins/f + f64.const 2 + f64.const 1 + f64.div + global.set $builtins/F + f32.const 2 + global.get $builtins/f + f32.div + global.set $builtins/f i32.const 8 i32.load global.set $builtins/i @@ -1578,7 +1678,7 @@ if i32.const 0 i32.const 80 - i32.const 298 + i32.const 307 i32.const 1 call $~lib/builtins/abort unreachable @@ -1594,7 +1694,7 @@ if i32.const 0 i32.const 80 - i32.const 299 + i32.const 308 i32.const 1 call $~lib/builtins/abort unreachable @@ -1608,7 +1708,7 @@ if i32.const 0 i32.const 80 - i32.const 300 + i32.const 309 i32.const 1 call $~lib/builtins/abort unreachable @@ -1621,7 +1721,7 @@ if i32.const 0 i32.const 80 - i32.const 301 + i32.const 310 i32.const 1 call $~lib/builtins/abort unreachable @@ -1634,7 +1734,7 @@ if i32.const 0 i32.const 80 - i32.const 302 + i32.const 311 i32.const 1 call $~lib/builtins/abort unreachable @@ -1648,7 +1748,7 @@ if i32.const 0 i32.const 80 - i32.const 303 + i32.const 312 i32.const 1 call $~lib/builtins/abort unreachable @@ -2007,14 +2107,30 @@ i64.const 1 i64.sub drop - i32.const 2 + i32.const 3 i32.const 1 i32.mul drop - i64.const 2 + i64.const 3 i64.const 1 i64.mul drop + i32.const 4 + i32.const 1 + i32.div_s + drop + i32.const 4 + i32.const 1 + i32.div_u + drop + i64.const 5 + i64.const 1 + i64.div_s + drop + i64.const 5 + i64.const 1 + i64.div_u + drop i32.const 8 i32.load8_s drop @@ -2081,6 +2197,14 @@ f64.const 2 f64.mul drop + f32.const 1.5 + f32.const 0.5 + f32.div + drop + f64.const 1.5 + f64.const 0.5 + f64.div + drop f32.const 1 f32.const 2 f32.max @@ -2172,7 +2296,7 @@ if i32.const 0 i32.const 80 - i32.const 479 + i32.const 494 i32.const 1 call $~lib/builtins/abort unreachable @@ -2185,7 +2309,7 @@ if i32.const 0 i32.const 80 - i32.const 480 + i32.const 495 i32.const 1 call $~lib/builtins/abort unreachable @@ -2198,7 +2322,7 @@ if i32.const 0 i32.const 80 - i32.const 481 + i32.const 496 i32.const 1 call $~lib/builtins/abort unreachable @@ -2211,7 +2335,7 @@ if i32.const 0 i32.const 80 - i32.const 482 + i32.const 497 i32.const 1 call $~lib/builtins/abort unreachable @@ -2224,7 +2348,7 @@ if i32.const 0 i32.const 80 - i32.const 483 + i32.const 498 i32.const 1 call $~lib/builtins/abort unreachable @@ -2237,7 +2361,7 @@ if i32.const 0 i32.const 80 - i32.const 484 + i32.const 499 i32.const 1 call $~lib/builtins/abort unreachable @@ -2250,7 +2374,7 @@ if i32.const 0 i32.const 80 - i32.const 485 + i32.const 500 i32.const 1 call $~lib/builtins/abort unreachable @@ -2285,7 +2409,7 @@ if i32.const 288 i32.const 80 - i32.const 495 + i32.const 510 i32.const 3 call $~lib/builtins/abort unreachable @@ -2297,7 +2421,7 @@ if i32.const 0 i32.const 80 - i32.const 496 + i32.const 511 i32.const 3 call $~lib/builtins/abort unreachable @@ -2309,7 +2433,7 @@ if i32.const 0 i32.const 80 - i32.const 497 + i32.const 512 i32.const 3 call $~lib/builtins/abort unreachable @@ -2321,7 +2445,7 @@ if i32.const 0 i32.const 80 - i32.const 498 + i32.const 513 i32.const 3 call $~lib/builtins/abort unreachable @@ -2333,7 +2457,7 @@ if i32.const 0 i32.const 80 - i32.const 502 + i32.const 517 i32.const 3 call $~lib/builtins/abort unreachable @@ -2345,7 +2469,7 @@ if i32.const 0 i32.const 80 - i32.const 503 + i32.const 518 i32.const 3 call $~lib/builtins/abort unreachable @@ -2357,7 +2481,7 @@ if i32.const 0 i32.const 80 - i32.const 504 + i32.const 519 i32.const 3 call $~lib/builtins/abort unreachable @@ -2369,7 +2493,7 @@ if i32.const 0 i32.const 80 - i32.const 505 + i32.const 520 i32.const 3 call $~lib/builtins/abort unreachable @@ -2381,7 +2505,7 @@ if i32.const 0 i32.const 80 - i32.const 506 + i32.const 521 i32.const 3 call $~lib/builtins/abort unreachable @@ -2393,7 +2517,7 @@ if i32.const 0 i32.const 80 - i32.const 507 + i32.const 522 i32.const 3 call $~lib/builtins/abort unreachable @@ -2405,7 +2529,7 @@ if i32.const 0 i32.const 80 - i32.const 508 + i32.const 523 i32.const 3 call $~lib/builtins/abort unreachable @@ -2417,7 +2541,7 @@ if i32.const 0 i32.const 80 - i32.const 509 + i32.const 524 i32.const 3 call $~lib/builtins/abort unreachable @@ -2429,7 +2553,7 @@ if i32.const 0 i32.const 80 - i32.const 510 + i32.const 525 i32.const 3 call $~lib/builtins/abort unreachable @@ -2441,7 +2565,7 @@ if i32.const 0 i32.const 80 - i32.const 511 + i32.const 526 i32.const 3 call $~lib/builtins/abort unreachable @@ -2453,7 +2577,7 @@ if i32.const 0 i32.const 80 - i32.const 512 + i32.const 527 i32.const 3 call $~lib/builtins/abort unreachable @@ -2465,7 +2589,7 @@ if i32.const 0 i32.const 80 - i32.const 513 + i32.const 528 i32.const 3 call $~lib/builtins/abort unreachable @@ -2477,7 +2601,7 @@ if i32.const 0 i32.const 80 - i32.const 514 + i32.const 529 i32.const 3 call $~lib/builtins/abort unreachable @@ -2489,7 +2613,7 @@ if i32.const 0 i32.const 80 - i32.const 515 + i32.const 530 i32.const 3 call $~lib/builtins/abort unreachable @@ -2501,7 +2625,7 @@ if i32.const 0 i32.const 80 - i32.const 516 + i32.const 531 i32.const 3 call $~lib/builtins/abort unreachable @@ -2513,7 +2637,7 @@ if i32.const 0 i32.const 80 - i32.const 517 + i32.const 532 i32.const 3 call $~lib/builtins/abort unreachable @@ -2525,7 +2649,7 @@ if i32.const 0 i32.const 80 - i32.const 518 + i32.const 533 i32.const 3 call $~lib/builtins/abort unreachable @@ -2537,7 +2661,7 @@ if i32.const 0 i32.const 80 - i32.const 519 + i32.const 534 i32.const 3 call $~lib/builtins/abort unreachable @@ -2549,7 +2673,7 @@ if i32.const 0 i32.const 80 - i32.const 520 + i32.const 535 i32.const 3 call $~lib/builtins/abort unreachable @@ -2561,7 +2685,7 @@ if i32.const 0 i32.const 80 - i32.const 521 + i32.const 536 i32.const 3 call $~lib/builtins/abort unreachable