Index: test/mjsunit/wasm/asm-wasm-stdlib.js |
diff --git a/test/mjsunit/wasm/asm-wasm-stdlib.js b/test/mjsunit/wasm/asm-wasm-stdlib.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b47d60c87c746a2ebe2876152d8441419560a4d8 |
--- /dev/null |
+++ b/test/mjsunit/wasm/asm-wasm-stdlib.js |
@@ -0,0 +1,356 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Flags: --expose-wasm |
+ |
+(function TestStdlibConstants() { |
+ function Module(stdlib) { |
+ "use asm"; |
+ |
+ var StdlibInfinity = stdlib.Infinity; |
+ var StdlibNaN = stdlib.NaN; |
+ var StdlibMathE = stdlib.Math.E; |
+ var StdlibMathLN10 = stdlib.Math.LN10; |
+ var StdlibMathLN2 = stdlib.Math.LN2; |
+ var StdlibMathLOG2E = stdlib.Math.LOG2E; |
+ var StdlibMathLOG10E = stdlib.Math.LOG10E; |
+ var StdlibMathPI = stdlib.Math.PI; |
+ var StdlibMathSQRT1_2 = stdlib.Math.SQRT1_2; |
+ var StdlibMathSQRT2 = stdlib.Math.SQRT2; |
+ |
+ function caller() { |
+ if (StdlibInfinity != 1.0 / 0.0) return 0; |
+ if (StdlibMathE != 2.718281828459045) return 0; |
+ if (StdlibMathLN10 != 2.302585092994046) return 0; |
+ if (StdlibMathLN2 != 0.6931471805599453) return 0; |
+ if (StdlibMathLOG2E != 1.4426950408889634) return 0; |
+ if (StdlibMathLOG10E != 0.4342944819032518) return 0; |
+ if (StdlibMathPI != 3.141592653589793) return 0; |
+ if (StdlibMathSQRT1_2 != 0.7071067811865476) return 0; |
+ if (StdlibMathSQRT2 != 1.4142135623730951) return 0; |
+ return 1; |
+ } |
+ |
+ function nanCheck() { |
+ return +StdlibNaN; |
+ } |
+ |
+ return {caller:caller, nanCheck:nanCheck}; |
+ } |
+ |
+ var m =Wasm.instantiateModuleFromAsm(Module.toString()); |
+ assertEquals(1, m.caller()); |
+ assertTrue(isNaN(m.nanCheck())); |
+})(); |
+ |
+ |
+(function TestStdlibFunctionsInside() { |
+ function Module(stdlib) { |
+ "use asm"; |
+ |
+ var StdlibMathCeil = stdlib.Math.ceil; |
+ var StdlibMathFloor = stdlib.Math.floor; |
+ var StdlibMathSqrt = stdlib.Math.sqrt; |
+ var StdlibMathAbs = stdlib.Math.abs; |
+ var StdlibMathMin = stdlib.Math.min; |
+ var StdlibMathMax = stdlib.Math.max; |
+ |
+ var StdlibMathAcos = stdlib.Math.acos; |
+ var StdlibMathAsin = stdlib.Math.asin; |
+ var StdlibMathAtan = stdlib.Math.atan; |
+ var StdlibMathCos = stdlib.Math.cos; |
+ var StdlibMathSin = stdlib.Math.sin; |
+ var StdlibMathTan = stdlib.Math.tan; |
+ var StdlibMathExp = stdlib.Math.exp; |
+ var StdlibMathLog = stdlib.Math.log; |
+ |
+ var StdlibMathAtan2 = stdlib.Math.atan2; |
+ var StdlibMathPow = stdlib.Math.pow; |
+ var StdlibMathImul = stdlib.Math.imul; |
+ |
+ var fround = stdlib.Math.fround; |
+ |
+ function deltaEqual(x, y) { |
+ x = +x; |
+ y = +y; |
+ var t = 0.0; |
+ t = x - y; |
+ if (t < 0.0) { |
+ t = t * -1.0; |
+ } |
+ return (t < 1.0e-10) | 0; |
+ } |
+ |
+ function caller() { |
+ if (!deltaEqual(StdlibMathSqrt(123.0), 11.090536506409418)) return 0; |
+ if (StdlibMathSqrt(fround(256.0)) != fround(16.0)) return 0; |
+ if (StdlibMathCeil(123.7) != 124.0) return 0; |
+ if (StdlibMathCeil(fround(123.7)) != fround(124.0)) return 0; |
+ if (StdlibMathFloor(123.7) != 123.0) return 0; |
+ if (StdlibMathFloor(fround(123.7)) != fround(123.0)) return 0; |
+ if (StdlibMathAbs(-123.0) != 123.0) return 0; |
+ if (StdlibMathAbs(fround(-123.0)) != fround(123.0)) return 0; |
+ if (StdlibMathMin(123.4, 1236.4) != 123.4) return 0; |
+ if (StdlibMathMin(fround(123.4), |
+ fround(1236.4)) != fround(123.4)) return 0; |
+ if (StdlibMathMax(123.4, 1236.4) != 1236.4) return 0; |
+ if (StdlibMathMax(fround(123.4), fround(1236.4)) |
+ != fround(1236.4)) return 0; |
+ |
+ if (!deltaEqual(StdlibMathAcos(0.1), 1.4706289056333368)) return 0; |
+ if (!deltaEqual(StdlibMathAsin(0.2), 0.2013579207903308)) return 0; |
+ if (!deltaEqual(StdlibMathAtan(0.2), 0.19739555984988078)) return 0; |
+ if (!deltaEqual(StdlibMathCos(0.2), 0.9800665778412416)) return 0; |
+ if (!deltaEqual(StdlibMathSin(0.2), 0.19866933079506122)) return 0; |
+ if (!deltaEqual(StdlibMathTan(0.2), 0.20271003550867250)) return 0; |
+ if (!deltaEqual(StdlibMathExp(0.2), 1.2214027581601699)) return 0; |
+ if (!deltaEqual(StdlibMathLog(0.2), -1.6094379124341003)) return 0; |
+ |
+ if (StdlibMathImul(6, 7) != 42) return 0; |
+ if (!deltaEqual(StdlibMathAtan2(6.0, 7.0), 0.7086262721276703)) return 0; |
+ if (StdlibMathPow(6.0, 7.0) != 279936.0) return 0; |
+ |
+ return 1; |
+ } |
+ |
+ return {caller:caller}; |
+ } |
+ |
+ var m = Wasm.instantiateModuleFromAsm(Module.toString()); |
+ assertEquals(1, m.caller()); |
+})(); |
+ |
+ |
+(function TestStdlibFunctionOutside() { |
+ function looseEqual(x, y, delta) { |
+ if (delta === undefined) { |
+ delta = 1.0e-13; |
+ } |
+ if (isNaN(x) && isNaN(y)) { |
+ return true; |
+ } |
+ if (!isFinite(x) && !isFinite(y)) { |
+ return true; |
+ } |
+ x = +x; |
+ y = +y; |
+ var t = 0.0; |
+ t = x - y; |
+ if (t < 0.0) { |
+ t = t * -1.0; |
+ } |
+ return (t < delta) | 0; |
+ } |
+ |
+ function plainEqual(x, y) { |
+ if (isNaN(x) && isNaN(y)) { |
+ return true; |
+ } |
+ return x === y; |
+ } |
+ |
+ function Module(stdlib) { |
+ "use asm"; |
+ var ceil = stdlib.Math.ceil; |
+ var floor = stdlib.Math.floor; |
+ var sqrt = stdlib.Math.sqrt; |
+ var abs = stdlib.Math.abs; |
+ var fround = stdlib.Math.fround; |
+ |
+ var acos = stdlib.Math.acos; |
+ var asin = stdlib.Math.asin; |
+ var atan = stdlib.Math.atan; |
+ var cos = stdlib.Math.cos; |
+ var sin = stdlib.Math.sin; |
+ var tan = stdlib.Math.tan; |
+ var exp = stdlib.Math.exp; |
+ var log = stdlib.Math.log; |
+ |
+ var atan2 = stdlib.Math.atan2; |
+ var pow = stdlib.Math.pow; |
+ var imul = stdlib.Math.imul; |
+ var min = stdlib.Math.min; |
+ var max = stdlib.Math.max; |
+ |
+ function ceil_f64(x) { x = +x; return +ceil(x); } |
+ function ceil_f32(x) { x = fround(x); return fround(ceil(x)); } |
+ |
+ function floor_f64(x) { x = +x; return +floor(x); } |
+ function floor_f32(x) { x = fround(x); return fround(floor(x)); } |
+ |
+ function sqrt_f64(x) { x = +x; return +sqrt(x); } |
+ function sqrt_f32(x) { x = fround(x); return fround(sqrt(x)); } |
+ |
+ function abs_f64(x) { x = +x; return +abs(x); } |
+ function abs_f32(x) { x = fround(x); return fround(abs(x)); } |
+ function abs_i32(x) { x = x | 0; return abs(x|0) | 0; } |
+ |
+ function acos_f64(x) { x = +x; return +acos(x); } |
+ function asin_f64(x) { x = +x; return +asin(x); } |
+ function atan_f64(x) { x = +x; return +atan(x); } |
+ function cos_f64(x) { x = +x; return +cos(x); } |
+ function sin_f64(x) { x = +x; return +sin(x); } |
+ function tan_f64(x) { x = +x; return +tan(x); } |
+ function exp_f64(x) { x = +x; return +exp(x); } |
+ function log_f64(x) { x = +x; return +log(x); } |
+ |
+ function atan2_f64(x, y) { x = +x; y = +y; return +atan2(x, y); } |
+ function pow_f64(x, y) { x = +x; y = +y; return +atan2(x, y); } |
+ |
+ function imul_i32(x, y) { x = x | 0; y = y | 0; return imul(x, y) | 0; } |
+ function imul_u32(x, y) { |
+ x = x | 0; y = y | 0; return imul(x>>>0, y>>>0) | 0; } |
+ |
+ function fround_i32(x) { x = x | 0; return fround(x|0) | 0; } |
+ function fround_u32(x) { x = x | 0; return fround(x>>>0) | 0; } |
+ function fround_f32(x) { x = fround(x); return fround(x); } |
+ // TODO(bradnelson): Fix and enable. |
+ //function fround_f64(x) { x = +x; return fround(x); } |
+ |
+ function min_i32(x, y) { x = x | 0; y = y | 0; return min(x|0, y|0) | 0; } |
+ // TODO(bradnelson): Fix and enable. |
+ //function min_u32(x, y) { |
+ // x = x | 0; y = y | 0; return min(x>>>0, y>>>0) | 0; } |
+ function min_f32(x, y) { |
+ x = fround(x); y = fround(y); return fround(min(x, y)); } |
+ function min_f64(x, y) { x = +x; y = +y; return +min(x, y); } |
+ |
+ function max_i32(x, y) { x = x | 0; y = y | 0; return max(x|0, y|0) | 0; } |
+ // TODO(bradnelson): Fix and enable. |
+ //function max_u32(x, y) { |
+ // x = x | 0; y = y | 0; return max(x>>>0, y>>>0) | 0; } |
+ function max_f32(x, y) { |
+ x = fround(x); y = fround(y); return fround(max(x, y)); } |
+ function max_f64(x, y) { x = +x; y = +y; return +max(x, y); } |
+ |
+ return { |
+ ceil_f64: ceil_f64, |
+ ceil_f32: ceil_f32, |
+ floor_f64: floor_f64, |
+ floor_f32: floor_f32, |
+ sqrt_f64: sqrt_f64, |
+ sqrt_f32: sqrt_f32, |
+ abs_f64: abs_f64, |
+ abs_f32: abs_f32, |
+ abs_i32: abs_i32, |
+ acos_f64: acos_f64, |
+ asin_f64: asin_f64, |
+ atan_f64: atan_f64, |
+ cos_f64: cos_f64, |
+ sin_f64: sin_f64, |
+ tan_f64: tan_f64, |
+ exp_f64: exp_f64, |
+ log_f64: log_f64, |
+ imul_i32: imul_i32, |
+ imul_u32: imul_u32, |
+ fround_i32: fround_i32, |
+ fround_u32: fround_u32, |
+ fround_f32: fround_f32, |
+ // TODO(bradnelson): Fix and enable. |
+ // fround_f64: fround_f64, |
+ min_i32: min_i32, |
+ // TODO(bradnelson): Fix and enable. |
+ // min_u32: min_u32, |
+ min_f32: min_f32, |
+ min_f64: min_f64, |
+ max_i32: max_i32, |
+ // TODO(bradnelson): Fix and enable. |
+ // max_u32: max_u32, |
+ max_f32: max_f32, |
+ max_f64: max_f64, |
+ }; |
+ } |
+ var m = Wasm.instantiateModuleFromAsm(Module.toString()); |
+ var values = { |
+ 'i32': [ |
+ 0, 1, -1, 123, 456, -123, -456, |
+ 0x40000000, 0x7FFFFFFF, -0x80000000, |
+ ], |
+ 'u32': [ |
+ 0, 1, 123, 456, |
+ 0x40000000, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000000, |
+ ], |
+ 'f32': [ |
+ 0, -0, 1, -1, 0.9, -0.9, 1.414, 0x7F, -0x80, -0x8000, -0x80000000, |
titzer
2016/03/16 09:44:05
Not sure if it matters here but 0.9 is not exactly
bradnelson
2016/03/19 03:48:48
Got these "edge case" values from the simd tests.
|
+ 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
+ ], |
+ 'f64': [ |
+ 0, -0, 1, -1, 0.9, -0.9, 1.414, 0x7F, -0x80, -0x8000, -0x80000000, |
+ 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
+ ], |
+ }; |
+ var converts = { |
+ 'i32': function(x) { return x | 0; }, |
titzer
2016/03/16 09:44:05
You can drop the single quotes from these property
bradnelson
2016/03/19 03:48:48
Done.
|
+ 'u32': function(x) { return x >>> 0; }, |
+ 'f32': function(x) { return Math.fround(x); }, |
+ 'f64': function(x) { return x; }, |
+ }; |
+ var two_args = {'atan2': true, 'pow': true, 'imul': true, |
+ 'min': true, 'max': true}; |
+ var funcs = { |
+ 'ceil': ['f32', 'f64'], |
+ 'floor': ['f32', 'f64'], |
+ 'sqrt': ['f32', 'f64'], |
+ 'abs': ['i32', 'f32', 'f64'], |
+ 'acos': ['f64'], |
+ 'asin': ['f64'], |
+ 'atan': ['f64'], |
+ 'cos': ['f64'], |
+ 'sin': ['f64'], |
+ 'tan': ['f64'], |
+ 'exp': ['f64'], |
+ 'log': ['f64'], |
+ 'imul': ['i32', 'u32'], |
+ // TODO(bradnelson): Fix and enable. |
+ // 'fround': ['i32', 'u32', 'f32', 'f64'], |
+ 'fround': ['i32', 'u32', 'f32'], |
+ // TODO(bradnelson): Fix and enable. |
+ // 'min': ['i32', 'u32', 'f32', 'f64'], |
+ 'min': ['i32', 'f32', 'f64'], |
+ // TODO(bradnelson): Fix and enable. |
+ // 'max': ['i32', 'u32', 'f32', 'f64'], |
+ 'max': ['i32', 'f32', 'f64'], |
+ }; |
+ var equals = { |
+ 'f64': looseEqual, |
+ 'f32': plainEqual, |
+ 'i32': plainEqual, |
+ }; |
+ var per_func_equals = { |
+ // exp not required to have a particular precision. |
+ 'exp_f64': function(x, y) { return looseEqual(x, y, 1e55); }, |
+ }; |
+ for (var func in funcs) { |
+ var types = funcs[func]; |
+ for (var i = 0; i < types.length; i++) { |
+ var type = types[i]; |
+ var interesting = values[type]; |
+ for (var j = 0; j < interesting.length; j++) { |
+ for (var k = 0; k < interesting.length; k++) { |
+ var val0 = interesting[j]; |
+ var val1 = interesting[k]; |
+ var input0 = converts[type](val0); |
+ var input1 = converts[type](val1); |
+ var name = func + '_' + type; |
+ if (two_args[func]) { |
+ var expected = converts[type](Math[func](input0, input1)); |
+ var actual = m[name](input0, input1); |
+ } else { |
+ var expected = converts[type](Math[func](input0, input1)); |
+ var actual = m[name](input0, input1); |
+ } |
+ var compare = per_func_equals[name]; |
+ if (compare === undefined) { |
+ compare = equals[type]; |
+ } |
+ if (!compare(expected, actual)) { |
+ print(expected + ' !== ' + actual + ' for ' + name + |
+ ' with input ' + input0 + ' ' + input1); |
+ assertTrue(false); |
+ } |
+ } |
+ } |
+ } |
+ } |
+})(); |