blob: 3b1a333c7fc0ff841c899e9d972ed1125b3e1716 [file] [log] [blame]
// Copyright 2018 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 --wasm-math-intrinsics
load('test/mjsunit/wasm/wasm-module-builder.js');
function verbose(args) {
// print(...args);
}
//=============================================
// Global count of failures
//=============================================
let numFailures = 0;
function reportFailure(name, vals, m, w) {
print(' error: ' + name + '(' + vals + ') == ' + w + ', expected ' + m);
numFailures++;
}
let global_imports = {Math: Math};
let inputs = [
1 / 0,
-1 / 0,
0 / 0,
-2.70497e+38,
-1.4698e+37,
-1.22813e+35,
-1.34584e+34,
-1.0079e+32,
-6.49364e+26,
-3.06077e+25,
-1.46821e+25,
-1.17658e+23,
-1.9617e+22,
-2.7357e+20,
-9223372036854775808.0, // INT64_MIN
-1.48708e+13,
-1.89633e+12,
-4.66622e+11,
-2.22581e+11,
-1.45381e+10,
-2147483904.0, // First float32 after INT32_MIN
-2147483648.0, // INT32_MIN
-2147483520.0, // Last float32 before INT32_MIN
-1.3956e+09,
-1.32951e+09,
-1.30721e+09,
-1.19756e+09,
-9.26822e+08,
-5.09256e+07,
-964300.0,
-192446.0,
-28455.0,
-27194.0,
-20575.0,
-17069.0,
-9167.0,
-960.178,
-113.0,
-62.0,
-15.0,
-7.0,
-1.0,
-0.0256635,
-4.60374e-07,
-3.63759e-10,
-4.30175e-14,
-5.27385e-15,
-1.5707963267948966,
-1.48084e-15,
-2.220446049250313e-16,
-1.05755e-19,
-3.2995e-21,
-1.67354e-23,
-1.11885e-23,
-1.78506e-30,
-1.43718e-34,
-1.27126e-38,
-0.0,
3e-88,
-2e66,
0.0,
2e66,
1.17549e-38,
1.56657e-37,
4.08512e-29,
6.25073e-22,
4.1723e-13,
1.44343e-09,
1.5707963267948966,
5.27004e-08,
9.48298e-08,
5.57888e-07,
4.89988e-05,
0.244326,
1.0,
12.4895,
19.0,
47.0,
106.0,
538.324,
564.536,
819.124,
7048.0,
12611.0,
19878.0,
20309.0,
797056.0,
1.77219e+09,
2147483648.0, // INT32_MAX + 1
4294967296.0, // UINT32_MAX + 1
1.51116e+11,
4.18193e+13,
3.59167e+16,
9223372036854775808.0, // INT64_MAX + 1
18446744073709551616.0, // UINT64_MAX + 1
3.38211e+19,
2.67488e+20,
1.78831e+21,
9.20914e+21,
8.35654e+23,
1.4495e+24,
5.94015e+25,
4.43608e+30,
2.44502e+33,
1.38178e+37,
1.71306e+37,
3.31899e+38,
3.40282e+38,
];
function genUnop(name, sig) {
var builder = new WasmModuleBuilder();
var sig_index = builder.addType(sig);
builder.addImport('Math', name, sig_index);
builder.addFunction('main', sig_index)
.addBody([
kExprGetLocal, 0, // --
kExprCallFunction, 0
]) // --
.exportAs('main');
return builder.instantiate(global_imports).exports.main;
}
function genBinop(name, sig) {
var builder = new WasmModuleBuilder();
var sig_index = builder.addType(sig);
builder.addImport('Math', name, sig_index);
builder.addFunction('main', sig_index)
.addBody([
kExprGetLocal, 0, // --
kExprGetLocal, 1, // --
kExprCallFunction, 0
]) // --
.exportAs('main');
return builder.instantiate(global_imports).exports.main;
}
function assertUnop(name, math_func, wasm_func) {
for (val of inputs) {
verbose(' ', val);
let m = math_func(val);
let w = wasm_func(val);
if (!deepEquals(m, w)) reportFailure(name, [val], m, w);
}
}
function assertBinop(name, math_func, wasm_func) {
let inputs2 = [1, 0.5, -1, -0.5, 0, -0, 1 / 0, -1 / 0, 0 / 0];
for (val of inputs) {
verbose(' ', val);
for (val2 of inputs2) {
verbose(' ', val2);
let m = math_func(val, val2);
let w = wasm_func(val, val2);
if (!deepEquals(m, w)) reportFailure(name, [val, val2], m, w);
m = math_func(val2, val);
w = wasm_func(val2, val);
if (!deepEquals(m, w)) reportFailure(name, [val2, val], m, w);
}
}
}
(function TestF64() {
let f64_intrinsics = [
'acos', 'asin', 'atan', 'cos', 'sin', 'tan', 'exp', 'log',
'atan2', 'pow', 'ceil', 'floor', 'sqrt', 'min', 'max', 'abs',
'min', 'max', 'abs', 'ceil', 'floor', 'sqrt',
];
for (name of f64_intrinsics) {
let math_func = Math[name];
let f32 = false;
print('Testing (f64) Math.' + name);
switch (math_func.length) {
case 1: {
let wasm_func = genUnop(name, kSig_d_d);
assertUnop('(f64)' + name, math_func, wasm_func);
break;
}
case 2: {
let wasm_func = genBinop(name, kSig_d_dd);
assertBinop('(f64)' + name, math_func, wasm_func);
break;
}
default:
throw 'Unexpected param count: ' + func.length;
}
}
})();
(function TestF32() {
let f32_intrinsics = ['min', 'max', 'abs', 'ceil', 'floor', 'sqrt'];
for (name of f32_intrinsics) {
let r = Math.fround, f = Math[name];
print('Testing (f32) Math.' + name);
switch (f.length) {
case 1: {
let wasm_func = genUnop(name, kSig_f_f);
let math_func = (val) => r(f(r(val)));
assertUnop('(f32)' + name, math_func, wasm_func);
break;
}
case 2: {
let wasm_func = genBinop(name, kSig_f_ff);
let math_func = (v1, v2) => r(f(r(v1), r(v2)));
assertBinop('(f32)' + name, math_func, wasm_func);
break;
}
default:
throw 'Unexpected param count: ' + func.length;
}
}
})();
(function TestFround() {
let name = 'fround';
print('Testing (f32) Math.' + name);
let wasm_func = genUnop(name, kSig_f_d); // fround has a special signature.
let f = Math[name];
let r = Math.fround;
let math_func = (val) => r(f(r(val)));
assertUnop(name, math_func, wasm_func);
})();
assertEquals(0, numFailures);