diff --git a/src/common.ts b/src/common.ts index f2f128775c..67208951db 100644 --- a/src/common.ts +++ b/src/common.ts @@ -214,6 +214,8 @@ export namespace CommonNames { export const trace = "trace"; export const seed = "seed"; export const pow = "pow"; + export const ipow32 = "ipow32"; + export const ipow64 = "ipow64"; export const mod = "mod"; export const alloc = "__alloc"; export const realloc = "__realloc"; diff --git a/src/compiler.ts b/src/compiler.ts index 55eb876ca0..8e6ac83679 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -3855,6 +3855,8 @@ export class Compiler extends DiagnosticEmitter { private f64ModInstance: Function | null = null; private f32PowInstance: Function | null = null; private f64PowInstance: Function | null = null; + private i32PowInstance: Function | null = null; + private i64PowInstance: Function | null = null; private compileBinaryExpression( expression: BinaryExpression, @@ -4786,82 +4788,198 @@ export class Compiler extends DiagnosticEmitter { ); return this.module.unreachable(); } + if (compound) { + leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType); + rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT); + rightType = commonType = this.currentType; + } else { + rightExpr = this.compileExpression(right, leftType); + rightType = this.currentType; + commonType = Type.commonDenominator(leftType, rightType, false); + if (commonType) { + leftExpr = this.convertExpression(leftExpr, + leftType, commonType, + false, true, // ! + left + ); + leftType = commonType; + rightExpr = this.convertExpression(rightExpr, + rightType, commonType, + false, true, // ! + right + ); + rightType = commonType; + } else { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + expression.range, "**", leftType.toString(), rightType.toString() + ); + this.currentType = contextualType; + return module.unreachable(); + } + } - let targetType = leftType; let instance: Function | null; - - // Mathf.pow if lhs is f32 (result is f32) - if (this.currentType.kind == TypeKind.F32) { - rightExpr = this.compileExpression(right, Type.f32, Constraints.CONV_IMPLICIT); - rightType = this.currentType; - instance = this.f32PowInstance; - if (!instance) { - let namespace = this.program.lookupGlobal(CommonNames.Mathf); - if (!namespace) { - this.error( - DiagnosticCode.Cannot_find_name_0, - expression.range, "Mathf" - ); + switch (commonType.kind) { + case TypeKind.BOOL: { + expr = module.select( + module.i32(1), + module.binary(BinaryOp.EqI32, rightExpr, module.i32(0)), + leftExpr + ); + break; + } + case TypeKind.I8: + case TypeKind.U8: + case TypeKind.I16: + case TypeKind.U16: + case TypeKind.I32: + case TypeKind.U32: { + instance = this.i32PowInstance; + if (!instance) { + let prototype = this.program.lookupGlobal(CommonNames.ipow32); + if (!prototype) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "ipow32" + ); + expr = module.unreachable(); + break; + } + assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); + this.i32PowInstance = instance = this.resolver.resolveFunction(prototype, null); + } + if (!instance || !this.compileFunction(instance)) { expr = module.unreachable(); - break; + } else { + expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); + if (commonType.size != 32) { + expr = this.ensureSmallIntegerWrap(expr, commonType); + } } - let namespaceMembers = namespace.members; - if (!namespaceMembers || !namespaceMembers.has(CommonNames.pow)) { - this.error( - DiagnosticCode.Cannot_find_name_0, - expression.range, "Mathf.pow" - ); + break; + } + case TypeKind.I64: + case TypeKind.U64: { + instance = this.i64PowInstance; + if (!instance) { + let prototype = this.program.lookupGlobal(CommonNames.ipow64); + if (!prototype) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "ipow64" + ); + expr = module.unreachable(); + break; + } + assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); + this.i64PowInstance = instance = this.resolver.resolveFunction(prototype, null); + } + if (!instance || !this.compileFunction(instance)) { expr = module.unreachable(); - break; + } else { + expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); } - let prototype = assert(namespaceMembers.get(CommonNames.pow)); - assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); - this.f32PowInstance = instance = this.resolver.resolveFunction(prototype, null); + break; } - - // Math.pow otherwise (result is f64) - // TODO: should the result be converted back? - } else { - leftExpr = this.convertExpression(leftExpr, - this.currentType, Type.f64, - false, false, - left - ); - leftType = this.currentType; - rightExpr = this.compileExpression(right, Type.f64, Constraints.CONV_IMPLICIT); - rightType = this.currentType; - instance = this.f64PowInstance; - if (!instance) { - let namespace = this.program.lookupGlobal(CommonNames.Math); - if (!namespace) { - this.error( - DiagnosticCode.Cannot_find_name_0, - expression.range, "Math" - ); + case TypeKind.ISIZE: + case TypeKind.USIZE: { + let isWasm64 = this.options.isWasm64; + instance = isWasm64 ? this.i64PowInstance : this.i32PowInstance; + if (!instance) { + let prototype = this.program.lookupGlobal(isWasm64 ? CommonNames.ipow64 : CommonNames.ipow32); + if (!prototype) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, isWasm64 ? "ipow64" : "ipow32" + ); + expr = module.unreachable(); + break; + } + assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); + instance = this.resolver.resolveFunction(prototype, null); + if (isWasm64) { + this.i64PowInstance = instance; + } else { + this.i32PowInstance = instance; + } + } + if (!instance || !this.compileFunction(instance)) { expr = module.unreachable(); - break; + } else { + expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); } - let namespaceMembers = namespace.members; - if (!namespaceMembers || !namespaceMembers.has(CommonNames.pow)) { - this.error( - DiagnosticCode.Cannot_find_name_0, - expression.range, "Math.pow" - ); + break; + } + case TypeKind.F32: { + instance = this.f32PowInstance; + if (!instance) { + let namespace = this.program.lookupGlobal(CommonNames.Mathf); + if (!namespace) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "Mathf" + ); + expr = module.unreachable(); + break; + } + let namespaceMembers = namespace.members; + if (!namespaceMembers || !namespaceMembers.has(CommonNames.pow)) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "Mathf.pow" + ); + expr = module.unreachable(); + break; + } + let prototype = assert(namespaceMembers.get(CommonNames.pow)); + assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); + this.f32PowInstance = instance = this.resolver.resolveFunction(prototype, null); + } + if (!instance || !this.compileFunction(instance)) { expr = module.unreachable(); - break; + } else { + expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); } - let prototype = assert(namespaceMembers.get(CommonNames.pow)); - assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); - this.f64PowInstance = instance = this.resolver.resolveFunction(prototype, null); + break; } - } - if (!instance || !this.compileFunction(instance)) { - expr = module.unreachable(); - } else { - expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); - if (compound && targetType != this.currentType) { - // this yields a proper error if target is i32 for example - expr = this.convertExpression(expr, this.currentType, targetType, false, false, expression); + // Math.pow otherwise (result is f64) + case TypeKind.F64: { + instance = this.f64PowInstance; + if (!instance) { + let namespace = this.program.lookupGlobal(CommonNames.Math); + if (!namespace) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "Math" + ); + expr = module.unreachable(); + break; + } + let namespaceMembers = namespace.members; + if (!namespaceMembers || !namespaceMembers.has(CommonNames.pow)) { + this.error( + DiagnosticCode.Cannot_find_name_0, + expression.range, "Math.pow" + ); + expr = module.unreachable(); + break; + } + let prototype = assert(namespaceMembers.get(CommonNames.pow)); + assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE); + this.f64PowInstance = instance = this.resolver.resolveFunction(prototype, null); + } + if (!instance || !this.compileFunction(instance)) { + expr = module.unreachable(); + } else { + expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], expression); + } + break; + } + default: { + assert(false); + expr = module.unreachable(); + break; } } break; diff --git a/src/glue/js/i64.d.ts b/src/glue/js/i64.d.ts index 47f7818b2e..a8a41796fd 100644 --- a/src/glue/js/i64.d.ts +++ b/src/glue/js/i64.d.ts @@ -15,6 +15,7 @@ declare function i64_high(value: i64): i32; declare function i64_add(left: i64, right: i64): i64; declare function i64_sub(left: i64, right: i64): i64; declare function i64_mul(left: i64, right: i64): i64; +declare function i64_pow(left: i64, right: i64): i64; declare function i64_div(left: i64, right: i64): i64; declare function i64_div_u(left: i64, right: i64): i64; declare function i64_rem(left: i64, right: i64): i64; diff --git a/src/glue/js/i64.js b/src/glue/js/i64.js index 18b70578f5..47b634f59d 100644 --- a/src/glue/js/i64.js +++ b/src/glue/js/i64.js @@ -7,9 +7,9 @@ const Long = global.Long || require("long"); -global.i64_zero = Long.ZERO; - -global.i64_one = Long.ONE; +global.i64_zero = Long.ZERO; +global.i64_one = Long.ONE; +global.i64_neg_one = Long.fromInt(-1); global.i64_new = function(lo, hi) { return Long.fromBits(lo, hi); @@ -35,6 +35,31 @@ global.i64_mul = function(left, right) { return left.mul(right); }; +global.i64_pow = function(left, right) { + var rightLo = right.low; + var rightHi = right.high; + if (rightHi <= 0) { + if (rightHi < 0) { + if (left.eq(global.i64_neg_one)) { + return rightLo & 1 ? left : Long.ONE; + } + return left.eq(Long.ONE) ? left : Long.ZERO; + } + if (rightLo == 0) return Long.ONE; + if (rightLo == 1) return left; + if (rightLo == 2) return left.mul(left); + } + var result = Long.ONE; + while (rightLo | rightHi) { + if (rightLo & 1) result = result.mul(left); + right = right.shru(1); + left = left.mul(left); + rightLo = right.low; + rightHi = right.high; + } + return result; +}; + global.i64_div = function(left, right) { return left.div(right); }; diff --git a/src/glue/wasm/i64.ts b/src/glue/wasm/i64.ts index 14ebe1f625..ff69d03c18 100644 --- a/src/glue/wasm/i64.ts +++ b/src/glue/wasm/i64.ts @@ -10,6 +10,9 @@ // @ts-ignore: decorator @global const i64_one: i64 = 1; +// @ts-ignore: decorator +@global const i64_neg_one: i64 = -1; + // @ts-ignore: decorator @global function i64_new(lo: i32, hi: i32 = 0): i64 { @@ -46,6 +49,24 @@ function i64_mul(left: i64, right: i64): i64 { return left * right; } +// @ts-ignore: decorator +@global +function i64_pow(left: i64, right: i64): i64 { + if (right <= 0) { + if (left == -1) return select(-1, 1, right & 1); + return i64(right == 0) | i64(left == 1); + } + if (right == 1) return left; + if (right == 2) return left * left; + var result: i64 = 1; + while (right) { + if (right & 1) result *= left; + right >>>= 1; + left *= left; + } + return result; +} + // @ts-ignore: decorator @global function i64_div(left: i64, right: i64): i64 { diff --git a/src/resolver.ts b/src/resolver.ts index 3cef9ca2c1..39b6f89543 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -2016,7 +2016,7 @@ export class Resolver extends DiagnosticEmitter { return commonType; } - // pow: result is f32 if LHS is f32, otherwise f64, preferring overloads + // pow: result is common type of LHS and RHS, preferring overloads case Token.ASTERISK_ASTERISK: { let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode); @@ -2024,11 +2024,22 @@ export class Resolver extends DiagnosticEmitter { if (leftType.is(TypeFlags.REFERENCE)) { let classReference = leftType.classReference; if (classReference) { - let overload = classReference.lookupOverload(OperatorKind.POW); + let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator)); if (overload) return overload.signature.returnType; } } - return leftType == Type.f32 ? Type.f32 : Type.f64; + let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode); + if (!rightType) return null; + let commonType = Type.commonDenominator(leftType, rightType, false); + if (!commonType) { + if (reportMode == ReportMode.REPORT) { + this.error( + DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, + node.range, leftType.toString(), rightType.toString() + ); + } + } + return commonType; } // shift: result is LHS (RHS is converted to LHS), preferring overloads diff --git a/std/assembly/math.ts b/std/assembly/math.ts index d5c865d39c..97883c503b 100644 --- a/std/assembly/math.ts +++ b/std/assembly/math.ts @@ -3077,37 +3077,35 @@ export namespace NativeMathf { export function ipow32(x: i32, e: i32): i32 { var out = 1; if (ASC_SHRINK_LEVEL < 1) { - if (e < 0) return 0; - - switch (e) { - case 0: return 1; - case 1: return x; - case 2: return x * x; - } - - let log = 32 - clz(e); - if (log <= 5) { + if (e <= 0) { + if (x == -1) return select(-1, 1, e & 1); + return i32(e == 0) | i32(x == 1); + } + else if (e == 1) return x; + else if (e == 2) return x * x; + else if (e < 32) { + let log = 32 - clz(e); // 32 = 2 ^ 5, so need only five cases. // But some extra cases needs for properly overflowing switch (log) { case 5: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 4: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 3: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 2: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 1: { @@ -3117,53 +3115,51 @@ export function ipow32(x: i32, e: i32): i32 { return out; } } - - while (e > 0) { + while (e) { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } return out; } -export function ipow64(x: i64, e: i32): i64 { +export function ipow64(x: i64, e: i64): i64 { var out: i64 = 1; if (ASC_SHRINK_LEVEL < 1) { - if (e < 0) return 0; - switch (e) { - case 0: return 1; - case 1: return x; - case 2: return x * x; - } - - let log = 32 - clz(e); - if (log <= 6) { + if (e <= 0) { + if (x == -1) return select(-1, 1, e & 1); + return i64(e == 0) | i64(x == 1); + } + else if (e == 1) return x; + else if (e == 2) return x * x; + else if (e < 64) { + let log = 64 - clz(e); // 64 = 2 ^ 6, so need only six cases. // But some extra cases needs for properly overflowing switch (log) { case 6: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 5: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 4: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 3: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 2: { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } case 1: { @@ -3173,35 +3169,60 @@ export function ipow64(x: i64, e: i32): i64 { return out; } } - - while (e > 0) { + while (e) { if (e & 1) out *= x; - e >>= 1; + e >>>= 1; x *= x; } return out; } -export function ipow32f(x: f32, e: i32): f32 { - var sign = e >> 31; - e = (e + sign) ^ sign; // abs(e) - var out: f32 = 1; - while (e) { - out *= select(x, 1.0, e & 1); - e >>= 1; - x *= x; - } - return sign ? 1.0 / out : out; +/* +TODO: +In compile time if only exponent is constant we could replace ipow32/ipow64 by shortest addition chains +which usually faster than exponentiation by squaring + +for ipow32 and e < 32: + +let b: i32, c: i32, d: i32, h: i32, k: i32, g: i32; +switch (e) { + case 1: return x; + case 2: return x * x; + case 3: return x * x * x; + case 4: return (b = x * x) * b; + case 5: return (b = x * x) * b * x; + case 6: return (b = x * x) * b * b; + case 7: return (b = x * x) * b * b * x; + case 8: return (d = (b = x * x) * b) * d; + case 9: return (c = x * x * x) * c * c; + case 10: return (d = (b = x * x) * b) * d * b; + case 11: return (d = (b = x * x) * b) * d * b * x; + case 12: return (d = (b = x * x) * b) * d * d; + case 13: return (d = (b = x * x) * b) * d * d * x; + case 14: return (d = (b = x * x) * b) * d * d * b; + case 15: return (k = (b = x * x) * b * x) * k * k; + case 16: return (h = (d = (b = x * x) * b) * d) * h; + case 17: return (h = (d = (b = x * x) * b) * d) * h * x; + case 18: return (h = (d = (b = x * x) * b) * d * x) * h; + case 19: return (h = (d = (b = x * x) * b) * d * x) * h * x; + case 20: return (h = (k = (b = x * x) * b * x) * k) * h; + case 21: return (h = (k = (b = x * x) * b * x) * k) * h * x; + case 22: return (g = (h = (k = (b = x * x) * b * x) * k) * x) * g; + case 23: return (h = (d = (c = (b = x * x) * x) * b) * d) * h * c; + case 24: return (h = (d = (c = x * x * x) * c) * d) * h; + case 25: return (h = (d = (c = x * x * x) * c) * d) * h * x; + case 26: return (g = (h = (d = (c = x * x * x) * c) * d) * x) * g; + case 27: return (h = (d = (c = x * x * x) * c) * d) * h * c; + case 28: return (h = (d = (c = x * x * x) * c * x) * d) * h; + case 29: return (h = (d = (c = x * x * x) * c * x) * d) * h * x; + case 30: return (h = (d = (c = x * x * x) * c) * d * c) * h; + case 31: return (h = (d = (c = x * x * x) * c) * d * c) * h * x; } -export function ipow64f(x: f64, e: i32): f64 { - var sign = e >> 31; - e = (e + sign) ^ sign; // abs(e) - var out = 1.0; - while (e) { - out *= select(x, 1.0, e & 1); - e >>= 1; - x *= x; - } - return sign ? 1.0 / out : out; +for ipow64: TODO +switch (e) { + case 32: + ... + case 63: } +*/ \ No newline at end of file diff --git a/tests/compiler/binary.optimized.wat b/tests/compiler/binary.optimized.wat index 8c9859b186..64f871f36e 100644 --- a/tests/compiler/binary.optimized.wat +++ b/tests/compiler/binary.optimized.wat @@ -1,5 +1,6 @@ (module (type $none_=>_none (func)) + (type $i32_=>_i32 (func (param i32) (result i32))) (type $f32_=>_f32 (func (param f32) (result f32))) (type $f64_=>_f64 (func (param f64) (result f64))) (memory $0 0) @@ -9,6 +10,38 @@ (global $binary/F (mut f64) (f64.const 0)) (export "memory" (memory $0)) (start $~start) + (func $~lib/math/ipow32 (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + i32.const 1 + local.set $1 + i32.const 1 + local.set $2 + loop $while-continue|0 + local.get $1 + if + local.get $0 + local.get $2 + i32.mul + local.get $2 + local.get $1 + i32.const 1 + i32.and + select + local.set $2 + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|0 + end + end + local.get $2 + ) (func $~lib/math/NativeMathf.mod (param $0 f32) (result f32) (local $1 i32) (local $2 i32) @@ -310,6 +343,9 @@ i32.rem_s drop global.get $binary/i + call $~lib/math/ipow32 + drop + global.get $binary/i i32.const 1 i32.add global.set $binary/i @@ -322,8 +358,7 @@ i32.rem_s global.set $binary/i global.get $binary/i - f64.convert_i32_s - i32.trunc_f64_s + call $~lib/math/ipow32 global.set $binary/i global.get $binary/i i32.const 1 diff --git a/tests/compiler/binary.untouched.wat b/tests/compiler/binary.untouched.wat index 75abfb6ac0..383098988f 100644 --- a/tests/compiler/binary.untouched.wat +++ b/tests/compiler/binary.untouched.wat @@ -2,6 +2,7 @@ (type $none_=>_none (func)) (type $f32_f32_=>_f32 (func (param f32 f32) (result f32))) (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (memory $0 1) (data (i32.const 8) "\00\00\00\00\00\a0\f6?\00\00\00\00\00\00\00\00\00\c8\b9\f2\82,\d6\bf\80V7($\b4\fa<\00\00\00\00\00\80\f6?\00\00\00\00\00\00\00\00\00\08X\bf\bd\d1\d5\bf \f7\e0\d8\08\a5\1c\bd\00\00\00\00\00`\f6?\00\00\00\00\00\00\00\00\00XE\17wv\d5\bfmP\b6\d5\a4b#\bd\00\00\00\00\00@\f6?\00\00\00\00\00\00\00\00\00\f8-\87\ad\1a\d5\bf\d5g\b0\9e\e4\84\e6\bc\00\00\00\00\00 \f6?\00\00\00\00\00\00\00\00\00xw\95_\be\d4\bf\e0>)\93i\1b\04\bd\00\00\00\00\00\00\f6?\00\00\00\00\00\00\00\00\00`\1c\c2\8ba\d4\bf\cc\84LH/\d8\13=\00\00\00\00\00\e0\f5?\00\00\00\00\00\00\00\00\00\a8\86\860\04\d4\bf:\0b\82\ed\f3B\dc<\00\00\00\00\00\c0\f5?\00\00\00\00\00\00\00\00\00HiUL\a6\d3\bf`\94Q\86\c6\b1 =\00\00\00\00\00\a0\f5?\00\00\00\00\00\00\00\00\00\80\98\9a\ddG\d3\bf\92\80\c5\d4MY%=\00\00\00\00\00\80\f5?\00\00\00\00\00\00\00\00\00 \e1\ba\e2\e8\d2\bf\d8+\b7\99\1e{&=\00\00\00\00\00`\f5?\00\00\00\00\00\00\00\00\00\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00`\f5?\00\00\00\00\00\00\00\00\00\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00@\f5?\00\00\00\00\00\00\00\00\00x\cf\fbA)\d2\bfv\daS($Z\16\bd\00\00\00\00\00 \f5?\00\00\00\00\00\00\00\00\00\98i\c1\98\c8\d1\bf\04T\e7h\bc\af\1f\bd\00\00\00\00\00\00\f5?\00\00\00\00\00\00\00\00\00\a8\ab\ab\\g\d1\bf\f0\a8\823\c6\1f\1f=\00\00\00\00\00\e0\f4?\00\00\00\00\00\00\00\00\00H\ae\f9\8b\05\d1\bffZ\05\fd\c4\a8&\bd\00\00\00\00\00\c0\f4?\00\00\00\00\00\00\00\00\00\90s\e2$\a3\d0\bf\0e\03\f4~\eek\0c\bd\00\00\00\00\00\a0\f4?\00\00\00\00\00\00\00\00\00\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\a0\f4?\00\00\00\00\00\00\00\00\00\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\80\f4?\00\00\00\00\00\00\00\00\00@^m\18\b9\cf\bf\87<\99\ab*W\0d=\00\00\00\00\00`\f4?\00\00\00\00\00\00\00\00\00`\dc\cb\ad\f0\ce\bf$\af\86\9c\b7&+=\00\00\00\00\00@\f4?\00\00\00\00\00\00\00\00\00\f0*n\07\'\ce\bf\10\ff?TO/\17\bd\00\00\00\00\00 \f4?\00\00\00\00\00\00\00\00\00\c0Ok!\\\cd\bf\1bh\ca\bb\91\ba!=\00\00\00\00\00\00\f4?\00\00\00\00\00\00\00\00\00\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy\'=\00\00\00\00\00\00\f4?\00\00\00\00\00\00\00\00\00\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy\'=\00\00\00\00\00\e0\f3?\00\00\00\00\00\00\00\00\00\90-t\86\c2\cb\bf\8f\b7\8b1\b0N\19=\00\00\00\00\00\c0\f3?\00\00\00\00\00\00\00\00\00\c0\80N\c9\f3\ca\bff\90\cd?cN\ba<\00\00\00\00\00\a0\f3?\00\00\00\00\00\00\00\00\00\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\a0\f3?\00\00\00\00\00\00\00\00\00\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\80\f3?\00\00\00\00\00\00\00\00\00P\f4\9cZR\c9\bf\e3\d4\c1\04\d9\d1*\bd\00\00\00\00\00`\f3?\00\00\00\00\00\00\00\00\00\d0 e\a0\7f\c8\bf\t\fa\db\7f\bf\bd+=\00\00\00\00\00@\f3?\00\00\00\00\00\00\00\00\00\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00@\f3?\00\00\00\00\00\00\00\00\00\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00 \f3?\00\00\00\00\00\00\00\00\00\d0\19\e7\0f\d6\c6\bff\e2\b2\a3j\e4\10\bd\00\00\00\00\00\00\f3?\00\00\00\00\00\00\00\00\00\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\00\f3?\00\00\00\00\00\00\00\00\00\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\e0\f2?\00\00\00\00\00\00\00\00\00\b0\a1\e3\e5&\c5\bf\8f[\07\90\8b\de \bd\00\00\00\00\00\c0\f2?\00\00\00\00\00\00\00\00\00\80\cbl+M\c4\bf\11\0e\bd\00\00\00\00\00\e0\ed?\00\00\00\00\00\00\00\00\00`F\d1;\97\b1?\9b\9e\0dV]2%\bd\00\00\00\00\00\a0\ed?\00\00\00\00\00\00\00\00\00\e0\d1\a7\f5\bd\b3?\d7N\db\a5^\c8,=\00\00\00\00\00`\ed?\00\00\00\00\00\00\00\00\00\a0\97MZ\e9\b5?\1e\1d]<\06i,\bd\00\00\00\00\00@\ed?\00\00\00\00\00\00\00\00\00\c0\ea\n\d3\00\b7?2\ed\9d\a9\8d\1e\ec<\00\00\00\00\00\00\ed?\00\00\00\00\00\00\00\00\00@Y]^3\b9?\daG\bd:\\\11#=\00\00\00\00\00\c0\ec?\00\00\00\00\00\00\00\00\00`\ad\8d\c8j\bb?\e5h\f7+\80\90\13\bd\00\00\00\00\00\a0\ec?\00\00\00\00\00\00\00\00\00@\bc\01X\88\bc?\d3\acZ\c6\d1F&=\00\00\00\00\00`\ec?\00\00\00\00\00\00\00\00\00 \n\839\c7\be?\e0E\e6\afh\c0-\bd\00\00\00\00\00@\ec?\00\00\00\00\00\00\00\00\00\e0\db9\91\e8\bf?\fd\n\a1O\d64%\bd\00\00\00\00\00\00\ec?\00\00\00\00\00\00\00\00\00\e0\'\82\8e\17\c1?\f2\07-\cex\ef!=\00\00\00\00\00\e0\eb?\00\00\00\00\00\00\00\00\00\f0#~+\aa\c1?4\998D\8e\a7,=\00\00\00\00\00\a0\eb?\00\00\00\00\00\00\00\00\00\80\86\0ca\d1\c2?\a1\b4\81\cbl\9d\03=\00\00\00\00\00\80\eb?\00\00\00\00\00\00\00\00\00\90\15\b0\fce\c3?\89rK#\a8/\c6<\00\00\00\00\00@\eb?\00\00\00\00\00\00\00\00\00\b03\83=\91\c4?x\b6\fdTy\83%=\00\00\00\00\00 \eb?\00\00\00\00\00\00\00\00\00\b0\a1\e4\e5\'\c5?\c7}i\e5\e83&=\00\00\00\00\00\e0\ea?\00\00\00\00\00\00\00\00\00\10\8c\beNW\c6?x.<,\8b\cf\19=\00\00\00\00\00\c0\ea?\00\00\00\00\00\00\00\00\00pu\8b\12\f0\c6?\e1!\9c\e5\8d\11%\bd\00\00\00\00\00\a0\ea?\00\00\00\00\00\00\00\00\00PD\85\8d\89\c7?\05C\91p\10f\1c\bd\00\00\00\00\00`\ea?\00\00\00\00\00\00\00\00\00\009\eb\af\be\c8?\d1,\e9\aaT=\07\bd\00\00\00\00\00@\ea?\00\00\00\00\00\00\00\00\00\00\f7\dcZZ\c9?o\ff\a0X(\f2\07=\00\00\00\00\00\00\ea?\00\00\00\00\00\00\00\00\00\e0\8a<\ed\93\ca?i!VPCr(\bd\00\00\00\00\00\e0\e9?\00\00\00\00\00\00\00\00\00\d0[W\d81\cb?\aa\e1\acN\8d5\0c\bd\00\00\00\00\00\c0\e9?\00\00\00\00\00\00\00\00\00\e0;8\87\d0\cb?\b6\12TY\c4K-\bd\00\00\00\00\00\a0\e9?\00\00\00\00\00\00\00\00\00\10\f0\c6\fbo\cc?\d2+\96\c5r\ec\f1\bc\00\00\00\00\00`\e9?\00\00\00\00\00\00\00\00\00\90\d4\b0=\b1\cd?5\b0\15\f7*\ff*\bd\00\00\00\00\00@\e9?\00\00\00\00\00\00\00\00\00\10\e7\ff\0eS\ce?0\f4A`\'\12\c2<\00\00\00\00\00 \e9?\00\00\00\00\00\00\00\00\00\00\dd\e4\ad\f5\ce?\11\8e\bbe\15!\ca\bc\00\00\00\00\00\00\e9?\00\00\00\00\00\00\00\00\00\b0\b3l\1c\99\cf?0\df\0c\ca\ec\cb\1b=\00\00\00\00\00\c0\e8?\00\00\00\00\00\00\00\00\00XM`8q\d0?\91N\ed\16\db\9c\f8<\00\00\00\00\00\a0\e8?\00\00\00\00\00\00\00\00\00`ag-\c4\d0?\e9\ea<\16\8b\18\'=\00\00\00\00\00\80\e8?\00\00\00\00\00\00\00\00\00\e8\'\82\8e\17\d1?\1c\f0\a5c\0e!,\bd\00\00\00\00\00`\e8?\00\00\00\00\00\00\00\00\00\f8\ac\cb\\k\d1?\81\16\a5\f7\cd\9a+=\00\00\00\00\00@\e8?\00\00\00\00\00\00\00\00\00hZc\99\bf\d1?\b7\bdGQ\ed\a6,=\00\00\00\00\00 \e8?\00\00\00\00\00\00\00\00\00\b8\0emE\14\d2?\ea\baF\ba\de\87\n=\00\00\00\00\00\e0\e7?\00\00\00\00\00\00\00\00\00\90\dc|\f0\be\d2?\f4\04PJ\fa\9c*=\00\00\00\00\00\c0\e7?\00\00\00\00\00\00\00\00\00`\d3\e1\f1\14\d3?\b8\9a\ec\ef?\d1f\87\10z^\90\bc\85\7fn\e8\15\e3\ef?\13\f6g5R\d2\8c\be\ef?m{\83]\a6\9a\97<\0f\89\f9lX\b5\ef?\fc\ef\fd\92\1a\b5\8e<\f7Gr+\92\ac\ef?\d1\9c/p=\be><\a2\d1\d32\ec\a3\ef?\0bn\90\894\03j\bc\1b\d3\fe\aff\9b\ef?\0e\bd/*RV\95\bcQ[\12\d0\01\93\ef?U\eaN\8c\ef\80P\bc\cc1l\c0\bd\8a\ef?\16\f4\d5\b9#\c9\91\bc\e0-\a9\ae\9a\82\ef?\afU\\\e9\e3\d3\80\f7\ec\9a<\aa\b9h1\87T\ef?\9d8\86\cb\82\e7\8f\bc\1d\d9\fc\"PM\ef?\8d\c3\a6DAo\8a<\d6\8cb\88;F\ef?}\04\e4\b0\05z\80<\96\dc}\91I?\ef?\94\a8\a8\e3\fd\8e\96<8bunz8\ef?}Ht\f2\18^\87\a9\af\0c\ef?\b6\ab\b0MuM\83<\15\b71\n\fe\06\ef?Lt\ac\e2\01B\86<1\d8L\fcp\01\ef?J\f8\d3]9\dd\8f<\ff\16d\b2\08\fc\ee?\04[\8e;\80\a3\86\bc\f1\9f\92_\c5\f6\ee?hPK\cc\edJ\92\bc\cb\a9:7\a7\f1\ee?\8e-Q\1b\f8\07\99\bcf\d8\05m\ae\ec\ee?\d26\94>\e8\d1q\bc\f7\9f\e54\db\e7\ee?\15\1b\ce\b3\19\19\99\bc\e5\a8\13\c3-\e3\ee?mL*\a7H\9f\85<\"4\12L\a6\de\ee?\8ai(z`\12\93\bc\1c\80\ac\04E\da\ee?[\89\17H\8f\a7X\bc*.\f7!\n\d6\ee?\1b\9aIg\9b,|\bc\97\a8P\d9\f5\d1\ee?\11\ac\c2`\edcC<-\89a`\08\ce\ee?\efd\06;\tf\96Z~d\1fx\bct_\ec\e8u\9f\ee?\b0}\8b\c0J\ee\86\bct\81\a5H\9a\9f\ee?\8a\e6U\1e2\19\86\bc\c9gBV\eb\9f\ee?\d3\d4\t^\cb\9c\90T\'\a4\ee?47;\f1\b6i\93\bc\13\ceL\99\89\a5\ee?\1e\ff\19:\84^\80\bc\ad\c7#F\1a\a7\ee?nWr\d8P\d4\94\bc\ed\92D\9b\d9\a8\ee?\00\8a\0e[g\ad\90<\99f\8a\d9\c7\aa\ee?\b4\ea\f0\c1/\b7\8d<\db\a0*B\e5\ac\ee?\ff\e7\c5\9c`\b6e\bc\8cD\b5\162\af\ee?D_\f3Y\83\f6{<6w\15\99\ae\b1\ee?\83=\1e\a7\1f\t\93\bc\c6\ff\91\0b[\b4\ee?)\1el\8b\b8\a9]\bc\e5\c5\cd\b07\b7\ee?Y\b9\90|\f9#l\bc\0fR\c8\cbD\ba\ee?\aa\f9\f4\"CC\92\bcPN\de\9f\82\bd\ee?K\8ef\d7l\ca\85\bc\ba\07\cap\f1\c0\ee?\'\ce\91+\fc\afq<\90\f0\a3\82\91\c4\ee?\bbs\n\e15\d2m<##\e3\19c\c8\ee?c\"b\"\04\c5\87\bce\e5]{f\cc\ee?\d51\e2\e3\86\1c\8b<3-J\ec\9b\d0\ee?\15\bb\bc\d3\d1\bb\91\bc]%>\b2\03\d5\ee?\d21\ee\9c1\cc\90\b4\07!\d5\82\bc_\9b{3\97|\ef?\c9\0dG;\b9*\89\bc)\a1\f5\14F\86\ef?\d3\88:`\04\b6t<\f6?\8b\e7.\90\ef?qr\9dQ\ec\c5\83<\83L\c7\fbQ\9a\ef?\f0\91\d3\8f\12\f7\8f\bc\da\90\a4\a2\af\a4\ef?}t#\e2\98\ae\8d\bc\f1g\8e-H\af\ef?\08 \aaA\bc\c3\8e<\'Za\ee\1b\ba\ef?2\eb\a9\c3\94+\84<\97\bak7+\c5\ef?\ee\85\d11\a9d\8a<@En[v\d0\ef?\ed\e3;\e4\ba7\8e\bc\14\be\9c\ad\fd\db\ef?\9d\cd\91M;\89w<\d8\90\9e\81\c1\e7\ef?\89\cc`A\c1\05S<\f1q\8f+\c2\f3\ef?") @@ -11,12 +12,217 @@ (global $binary/b (mut i32) (i32.const 0)) (global $binary/i (mut i32) (i32.const 0)) (global $~lib/ASC_SHRINK_LEVEL i32 (i32.const 0)) - (global $~lib/util/math/log_tail (mut f64) (f64.const 0)) (global $binary/I (mut i64) (i64.const 0)) + (global $~lib/util/math/log_tail (mut f64) (f64.const 0)) (global $binary/f (mut f32) (f32.const 0)) (global $binary/F (mut f64) (f64.const 0)) (export "memory" (memory $0)) (start $~start) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select + return + end + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 + end + end + local.get $2 + ) (func $~lib/math/NativeMath.pow (param $0 f64) (param $1 f64) (result f64) (local $2 f64) (local $3 f64) @@ -2159,9 +2365,8 @@ i32.rem_s drop global.get $binary/i - f64.convert_i32_s - f64.const 1 - call $~lib/math/NativeMath.pow + i32.const 1 + call $~lib/math/ipow32 drop global.get $binary/i i32.const 1 @@ -2232,10 +2437,8 @@ i32.rem_s global.set $binary/i global.get $binary/i - f64.convert_i32_s - f64.const 1 - call $~lib/math/NativeMath.pow - i32.trunc_f64_s + i32.const 1 + call $~lib/math/ipow32 global.set $binary/i global.get $binary/i i32.const 1 diff --git a/tests/compiler/resolve-binary.optimized.wat b/tests/compiler/resolve-binary.optimized.wat index 3bf6705315..842873e15a 100644 --- a/tests/compiler/resolve-binary.optimized.wat +++ b/tests/compiler/resolve-binary.optimized.wat @@ -1423,6 +1423,9 @@ end ) (func $start:resolve-binary + (local $0 i32) + (local $1 i32) + (local $2 i32) i32.const 1040 i32.const 1040 call $~lib/string/String.__eq @@ -1800,6 +1803,48 @@ call $~lib/builtins/abort unreachable end + i32.const 2 + local.set $0 + i32.const 2 + local.set $1 + i32.const 1 + local.set $2 + loop $while-continue|0 + local.get $1 + if + local.get $0 + local.get $2 + i32.mul + local.get $2 + local.get $1 + i32.const 1 + i32.and + select + local.set $2 + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|0 + end + end + local.get $2 + call $~lib/number/I32#toString + i32.const 2736 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 1104 + i32.const 144 + i32.const 1 + call $~lib/builtins/abort + unreachable + end call $~lib/number/F64#toString i32.const 2704 call $~lib/string/String.__eq @@ -1807,7 +1852,19 @@ if i32.const 0 i32.const 1104 - i32.const 144 + i32.const 151 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $~lib/number/F64#toString + i32.const 2704 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 1104 + i32.const 158 i32.const 1 call $~lib/builtins/abort unreachable @@ -1820,7 +1877,7 @@ if i32.const 0 i32.const 1104 - i32.const 151 + i32.const 165 i32.const 1 call $~lib/builtins/abort unreachable @@ -1833,7 +1890,7 @@ if i32.const 0 i32.const 1104 - i32.const 156 + i32.const 170 i32.const 1 call $~lib/builtins/abort unreachable @@ -1846,7 +1903,7 @@ if i32.const 0 i32.const 1104 - i32.const 161 + i32.const 175 i32.const 1 call $~lib/builtins/abort unreachable @@ -1859,7 +1916,7 @@ if i32.const 0 i32.const 1104 - i32.const 168 + i32.const 182 i32.const 1 call $~lib/builtins/abort unreachable @@ -1872,7 +1929,7 @@ if i32.const 0 i32.const 1104 - i32.const 173 + i32.const 187 i32.const 1 call $~lib/builtins/abort unreachable @@ -1885,7 +1942,7 @@ if i32.const 0 i32.const 1104 - i32.const 178 + i32.const 192 i32.const 1 call $~lib/builtins/abort unreachable @@ -1898,7 +1955,7 @@ if i32.const 0 i32.const 1104 - i32.const 185 + i32.const 199 i32.const 1 call $~lib/builtins/abort unreachable @@ -1911,7 +1968,7 @@ if i32.const 0 i32.const 1104 - i32.const 190 + i32.const 204 i32.const 1 call $~lib/builtins/abort unreachable @@ -1924,7 +1981,7 @@ if i32.const 0 i32.const 1104 - i32.const 195 + i32.const 209 i32.const 1 call $~lib/builtins/abort unreachable @@ -1937,7 +1994,7 @@ if i32.const 0 i32.const 1104 - i32.const 200 + i32.const 214 i32.const 1 call $~lib/builtins/abort unreachable @@ -1953,7 +2010,7 @@ if i32.const 0 i32.const 1104 - i32.const 261 + i32.const 275 i32.const 1 call $~lib/builtins/abort unreachable @@ -1965,7 +2022,7 @@ if i32.const 0 i32.const 1104 - i32.const 266 + i32.const 280 i32.const 1 call $~lib/builtins/abort unreachable @@ -1977,7 +2034,7 @@ if i32.const 0 i32.const 1104 - i32.const 271 + i32.const 285 i32.const 1 call $~lib/builtins/abort unreachable @@ -1989,7 +2046,7 @@ if i32.const 0 i32.const 1104 - i32.const 276 + i32.const 290 i32.const 1 call $~lib/builtins/abort unreachable @@ -2001,7 +2058,7 @@ if i32.const 0 i32.const 1104 - i32.const 281 + i32.const 295 i32.const 1 call $~lib/builtins/abort unreachable @@ -2013,7 +2070,7 @@ if i32.const 0 i32.const 1104 - i32.const 286 + i32.const 300 i32.const 1 call $~lib/builtins/abort unreachable @@ -2025,7 +2082,7 @@ if i32.const 0 i32.const 1104 - i32.const 291 + i32.const 305 i32.const 1 call $~lib/builtins/abort unreachable @@ -2037,7 +2094,7 @@ if i32.const 0 i32.const 1104 - i32.const 296 + i32.const 310 i32.const 1 call $~lib/builtins/abort unreachable @@ -2049,7 +2106,7 @@ if i32.const 0 i32.const 1104 - i32.const 301 + i32.const 315 i32.const 1 call $~lib/builtins/abort unreachable @@ -2061,7 +2118,7 @@ if i32.const 0 i32.const 1104 - i32.const 306 + i32.const 320 i32.const 1 call $~lib/builtins/abort unreachable @@ -2073,7 +2130,7 @@ if i32.const 0 i32.const 1104 - i32.const 311 + i32.const 325 i32.const 1 call $~lib/builtins/abort unreachable @@ -2085,7 +2142,7 @@ if i32.const 0 i32.const 1104 - i32.const 316 + i32.const 330 i32.const 1 call $~lib/builtins/abort unreachable @@ -2106,7 +2163,7 @@ if i32.const 0 i32.const 1104 - i32.const 334 + i32.const 348 i32.const 1 call $~lib/builtins/abort unreachable @@ -2117,7 +2174,7 @@ if i32.const 0 i32.const 1104 - i32.const 339 + i32.const 353 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/resolve-binary.ts b/tests/compiler/resolve-binary.ts index cdfcb417b1..349a7e3634 100644 --- a/tests/compiler/resolve-binary.ts +++ b/tests/compiler/resolve-binary.ts @@ -140,11 +140,25 @@ assert( "1" ); -// pow +// pow i32 only assert( (2 ** 2).toString() == - "4.0" // TBD + "4" +); + +// pow mixed i32 and f64 +assert( + (2 ** 2.0).toString() + == + "4.0" +); + +// pow mixed f64 and i32 +assert( + (2.0 ** 2).toString() + == + "4.0" ); // shift diff --git a/tests/compiler/resolve-binary.untouched.wat b/tests/compiler/resolve-binary.untouched.wat index bf5e030a72..aab348e14b 100644 --- a/tests/compiler/resolve-binary.untouched.wat +++ b/tests/compiler/resolve-binary.untouched.wat @@ -4682,6 +4682,211 @@ local.get $0 call $~lib/util/number/dtoa ) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select + return + end + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 + end + end + local.get $2 + ) (func $resolve-binary/Foo#constructor (param $0 i32) (result i32) local.get $0 i32.eqz @@ -4922,6 +5127,8 @@ (local $61 i32) (local $62 i32) (local $63 i32) + (local $64 i32) + (local $65 i32) i32.const 1 i32.const 2 i32.lt_s @@ -5402,19 +5609,53 @@ call $~lib/builtins/abort unreachable end + i32.const 2 + i32.const 2 + call $~lib/math/ipow32 + i32.const 10 + call $~lib/number/I32#toString + local.tee $26 + i32.const 9312 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 144 + i32.const 1 + call $~lib/builtins/abort + unreachable + end f64.const 2 f64.const 2 call $~lib/math/NativeMath.pow i32.const 0 call $~lib/number/F64#toString - local.tee $26 + local.tee $27 i32.const 9280 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 144 + i32.const 151 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 2 + f64.const 2 + call $~lib/math/NativeMath.pow + i32.const 0 + call $~lib/number/F64#toString + local.tee $28 + i32.const 9280 + call $~lib/string/String.__eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 158 i32.const 1 call $~lib/builtins/abort unreachable @@ -5424,14 +5665,14 @@ i32.shl i32.const 10 call $~lib/number/I32#toString - local.tee $27 + local.tee $29 i32.const 9312 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 151 + i32.const 165 i32.const 1 call $~lib/builtins/abort unreachable @@ -5441,14 +5682,14 @@ i32.shr_s i32.const 10 call $~lib/number/I32#toString - local.tee $28 + local.tee $30 i32.const 1952 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 156 + i32.const 170 i32.const 1 call $~lib/builtins/abort unreachable @@ -5458,14 +5699,14 @@ i32.shr_u i32.const 10 call $~lib/number/I32#toString - local.tee $29 + local.tee $31 i32.const 9344 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 161 + i32.const 175 i32.const 1 call $~lib/builtins/abort unreachable @@ -5475,14 +5716,14 @@ i32.and i32.const 10 call $~lib/number/I32#toString - local.tee $30 + local.tee $32 i32.const 1952 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 168 + i32.const 182 i32.const 1 call $~lib/builtins/abort unreachable @@ -5492,14 +5733,14 @@ i32.or i32.const 10 call $~lib/number/I32#toString - local.tee $31 + local.tee $33 i32.const 9344 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 173 + i32.const 187 i32.const 1 call $~lib/builtins/abort unreachable @@ -5509,14 +5750,14 @@ i32.xor i32.const 10 call $~lib/number/I32#toString - local.tee $32 + local.tee $34 i32.const 1984 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 178 + i32.const 192 i32.const 1 call $~lib/builtins/abort unreachable @@ -5529,14 +5770,14 @@ end i32.const 10 call $~lib/number/I32#toString - local.tee $33 + local.tee $35 i32.const 1984 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 185 + i32.const 199 i32.const 1 call $~lib/builtins/abort unreachable @@ -5549,14 +5790,14 @@ end i32.const 10 call $~lib/number/I32#toString - local.tee $34 + local.tee $36 i32.const 384 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 190 + i32.const 204 i32.const 1 call $~lib/builtins/abort unreachable @@ -5569,14 +5810,14 @@ end i32.const 10 call $~lib/number/I32#toString - local.tee $35 + local.tee $37 i32.const 1952 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 195 + i32.const 209 i32.const 1 call $~lib/builtins/abort unreachable @@ -5589,14 +5830,14 @@ end i32.const 10 call $~lib/number/I32#toString - local.tee $36 + local.tee $38 i32.const 1984 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 200 + i32.const 214 i32.const 1 call $~lib/builtins/abort unreachable @@ -5607,16 +5848,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#lt - local.tee $37 + local.tee $39 call $~lib/string/String#toString - local.tee $38 + local.tee $40 i32.const 9408 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 261 + i32.const 275 i32.const 1 call $~lib/builtins/abort unreachable @@ -5624,16 +5865,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#gt - local.tee $39 + local.tee $41 call $~lib/string/String#toString - local.tee $40 + local.tee $42 i32.const 9440 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 266 + i32.const 280 i32.const 1 call $~lib/builtins/abort unreachable @@ -5641,16 +5882,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#le - local.tee $41 + local.tee $43 call $~lib/string/String#toString - local.tee $42 + local.tee $44 i32.const 9472 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 271 + i32.const 285 i32.const 1 call $~lib/builtins/abort unreachable @@ -5658,16 +5899,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#ge - local.tee $43 + local.tee $45 call $~lib/string/String#toString - local.tee $44 + local.tee $46 i32.const 9504 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 276 + i32.const 290 i32.const 1 call $~lib/builtins/abort unreachable @@ -5675,16 +5916,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#eq - local.tee $45 + local.tee $47 call $~lib/string/String#toString - local.tee $46 + local.tee $48 i32.const 9536 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 281 + i32.const 295 i32.const 1 call $~lib/builtins/abort unreachable @@ -5692,16 +5933,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#ne - local.tee $47 + local.tee $49 call $~lib/string/String#toString - local.tee $48 + local.tee $50 i32.const 9568 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 286 + i32.const 300 i32.const 1 call $~lib/builtins/abort unreachable @@ -5709,16 +5950,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#add - local.tee $49 + local.tee $51 call $~lib/string/String#toString - local.tee $50 + local.tee $52 i32.const 9600 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 291 + i32.const 305 i32.const 1 call $~lib/builtins/abort unreachable @@ -5726,16 +5967,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo.sub - local.tee $51 + local.tee $53 call $~lib/string/String#toString - local.tee $52 + local.tee $54 i32.const 9632 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 296 + i32.const 310 i32.const 1 call $~lib/builtins/abort unreachable @@ -5743,16 +5984,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#mul - local.tee $53 + local.tee $55 call $~lib/string/String#toString - local.tee $54 + local.tee $56 i32.const 9664 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 301 + i32.const 315 i32.const 1 call $~lib/builtins/abort unreachable @@ -5760,16 +6001,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#div - local.tee $55 + local.tee $57 call $~lib/string/String#toString - local.tee $56 + local.tee $58 i32.const 9696 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 306 + i32.const 320 i32.const 1 call $~lib/builtins/abort unreachable @@ -5777,16 +6018,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#rem - local.tee $57 + local.tee $59 call $~lib/string/String#toString - local.tee $58 + local.tee $60 i32.const 9728 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 311 + i32.const 325 i32.const 1 call $~lib/builtins/abort unreachable @@ -5794,16 +6035,16 @@ global.get $resolve-binary/foo global.get $resolve-binary/foo call $resolve-binary/Foo#pow - local.tee $59 + local.tee $61 call $~lib/string/String#toString - local.tee $60 + local.tee $62 i32.const 9760 call $~lib/string/String.__eq i32.eqz if i32.const 0 i32.const 96 - i32.const 316 + i32.const 330 i32.const 1 call $~lib/builtins/abort unreachable @@ -5817,30 +6058,30 @@ global.get $resolve-binary/bar global.get $resolve-binary/bar2 call $resolve-binary/Bar#add - local.tee $61 - local.tee $62 - global.get $resolve-binary/bar local.tee $63 + local.tee $64 + global.get $resolve-binary/bar + local.tee $65 i32.ne if - local.get $62 + local.get $64 call $~lib/rt/stub/__retain - local.set $62 - local.get $63 + local.set $64 + local.get $65 call $~lib/rt/stub/__release end - local.get $62 + local.get $64 global.set $resolve-binary/bar global.get $resolve-binary/bar call $resolve-binary/Bar#self - local.tee $62 + local.tee $64 global.get $resolve-binary/bar2 i32.eq i32.eqz if i32.const 0 i32.const 96 - i32.const 334 + i32.const 348 i32.const 1 call $~lib/builtins/abort unreachable @@ -5852,7 +6093,7 @@ if i32.const 0 i32.const 96 - i32.const 339 + i32.const 353 i32.const 1 call $~lib/builtins/abort unreachable @@ -5983,6 +6224,10 @@ call $~lib/rt/stub/__release local.get $62 call $~lib/rt/stub/__release + local.get $63 + call $~lib/rt/stub/__release + local.get $64 + call $~lib/rt/stub/__release ) (func $~start call $start:resolve-binary diff --git a/tests/compiler/std/math.optimized.wat b/tests/compiler/std/math.optimized.wat index cea64b836f..a576a4a5a6 100644 --- a/tests/compiler/std/math.optimized.wat +++ b/tests/compiler/std/math.optimized.wat @@ -10,21 +10,22 @@ (type $f32_f32_f32_f32_=>_i32 (func (param f32 f32 f32 f32) (result i32))) (type $f64_f64_f64_f64_=>_i32 (func (param f64 f64 f64 f64) (result i32))) (type $none_=>_none (func)) - (type $f32_i32_=>_f32 (func (param f32 i32) (result f32))) (type $none_=>_f64 (func (result f64))) - (type $f64_i32_=>_f64 (func (param f64 i32) (result f64))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i64_=>_none (func (param i64))) (type $i64_i64_i64_i64_i64_=>_none (func (param i64 i64 i64 i64 i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_=>_i32 (func (param i64) (result i32))) (type $f32_i32_f32_=>_i32 (func (param f32 i32 f32) (result i32))) (type $f64_=>_i32 (func (param f64) (result i32))) (type $f64_i32_f64_=>_i32 (func (param f64 i32 f64) (result i32))) (type $i64_=>_i64 (func (param i64) (result i64))) - (type $i64_i32_=>_i64 (func (param i64 i32) (result i64))) + (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) + (type $f32_i32_=>_f32 (func (param f32 i32) (result f32))) (type $f32_f32_f32_=>_f32 (func (param f32 f32 f32) (result f32))) + (type $f64_i32_=>_f64 (func (param f64 i32) (result f64))) (type $f64_f64_i32_=>_f64 (func (param f64 f64 i32) (result f64))) (type $f64_f64_f64_=>_f64 (func (param f64 f64 f64) (result f64))) (import "Math" "E" (global $~lib/bindings/Math/E f64)) @@ -11098,27 +11099,29 @@ i32.clz f64.convert_i32_s ) - (func $~lib/math/ipow64 (param $0 i64) (param $1 i32) (result i64) + (func $~lib/math/ipow64 (param $0 i64) (param $1 i64) (result i64) (local $2 i64) i64.const 1 local.set $2 loop $while-continue|0 local.get $1 - i32.const 0 - i32.gt_s + i64.const 0 + i64.ne if local.get $0 local.get $2 i64.mul local.get $2 local.get $1 - i32.const 1 - i32.and + i64.const 1 + i64.and + i64.const 0 + i64.ne select local.set $2 local.get $1 - i32.const 1 - i32.shr_s + i64.const 1 + i64.shr_u local.set $1 local.get $0 local.get $0 @@ -11129,107 +11132,44 @@ end local.get $2 ) - (func $~lib/math/ipow32f (param $0 f32) (param $1 i32) (result f32) - (local $2 f32) - (local $3 i32) - local.get $1 - i32.const 31 - i32.shr_s - local.tee $3 - local.get $1 - local.get $3 - i32.add - i32.xor - local.set $1 - f32.const 1 + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + i32.const 1 local.set $2 loop $while-continue|0 local.get $1 if - local.get $2 local.get $0 - f32.const 1 - local.get $1 - i32.const 1 - i32.and - select - f32.mul - local.set $2 - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - f32.mul - local.set $0 - br $while-continue|0 - end - end - local.get $3 - if - f32.const 1 - local.get $2 - f32.div - local.set $2 - end - local.get $2 - ) - (func $~lib/math/ipow64f (param $0 f64) (param $1 i32) (result f64) - (local $2 f64) - (local $3 i32) - local.get $1 - i32.const 31 - i32.shr_s - local.tee $3 - local.get $1 - local.get $3 - i32.add - i32.xor - local.set $1 - f64.const 1 - local.set $2 - loop $while-continue|0 - local.get $1 - if local.get $2 - local.get $0 - f64.const 1 + i32.mul + local.get $2 local.get $1 i32.const 1 i32.and select - f64.mul local.set $2 local.get $1 i32.const 1 - i32.shr_s + i32.shr_u local.set $1 local.get $0 local.get $0 - f64.mul + i32.mul local.set $0 br $while-continue|0 end end - local.get $3 - if - f64.const 1 - local.get $2 - f64.div - local.set $2 - end local.get $2 ) (func $start:std/math (local $0 f64) - (local $1 f32) - (local $2 i32) + (local $1 i32) + (local $2 i64) (local $3 i64) - (local $4 i64) + (local $4 i32) (local $5 i32) - (local $6 i32) - (local $7 f64) + (local $6 f64) + (local $7 f32) (local $8 f32) f64.const 2.718281828459045 global.get $~lib/bindings/Math/E @@ -38332,7 +38272,7 @@ i64.reinterpret_f64 call $~lib/math/NativeMath.seedRandom loop $for-loop|0 - local.get $2 + local.get $1 f64.convert_i32_s f64.const 1e6 f64.lt @@ -38345,28 +38285,28 @@ call $~lib/math/NativeMath.seedRandom end global.get $~lib/math/random_state0_64 - local.set $3 + local.set $2 global.get $~lib/math/random_state1_64 - local.tee $4 + local.tee $3 global.set $~lib/math/random_state0_64 - local.get $4 - local.get $3 local.get $3 + local.get $2 + local.get $2 i64.const 23 i64.shl i64.xor - local.tee $3 - local.get $3 + local.tee $2 + local.get $2 i64.const 17 i64.shr_u i64.xor i64.xor - local.get $4 + local.get $3 i64.const 26 i64.shr_u i64.xor global.set $~lib/math/random_state1_64 - local.get $4 + local.get $3 i64.const 12 i64.shr_u i64.const 4607182418800017408 @@ -38391,10 +38331,10 @@ call $~lib/builtins/abort unreachable end - local.get $2 + local.get $1 i32.const 1 i32.add - local.set $2 + local.set $1 br $for-loop|0 end end @@ -38402,9 +38342,9 @@ i64.reinterpret_f64 call $~lib/math/NativeMath.seedRandom i32.const 0 - local.set $2 + local.set $1 loop $for-loop|1 - local.get $2 + local.get $1 f64.convert_i32_s f64.const 1e6 f64.lt @@ -38417,24 +38357,24 @@ call $~lib/math/NativeMath.seedRandom end global.get $~lib/math/random_state0_32 - local.tee $5 + local.tee $4 global.get $~lib/math/random_state1_32 i32.xor - local.tee $6 - local.get $5 + local.tee $5 + local.get $4 i32.const 26 i32.rotl i32.xor - local.get $6 + local.get $5 i32.const 9 i32.shl i32.xor global.set $~lib/math/random_state0_32 - local.get $6 + local.get $5 i32.const 13 i32.rotl global.set $~lib/math/random_state1_32 - local.get $5 + local.get $4 i32.const -1640531525 i32.mul i32.const 5 @@ -38448,11 +38388,11 @@ f32.reinterpret_i32 f32.const 1 f32.sub - local.tee $1 + local.tee $7 f32.const 1 f32.lt i32.const 0 - local.get $1 + local.get $7 f32.const 0 f32.ge select @@ -38465,10 +38405,10 @@ call $~lib/builtins/abort unreachable end - local.get $2 + local.get $1 i32.const 1 i32.add - local.set $2 + local.set $1 br $for-loop|1 end end @@ -47972,7 +47912,7 @@ unreachable end i64.const 0 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -47985,7 +47925,7 @@ unreachable end i64.const 0 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.eqz i32.eqz @@ -47998,7 +47938,7 @@ unreachable end i64.const 0 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.eqz i32.eqz @@ -48011,7 +47951,7 @@ unreachable end i64.const 0 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.eqz i32.eqz @@ -48024,7 +47964,7 @@ unreachable end i64.const 1 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48037,7 +47977,7 @@ unreachable end i64.const 1 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48050,7 +47990,7 @@ unreachable end i64.const 1 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48063,7 +48003,7 @@ unreachable end i64.const 1 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48076,7 +48016,7 @@ unreachable end i64.const 2 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48089,7 +48029,7 @@ unreachable end i64.const 2 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const 2 i64.ne @@ -48102,7 +48042,7 @@ unreachable end i64.const 2 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 4 i64.ne @@ -48115,7 +48055,7 @@ unreachable end i64.const 2 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const 8 i64.ne @@ -48128,7 +48068,7 @@ unreachable end i64.const -1 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48141,7 +48081,7 @@ unreachable end i64.const -1 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const -1 i64.ne @@ -48154,7 +48094,7 @@ unreachable end i64.const -1 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48167,7 +48107,7 @@ unreachable end i64.const -1 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const -1 i64.ne @@ -48180,7 +48120,7 @@ unreachable end i64.const -2 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.ne @@ -48193,7 +48133,7 @@ unreachable end i64.const -2 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const -2 i64.ne @@ -48206,7 +48146,7 @@ unreachable end i64.const -2 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 4 i64.ne @@ -48219,7 +48159,7 @@ unreachable end i64.const -2 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const -8 i64.ne @@ -48231,10 +48171,10 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 40 + i64.const 2 + i64.const 63 call $~lib/math/ipow64 - i64.const -6289078614652622815 + i64.const -9223372036854775808 i64.ne if i32.const 0 @@ -48245,9 +48185,9 @@ unreachable end i64.const 3 - i32.const 41 + i64.const 40 call $~lib/math/ipow64 - i64.const -420491770248316829 + i64.const -6289078614652622815 i64.ne if i32.const 0 @@ -48257,11 +48197,11 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 42 + i64.const 2 + i64.const 64 call $~lib/math/ipow64 - i64.const -1261475310744950487 - i64.ne + i64.eqz + i32.eqz if i32.const 0 i32.const 1040 @@ -48271,9 +48211,9 @@ unreachable end i64.const 3 - i32.const 43 + i64.const 41 call $~lib/math/ipow64 - i64.const -3784425932234851461 + i64.const -420491770248316829 i64.ne if i32.const 0 @@ -48284,9 +48224,9 @@ unreachable end i64.const 3 - i32.const 63 + i64.const 128 call $~lib/math/ipow64 - i64.const -3237885987332494933 + i64.const -9204772141784466943 i64.ne if i32.const 0 @@ -48296,467 +48236,469 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 64 + i64.const 1 + i64.const -1 call $~lib/math/ipow64 - i64.const 8733086111712066817 + i64.const 1 i64.ne if i32.const 0 i32.const 1040 - i32.const 4074 + i32.const 4075 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 128 + i64.const 2 + i64.const -1 call $~lib/math/ipow64 - i64.const -9204772141784466943 - i64.ne + i64.eqz + i32.eqz if i32.const 0 i32.const 1040 - i32.const 4075 + i32.const 4076 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 57055 - i32.const 3 - call $~lib/math/ipow64 - i64.const 339590 + i32.const 1 i32.const 3 - call $~lib/math/ipow64 - i64.add - i64.const 39347712995520375 - i64.ne + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4077 + i32.const 4082 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 0 - i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.ne + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const -8 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4081 + i32.const 4083 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 + i32.const -1 i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.ne + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4082 + i32.const 4084 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 - i32.const 1 - call $~lib/math/ipow32f - local.tee $1 - local.get $1 - f32.eq + i32.const -1 + i32.const -1 + call $~lib/math/ipow32 + i32.const -1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4083 + i32.const 4085 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 i32.const -1 - call $~lib/math/ipow32f - local.tee $1 - local.get $1 - f32.eq + i32.const -2 + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4084 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 - i32.const 2 - call $~lib/math/ipow32f - local.tee $1 - local.get $1 - f32.eq + i32.const -1 + i32.const -3 + call $~lib/math/ipow32 + i32.const -1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4085 + i32.const 4087 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.ne + i32.const -2 + call $~lib/math/ipow32 if i32.const 0 i32.const 1040 - i32.const 4086 + i32.const 4089 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf - i32.const 1 - call $~lib/math/ipow32f - f32.const inf - f32.ne + i32.const 0 + i32.const -1 + call $~lib/math/ipow32 if i32.const 0 i32.const 1040 - i32.const 4087 + i32.const 4090 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const -inf i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.ne + i32.const 2 + call $~lib/math/ipow32 if i32.const 0 i32.const 1040 - i32.const 4088 + i32.const 4093 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const -inf i32.const 1 - call $~lib/math/ipow32f - f32.const -inf - f32.ne + i32.const -2 + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4089 + i32.const 4095 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const -inf - i32.const 2 - call $~lib/math/ipow32f - f32.const inf - f32.ne + i32.const 1 + i32.const -1 + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4090 + i32.const 4096 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 1 - i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.ne + i32.const 1 + i32.const 2 + call $~lib/math/ipow32 + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4091 + i32.const 4099 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 3402823466385288598117041e14 - i32.const 2 - call $~lib/math/ipow32f - f32.const inf - f32.ne + i32.const 1 + i32.const 3 + call $~lib/math/ipow32 + i32.const 255 + i32.and + i32.const 1 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4092 + i32.const 4101 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 1.401298464324817e-45 - i32.const 2 - call $~lib/math/ipow32f - f32.const 0 - f32.ne + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const 255 + i32.and + i32.const 248 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4093 + i32.const 4102 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 3402823466385288598117041e14 - i32.const -1 - call $~lib/math/ipow32f - f32.const 2.938735877055719e-39 - f32.ne + i32.const 4 + i32.const 7 + call $~lib/math/ipow32 + i32.const 65535 + i32.and + i32.const 16384 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4094 + i32.const 4103 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 10 - i32.const 36 - call $~lib/math/ipow32f - f32.const 1000000040918478759629753e12 - f32.ne + i32.const 4 + i32.const 8 + call $~lib/math/ipow32 + i32.const 65535 + i32.and if i32.const 0 i32.const 1040 - i32.const 4095 + i32.const 4104 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 10 - i32.const -36 - call $~lib/math/ipow32f - f32.const 9.999999462560281e-37 - f32.ne + i32.const 5 + i32.const 10 + call $~lib/math/ipow32 + i32.const 65535 + i32.and + i32.const 761 + i32.ne if i32.const 0 i32.const 1040 - i32.const 4096 + i32.const 4105 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 0 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.ne + i64.const 0 + i64.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4100 + i32.const 4107 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.ne + i64.const 0 + i64.const 1 + call $~lib/math/ipow64 + i64.eqz + i32.eqz if i32.const 0 i32.const 1040 - i32.const 4101 + i32.const 4108 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 1 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.eq + i64.const 1 + i64.const 3 + call $~lib/math/ipow64 + i64.const 1 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4102 + i32.const 4109 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const -1 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.eq + i64.const 2 + i64.const 3 + call $~lib/math/ipow64 + i64.const 8 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4103 + i32.const 4110 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 2 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.eq + i64.const 4294967295 + i64.const 3 + call $~lib/math/ipow64 + i64.const 12884901887 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4104 + i32.const 4111 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.ne + i64.const 65535 + i64.const 3 + call $~lib/math/ipow64 + i64.const 281462092005375 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4105 + i32.const 4112 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - i32.const 1 - call $~lib/math/ipow64f - f64.const inf - f64.ne + i64.const 65535 + i64.const 8 + call $~lib/math/ipow64 + i64.const -15762478437236735 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4106 + i32.const 4113 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const -inf - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.ne + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 + i64.const -3925184889716469295 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4107 + i32.const 4114 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const -inf - i32.const 1 - call $~lib/math/ipow64f - f64.const -inf - f64.ne + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 + i64.const -3925184889716469295 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4108 + i32.const 4115 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const -inf - i32.const 2 - call $~lib/math/ipow64f - f64.const inf - f64.ne + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 + i64.add + i64.const 340126 + i64.const 3 + call $~lib/math/ipow64 + i64.eq if i32.const 0 i32.const 1040 - i32.const 4109 + i32.const 4117 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 1 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.ne + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 + i64.add + i64.const 39347712995520375 + i64.ne if i32.const 0 i32.const 1040 - i32.const 4110 + i32.const 4118 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 1797693134862315708145274e284 - i32.const 2 - call $~lib/math/ipow64f - f64.const inf + f64.const 1 + f64.const 0.5 + call $~lib/math/NativeMath.pow + f64.const 1 f64.ne if i32.const 0 i32.const 1040 - i32.const 4111 + i32.const 4120 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 5e-324 - i32.const 2 - call $~lib/math/ipow64f + f64.const 0 + f64.const 0.5 + call $~lib/math/NativeMath.pow f64.const 0 f64.ne if i32.const 0 i32.const 1040 - i32.const 4112 + i32.const 4121 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 1797693134862315708145274e284 - i32.const -1 - call $~lib/math/ipow64f - f64.const 5.562684646268003e-309 + f64.const 0 + f64.const -1 + call $~lib/math/NativeMath.pow + f64.const inf f64.ne if i32.const 0 i32.const 1040 - i32.const 4113 + i32.const 4122 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 10 - i32.const 127 - call $~lib/math/ipow64f - f64.const 1000000000000000195419867e103 + f64.const 0 + f64.const 0 + call $~lib/math/NativeMath.pow + f64.const 1 f64.ne if i32.const 0 i32.const 1040 - i32.const 4114 + i32.const 4123 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 10 - i32.const -127 - call $~lib/math/ipow64f - f64.const 9.999999999999998e-128 + f64.const 1 + f64.const 1 + call $~lib/math/NativeMath.pow + f64.const 1 f64.ne if i32.const 0 i32.const 1040 - i32.const 4115 + i32.const 4124 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index 00e394abca..d9afeed0c2 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -4066,50 +4066,59 @@ assert(ipow64(-2, 1) == -2); assert(ipow64(-2, 2) == 4); assert(ipow64(-2, 3) == -8); +assert(ipow64(2, 63) == 9223372036854775808); assert(ipow64(3, 40) == 12157665459056928801); +assert(ipow64(2, 64) == 0); // should overflow assert(ipow64(3, 41) == -420491770248316829); // should overflow -assert(ipow64(3, 42) == -1261475310744950487); // should overflow -assert(ipow64(3, 43) == -3784425932234851461); // should overflow -assert(ipow64(3, 63) == -3237885987332494933); // should overflow -assert(ipow64(3, 64) == 8733086111712066817); // should overflow assert(ipow64(3, 128) == -9204772141784466943); // should overflow -assert(ipow64(57055, 3) + ipow64(339590, 3) == 39347712995520375); // add Buterin's twit example - -// ipow32f ///////////////////////////////////////////////////////////////////////////////////// - -assert(ipow32f(0, 0) == 1.0); -assert(ipow32f(NaN, 0) == 1.0); -assert(isNaN(ipow32f(NaN, 1))); -assert(isNaN(ipow32f(NaN, -1))); -assert(isNaN(ipow32f(NaN, 2))); -assert(ipow32f(Infinity, 0) == 1.0); -assert(ipow32f(Infinity, 1) == Infinity); -assert(ipow32f(-Infinity, 0) == 1.0); -assert(ipow32f(-Infinity, 1) == -Infinity); -assert(ipow32f(-Infinity, 2) == Infinity); -assert(ipow32f(1.0, 0) == 1.0); -assert(ipow32f(f32.MAX_VALUE, 2) == Infinity); -assert(ipow32f(f32.MIN_VALUE, 2) == 0.0); -assert(ipow32f(f32.MAX_VALUE, -1) == 2.938735877055719e-39); -assert(ipow32f(10.0, 36) == 1.0000000409184788e+36); -assert(ipow32f(10.0,-36) == 9.999999462560281e-37); - -// ipow64f ///////////////////////////////////////////////////////////////////////////////////// - -assert(ipow64f(0, 0) == 1.0); -assert(ipow64f(NaN, 0) == 1.0); -assert(isNaN(ipow64f(NaN, 1))); -assert(isNaN(ipow64f(NaN, -1))); -assert(isNaN(ipow64f(NaN, 2))); -assert(ipow64f(Infinity, 0) == 1.0); -assert(ipow64f(Infinity, 1) == Infinity); -assert(ipow64f(-Infinity, 0) == 1.0); -assert(ipow64f(-Infinity, 1) == -Infinity); -assert(ipow64f(-Infinity, 2) == Infinity); -assert(ipow64f(1.0, 0) == 1.0); -assert(ipow64f(f64.MAX_VALUE, 2) == Infinity); -assert(ipow64f(f64.MIN_VALUE, 2) == 0.0); -assert(ipow64f(f64.MAX_VALUE, -1) == 5.562684646268003e-309); -assert(ipow64f(10.0, 127) == 1.0000000000000002e+127); -assert(ipow64f(10.0,-127) == 9.999999999999998e-128); +assert(ipow64(1, -1) == 1); +assert(ipow64(2, -1) == 0); + +// integer pow operators + +assert( 0 ** 0 == 1); +assert( 0 ** 1 == 0); +assert( 1 ** 3 == 1); +assert((-2) ** 3 == -8); +assert((-1) ** 0 == 1); +assert((-1) ** -1 == -1); +assert((-1) ** -2 == 1); +assert((-1) ** -3 == -1); + +assert(false ** -2 == 0); +assert(false ** -1 == 0); +assert(false ** 0 == 1); +assert(false ** 1 == 0); +assert(false ** 2 == 0); + +assert(true ** -2 == 1); +assert(true ** -1 == 1); +assert(true ** 0 == 1); +assert(true ** 1 == 1); +assert(true ** 2 == 1); + +assert(( 1) ** 3 == 1); +assert((-2) ** 3 == -8); +assert((4) ** 7 == 16384); +assert((4) ** 8 == 0); // should overflow +assert((5) ** 10 == 761); // should overflow + +assert((0) ** 0 == 1); +assert((0) ** 1 == 0); +assert((1) ** 3 == 1); +assert((2) ** 3 == 8); +assert((0xFFFFFFFF) ** 3 == 12884901887); +assert((0xFFFF) ** 3 == 281462092005375); +assert((0xFFFF) ** 8 == 18430981595272314881); +assert(0xF123 ** 4 as u64 == 14521559183993082321); +assert(0xF123 as u64 ** 4 == 14521559183993082321); +// Fermat's Last Theorem +assert((57055) ** 3 + (339590) ** 3 != (340126) ** 3); // On JS it return false +assert((57055) ** 3 + (339590) ** 3 == 39347712995520375); + +assert(1 ** 0.5 == 1.0); +assert(0 ** 0.5 == 0.0); +assert(0 ** -1.0 == Infinity); +assert(0.0 ** 0 == 1.0); +assert(1.0 ** 1 == 1.0); \ No newline at end of file diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index dd414f8d2e..6035f6844a 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -10,21 +10,22 @@ (type $none_=>_f64 (func (result f64))) (type $none_=>_none (func)) (type $f64_=>_i32 (func (param f64) (result i32))) - (type $f32_i32_=>_f32 (func (param f32 i32) (result f32))) - (type $f64_i32_=>_f64 (func (param f64 i32) (result f64))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i64_=>_none (func (param i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_i64_i64_i64_i64_i32_=>_i32 (func (param i64 i64 i64 i64 i64 i32) (result i32))) (type $f32_=>_i32 (func (param f32) (result i32))) (type $f32_i32_f32_f32_i32_=>_i32 (func (param f32 i32 f32 f32 i32) (result i32))) (type $f64_i32_f64_f64_i32_=>_i32 (func (param f64 i32 f64 f64 i32) (result i32))) (type $f64_i64_=>_i32 (func (param f64 i64) (result i32))) (type $i64_=>_i64 (func (param i64) (result i64))) - (type $i64_i32_=>_i64 (func (param i64 i32) (result i64))) + (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) (type $none_=>_f32 (func (result f32))) + (type $f32_i32_=>_f32 (func (param f32 i32) (result f32))) (type $f32_f32_f32_=>_f32 (func (param f32 f32 f32) (result f32))) + (type $f64_i32_=>_f64 (func (param f64 i32) (result f64))) (type $f64_f64_i32_=>_f64 (func (param f64 f64 i32) (result f64))) (type $f64_f64_f64_=>_f64 (func (param f64 f64 f64) (result f64))) (import "Math" "E" (global $~lib/bindings/Math/E f64)) @@ -122,7 +123,6 @@ (global $~lib/builtins/f64.MAX_VALUE f64 (f64.const 1797693134862315708145274e284)) (global $~lib/builtins/f64.MAX_SAFE_INTEGER f64 (f64.const 9007199254740991)) (global $~lib/builtins/f64.EPSILON f64 (f64.const 2.220446049250313e-16)) - (global $~lib/builtins/f32.MIN_VALUE f32 (f32.const 1.401298464324817e-45)) (export "memory" (memory $0)) (start $~start) (func $std/math/eulp (param $0 f64) (result i32) @@ -15970,7 +15970,7 @@ i32.clz f64.convert_i32_s ) - (func $~lib/math/ipow64 (param $0 i64) (param $1 i32) (result i64) + (func $~lib/math/ipow64 (param $0 i64) (param $1 i64) (result i64) (local $2 i64) (local $3 i32) (local $4 i32) @@ -15981,90 +15981,160 @@ i32.lt_s drop local.get $1 - i32.const 0 - i32.lt_s + i64.const 0 + i64.le_s if - i64.const 0 - return - end - block $break|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $1 - local.set $3 - local.get $3 - i32.const 0 - i32.eq - br_if $case0|0 - local.get $3 - i32.const 1 - i32.eq - br_if $case1|0 - local.get $3 - i32.const 2 - i32.eq - br_if $case2|0 - br $break|0 - end - i64.const 1 - return - end - local.get $0 + local.get $0 + i64.const -1 + i64.eq + if + i64.const -1 + i64.const 1 + local.get $1 + i64.const 1 + i64.and + i64.const 0 + i64.ne + select return end + local.get $1 + i64.const 0 + i64.eq + i64.extend_i32_u local.get $0 - local.get $0 - i64.mul + i64.const 1 + i64.eq + i64.extend_i32_u + i64.or return - end - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - local.get $3 - i32.const 6 - i32.le_s - if - block $break|1 - block $case5|1 - block $case4|1 - block $case3|1 - block $case2|1 - block $case1|1 - block $case0|1 - local.get $3 - local.set $4 - local.get $4 - i32.const 6 - i32.eq - br_if $case0|1 - local.get $4 - i32.const 5 - i32.eq - br_if $case1|1 - local.get $4 - i32.const 4 - i32.eq - br_if $case2|1 - local.get $4 - i32.const 3 - i32.eq - br_if $case3|1 - local.get $4 - i32.const 2 - i32.eq - br_if $case4|1 - local.get $4 - i32.const 1 - i32.eq - br_if $case5|1 - br $break|1 + else + local.get $1 + i64.const 1 + i64.eq + if + local.get $0 + return + else + local.get $1 + i64.const 2 + i64.eq + if + local.get $0 + local.get $0 + i64.mul + return + else + local.get $1 + i64.const 64 + i64.lt_s + if + i32.const 64 + local.get $1 + i64.clz + i32.wrap_i64 + i32.sub + local.set $3 + block $break|0 + block $case5|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 6 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 5 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case4|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case5|0 + br $break|0 + end + local.get $1 + i64.const 1 + i64.and + i64.const 0 + i64.ne + if + local.get $2 + local.get $0 + i64.mul + local.set $2 + end + local.get $1 + i64.const 1 + i64.shr_u + local.set $1 + local.get $0 + local.get $0 + i64.mul + local.set $0 + end + local.get $1 + i64.const 1 + i64.and + i64.const 0 + i64.ne + if + local.get $2 + local.get $0 + i64.mul + local.set $2 + end + local.get $1 + i64.const 1 + i64.shr_u + local.set $1 + local.get $0 + local.get $0 + i64.mul + local.set $0 + end + local.get $1 + i64.const 1 + i64.and + i64.const 0 + i64.ne + if + local.get $2 + local.get $0 + i64.mul + local.set $2 + end + local.get $1 + i64.const 1 + i64.shr_u + local.set $1 + local.get $0 + local.get $0 + i64.mul + local.set $0 end local.get $1 - i32.const 1 - i32.and + i64.const 1 + i64.and + i64.const 0 + i64.ne if local.get $2 local.get $0 @@ -16072,8 +16142,8 @@ local.set $2 end local.get $1 - i32.const 1 - i32.shr_s + i64.const 1 + i64.shr_u local.set $1 local.get $0 local.get $0 @@ -16081,8 +16151,10 @@ local.set $0 end local.get $1 - i32.const 1 - i32.and + i64.const 1 + i64.and + i64.const 0 + i64.ne if local.get $2 local.get $0 @@ -16090,8 +16162,8 @@ local.set $2 end local.get $1 - i32.const 1 - i32.shr_s + i64.const 1 + i64.shr_u local.set $1 local.get $0 local.get $0 @@ -16099,82 +16171,35 @@ local.set $0 end local.get $1 - i32.const 1 - i32.and + i64.const 1 + i64.and + i64.const 0 + i64.ne if local.get $2 local.get $0 i64.mul local.set $2 end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i64.mul - local.set $0 end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i64.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i64.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if local.get $2 - local.get $0 - i64.mul - local.set $2 + return end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i64.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i64.mul - local.set $2 end end - local.get $2 - return end - loop $while-continue|2 + loop $while-continue|1 local.get $1 - i32.const 0 - i32.gt_s + i64.const 0 + i64.ne local.set $3 local.get $3 if local.get $1 - i32.const 1 - i32.and + i64.const 1 + i64.and + i64.const 0 + i64.ne if local.get $2 local.get $0 @@ -16182,117 +16207,222 @@ local.set $2 end local.get $1 - i32.const 1 - i32.shr_s + i64.const 1 + i64.shr_u local.set $1 local.get $0 local.get $0 i64.mul local.set $0 - br $while-continue|2 + br $while-continue|1 end end local.get $2 ) - (func $~lib/math/ipow32f (param $0 f32) (param $1 i32) (result f32) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) (local $2 i32) - (local $3 f32) + (local $3 i32) (local $4 i32) - local.get $1 - i32.const 31 - i32.shr_s + i32.const 1 local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop local.get $1 - local.get $2 - i32.add - local.get $2 - i32.xor - local.set $1 - f32.const 1 - local.set $3 - loop $while-continue|0 - local.get $1 - local.set $4 - local.get $4 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq if - local.get $3 - local.get $0 - f32.const 1 + i32.const -1 + i32.const 1 local.get $1 i32.const 1 i32.and select - f32.mul - local.set $3 - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - f32.mul - local.set $0 - br $while-continue|0 + return end - end - local.get $2 - if (result f32) - f32.const 1 - local.get $3 - f32.div + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return else - local.get $3 - end - ) - (func $~lib/math/ipow64f (param $0 f64) (param $1 i32) (result f64) - (local $2 i32) - (local $3 f64) - (local $4 i32) - local.get $1 - i32.const 31 - i32.shr_s - local.set $2 - local.get $1 - local.get $2 - i32.add - local.get $2 - i32.xor - local.set $1 - f64.const 1 - local.set $3 - loop $while-continue|0 local.get $1 - local.set $4 - local.get $4 + i32.const 1 + i32.eq if - local.get $3 local.get $0 - f64.const 1 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if local.get $1 i32.const 1 i32.and - select - f64.mul - local.set $3 + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end local.get $1 i32.const 1 - i32.shr_s + i32.shr_u local.set $1 local.get $0 local.get $0 - f64.mul + i32.mul local.set $0 - br $while-continue|0 + br $while-continue|1 end end local.get $2 - if (result f64) - f64.const 1 - local.get $3 - f64.div - else - local.get $3 - end ) (func $start:std/math (local $0 f64) @@ -58320,7 +58450,7 @@ unreachable end i64.const 0 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58334,7 +58464,7 @@ unreachable end i64.const 0 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const 0 i64.eq @@ -58348,7 +58478,7 @@ unreachable end i64.const 0 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 0 i64.eq @@ -58362,7 +58492,7 @@ unreachable end i64.const 0 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const 0 i64.eq @@ -58376,7 +58506,7 @@ unreachable end i64.const 1 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58390,7 +58520,7 @@ unreachable end i64.const 1 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58404,7 +58534,7 @@ unreachable end i64.const 1 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58418,7 +58548,7 @@ unreachable end i64.const 1 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58432,7 +58562,7 @@ unreachable end i64.const 2 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58446,7 +58576,7 @@ unreachable end i64.const 2 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const 2 i64.eq @@ -58460,7 +58590,7 @@ unreachable end i64.const 2 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 4 i64.eq @@ -58474,7 +58604,7 @@ unreachable end i64.const 2 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const 8 i64.eq @@ -58488,7 +58618,7 @@ unreachable end i64.const -1 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58502,7 +58632,7 @@ unreachable end i64.const -1 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const -1 i64.eq @@ -58516,7 +58646,7 @@ unreachable end i64.const -1 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58530,7 +58660,7 @@ unreachable end i64.const -1 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const -1 i64.eq @@ -58544,7 +58674,7 @@ unreachable end i64.const -2 - i32.const 0 + i64.const 0 call $~lib/math/ipow64 i64.const 1 i64.eq @@ -58558,7 +58688,7 @@ unreachable end i64.const -2 - i32.const 1 + i64.const 1 call $~lib/math/ipow64 i64.const -2 i64.eq @@ -58572,7 +58702,7 @@ unreachable end i64.const -2 - i32.const 2 + i64.const 2 call $~lib/math/ipow64 i64.const 4 i64.eq @@ -58586,7 +58716,7 @@ unreachable end i64.const -2 - i32.const 3 + i64.const 3 call $~lib/math/ipow64 i64.const -8 i64.eq @@ -58599,10 +58729,10 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 40 + i64.const 2 + i64.const 63 call $~lib/math/ipow64 - i64.const -6289078614652622815 + i64.const -9223372036854775808 i64.eq i32.eqz if @@ -58614,9 +58744,9 @@ unreachable end i64.const 3 - i32.const 41 + i64.const 40 call $~lib/math/ipow64 - i64.const -420491770248316829 + i64.const -6289078614652622815 i64.eq i32.eqz if @@ -58627,10 +58757,10 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 42 + i64.const 2 + i64.const 64 call $~lib/math/ipow64 - i64.const -1261475310744950487 + i64.const 0 i64.eq i32.eqz if @@ -58642,9 +58772,9 @@ unreachable end i64.const 3 - i32.const 43 + i64.const 41 call $~lib/math/ipow64 - i64.const -3784425932234851461 + i64.const -420491770248316829 i64.eq i32.eqz if @@ -58656,9 +58786,9 @@ unreachable end i64.const 3 - i32.const 63 + i64.const 128 call $~lib/math/ipow64 - i64.const -3237885987332494933 + i64.const -9204772141784466943 i64.eq i32.eqz if @@ -58669,510 +58799,573 @@ call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 64 + i64.const 1 + i64.const -1 call $~lib/math/ipow64 - i64.const 8733086111712066817 + i64.const 1 i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4074 + i32.const 4075 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 - i32.const 128 + i64.const 2 + i64.const -1 call $~lib/math/ipow64 - i64.const -9204772141784466943 + i64.const 0 i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4075 + i32.const 4076 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 57055 - i32.const 3 - call $~lib/math/ipow64 - i64.const 339590 + i32.const 1 + i32.const 0 + i32.const 0 + i32.eq + i32.const 0 + select + i32.const 1 + i32.eq + drop + i32.const 1 + i32.const 1 + i32.const 0 + i32.eq + i32.const 0 + select + i32.const 0 + i32.eq + drop + i32.const 1 i32.const 3 - call $~lib/math/ipow64 - i64.add - i64.const 39347712995520375 - i64.eq + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4077 + i32.const 4082 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 0 - i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.eq + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const -8 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4081 + i32.const 4083 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 + i32.const -1 i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.eq + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4082 + i32.const 4084 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 - i32.const 1 - call $~lib/math/ipow32f - local.tee $4 - local.get $4 - f32.ne + i32.const -1 + i32.const -1 + call $~lib/math/ipow32 + i32.const -1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4083 + i32.const 4085 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 i32.const -1 - call $~lib/math/ipow32f - local.tee $4 - local.get $4 - f32.ne + i32.const -2 + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4084 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const nan:0x400000 - i32.const 2 - call $~lib/math/ipow32f - local.tee $4 - local.get $4 - f32.ne + i32.const -1 + i32.const -3 + call $~lib/math/ipow32 + i32.const -1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4085 + i32.const 4087 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.eq + i32.const -2 + call $~lib/math/ipow32 + i32.const 0 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4086 + i32.const 4089 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf - i32.const 1 - call $~lib/math/ipow32f - f32.const inf - f32.eq + i32.const 0 + i32.const -1 + call $~lib/math/ipow32 + i32.const 0 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4087 + i32.const 4090 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf - f32.neg + i32.const 1 i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.eq + i32.const 0 + i32.eq + i32.const 0 + select + i32.const 1 + i32.eq + drop + i32.const 1 + i32.const 1 + i32.const 0 + i32.eq + i32.const 0 + select + i32.const 0 + i32.eq + drop + i32.const 0 + i32.const 2 + call $~lib/math/ipow32 + i32.const 0 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4088 + i32.const 4093 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf - f32.neg i32.const 1 - call $~lib/math/ipow32f - f32.const inf - f32.neg - f32.eq + i32.const -2 + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4089 + i32.const 4095 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const inf - f32.neg - i32.const 2 - call $~lib/math/ipow32f - f32.const inf - f32.eq + i32.const 1 + i32.const -1 + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4090 + i32.const 4096 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 1 + i32.const 1 i32.const 0 - call $~lib/math/ipow32f - f32.const 1 - f32.eq + i32.const 0 + i32.eq + i32.const 1 + select + i32.const 1 + i32.eq + drop + i32.const 1 + i32.const 1 + i32.const 0 + i32.eq + i32.const 1 + select + i32.const 1 + i32.eq + drop + i32.const 1 + i32.const 2 + call $~lib/math/ipow32 + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4091 + i32.const 4099 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f32.MAX_VALUE - i32.const 2 - call $~lib/math/ipow32f - f32.const inf - f32.eq + i32.const 1 + i32.const 3 + call $~lib/math/ipow32 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 1 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4092 + i32.const 4101 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f32.MIN_VALUE - i32.const 2 - call $~lib/math/ipow32f - f32.const 0 - f32.eq + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -8 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4093 + i32.const 4102 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f32.MAX_VALUE - i32.const -1 - call $~lib/math/ipow32f - f32.const 2.938735877055719e-39 - f32.eq + i32.const 4 + i32.const 7 + call $~lib/math/ipow32 + i32.const 65535 + i32.and + i32.const 16384 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4094 + i32.const 4103 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 10 - i32.const 36 - call $~lib/math/ipow32f - f32.const 1000000040918478759629753e12 - f32.eq + i32.const 4 + i32.const 8 + call $~lib/math/ipow32 + i32.const 65535 + i32.and + i32.const 0 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4095 + i32.const 4104 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 10 - i32.const -36 - call $~lib/math/ipow32f - f32.const 9.999999462560281e-37 - f32.eq + i32.const 5 + i32.const 10 + call $~lib/math/ipow32 + i32.const 65535 + i32.and + i32.const 761 + i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4096 + i32.const 4105 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 0 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.eq + i64.const 0 + i64.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4100 + i32.const 4107 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.eq + i64.const 0 + i64.const 1 + call $~lib/math/ipow64 + i64.const 0 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4101 + i32.const 4108 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 1 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.ne + i64.const 1 + i64.const 3 + call $~lib/math/ipow64 + i64.const 1 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4102 + i32.const 4109 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const -1 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.ne + i64.const 2 + i64.const 3 + call $~lib/math/ipow64 + i64.const 8 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4103 + i32.const 4110 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const nan:0x8000000000000 - i32.const 2 - call $~lib/math/ipow64f - local.tee $0 - local.get $0 - f64.ne + i64.const 4294967295 + i64.const 3 + call $~lib/math/ipow64 + i64.const 12884901887 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4104 + i32.const 4111 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.eq + i64.const 65535 + i64.const 3 + call $~lib/math/ipow64 + i64.const 281462092005375 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4105 + i32.const 4112 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - i32.const 1 - call $~lib/math/ipow64f - f64.const inf - f64.eq + i64.const 65535 + i64.const 8 + call $~lib/math/ipow64 + i64.const -15762478437236735 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4106 + i32.const 4113 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - f64.neg - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.eq + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 + i64.const -3925184889716469295 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4107 + i32.const 4114 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - f64.neg - i32.const 1 - call $~lib/math/ipow64f - f64.const inf - f64.neg - f64.eq + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 + i64.const -3925184889716469295 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4108 + i32.const 4115 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const inf - f64.neg - i32.const 2 - call $~lib/math/ipow64f - f64.const inf - f64.eq + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 + i64.add + i64.const 340126 + i64.const 3 + call $~lib/math/ipow64 + i64.ne i32.eqz if i32.const 0 i32.const 32 - i32.const 4109 + i32.const 4117 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 1 - i32.const 0 - call $~lib/math/ipow64f - f64.const 1 - f64.eq + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 + i64.add + i64.const 39347712995520375 + i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4110 + i32.const 4118 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f64.MAX_VALUE - i32.const 2 - call $~lib/math/ipow64f - f64.const inf + i32.const 1 + f64.convert_i32_u + f64.const 0.5 + call $~lib/math/NativeMath.pow + f64.const 1 f64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4111 + i32.const 4120 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f64.MIN_VALUE - i32.const 2 - call $~lib/math/ipow64f + i32.const 0 + f64.convert_i32_u + f64.const 0.5 + call $~lib/math/NativeMath.pow f64.const 0 f64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4112 + i32.const 4121 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/builtins/f64.MAX_VALUE - i32.const -1 - call $~lib/math/ipow64f - f64.const 5.562684646268003e-309 + i32.const 0 + f64.convert_i32_u + f64.const -1 + call $~lib/math/NativeMath.pow + f64.const inf f64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4113 + i32.const 4122 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 10 - i32.const 127 - call $~lib/math/ipow64f - f64.const 1000000000000000195419867e103 + f64.const 0 + f64.const 0 + call $~lib/math/NativeMath.pow + f64.const 1 f64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4114 + i32.const 4123 i32.const 1 call $~lib/builtins/abort unreachable end - f64.const 10 - i32.const -127 - call $~lib/math/ipow64f - f64.const 9.999999999999998e-128 + f64.const 1 + f64.const 1 + call $~lib/math/NativeMath.pow + f64.const 1 f64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4115 + i32.const 4124 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/operator-overloading.optimized.wat b/tests/compiler/std/operator-overloading.optimized.wat index fc82d12ebf..868a0b1ae3 100644 --- a/tests/compiler/std/operator-overloading.optimized.wat +++ b/tests/compiler/std/operator-overloading.optimized.wat @@ -3,8 +3,6 @@ (type $none_=>_none (func)) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_=>_i32 (func (param i32) (result i32))) - (type $f64_i32_=>_f64 (func (param f64 i32) (result f64))) - (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) (data (i32.const 1024) "6\00\00\00\01\00\00\00\01\00\00\006\00\00\00s\00t\00d\00/\00o\00p\00e\00r\00a\00t\00o\00r\00-\00o\00v\00e\00r\00l\00o\00a\00d\00i\00n\00g\00.\00t\00s") @@ -155,1026 +153,34 @@ i32.store offset=4 local.get $2 ) - (func $~lib/math/NativeMath.scalbn (param $0 f64) (param $1 i32) (result f64) - local.get $1 - i32.const 1023 - i32.gt_s - if (result f64) - local.get $0 - f64.const 8988465674311579538646525e283 - f64.mul - local.set $0 - local.get $1 - i32.const 1023 - i32.sub - local.tee $1 - i32.const 1023 - i32.gt_s - if (result f64) - local.get $1 - i32.const 1023 - i32.sub - local.tee $1 - i32.const 1023 - local.get $1 - i32.const 1023 - i32.lt_s - select - local.set $1 - local.get $0 - f64.const 8988465674311579538646525e283 - f64.mul - else - local.get $0 - end - else - local.get $1 - i32.const -1022 - i32.lt_s - if (result f64) - local.get $0 - f64.const 2.004168360008973e-292 - f64.mul - local.set $0 - local.get $1 - i32.const 969 - i32.add - local.tee $1 - i32.const -1022 - i32.lt_s - if (result f64) - local.get $1 - i32.const 969 - i32.add - local.tee $1 - i32.const -1022 - local.get $1 - i32.const -1022 - i32.gt_s - select - local.set $1 - local.get $0 - f64.const 2.004168360008973e-292 - f64.mul - else - local.get $0 - end - else - local.get $0 - end - end - local.get $1 - i64.extend_i32_s - i64.const 1023 - i64.add - i64.const 52 - i64.shl - f64.reinterpret_i64 - f64.mul - ) - (func $~lib/math/NativeMath.pow (param $0 f64) (param $1 f64) (result f64) - (local $2 f64) - (local $3 f64) - (local $4 i32) - (local $5 i32) - (local $6 f64) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 f64) - (local $11 i32) - (local $12 f64) - (local $13 i64) - (local $14 f64) - (local $15 i32) - (local $16 i32) - (local $17 f64) - (local $18 i32) - (local $19 i32) - (local $20 f64) - local.get $1 - f64.abs - f64.const 2 - f64.le - if - local.get $1 - f64.const 2 - f64.eq - if - local.get $0 - local.get $0 - f64.mul - return - end - local.get $1 - f64.const 0.5 - f64.eq - if - local.get $0 - f64.sqrt - f64.abs - f64.const inf - local.get $0 - f64.const -inf - f64.ne - select - return - end - local.get $1 - f64.const -1 - f64.eq - if - f64.const 1 - local.get $0 - f64.div - return - end - local.get $1 - f64.const 1 - f64.eq - if - local.get $0 - return - end - local.get $1 - f64.const 0 - f64.eq - if - f64.const 1 - return - end - end - local.get $0 - i64.reinterpret_f64 - local.tee $13 - i32.wrap_i64 - local.set $18 - local.get $13 - i64.const 32 - i64.shr_u - i32.wrap_i64 - local.tee $15 - i32.const 2147483647 - i32.and - local.set $4 - local.get $1 - i64.reinterpret_f64 - local.tee $13 - i64.const 32 - i64.shr_u - i32.wrap_i64 - local.tee $7 - i32.const 2147483647 - i32.and - local.tee $8 - local.get $13 - i32.wrap_i64 - local.tee $19 - i32.or - i32.eqz - if - f64.const 1 - return - end - i32.const 1 - local.get $19 - i32.const 0 - local.get $8 - i32.const 2146435072 - i32.eq - select - i32.const 1 - local.get $8 - i32.const 2146435072 - i32.gt_s + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) i32.const 1 - local.get $18 - i32.const 0 - local.get $4 - i32.const 2146435072 - i32.eq - select - local.get $4 - i32.const 2146435072 - i32.gt_s - select - select - select - if - local.get $0 + local.set $2 + loop $while-continue|0 local.get $1 - f64.add - return - end - local.get $15 - i32.const 0 - i32.lt_s - if - local.get $8 - i32.const 1128267776 - i32.ge_s - if (result i32) - i32.const 2 - else - local.get $8 - i32.const 1072693248 - i32.ge_s - if (result i32) - i32.const 52 - i32.const 20 - local.get $8 - i32.const 20 - i32.shr_s - i32.const 1023 - i32.sub - local.tee $9 - i32.const 20 - i32.gt_s - local.tee $5 - select - local.get $9 - i32.sub - local.set $11 - i32.const 2 - local.get $19 - local.get $8 - local.get $5 - select - local.tee $5 - local.get $11 - i32.shr_u - local.tee $9 - i32.const 1 - i32.and - i32.sub - i32.const 0 - local.get $5 - local.get $9 - local.get $11 - i32.shl - i32.eq - select - else - i32.const 0 - end - end - local.set $5 - end - local.get $19 - i32.eqz - if - local.get $8 - i32.const 2146435072 - i32.eq - if - local.get $18 - local.get $4 - i32.const 1072693248 - i32.sub - i32.or - if - local.get $4 - i32.const 1072693248 - i32.ge_s - if - local.get $1 - f64.const 0 - local.get $7 - i32.const 0 - i32.ge_s - select - return - else - local.get $1 - f64.neg - f64.const 0 - local.get $7 - i32.const 0 - i32.lt_s - select - return - end - unreachable - else - f64.const nan:0x8000000000000 - return - end - unreachable - end - local.get $8 - i32.const 1072693248 - i32.eq if - local.get $7 - i32.const 0 - i32.ge_s - if - local.get $0 - return - end - f64.const 1 - local.get $0 - f64.div - return - end - local.get $7 - i32.const 1073741824 - i32.eq - if - local.get $0 local.get $0 - f64.mul - return - end - local.get $7 - i32.const 1071644672 - i32.eq - if - local.get $15 - i32.const 0 - i32.ge_s - if - local.get $0 - f64.sqrt - return - end - end - end - local.get $0 - f64.abs - local.set $2 - local.get $18 - i32.eqz - if - i32.const 1 - local.get $4 - i32.const 1072693248 - i32.eq - local.get $4 - i32.const 2146435072 - i32.eq - i32.const 1 - local.get $4 - select - select - if - f64.const 1 local.get $2 - f64.div + i32.mul local.get $2 - local.get $7 - i32.const 0 - i32.lt_s + local.get $1 + i32.const 1 + i32.and select local.set $2 - local.get $15 - i32.const 0 - i32.lt_s - if (result f64) - local.get $5 - local.get $4 - i32.const 1072693248 - i32.sub - i32.or - if (result f64) - local.get $2 - f64.neg - local.get $2 - local.get $5 - i32.const 1 - i32.eq - select - else - local.get $2 - local.get $2 - f64.sub - local.tee $0 - local.get $0 - f64.div - end - else - local.get $2 - end - return - end - end - f64.const 1 - local.set $10 - local.get $15 - i32.const 0 - i32.lt_s - if - local.get $5 - i32.eqz - if - local.get $0 - local.get $0 - f64.sub - local.tee $0 - local.get $0 - f64.div - return - end - f64.const -1 - f64.const 1 - local.get $5 - i32.const 1 - i32.eq - select - local.set $10 - end - local.get $8 - i32.const 1105199104 - i32.gt_s - if (result f64) - local.get $8 - i32.const 1139802112 - i32.gt_s - if - local.get $4 - i32.const 1072693247 - i32.le_s - if - f64.const inf - f64.const 0 - local.get $7 - i32.const 0 - i32.lt_s - select - return - end - local.get $4 - i32.const 1072693248 - i32.ge_s - if - f64.const inf - f64.const 0 - local.get $7 - i32.const 0 - i32.gt_s - select - return - end - end - local.get $4 - i32.const 1072693247 - i32.lt_s - if - local.get $10 - f64.const 1.e+300 - f64.mul - f64.const 1.e+300 - f64.mul - local.get $10 - f64.const 1e-300 - f64.mul - f64.const 1e-300 - f64.mul - local.get $7 - i32.const 0 - i32.lt_s - select - return - end - local.get $4 - i32.const 1072693248 - i32.gt_s - if - local.get $10 - f64.const 1.e+300 - f64.mul - f64.const 1.e+300 - f64.mul - local.get $10 - f64.const 1e-300 - f64.mul - f64.const 1e-300 - f64.mul - local.get $7 - i32.const 0 - i32.gt_s - select - return - end - f64.const 1.4426950216293335 - local.get $2 - f64.const 1 - f64.sub - local.tee $0 - f64.mul - local.tee $2 - local.get $0 - f64.const 1.9259629911266175e-08 - f64.mul - local.get $0 - local.get $0 - f64.mul - f64.const 0.5 - local.get $0 - f64.const 0.3333333333333333 - local.get $0 - f64.const 0.25 - f64.mul - f64.sub - f64.mul - f64.sub - f64.mul - f64.const 1.4426950408889634 - f64.mul - f64.sub - local.tee $0 - f64.add - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.set $6 - local.get $0 - local.get $6 - local.get $2 - f64.sub - f64.sub - else - local.get $4 - i32.const 1048576 - i32.lt_s - if (result i32) - local.get $2 - f64.const 9007199254740992 - f64.mul - local.tee $2 - i64.reinterpret_f64 - i64.const 32 - i64.shr_u - i32.wrap_i64 - local.set $4 - i32.const -53 - else - i32.const 0 - end - local.get $4 - i32.const 20 - i32.shr_s - i32.const 1023 - i32.sub - i32.add - local.set $7 - local.get $4 - i32.const 1048575 - i32.and - local.tee $5 - i32.const 1072693248 - i32.or - local.set $4 - local.get $5 - i32.const 235662 - i32.gt_s - if - local.get $5 - i32.const 767610 - i32.lt_s - if - i32.const 1 - local.set $16 - else - local.get $7 - i32.const 1 - i32.add - local.set $7 - local.get $4 - i32.const -1048576 - i32.add - local.set $4 - end - end - f64.const 0.9617967009544373 - local.get $2 - i64.reinterpret_f64 - i64.const 4294967295 - i64.and - local.get $4 - i64.extend_i32_s - i64.const 32 - i64.shl - i64.or - f64.reinterpret_i64 - local.tee $6 - f64.const 1.5 - f64.const 1 - local.get $16 - select - local.tee $3 - f64.sub - local.tee $2 - f64.const 1 - local.get $6 - local.get $3 - f64.add - f64.div - local.tee $0 - f64.mul - local.tee $17 - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.tee $14 - f64.const 3 - local.get $14 - local.get $14 - f64.mul - local.tee $20 - f64.add - local.get $17 - local.get $17 - f64.mul - local.tee $12 - local.get $12 - f64.mul - f64.const 0.5999999999999946 - local.get $12 - f64.const 0.4285714285785502 - local.get $12 - f64.const 0.33333332981837743 - local.get $12 - f64.const 0.272728123808534 - local.get $12 - f64.const 0.23066074577556175 - local.get $12 - f64.const 0.20697501780033842 - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - local.get $0 - local.get $2 - local.get $14 - local.get $4 - i32.const 1 - i32.shr_s - i32.const 536870912 - i32.or - i32.const 524288 - i32.add - local.get $16 - i32.const 18 - i32.shl - i32.add - i64.extend_i32_s - i64.const 32 - i64.shl - f64.reinterpret_i64 - local.tee $0 - f64.mul - f64.sub - local.get $14 - local.get $6 - local.get $0 - local.get $3 - f64.sub - f64.sub - f64.mul - f64.sub - f64.mul - local.tee $3 - local.get $14 - local.get $17 - f64.add - f64.mul - f64.add - local.tee $0 - f64.add - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.tee $6 - f64.mul - local.tee $2 - local.get $3 - local.get $6 - f64.mul - local.get $0 - local.get $6 - f64.const 3 - f64.sub - local.get $20 - f64.sub - f64.sub - local.get $17 - f64.mul - f64.add - local.tee $0 - f64.add - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.tee $3 - f64.mul - local.tee $20 - f64.const -7.028461650952758e-09 - local.get $3 - f64.mul - local.get $0 - local.get $3 - local.get $2 - f64.sub - f64.sub - f64.const 0.9617966939259756 - f64.mul - f64.add - f64.const 1.350039202129749e-08 - f64.const 0 - local.get $16 - select - f64.add - local.tee $3 - f64.add - f64.const 0.5849624872207642 - f64.const 0 - local.get $16 - select - local.tee $2 - f64.add - local.get $7 - f64.convert_i32_s - local.tee $0 - f64.add - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.set $6 - local.get $3 - local.get $6 - local.get $0 - f64.sub - local.get $2 - f64.sub - local.get $20 - f64.sub - f64.sub - end - local.set $2 - local.get $1 - local.get $1 - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.tee $0 - f64.sub - local.get $6 - f64.mul - local.get $1 - local.get $2 - f64.mul - f64.add - local.tee $1 - local.get $0 - local.get $6 - f64.mul - local.tee $3 - f64.add - local.tee $0 - i64.reinterpret_f64 - local.tee $13 - i32.wrap_i64 - local.set $5 - block $folding-inner1 - block $folding-inner0 - local.get $13 - i64.const 32 - i64.shr_u - i32.wrap_i64 - local.tee $11 - i32.const 1083179008 - i32.ge_s - if - local.get $5 - local.get $11 - i32.const 1083179008 - i32.sub - i32.or - local.get $1 - f64.const 8.008566259537294e-17 - f64.add - local.get $0 - local.get $3 - f64.sub - f64.gt - i32.or - br_if $folding-inner0 - else - local.get $11 - i32.const 2147483647 - i32.and - i32.const 1083231232 - i32.ge_s - i32.const 0 - local.get $5 - local.get $11 - i32.const -1064252416 - i32.sub - i32.or - local.get $1 - local.get $0 - local.get $3 - f64.sub - f64.le - i32.or - select - br_if $folding-inner1 - end - local.get $11 - i32.const 2147483647 - i32.and - local.tee $9 - i32.const 20 - i32.shr_s - i32.const 1023 - i32.sub - local.set $5 - i32.const 0 - local.set $7 - local.get $9 - i32.const 1071644672 - i32.gt_s - if - i32.const 1048575 - local.get $11 - i32.const 1048576 - local.get $5 - i32.const 1 - i32.add - i32.shr_s - i32.add - local.tee $9 - i32.const 2147483647 - i32.and - i32.const 20 - i32.shr_s - i32.const 1023 - i32.sub - local.tee $5 - i32.shr_s - i32.const -1 - i32.xor - local.get $9 - i32.and - i64.extend_i32_s - i64.const 32 - i64.shl - f64.reinterpret_i64 - local.set $0 - i32.const 0 - local.get $9 - i32.const 1048575 - i32.and - i32.const 1048576 - i32.or - i32.const 20 - local.get $5 - i32.sub - i32.shr_s - local.tee $7 - i32.sub - local.get $7 - local.get $11 - i32.const 0 - i32.lt_s - select - local.set $7 - local.get $3 - local.get $0 - f64.sub - local.set $3 - end - local.get $1 - local.get $3 - f64.add - i64.reinterpret_f64 - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.tee $0 - f64.const 0.6931471824645996 - f64.mul - local.tee $2 local.get $1 + i32.const 1 + i32.shr_u + local.set $1 local.get $0 - local.get $3 - f64.sub - f64.sub - f64.const 0.6931471805599453 - f64.mul local.get $0 - f64.const -1.904654299957768e-09 - f64.mul - f64.add - local.tee $1 - f64.add - local.tee $3 - local.get $3 - f64.mul + i32.mul local.set $0 - local.get $10 - f64.const 1 - local.get $3 - local.get $3 - local.get $0 - f64.const 0.16666666666666602 - local.get $0 - f64.const -2.7777777777015593e-03 - local.get $0 - f64.const 6.613756321437934e-05 - local.get $0 - f64.const -1.6533902205465252e-06 - local.get $0 - f64.const 4.1381367970572385e-08 - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.sub - local.tee $0 - f64.mul - local.get $0 - f64.const 2 - f64.sub - f64.div - local.get $1 - local.get $3 - local.get $2 - f64.sub - f64.sub - local.tee $0 - local.get $3 - local.get $0 - f64.mul - f64.add - f64.sub - local.get $3 - f64.sub - f64.sub - local.tee $0 - i64.reinterpret_f64 - i64.const 32 - i64.shr_u - i32.wrap_i64 - local.get $7 - i32.const 20 - i32.shl - i32.add - local.tee $5 - i32.const 20 - i32.shr_s - i32.const 0 - i32.le_s - if (result f64) - local.get $0 - local.get $7 - call $~lib/math/NativeMath.scalbn - else - local.get $0 - i64.reinterpret_f64 - i64.const 4294967295 - i64.and - local.get $5 - i64.extend_i32_s - i64.const 32 - i64.shl - i64.or - f64.reinterpret_i64 - end - f64.mul - return + br $while-continue|0 end - local.get $10 - f64.const 1.e+300 - f64.mul - f64.const 1.e+300 - f64.mul - return - end - local.get $10 - f64.const 1e-300 - f64.mul - f64.const 1e-300 - f64.mul + end + local.get $2 ) (func $std/operator-overloading/Tester.equals (param $0 i32) (param $1 i32) (result i32) local.get $0 @@ -1460,21 +466,15 @@ global.get $std/operator-overloading/p1 local.tee $0 i32.load - f64.convert_i32_s global.get $std/operator-overloading/p2 local.tee $1 i32.load - f64.convert_i32_s - call $~lib/math/NativeMath.pow - i32.trunc_f64_s + call $~lib/math/ipow32 local.get $0 i32.load offset=4 - f64.convert_i32_s local.get $1 i32.load offset=4 - f64.convert_i32_s - call $~lib/math/NativeMath.pow - i32.trunc_f64_s + call $~lib/math/ipow32 call $std/operator-overloading/Tester#constructor global.set $std/operator-overloading/p global.get $std/operator-overloading/p diff --git a/tests/compiler/std/operator-overloading.untouched.wat b/tests/compiler/std/operator-overloading.untouched.wat index ca613cd6b6..3722cbd445 100644 --- a/tests/compiler/std/operator-overloading.untouched.wat +++ b/tests/compiler/std/operator-overloading.untouched.wat @@ -5,12 +5,9 @@ (type $none_=>_none (func)) (type $i32_=>_none (func (param i32))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) - (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) (data (i32.const 16) "6\00\00\00\01\00\00\00\01\00\00\006\00\00\00s\00t\00d\00/\00o\00p\00e\00r\00a\00t\00o\00r\00-\00o\00v\00e\00r\00l\00o\00a\00d\00i\00n\00g\00.\00t\00s\00") - (data (i32.const 88) "\00\00\00\00\00\a0\f6?\00\00\00\00\00\00\00\00\00\c8\b9\f2\82,\d6\bf\80V7($\b4\fa<\00\00\00\00\00\80\f6?\00\00\00\00\00\00\00\00\00\08X\bf\bd\d1\d5\bf \f7\e0\d8\08\a5\1c\bd\00\00\00\00\00`\f6?\00\00\00\00\00\00\00\00\00XE\17wv\d5\bfmP\b6\d5\a4b#\bd\00\00\00\00\00@\f6?\00\00\00\00\00\00\00\00\00\f8-\87\ad\1a\d5\bf\d5g\b0\9e\e4\84\e6\bc\00\00\00\00\00 \f6?\00\00\00\00\00\00\00\00\00xw\95_\be\d4\bf\e0>)\93i\1b\04\bd\00\00\00\00\00\00\f6?\00\00\00\00\00\00\00\00\00`\1c\c2\8ba\d4\bf\cc\84LH/\d8\13=\00\00\00\00\00\e0\f5?\00\00\00\00\00\00\00\00\00\a8\86\860\04\d4\bf:\0b\82\ed\f3B\dc<\00\00\00\00\00\c0\f5?\00\00\00\00\00\00\00\00\00HiUL\a6\d3\bf`\94Q\86\c6\b1 =\00\00\00\00\00\a0\f5?\00\00\00\00\00\00\00\00\00\80\98\9a\ddG\d3\bf\92\80\c5\d4MY%=\00\00\00\00\00\80\f5?\00\00\00\00\00\00\00\00\00 \e1\ba\e2\e8\d2\bf\d8+\b7\99\1e{&=\00\00\00\00\00`\f5?\00\00\00\00\00\00\00\00\00\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00`\f5?\00\00\00\00\00\00\00\00\00\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00@\f5?\00\00\00\00\00\00\00\00\00x\cf\fbA)\d2\bfv\daS($Z\16\bd\00\00\00\00\00 \f5?\00\00\00\00\00\00\00\00\00\98i\c1\98\c8\d1\bf\04T\e7h\bc\af\1f\bd\00\00\00\00\00\00\f5?\00\00\00\00\00\00\00\00\00\a8\ab\ab\\g\d1\bf\f0\a8\823\c6\1f\1f=\00\00\00\00\00\e0\f4?\00\00\00\00\00\00\00\00\00H\ae\f9\8b\05\d1\bffZ\05\fd\c4\a8&\bd\00\00\00\00\00\c0\f4?\00\00\00\00\00\00\00\00\00\90s\e2$\a3\d0\bf\0e\03\f4~\eek\0c\bd\00\00\00\00\00\a0\f4?\00\00\00\00\00\00\00\00\00\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\a0\f4?\00\00\00\00\00\00\00\00\00\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\80\f4?\00\00\00\00\00\00\00\00\00@^m\18\b9\cf\bf\87<\99\ab*W\0d=\00\00\00\00\00`\f4?\00\00\00\00\00\00\00\00\00`\dc\cb\ad\f0\ce\bf$\af\86\9c\b7&+=\00\00\00\00\00@\f4?\00\00\00\00\00\00\00\00\00\f0*n\07\'\ce\bf\10\ff?TO/\17\bd\00\00\00\00\00 \f4?\00\00\00\00\00\00\00\00\00\c0Ok!\\\cd\bf\1bh\ca\bb\91\ba!=\00\00\00\00\00\00\f4?\00\00\00\00\00\00\00\00\00\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy\'=\00\00\00\00\00\00\f4?\00\00\00\00\00\00\00\00\00\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy\'=\00\00\00\00\00\e0\f3?\00\00\00\00\00\00\00\00\00\90-t\86\c2\cb\bf\8f\b7\8b1\b0N\19=\00\00\00\00\00\c0\f3?\00\00\00\00\00\00\00\00\00\c0\80N\c9\f3\ca\bff\90\cd?cN\ba<\00\00\00\00\00\a0\f3?\00\00\00\00\00\00\00\00\00\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\a0\f3?\00\00\00\00\00\00\00\00\00\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\80\f3?\00\00\00\00\00\00\00\00\00P\f4\9cZR\c9\bf\e3\d4\c1\04\d9\d1*\bd\00\00\00\00\00`\f3?\00\00\00\00\00\00\00\00\00\d0 e\a0\7f\c8\bf\t\fa\db\7f\bf\bd+=\00\00\00\00\00@\f3?\00\00\00\00\00\00\00\00\00\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00@\f3?\00\00\00\00\00\00\00\00\00\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00 \f3?\00\00\00\00\00\00\00\00\00\d0\19\e7\0f\d6\c6\bff\e2\b2\a3j\e4\10\bd\00\00\00\00\00\00\f3?\00\00\00\00\00\00\00\00\00\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\00\f3?\00\00\00\00\00\00\00\00\00\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\e0\f2?\00\00\00\00\00\00\00\00\00\b0\a1\e3\e5&\c5\bf\8f[\07\90\8b\de \bd\00\00\00\00\00\c0\f2?\00\00\00\00\00\00\00\00\00\80\cbl+M\c4\bf\11\0e\bd\00\00\00\00\00\e0\ed?\00\00\00\00\00\00\00\00\00`F\d1;\97\b1?\9b\9e\0dV]2%\bd\00\00\00\00\00\a0\ed?\00\00\00\00\00\00\00\00\00\e0\d1\a7\f5\bd\b3?\d7N\db\a5^\c8,=\00\00\00\00\00`\ed?\00\00\00\00\00\00\00\00\00\a0\97MZ\e9\b5?\1e\1d]<\06i,\bd\00\00\00\00\00@\ed?\00\00\00\00\00\00\00\00\00\c0\ea\n\d3\00\b7?2\ed\9d\a9\8d\1e\ec<\00\00\00\00\00\00\ed?\00\00\00\00\00\00\00\00\00@Y]^3\b9?\daG\bd:\\\11#=\00\00\00\00\00\c0\ec?\00\00\00\00\00\00\00\00\00`\ad\8d\c8j\bb?\e5h\f7+\80\90\13\bd\00\00\00\00\00\a0\ec?\00\00\00\00\00\00\00\00\00@\bc\01X\88\bc?\d3\acZ\c6\d1F&=\00\00\00\00\00`\ec?\00\00\00\00\00\00\00\00\00 \n\839\c7\be?\e0E\e6\afh\c0-\bd\00\00\00\00\00@\ec?\00\00\00\00\00\00\00\00\00\e0\db9\91\e8\bf?\fd\n\a1O\d64%\bd\00\00\00\00\00\00\ec?\00\00\00\00\00\00\00\00\00\e0\'\82\8e\17\c1?\f2\07-\cex\ef!=\00\00\00\00\00\e0\eb?\00\00\00\00\00\00\00\00\00\f0#~+\aa\c1?4\998D\8e\a7,=\00\00\00\00\00\a0\eb?\00\00\00\00\00\00\00\00\00\80\86\0ca\d1\c2?\a1\b4\81\cbl\9d\03=\00\00\00\00\00\80\eb?\00\00\00\00\00\00\00\00\00\90\15\b0\fce\c3?\89rK#\a8/\c6<\00\00\00\00\00@\eb?\00\00\00\00\00\00\00\00\00\b03\83=\91\c4?x\b6\fdTy\83%=\00\00\00\00\00 \eb?\00\00\00\00\00\00\00\00\00\b0\a1\e4\e5\'\c5?\c7}i\e5\e83&=\00\00\00\00\00\e0\ea?\00\00\00\00\00\00\00\00\00\10\8c\beNW\c6?x.<,\8b\cf\19=\00\00\00\00\00\c0\ea?\00\00\00\00\00\00\00\00\00pu\8b\12\f0\c6?\e1!\9c\e5\8d\11%\bd\00\00\00\00\00\a0\ea?\00\00\00\00\00\00\00\00\00PD\85\8d\89\c7?\05C\91p\10f\1c\bd\00\00\00\00\00`\ea?\00\00\00\00\00\00\00\00\00\009\eb\af\be\c8?\d1,\e9\aaT=\07\bd\00\00\00\00\00@\ea?\00\00\00\00\00\00\00\00\00\00\f7\dcZZ\c9?o\ff\a0X(\f2\07=\00\00\00\00\00\00\ea?\00\00\00\00\00\00\00\00\00\e0\8a<\ed\93\ca?i!VPCr(\bd\00\00\00\00\00\e0\e9?\00\00\00\00\00\00\00\00\00\d0[W\d81\cb?\aa\e1\acN\8d5\0c\bd\00\00\00\00\00\c0\e9?\00\00\00\00\00\00\00\00\00\e0;8\87\d0\cb?\b6\12TY\c4K-\bd\00\00\00\00\00\a0\e9?\00\00\00\00\00\00\00\00\00\10\f0\c6\fbo\cc?\d2+\96\c5r\ec\f1\bc\00\00\00\00\00`\e9?\00\00\00\00\00\00\00\00\00\90\d4\b0=\b1\cd?5\b0\15\f7*\ff*\bd\00\00\00\00\00@\e9?\00\00\00\00\00\00\00\00\00\10\e7\ff\0eS\ce?0\f4A`\'\12\c2<\00\00\00\00\00 \e9?\00\00\00\00\00\00\00\00\00\00\dd\e4\ad\f5\ce?\11\8e\bbe\15!\ca\bc\00\00\00\00\00\00\e9?\00\00\00\00\00\00\00\00\00\b0\b3l\1c\99\cf?0\df\0c\ca\ec\cb\1b=\00\00\00\00\00\c0\e8?\00\00\00\00\00\00\00\00\00XM`8q\d0?\91N\ed\16\db\9c\f8<\00\00\00\00\00\a0\e8?\00\00\00\00\00\00\00\00\00`ag-\c4\d0?\e9\ea<\16\8b\18\'=\00\00\00\00\00\80\e8?\00\00\00\00\00\00\00\00\00\e8\'\82\8e\17\d1?\1c\f0\a5c\0e!,\bd\00\00\00\00\00`\e8?\00\00\00\00\00\00\00\00\00\f8\ac\cb\\k\d1?\81\16\a5\f7\cd\9a+=\00\00\00\00\00@\e8?\00\00\00\00\00\00\00\00\00hZc\99\bf\d1?\b7\bdGQ\ed\a6,=\00\00\00\00\00 \e8?\00\00\00\00\00\00\00\00\00\b8\0emE\14\d2?\ea\baF\ba\de\87\n=\00\00\00\00\00\e0\e7?\00\00\00\00\00\00\00\00\00\90\dc|\f0\be\d2?\f4\04PJ\fa\9c*=\00\00\00\00\00\c0\e7?\00\00\00\00\00\00\00\00\00`\d3\e1\f1\14\d3?\b8\9a\ec\ef?\d1f\87\10z^\90\bc\85\7fn\e8\15\e3\ef?\13\f6g5R\d2\8c\be\ef?m{\83]\a6\9a\97<\0f\89\f9lX\b5\ef?\fc\ef\fd\92\1a\b5\8e<\f7Gr+\92\ac\ef?\d1\9c/p=\be><\a2\d1\d32\ec\a3\ef?\0bn\90\894\03j\bc\1b\d3\fe\aff\9b\ef?\0e\bd/*RV\95\bcQ[\12\d0\01\93\ef?U\eaN\8c\ef\80P\bc\cc1l\c0\bd\8a\ef?\16\f4\d5\b9#\c9\91\bc\e0-\a9\ae\9a\82\ef?\afU\\\e9\e3\d3\80\f7\ec\9a<\aa\b9h1\87T\ef?\9d8\86\cb\82\e7\8f\bc\1d\d9\fc\"PM\ef?\8d\c3\a6DAo\8a<\d6\8cb\88;F\ef?}\04\e4\b0\05z\80<\96\dc}\91I?\ef?\94\a8\a8\e3\fd\8e\96<8bunz8\ef?}Ht\f2\18^\87\a9\af\0c\ef?\b6\ab\b0MuM\83<\15\b71\n\fe\06\ef?Lt\ac\e2\01B\86<1\d8L\fcp\01\ef?J\f8\d3]9\dd\8f<\ff\16d\b2\08\fc\ee?\04[\8e;\80\a3\86\bc\f1\9f\92_\c5\f6\ee?hPK\cc\edJ\92\bc\cb\a9:7\a7\f1\ee?\8e-Q\1b\f8\07\99\bcf\d8\05m\ae\ec\ee?\d26\94>\e8\d1q\bc\f7\9f\e54\db\e7\ee?\15\1b\ce\b3\19\19\99\bc\e5\a8\13\c3-\e3\ee?mL*\a7H\9f\85<\"4\12L\a6\de\ee?\8ai(z`\12\93\bc\1c\80\ac\04E\da\ee?[\89\17H\8f\a7X\bc*.\f7!\n\d6\ee?\1b\9aIg\9b,|\bc\97\a8P\d9\f5\d1\ee?\11\ac\c2`\edcC<-\89a`\08\ce\ee?\efd\06;\tf\96Z~d\1fx\bct_\ec\e8u\9f\ee?\b0}\8b\c0J\ee\86\bct\81\a5H\9a\9f\ee?\8a\e6U\1e2\19\86\bc\c9gBV\eb\9f\ee?\d3\d4\t^\cb\9c\90T\'\a4\ee?47;\f1\b6i\93\bc\13\ceL\99\89\a5\ee?\1e\ff\19:\84^\80\bc\ad\c7#F\1a\a7\ee?nWr\d8P\d4\94\bc\ed\92D\9b\d9\a8\ee?\00\8a\0e[g\ad\90<\99f\8a\d9\c7\aa\ee?\b4\ea\f0\c1/\b7\8d<\db\a0*B\e5\ac\ee?\ff\e7\c5\9c`\b6e\bc\8cD\b5\162\af\ee?D_\f3Y\83\f6{<6w\15\99\ae\b1\ee?\83=\1e\a7\1f\t\93\bc\c6\ff\91\0b[\b4\ee?)\1el\8b\b8\a9]\bc\e5\c5\cd\b07\b7\ee?Y\b9\90|\f9#l\bc\0fR\c8\cbD\ba\ee?\aa\f9\f4\"CC\92\bcPN\de\9f\82\bd\ee?K\8ef\d7l\ca\85\bc\ba\07\cap\f1\c0\ee?\'\ce\91+\fc\afq<\90\f0\a3\82\91\c4\ee?\bbs\n\e15\d2m<##\e3\19c\c8\ee?c\"b\"\04\c5\87\bce\e5]{f\cc\ee?\d51\e2\e3\86\1c\8b<3-J\ec\9b\d0\ee?\15\bb\bc\d3\d1\bb\91\bc]%>\b2\03\d5\ee?\d21\ee\9c1\cc\90\b4\07!\d5\82\bc_\9b{3\97|\ef?\c9\0dG;\b9*\89\bc)\a1\f5\14F\86\ef?\d3\88:`\04\b6t<\f6?\8b\e7.\90\ef?qr\9dQ\ec\c5\83<\83L\c7\fbQ\9a\ef?\f0\91\d3\8f\12\f7\8f\bc\da\90\a4\a2\af\a4\ef?}t#\e2\98\ae\8d\bc\f1g\8e-H\af\ef?\08 \aaA\bc\c3\8e<\'Za\ee\1b\ba\ef?2\eb\a9\c3\94+\84<\97\bak7+\c5\ef?\ee\85\d11\a9d\8a<@En[v\d0\ef?\ed\e3;\e4\ba7\8e\bc\14\be\9c\ad\fd\db\ef?\9d\cd\91M;\89w<\d8\90\9e\81\c1\e7\ef?\89\cc`A\c1\05S<\f1q\8f+\c2\f3\ef?") (table $0 1 funcref) (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0)) (global $~lib/rt/stub/offset (mut i32) (i32.const 0)) @@ -32,7 +29,6 @@ (global $std/operator-overloading/p1 (mut i32) (i32.const 0)) (global $std/operator-overloading/p2 (mut i32) (i32.const 0)) (global $~lib/ASC_SHRINK_LEVEL i32 (i32.const 0)) - (global $~lib/util/math/log_tail (mut f64) (f64.const 0)) (global $std/operator-overloading/p (mut i32) (i32.const 0)) (global $std/operator-overloading/n1 (mut i32) (i32.const 0)) (global $std/operator-overloading/n2 (mut i32) (i32.const 0)) @@ -83,7 +79,7 @@ (global $std/operator-overloading/aii1 (mut i32) (i32.const 0)) (global $std/operator-overloading/aii2 (mut i32) (i32.const 0)) (global $std/operator-overloading/aii (mut i32) (i32.const 0)) - (global $~lib/heap/__heap_base i32 (i32.const 6232)) + (global $~lib/heap/__heap_base i32 (i32.const 88)) (export "memory" (memory $0)) (start $~start) (func $~lib/rt/stub/maybeGrowMemory (param $0 i32) @@ -354,985 +350,210 @@ call $~lib/rt/stub/__release local.get $2 ) - (func $~lib/math/NativeMath.pow (param $0 f64) (param $1 f64) (result f64) - (local $2 f64) - (local $3 f64) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 f64) - (local $11 i64) - (local $12 i32) - (local $13 i64) - (local $14 i64) - (local $15 f64) - (local $16 f64) - (local $17 f64) - (local $18 f64) - (local $19 f64) - (local $20 f64) - (local $21 f64) - (local $22 f64) - (local $23 f64) - (local $24 f64) - (local $25 f64) - (local $26 f64) - (local $27 f64) - (local $28 f64) - (local $29 f64) - (local $30 f64) - (local $31 f64) - (local $32 f64) - (local $33 f64) - (local $34 f64) - (local $35 f64) - (local $36 f64) - (local $37 f64) - (local $38 f64) - (local $39 i32) - (local $40 i32) - (local $41 i32) - (local $42 i32) - (local $43 i64) - (local $44 i64) - local.get $1 - f64.abs - f64.const 2 - f64.le + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s if - local.get $1 - f64.const 2 - f64.eq - if - local.get $0 - local.get $0 - f64.mul - return - end - local.get $1 - f64.const 0.5 - f64.eq + local.get $0 + i32.const -1 + i32.eq if - local.get $0 - f64.sqrt - f64.abs - f64.const inf - local.get $0 - f64.const inf - f64.neg - f64.ne + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and select return end local.get $1 - f64.const -1 - f64.eq - if - f64.const 1 - local.get $0 - f64.div - return - end + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else local.get $1 - f64.const 1 - f64.eq + i32.const 1 + i32.eq if local.get $0 return - end - local.get $1 - f64.const 0 - f64.eq - if - f64.const 1 - return - end - end - i32.const 0 - i32.const 1 - i32.lt_s - drop - block $~lib/util/math/pow_lut|inlined.0 (result f64) - local.get $0 - local.set $3 - local.get $1 - local.set $2 - i32.const 0 - local.set $4 - local.get $3 - i64.reinterpret_f64 - local.set $5 - local.get $2 - i64.reinterpret_f64 - local.set $6 - local.get $5 - i64.const 52 - i64.shr_u - local.set $7 - local.get $6 - i64.const 52 - i64.shr_u - local.set $8 - local.get $7 - i64.const 1 - i64.sub - i64.const 2047 - i64.const 1 - i64.sub - i64.ge_u - if (result i32) - i32.const 1 else - local.get $8 - i64.const 2047 - i64.and - i64.const 958 - i64.sub - i64.const 1086 - i64.const 958 - i64.sub - i64.ge_u - end - if - local.get $6 - local.set $9 - local.get $9 - i64.const 1 - i64.shl - i64.const 1 - i64.sub - i64.const -9007199254740992 - i64.const 1 - i64.sub - i64.ge_u + local.get $1 + i32.const 2 + i32.eq if - local.get $6 - i64.const 1 - i64.shl - i64.const 0 - i64.eq - if - f64.const 1 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 4607182418800017408 - i64.eq + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s if - f64.const nan:0x8000000000000 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 1 - i64.shl - i64.const -9007199254740992 - i64.gt_u - if (result i32) - i32.const 1 - else - local.get $6 - i64.const 1 - i64.shl - i64.const -9007199254740992 - i64.gt_u - end - if - local.get $3 - local.get $2 - f64.add - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 1 - i64.shl - i64.const 9214364837600034816 - i64.eq - if - f64.const nan:0x8000000000000 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 1 - i64.shl - i64.const 9214364837600034816 - i64.lt_u - local.get $6 - i64.const 63 - i64.shr_u - i64.const 0 - i64.ne - i32.eqz - i32.eq - if - f64.const 0 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $2 - local.get $2 - f64.mul - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - local.set $9 - local.get $9 - i64.const 1 - i64.shl - i64.const 1 - i64.sub - i64.const -9007199254740992 - i64.const 1 - i64.sub - i64.ge_u - if - local.get $3 - local.get $3 - f64.mul - local.set $10 - local.get $5 - i64.const 63 - i64.shr_u - i32.wrap_i64 - if (result i32) - block $~lib/util/math/checkint|inlined.0 (result i32) - local.get $6 - local.set $9 - local.get $9 - i64.const 52 - i64.shr_u - i64.const 2047 - i64.and - local.set $11 - local.get $11 - i64.const 1023 - i64.lt_u - if - i32.const 0 - br $~lib/util/math/checkint|inlined.0 - end - local.get $11 - i64.const 1023 - i64.const 52 - i64.add - i64.gt_u - if - i32.const 2 - br $~lib/util/math/checkint|inlined.0 - end - i64.const 1 - i64.const 1023 - i64.const 52 - i64.add - local.get $11 - i64.sub - i64.shl - local.set $11 - local.get $9 - local.get $11 - i64.const 1 - i64.sub - i64.and - i64.const 0 - i64.ne - if - i32.const 0 - br $~lib/util/math/checkint|inlined.0 - end - local.get $9 - local.get $11 - i64.and - i64.const 0 - i64.ne - if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 i32.const 1 - br $~lib/util/math/checkint|inlined.0 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 end - i32.const 2 - end - i32.const 1 - i32.eq - else - i32.const 0 - end - if - local.get $10 - f64.neg - local.set $10 - end - local.get $6 - i64.const 63 - i64.shr_u - i64.const 0 - i64.ne - if (result f64) - f64.const 1 - local.get $10 - f64.div - else - local.get $10 - end - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 63 - i64.shr_u - i64.const 0 - i64.ne - if - block $~lib/util/math/checkint|inlined.1 (result i32) - local.get $6 - local.set $9 - local.get $9 - i64.const 52 - i64.shr_u - i64.const 2047 - i64.and - local.set $11 - local.get $11 - i64.const 1023 - i64.lt_u - if - i32.const 0 - br $~lib/util/math/checkint|inlined.1 - end - local.get $11 - i64.const 1023 - i64.const 52 - i64.add - i64.gt_u - if - i32.const 2 - br $~lib/util/math/checkint|inlined.1 - end - i64.const 1 - i64.const 1023 - i64.const 52 - i64.add - local.get $11 - i64.sub - i64.shl - local.set $11 - local.get $9 - local.get $11 - i64.const 1 - i64.sub - i64.and - i64.const 0 - i64.ne - if - i32.const 0 - br $~lib/util/math/checkint|inlined.1 - end - local.get $9 - local.get $11 - i64.and - i64.const 0 - i64.ne - if + local.get $1 i32.const 1 - br $~lib/util/math/checkint|inlined.1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end end - i32.const 2 - end - local.set $12 - local.get $12 - i32.const 0 - i32.eq - if - local.get $3 - local.get $3 - f64.sub - local.get $3 - local.get $3 - f64.sub - f64.div - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $12 - i32.const 1 - i32.eq - if - i32.const 262144 - local.set $4 - end - local.get $5 - i64.const 9223372036854775807 - i64.and - local.set $5 - local.get $7 - i64.const 2047 - i64.and - local.set $7 - end - local.get $8 - i64.const 2047 - i64.and - i64.const 958 - i64.sub - i64.const 1086 - i64.const 958 - i64.sub - i64.ge_u - if - local.get $5 - i64.const 4607182418800017408 - i64.eq - if - f64.const 1 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $8 - i64.const 2047 - i64.and - i64.const 958 - i64.lt_u - if - f64.const 1 - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $5 - i64.const 4607182418800017408 - i64.gt_u - local.get $8 - i64.const 2048 - i64.lt_u - i32.eq - if (result f64) - f64.const inf - else - f64.const 0 + local.get $2 + return end - br $~lib/util/math/pow_lut|inlined.0 - end - local.get $7 - i64.const 0 - i64.eq - if - local.get $3 - f64.const 4503599627370496 - f64.mul - i64.reinterpret_f64 - local.set $5 - local.get $5 - i64.const 9223372036854775807 - i64.and - local.set $5 - local.get $5 - i64.const 52 - i64.const 52 - i64.shl - i64.sub - local.set $5 end end - local.get $5 - local.set $9 - local.get $9 - i64.const 4604531861337669632 - i64.sub - local.set $11 - local.get $11 - i64.const 52 - i64.const 7 - i64.sub - i64.shr_u - i64.const 127 - i64.and - i32.wrap_i64 - local.set $12 - local.get $11 - i64.const 52 - i64.shr_s - local.set $13 - local.get $9 - local.get $11 - i64.const 4095 - i64.const 52 - i64.shl - i64.and - i64.sub - local.set $14 - local.get $14 - f64.reinterpret_i64 - local.set $10 - local.get $13 - f64.convert_i64_s - local.set $15 - i32.const 88 - local.get $12 - i32.const 2 - i32.const 3 - i32.add - i32.shl - i32.add - f64.load - local.set $16 - i32.const 88 - local.get $12 - i32.const 2 - i32.const 3 - i32.add - i32.shl - i32.add - f64.load offset=16 - local.set $17 - i32.const 88 - local.get $12 - i32.const 2 - i32.const 3 - i32.add - i32.shl - i32.add - f64.load offset=24 - local.set $18 - local.get $14 - i64.const 2147483648 - i64.add - i64.const -4294967296 - i64.and - f64.reinterpret_i64 - local.set $19 - local.get $10 - local.get $19 - f64.sub - local.set $20 - local.get $19 - local.get $16 - f64.mul - f64.const 1 - f64.sub - local.set $21 - local.get $20 - local.get $16 - f64.mul - local.set $22 - local.get $21 - local.get $22 - f64.add - local.set $23 - local.get $15 - f64.const 0.6931471805598903 - f64.mul - local.get $17 - f64.add - local.set $24 - local.get $24 - local.get $23 - f64.add - local.set $25 - local.get $15 - f64.const 5.497923018708371e-14 - f64.mul - local.get $18 - f64.add - local.set $26 - local.get $24 - local.get $25 - f64.sub - local.get $23 - f64.add - local.set $27 - f64.const -0.5 - local.get $23 - f64.mul - local.set $28 - local.get $23 - local.get $28 - f64.mul - local.set $29 - local.get $23 - local.get $29 - f64.mul - local.set $30 - f64.const -0.5 - local.get $21 - f64.mul - local.set $31 - local.get $21 - local.get $31 - f64.mul - local.set $32 - local.get $25 - local.get $32 - f64.add - local.set $33 - local.get $22 - local.get $28 - local.get $31 - f64.add - f64.mul - local.set $34 - local.get $25 - local.get $33 - f64.sub - local.get $32 - f64.add - local.set $35 - local.get $30 - f64.const -0.6666666666666679 - local.get $23 - f64.const 0.5000000000000007 - f64.mul - f64.add - local.get $29 - f64.const 0.7999999995323976 - local.get $23 - f64.const -0.6666666663487739 - f64.mul - f64.add - local.get $29 - f64.const -1.142909628459501 - local.get $23 - f64.const 1.0000415263675542 - f64.mul - f64.add - f64.mul - f64.add - f64.mul - f64.add - f64.mul - local.set $36 - local.get $26 - local.get $27 - f64.add - local.get $34 - f64.add - local.get $35 - f64.add - local.get $36 - f64.add - local.set $37 - local.get $33 - local.get $37 - f64.add - local.set $38 - local.get $33 - local.get $38 - f64.sub - local.get $37 - f64.add - global.set $~lib/util/math/log_tail - local.get $38 - local.set $38 - global.get $~lib/util/math/log_tail - local.set $37 - local.get $6 - i64.const -134217728 - i64.and - f64.reinterpret_i64 - local.set $34 - local.get $2 - local.get $34 - f64.sub - local.set $33 - local.get $38 - i64.reinterpret_f64 - i64.const -134217728 - i64.and - f64.reinterpret_i64 - local.set $32 - local.get $38 - local.get $32 - f64.sub - local.get $37 - f64.add - local.set $31 - local.get $34 - local.get $32 - f64.mul - local.set $36 - local.get $33 - local.get $32 - f64.mul - local.get $2 - local.get $31 - f64.mul - f64.add - local.set $35 - block $~lib/util/math/exp_inline|inlined.0 (result f64) - local.get $36 - local.set $15 - local.get $35 - local.set $10 - local.get $4 - local.set $12 - local.get $15 - i64.reinterpret_f64 - local.set $9 - local.get $9 - i64.const 52 - i64.shr_u - i32.wrap_i64 - i32.const 2047 + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 i32.and - local.set $39 - local.get $39 - i32.const 969 - i32.sub - i32.const 63 - i32.ge_u - if - local.get $39 - i32.const 969 - i32.sub - i32.const -2147483648 - i32.ge_u - if - f64.const -1 - f64.const 1 - local.get $12 - select - br $~lib/util/math/exp_inline|inlined.0 - end - local.get $39 - i32.const 1033 - i32.ge_u - if - local.get $9 - i64.const 63 - i64.shr_u - i64.const 0 - i64.ne - if (result f64) - local.get $12 - local.set $41 - local.get $41 - local.set $42 - i64.const 1152921504606846976 - f64.reinterpret_i64 - local.set $16 - local.get $16 - f64.neg - local.get $16 - local.get $42 - select - local.get $16 - f64.mul - else - local.get $12 - local.set $42 - local.get $42 - local.set $41 - i64.const 8070450532247928832 - f64.reinterpret_i64 - local.set $17 - local.get $17 - f64.neg - local.get $17 - local.get $41 - select - local.get $17 - f64.mul - end - br $~lib/util/math/exp_inline|inlined.0 - end - i32.const 0 - local.set $39 - end - f64.const 184.6649652337873 - local.get $15 - f64.mul - local.set $29 - local.get $29 - f64.const 6755399441055744 - f64.add - local.set $30 - local.get $30 - i64.reinterpret_f64 - local.set $14 - local.get $30 - f64.const 6755399441055744 - f64.sub - local.set $30 - local.get $15 - local.get $30 - f64.const -0.005415212348111709 - f64.mul - f64.add - local.get $30 - f64.const -1.2864023111638346e-14 - f64.mul - f64.add - local.set $28 - local.get $28 - local.get $10 - f64.add - local.set $28 - local.get $14 - i64.const 127 - i64.and - i64.const 1 - i64.shl - i32.wrap_i64 - local.set $40 - local.get $14 - local.get $12 - i64.extend_i32_u - i64.add - i64.const 52 - i64.const 7 - i64.sub - i64.shl - local.set $13 - i32.const 4184 - local.get $40 - i32.const 3 - i32.shl - i32.add - i64.load - f64.reinterpret_i64 - local.set $25 - i32.const 4184 - local.get $40 - i32.const 3 - i32.shl - i32.add - i64.load offset=8 - local.get $13 - i64.add - local.set $11 - local.get $28 - local.get $28 - f64.mul - local.set $27 - local.get $25 - local.get $28 - f64.add - local.get $27 - f64.const 0.49999999999996786 - local.get $28 - f64.const 0.16666666666665886 - f64.mul - f64.add - f64.mul - f64.add - local.get $27 - local.get $27 - f64.mul - f64.const 0.0416666808410674 - local.get $28 - f64.const 0.008333335853059549 - f64.mul - f64.add - f64.mul - f64.add - local.set $24 - local.get $39 - i32.const 0 - i32.eq if - block $~lib/util/math/specialcase|inlined.0 (result f64) - local.get $24 - local.set $18 - local.get $11 - local.set $44 - local.get $14 - local.set $43 - local.get $43 - i64.const 2147483648 - i64.and - i64.const 0 - i64.ne - i32.eqz - if - local.get $44 - i64.const 1009 - i64.const 52 - i64.shl - i64.sub - local.set $44 - local.get $44 - f64.reinterpret_i64 - local.set $17 - f64.const 5486124068793688683255936e279 - local.get $17 - local.get $17 - local.get $18 - f64.mul - f64.add - f64.mul - br $~lib/util/math/specialcase|inlined.0 - end - local.get $44 - i64.const 1022 - i64.const 52 - i64.shl - i64.add - local.set $44 - local.get $44 - f64.reinterpret_i64 - local.set $17 - local.get $17 - local.get $17 - local.get $18 - f64.mul - f64.add - local.set $16 - local.get $16 - f64.abs - f64.const 1 - f64.lt - if - f64.const 1 - local.get $16 - f64.copysign - local.set $23 - local.get $17 - local.get $16 - f64.sub - local.get $17 - local.get $18 - f64.mul - f64.add - local.set $22 - local.get $23 - local.get $16 - f64.add - local.set $21 - local.get $23 - local.get $21 - f64.sub - local.get $16 - f64.add - local.get $22 - f64.add - local.set $22 - local.get $21 - local.get $22 - f64.add - local.get $23 - f64.sub - local.set $16 - local.get $16 - f64.const 0 - f64.eq - if - local.get $44 - i64.const -9223372036854775808 - i64.and - f64.reinterpret_i64 - local.set $16 - end - end - local.get $16 - f64.const 2.2250738585072014e-308 - f64.mul - end - br $~lib/util/math/exp_inline|inlined.0 + local.get $2 + local.get $0 + i32.mul + local.set $2 end - local.get $11 - f64.reinterpret_i64 - local.set $26 - local.get $26 - local.get $26 - local.get $24 - f64.mul - f64.add + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 end end - return + local.get $2 ) (func $std/operator-overloading/Tester.pow (param $0 i32) (param $1 i32) (result i32) (local $2 i32) @@ -1345,20 +566,14 @@ i32.const 0 local.get $0 i32.load - f64.convert_i32_s local.get $1 i32.load - f64.convert_i32_s - call $~lib/math/NativeMath.pow - i32.trunc_f64_s + call $~lib/math/ipow32 local.get $0 i32.load offset=4 - f64.convert_i32_s local.get $1 i32.load offset=4 - f64.convert_i32_s - call $~lib/math/NativeMath.pow - i32.trunc_f64_s + call $~lib/math/ipow32 call $std/operator-overloading/Tester#constructor local.set $2 local.get $0 diff --git a/tests/compiler/std/string.optimized.wat b/tests/compiler/std/string.optimized.wat index 950fca09ad..bd68a690ad 100644 --- a/tests/compiler/std/string.optimized.wat +++ b/tests/compiler/std/string.optimized.wat @@ -3284,8 +3284,6 @@ local.set $2 loop $while-continue|0 local.get $0 - i32.const 0 - i32.gt_s if local.get $1 local.get $2 @@ -3298,7 +3296,7 @@ local.set $2 local.get $0 i32.const 1 - i32.shr_s + i32.shr_u local.set $0 local.get $1 local.get $1 diff --git a/tests/compiler/std/string.untouched.wat b/tests/compiler/std/string.untouched.wat index 5f8ef11c8f..dd051f2a7c 100644 --- a/tests/compiler/std/string.untouched.wat +++ b/tests/compiler/std/string.untouched.wat @@ -5482,80 +5482,137 @@ drop local.get $1 i32.const 0 - i32.lt_s + i32.le_s if - i32.const 0 - return - end - block $break|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $1 - local.set $3 - local.get $3 - i32.const 0 - i32.eq - br_if $case0|0 - local.get $3 - i32.const 1 - i32.eq - br_if $case1|0 - local.get $3 - i32.const 2 - i32.eq - br_if $case2|0 - br $break|0 - end - i32.const 1 - return - end - local.get $0 + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select return end + local.get $1 + i32.const 0 + i32.eq local.get $0 - local.get $0 - i32.mul + i32.const 1 + i32.eq + i32.or return - end - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - local.get $3 - i32.const 5 - i32.le_s - if - block $break|1 - block $case4|1 - block $case3|1 - block $case2|1 - block $case1|1 - block $case0|1 - local.get $3 - local.set $4 - local.get $4 - i32.const 5 - i32.eq - br_if $case0|1 - local.get $4 - i32.const 4 - i32.eq - br_if $case1|1 - local.get $4 - i32.const 3 - i32.eq - br_if $case2|1 - local.get $4 - i32.const 2 - i32.eq - br_if $case3|1 - local.get $4 + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 i32.const 1 - i32.eq - br_if $case4|1 - br $break|1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 end local.get $1 i32.const 1 @@ -5568,7 +5625,7 @@ end local.get $1 i32.const 1 - i32.shr_s + i32.shr_u local.set $1 local.get $0 local.get $0 @@ -5584,68 +5641,15 @@ i32.mul local.set $2 end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if local.get $2 - local.get $0 - i32.mul - local.set $2 + return end - local.get $1 - i32.const 1 - i32.shr_s - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 end end - local.get $2 - return end - loop $while-continue|2 + loop $while-continue|1 local.get $1 - i32.const 0 - i32.gt_s local.set $3 local.get $3 if @@ -5660,13 +5664,13 @@ end local.get $1 i32.const 1 - i32.shr_s + i32.shr_u local.set $1 local.get $0 local.get $0 i32.mul local.set $0 - br $while-continue|2 + br $while-continue|1 end end local.get $2