// 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([
        kExprLocalGet, 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([
        kExprLocalGet, 0,  // --
        kExprLocalGet, 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);
