1ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 2ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Redistribution and use in source and binary forms, with or without 3ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// modification, are permitted provided that the following conditions are 4ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// met: 5ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 6ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// * Redistributions of source code must retain the above copyright 7ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// notice, this list of conditions and the following disclaimer. 8ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// * Redistributions in binary form must reproduce the above 9ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// copyright notice, this list of conditions and the following 10ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// disclaimer in the documentation and/or other materials provided 11ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// with the distribution. 12ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// * Neither the name of Google Inc. nor the names of its 13ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// contributors may be used to endorse or promote products derived 14ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// from this software without specific prior written permission. 15ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 16ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 28ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Flags: --allow-natives-syntax --max-opt-count=1000 29ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 30ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvar imul_func = Math.imul; 31ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgfunction imul_polyfill(a, b) { 32ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org var ah = (a >>> 16) & 0xffff; 33ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org var al = a & 0xffff; 34ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org var bh = (b >>> 16) & 0xffff; 35ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org var bl = b & 0xffff; 36ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0); 37ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 38ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 39ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgfunction TestMathImul(expected, a, b) { 40ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org function imul_meth_closure(a, b) { return Math.imul(a, b); } 41ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org function imul_func_closure(a, b) { return imul_func(a, b); } 42ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 43ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Test reference implementation. 44ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_polyfill(a, b)); 45ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 46ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Test direct method call. 47ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, Math.imul(a, b)); 48ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 49ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Test direct function call. 50ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_func(a, b)); 51ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 52ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Test optimized method call inside closure. 53ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_meth_closure(a, b)); 54ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_meth_closure(a, b)); 55ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %OptimizeFunctionOnNextCall(imul_meth_closure); 56ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_meth_closure(a, b)); 57ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 58ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Test optimized function call inside closure. 59ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_func_closure(a, b)); 60ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_func_closure(a, b)); 61ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %OptimizeFunctionOnNextCall(imul_func_closure); 62ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org assertEquals(expected, imul_func_closure(a, b)); 63ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 64ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Deoptimize closures and forget type feedback. 65ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %DeoptimizeFunction(imul_meth_closure); 66ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %DeoptimizeFunction(imul_func_closure); 67ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %ClearFunctionTypeFeedback(imul_meth_closure); 68ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org %ClearFunctionTypeFeedback(imul_func_closure); 69ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 70ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 71ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(8, 2, 4); 72ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-8, -1, 8); 73ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(4, -2, -2); 74ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-5, 0xffffffff, 5); 75ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-10, 0xfffffffe, 5); 76ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 77ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, false, 7); 78ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, false); 79ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, false, false); 80ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 81ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, true, 7); 82ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, 7, true); 83ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(1, true, true); 84ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 85ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, false, true); 86ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, true, false); 87ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 88ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, undefined, 7); 89ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, undefined); 90ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, undefined, undefined); 91ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 92ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, -0, 7); 93ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, -0); 94ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 95ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 0.1, 7); 96ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, 0.1); 97ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 0.9, 7); 98ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, 0.9); 99ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, 1.1, 7); 100ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, 7, 1.1); 101ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, 1.9, 7); 102ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(7, 7, 1.9); 103ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 104ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, "str", 7); 105ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, "str"); 106ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 107ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, {}, 7); 108ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, {}); 109ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 110ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, [], 7); 111ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, 7, []); 112ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 113ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 2^30 is a smi boundary on arm and ia32. 114ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvar two_30 = 1 << 30; 115ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 116ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_30, two_30, 7); 117ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_30, 7, two_30); 118ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, two_30, two_30); 119ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 120ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(two_30, -two_30, 7); 121ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(two_30, 7, -two_30); 122ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, -two_30, -two_30); 123ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 124ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 2^31 is a smi boundary on x64. 125ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvar two_31 = 2 * two_30; 126ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 127ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_31, two_31, 7); 128ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_31, 7, two_31); 129ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, two_31, two_31); 130ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 131ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_31, -two_31, 7); 132ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_31, 7, -two_31); 133ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, -two_31, -two_31); 134ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 135ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 2^31 - 1 is the largest int32 value. 136ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvar max_val = two_31 - 1; 137ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 138ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(two_31 - 7, max_val, 7); 139ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(two_31 - 7, 7, max_val); 140ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(1, max_val, max_val); 141ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 142ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// 2^16 is a boundary value that overflows when squared. 143ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvar two_16 = 1 << 16; 144ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 145ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(0, two_16, two_16); 146ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_16, two_16 - 1, two_16); 147ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-two_16, two_16, two_16 - 1); 148ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgTestMathImul(-2 * two_16 + 1, two_16 - 1, two_16 - 1); 149