michael@0: setJitCompilerOption("ion.usecount.trigger", 50); michael@0: michael@0: var f32 = new Float32Array(10); michael@0: michael@0: function test(setup, f) { michael@0: if (f === undefined) { michael@0: f = setup; michael@0: setup = function(){}; michael@0: } michael@0: setup(); michael@0: for(var n = 200; n; --n) { michael@0: f(); michael@0: } michael@0: } michael@0: michael@0: // Basic arithmetic michael@0: function setupBasicArith() { michael@0: f32[0] = -Infinity; michael@0: f32[1] = -1; michael@0: f32[2] = -0; michael@0: f32[3] = 0; michael@0: f32[4] = 1.337; michael@0: f32[5] = 42; michael@0: f32[6] = Infinity; michael@0: f32[7] = NaN; michael@0: } michael@0: function basicArith() { michael@0: for (var i = 0; i < 7; ++i) { michael@0: var opf = Math.fround(f32[i] + f32[i+1]); michael@0: var opd = (1 / (1 / f32[i])) + f32[i+1]; michael@0: assertFloat32(opf, true); michael@0: assertFloat32(opd, false); michael@0: assertEq(opf, Math.fround(opd)); michael@0: michael@0: opf = Math.fround(f32[i] - f32[i+1]); michael@0: opd = (1 / (1 / f32[i])) - f32[i+1]; michael@0: assertFloat32(opf, true); michael@0: assertFloat32(opd, false); michael@0: assertEq(opf, Math.fround(opd)); michael@0: michael@0: opf = Math.fround(f32[i] * f32[i+1]); michael@0: opd = (1 / (1 / f32[i])) * f32[i+1]; michael@0: assertFloat32(opf, true); michael@0: assertFloat32(opd, false); michael@0: assertEq(opf, Math.fround(opd)); michael@0: michael@0: opf = Math.fround(f32[i] / f32[i+1]); michael@0: opd = (1 / (1 / f32[i])) / f32[i+1]; michael@0: assertFloat32(opf, true); michael@0: assertFloat32(opd, false); michael@0: assertEq(opf, Math.fround(opd)); michael@0: } michael@0: } michael@0: test(setupBasicArith, basicArith); michael@0: michael@0: // MAbs michael@0: function setupAbs() { michael@0: f32[0] = -0; michael@0: f32[1] = 0; michael@0: f32[2] = -3.14159; michael@0: f32[3] = 3.14159; michael@0: f32[4] = -Infinity; michael@0: f32[5] = Infinity; michael@0: f32[6] = NaN; michael@0: } michael@0: function abs() { michael@0: for(var i = 0; i < 7; ++i) { michael@0: assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) ); michael@0: } michael@0: } michael@0: test(setupAbs, abs); michael@0: michael@0: // MSqrt michael@0: function setupSqrt() { michael@0: f32[0] = 0; michael@0: f32[1] = 1; michael@0: f32[2] = 4; michael@0: f32[3] = -1; michael@0: f32[4] = Infinity; michael@0: f32[5] = NaN; michael@0: f32[6] = 13.37; michael@0: } michael@0: function sqrt() { michael@0: for(var i = 0; i < 7; ++i) { michael@0: var sqrtf = Math.fround(Math.sqrt(f32[i])); michael@0: var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops michael@0: assertEq( sqrtf, Math.fround(sqrtd) ); michael@0: } michael@0: } michael@0: test(setupSqrt, sqrt); michael@0: michael@0: // MTruncateToInt32 michael@0: // The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul michael@0: function setupTruncateToInt32() { michael@0: f32[0] = -1; michael@0: f32[1] = 4; michael@0: f32[2] = 5.13; michael@0: } michael@0: function truncateToInt32() { michael@0: assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) ); michael@0: assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) ); michael@0: } michael@0: test(setupTruncateToInt32, truncateToInt32); michael@0: michael@0: // MCompare michael@0: function comp() { michael@0: for(var i = 0; i < 9; ++i) { michael@0: assertEq( f32[i] < f32[i+1], true ); michael@0: } michael@0: } michael@0: function setupComp() { michael@0: f32[0] = -Infinity; michael@0: f32[1] = -1; michael@0: f32[2] = -0.01; michael@0: f32[3] = 0; michael@0: f32[4] = 0.01; michael@0: f32[5] = 1; michael@0: f32[6] = 10; michael@0: f32[7] = 13.37; michael@0: f32[8] = 42; michael@0: f32[9] = Infinity; michael@0: } michael@0: test(setupComp, comp); michael@0: michael@0: // MNot michael@0: function setupNot() { michael@0: f32[0] = -0; michael@0: f32[1] = 0; michael@0: f32[2] = 1; michael@0: f32[3] = NaN; michael@0: f32[4] = Infinity; michael@0: f32[5] = 42; michael@0: f32[5] = -23; michael@0: } michael@0: function not() { michael@0: assertEq( !f32[0], true ); michael@0: assertEq( !f32[1], true ); michael@0: assertEq( !f32[2], false ); michael@0: assertEq( !f32[3], true ); michael@0: assertEq( !f32[4], false ); michael@0: assertEq( !f32[5], false ); michael@0: assertEq( !f32[6], false ); michael@0: } michael@0: test(setupNot, not); michael@0: michael@0: // MToInt32 michael@0: var str = "can haz cheezburger? okthxbye;"; michael@0: function setupToInt32() { michael@0: f32[0] = 0; michael@0: f32[1] = 1; michael@0: f32[2] = 2; michael@0: f32[3] = 4; michael@0: f32[4] = 5; michael@0: } michael@0: function testToInt32() { michael@0: assertEq(str[f32[0]], 'c'); michael@0: assertEq(str[f32[1]], 'a'); michael@0: assertEq(str[f32[2]], 'n'); michael@0: assertEq(str[f32[3]], 'h'); michael@0: assertEq(str[f32[4]], 'a'); michael@0: } michael@0: test(setupToInt32, testToInt32); michael@0: michael@0: function setupBailoutToInt32() { michael@0: f32[0] = .5; michael@0: } michael@0: function testBailoutToInt32() { michael@0: assertEq(typeof str[f32[0]], 'undefined'); michael@0: } michael@0: test(setupBailoutToInt32, testBailoutToInt32); michael@0: michael@0: // MMath (no trigo - see also testFloat32-trigo.js michael@0: function assertNear(a, b) { michael@0: var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b; michael@0: if (!r) { michael@0: print('Precision error: '); michael@0: print(new Error().stack); michael@0: print('Got', a, ', expected near', b); michael@0: assertEq(false, true); michael@0: } michael@0: } michael@0: michael@0: function setupOtherMath() { michael@0: setupComp(); michael@0: f32[8] = 4.2; michael@0: } michael@0: function otherMath() { michael@0: for (var i = 0; i < 9; ++i) { michael@0: assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i])); michael@0: assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i])); michael@0: } michael@0: }; michael@0: test(setupOtherMath, otherMath); michael@0: michael@0: function setupFloor() { michael@0: f32[0] = -5.5; michael@0: f32[1] = -0.5; michael@0: f32[2] = 0; michael@0: f32[3] = 1.5; michael@0: } michael@0: function setupFloorDouble() { michael@0: f32[4] = NaN; michael@0: f32[5] = -0; michael@0: f32[6] = Infinity; michael@0: f32[7] = -Infinity; michael@0: f32[8] = Math.pow(2,31); // too big to fit into a int michael@0: } michael@0: function testFloor() { michael@0: for (var i = 0; i < 4; ++i) { michael@0: var f = Math.floor(f32[i]); michael@0: assertFloat32(f, false); // f is an int32 michael@0: michael@0: var g = Math.floor(-0 + f32[i]); michael@0: assertFloat32(g, false); michael@0: michael@0: assertEq(f, g); michael@0: } michael@0: } michael@0: function testFloorDouble() { michael@0: for (var i = 4; i < 9; ++i) { michael@0: var f = Math.fround(Math.floor(f32[i])); michael@0: assertFloat32(f, true); michael@0: michael@0: var g = Math.floor(-0 + f32[i]); michael@0: assertFloat32(g, false); michael@0: michael@0: assertEq(f, g); michael@0: } michael@0: } michael@0: test(setupFloor, testFloor); michael@0: test(setupFloorDouble, testFloorDouble); michael@0: michael@0: function setupRound() { michael@0: f32[0] = -5.5; michael@0: f32[1] = -0.6; michael@0: f32[2] = 1.5; michael@0: f32[3] = 1; michael@0: } michael@0: function setupRoundDouble() { michael@0: f32[4] = NaN; michael@0: f32[5] = -0.49; // rounded to -0 michael@0: f32[6] = Infinity; michael@0: f32[7] = -Infinity; michael@0: f32[8] = Math.pow(2,31); // too big to fit into a int michael@0: f32[9] = -0; michael@0: } michael@0: function testRound() { michael@0: for (var i = 0; i < 4; ++i) { michael@0: var r32 = Math.round(f32[i]); michael@0: assertFloat32(r32, false); // r32 is an int32 michael@0: michael@0: var r64 = Math.round(-0 + f32[i]); michael@0: assertFloat32(r64, false); michael@0: michael@0: assertEq(r32, r64); michael@0: } michael@0: } michael@0: function testRoundDouble() { michael@0: for (var i = 4; i < 10; ++i) { michael@0: var r32 = Math.fround(Math.round(f32[i])); michael@0: assertFloat32(r32, true); michael@0: michael@0: var r64 = Math.round(-0 + f32[i]); michael@0: assertFloat32(r64, false); michael@0: michael@0: assertEq(r32, r64); michael@0: } michael@0: } michael@0: test(setupRound, testRound); michael@0: test(setupRoundDouble, testRoundDouble); michael@0: michael@0: function setupCeil() { michael@0: f32[0] = -5.5; michael@0: f32[1] = -1.5; michael@0: f32[2] = 0; michael@0: f32[3] = 1.5; michael@0: } michael@0: function setupCeilDouble() { michael@0: f32[4] = NaN; michael@0: f32[5] = -0; michael@0: f32[6] = Infinity; michael@0: f32[7] = -Infinity; michael@0: f32[8] = Math.pow(2,31); // too big to fit into a int michael@0: } michael@0: function testCeil() { michael@0: for(var i = 0; i < 2; ++i) { michael@0: var f = Math.ceil(f32[i]); michael@0: assertFloat32(f, false); michael@0: michael@0: var g = Math.ceil(-0 + f32[i]); michael@0: assertFloat32(g, false); michael@0: michael@0: assertEq(f, g); michael@0: } michael@0: } michael@0: function testCeilDouble() { michael@0: for(var i = 4; i < 9; ++i) { michael@0: var f = Math.fround(Math.ceil(f32[i])); michael@0: assertFloat32(f, true); michael@0: michael@0: var g = Math.ceil(-0 + f32[i]); michael@0: assertFloat32(g, false); michael@0: michael@0: assertEq(f, g); michael@0: } michael@0: } michael@0: test(setupCeil, testCeil); michael@0: test(setupCeilDouble, testCeilDouble);