1f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 2f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Use of this source code is governed by a BSD-style license that can be 3f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// found in the LICENSE file. 4f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// Flags: --allow-natives-syntax 6dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 7f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Monkey-patch Float32Array. 8f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgFloat32Array = function(x) { this[0] = 0; }; 9f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 10f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgassertTrue(isNaN(Math.fround(NaN))); 11f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgassertTrue(isNaN(Math.fround(function() {}))); 12f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgassertTrue(isNaN(Math.fround({ toString: function() { return NaN; } }))); 13f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgassertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } }))); 14dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertTrue(isNaN(Math.fround(NaN))); 15dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertTrue(isNaN(Math.fround(function() {}))); 16dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertTrue(isNaN(Math.fround({ toString: function() { return NaN; } }))); 17dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } }))); 18f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 19dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgfunction unopt(x) { return Math.fround(x); } 20dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgfunction opt(y) { return Math.fround(y); } 21dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 22dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgopt(0.1); 23dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgopt(0.1); 24dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgunopt(0.1); 25dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org%NeverOptimizeFunction(unopt); 26dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org%OptimizeFunctionOnNextCall(opt); 27dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 28dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgfunction test(f) { 29dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("Infinity", String(1/f(0))); 30dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("-Infinity", String(1/f(-0))); 31dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("Infinity", String(f(Infinity))); 32dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("-Infinity", String(f(-Infinity))); 33dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("Infinity", String(f(1E200))); 34dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("-Infinity", String(f(-1E200))); 35dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("Infinity", String(1/f(1E-300))); 36dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals("-Infinity", String(1/f(-1E-300))); 37dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org} 38dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 39dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgtest(opt); 40dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgtest(unopt); 41f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 42f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgmantissa_23_shift = Math.pow(2, -23); 43f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgmantissa_29_shift = Math.pow(2, -23-29); 44f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 45f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Javascript implementation of IEEE 754 to test double to single conversion. 46f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgfunction ieee754float(sign_bit, 47f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org exponent_bits, 48f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org mantissa_23_bits, 49f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org mantissa_29_bits) { 50f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this.sign_bit = sign_bit & 1; 51f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this.exponent_bits = exponent_bits & ((1 << 11) - 1); 52f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this.mantissa_23_bits = mantissa_23_bits & ((1 << 23) - 1); 53f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this.mantissa_29_bits = mantissa_29_bits & ((1 << 29) - 1); 54f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 55f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 56f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgieee754float.prototype.returnSpecial = function() { 57f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (mantissa_23_bits == 0 && mantissa_29_bits == 0) return sign * Infinity; 58f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return NaN; 59f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 60f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 61f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgieee754float.prototype.toDouble = function() { 62f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var sign = this.sign_bit ? -1 : 1; 63f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var exponent = this.exponent_bits - 1023; 64f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (exponent == -1023) returnSpecial(); 65f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var mantissa = 1 + this.mantissa_23_bits * mantissa_23_shift + 66f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this.mantissa_29_bits * mantissa_29_shift; 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return sign * Math.pow(2, exponent) * mantissa; 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgieee754float.prototype.toSingle = function() { 71f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var sign = this.sign_bit ? -1 : 1; 72f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var exponent = this.exponent_bits - 1023; 73f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (exponent == -1023) returnSpecial(); 74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (exponent > 127) return sign * Infinity; 75f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (exponent < -126) return this.toSingleSubnormal(sign, exponent); 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var round = this.mantissa_29_bits >> 28; 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var mantissa = 1 + (this.mantissa_23_bits + round) * mantissa_23_shift; 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return sign * Math.pow(2, exponent) * mantissa; 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 80f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 81f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgieee754float.prototype.toSingleSubnormal = function(sign, exponent) { 82f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var shift = -126 - exponent; 83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (shift > 24) return sign * 0; 84f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var round_mask = 1 << (shift - 1); 85f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var mantissa_23_bits = this.mantissa_23_bits + (1 << 23); 86f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var round = ((mantissa_23_bits & round_mask) != 0) | 0; 87f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (round) { // Round to even if tied. 88f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var tied_mask = round_mask - 1; 89f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var result_last_bit_mask = 1 << shift; 90f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var tied = this.mantissa_29_bits == 0 && 91f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (mantissa_23_bits & tied_mask ) == 0; 92f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var result_already_even = (mantissa_23_bits & result_last_bit_mask) == 0; 93f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (tied && result_already_even) round = 0; 94f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 95f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org mantissa_23_bits >>= shift; 96f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var mantissa = (mantissa_23_bits + round) * mantissa_23_shift; 97f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return sign * Math.pow(2, -126) * mantissa; 98f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 99f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvar pi = new ieee754float(0, 0x400, 0x490fda, 0x14442d18); 102dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertEquals(pi.toSingle(), opt(pi.toDouble())); 103dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgassertEquals(pi.toSingle(), unopt(pi.toDouble())); 104dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgfunction fuzz_mantissa(sign, exp, m1inc, m2inc) { 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (var m1 = 0; m1 < (1 << 23); m1 += m1inc) { 108f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (var m2 = 0; m2 < (1 << 29); m2 += m2inc) { 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org var float = new ieee754float(sign, exp, m1, m2); 110dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals(float.toSingle(), unopt(float.toDouble())); 111dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org assertEquals(float.toSingle(), opt(float.toDouble())); 112f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 113f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 114f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 115f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 116f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgfor (var sign = 0; sign < 2; sign++) { 117f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (var exp = 1024 - 170; exp < 1024 + 170; exp++) { 118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org fuzz_mantissa(sign, exp, 1337 * exp - sign, 127913 * exp - sign); 119f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 120f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 121