From d3d406356c55127042a7d5f97001403f463d6845 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 20 Dec 2016 12:50:37 +0300 Subject: [PATCH] JS: use optimized emulation of int32 multiplication. Add test for emulated int32 multiplication --- .../js/test/semantics/BoxJsTestGenerated.java | 6 ++++ .../testData/box/number/mulInt32.kt | 32 +++++++++++++++++++ js/js.translator/testData/kotlin_lib_ecma5.js | 14 ++++---- 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 js/js.translator/testData/box/number/mulInt32.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 8eee9443661..cb98efdceb3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -6065,6 +6065,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("mulInt32.kt") + public void testMulInt32() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/mulInt32.kt"); + doTest(fileName); + } + @TestMetadata("numberCompareTo.kt") public void testNumberCompareTo() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/numberCompareTo.kt"); diff --git a/js/js.translator/testData/box/number/mulInt32.kt b/js/js.translator/testData/box/number/mulInt32.kt new file mode 100644 index 00000000000..886372cf93d --- /dev/null +++ b/js/js.translator/testData/box/number/mulInt32.kt @@ -0,0 +1,32 @@ +fun imul32(a: Int, b: Int): Int = js("Kotlin").imulEmulated(a, b) + +fun imul64(a: Int, b: Int): Int = (a.toLong() * b.toLong()).toInt() + +fun generateSeries(data: List): List> { + val result = mutableListOf>() + for (i in data.indices) { + for (j in i..data.lastIndex) { + result += Pair(data[i], data[j]) + } + } + return result +} + +fun test(series: List>): String? { + for ((a, b) in series) { + (testSingle(a, b) ?: testSingle(a, -b) ?: testSingle(-a, b) ?: testSingle(-a, -b))?.let { return it } + } + return null +} + +fun testSingle(a: Int, b: Int): String? { + var actual = imul32(a, b) + var expected = imul64(a, b) + return if (actual != expected) "$a * $b = $expected, got $actual" else null +} + +fun box(): String { + val error = test(generateSeries(listOf(3, 0x1234, 0xFFFF, 0xABCD, 0xABCDEF, 0x43211234, 0x7FFFFFFC, 0x7FFFFFFF))) + if (error != null) return "fail: error" + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index 32f04a6058e..2cf01256ce5 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -313,11 +313,11 @@ Kotlin.kotlinModuleMetadata = function (abiVersion, moduleName, data) { }; - Kotlin.imul = Math.imul || function (a, b) { - var ah = (a >>> 16) & 0xffff; - var al = a & 0xffff; - var bh = (b >>> 16) & 0xffff; - var bl = b & 0xffff; - return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0); - }; + Kotlin.imul = Math.imul || imul; + + Kotlin.imulEmulated = imul; + + function imul(a, b) { + return ((a & 0xffff0000) * (b & 0xffff) + (a & 0xffff) * (b | 0)) | 0; + } })();