Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 1 | // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // Flags: --allow-natives-syntax |
| 6 | |
| 7 | function mul(a, b) { |
| 8 | const l = a & 0x3ffffff; |
| 9 | const h = b & 0x3ffffff; |
| 10 | |
| 11 | return (l * h) >>> 0; |
| 12 | } |
| 13 | |
| 14 | function mulAndDiv(a, b) { |
| 15 | const l = a & 0x3ffffff; |
| 16 | const h = b & 0x3ffffff; |
| 17 | const m = l * h; |
| 18 | |
| 19 | const rl = m & 0x3ffffff; |
| 20 | const rh = (m / 0x4000000) >>> 0; |
| 21 | |
| 22 | return rl | rh; |
| 23 | } |
| 24 | |
| 25 | function overflowMul(a, b) { |
| 26 | const l = a | 0; |
| 27 | const h = b | 0; |
| 28 | |
| 29 | return (l * h) >>> 0; |
| 30 | } |
| 31 | |
| 32 | function overflowDiv(a, b) { |
| 33 | const l = a & 0x3ffffff; |
| 34 | const h = b & 0x3ffffff; |
| 35 | const m = l * h; |
| 36 | |
| 37 | return (m / 0x10) >>> 0; |
| 38 | } |
| 39 | |
| 40 | function nonPowerOfTwoDiv(a, b) { |
| 41 | const l = a & 0x3ffffff; |
| 42 | const h = b & 0x3ffffff; |
| 43 | const m = l * h; |
| 44 | |
| 45 | return (m / 0x4000001) >>> 0; |
| 46 | } |
| 47 | |
| 48 | function test(fn, a, b, sets) { |
| 49 | const expected = fn(a, b); |
| 50 | fn(1, 2); |
| 51 | fn(0, 0); |
| 52 | %OptimizeFunctionOnNextCall(fn); |
| 53 | const actual = fn(a, b); |
| 54 | |
| 55 | assertEquals(expected, actual); |
| 56 | |
| 57 | sets.forEach(function(set, i) { |
| 58 | assertEquals(set.expected, fn(set.a, set.b), fn.name + ', set #' + i); |
| 59 | }); |
| 60 | } |
| 61 | |
| 62 | test(mul, 0x3ffffff, 0x3ffffff, [ |
| 63 | { a: 0, b: 0, expected: 0 }, |
| 64 | { a: 0xdead, b: 0xbeef, expected: 0xa6144983 }, |
| 65 | { a: 0x1aa1dea, b: 0x2badead, expected: 0x35eb2322 } |
| 66 | ]); |
| 67 | test(mulAndDiv, 0x3ffffff, 0x3ffffff, [ |
| 68 | { a: 0, b: 0, expected: 0 }, |
| 69 | { a: 0xdead, b: 0xbeef, expected: 0x21449ab }, |
| 70 | { a: 0x1aa1dea, b: 0x2badead, expected: 0x1ebf32f } |
| 71 | ]); |
| 72 | test(overflowMul, 0x4ffffff, 0x4ffffff, [ |
| 73 | { a: 0, b: 0, expected: 0 }, |
| 74 | { a: 0xdead, b: 0xbeef, expected: 0xa6144983 }, |
| 75 | { a: 0x1aa1dea, b: 0x2badead, expected: 0x35eb2322 } |
| 76 | ]); |
| 77 | test(overflowDiv, 0x3ffffff, 0x3ffffff, [ |
| 78 | { a: 0, b: 0, expected: 0 }, |
| 79 | { a: 0xdead, b: 0xbeef, expected: 0xa614498 }, |
| 80 | { a: 0x1aa1dea, b: 0x2badead, expected: 0x835eb232 } |
| 81 | ]); |
| 82 | test(nonPowerOfTwoDiv, 0x3ffffff, 0x3ffffff, [ |
| 83 | { a: 0, b: 0, expected: 0 }, |
| 84 | { a: 0xdead, b: 0xbeef, expected: 0x29 }, |
| 85 | { a: 0x1aa1dea, b: 0x2badead, expected: 0x122d20d } |
| 86 | ]); |