Commit 3e0b6daf authored by titzer's avatar titzer Committed by Commit bot

[wasm] Add more extensive tests for asm->wasm translation.

R=bradnelson@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1825333004

Cr-Commit-Position: refs/heads/master@{#35045}
parent f3e080c2
// 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 WrapInAsmModule(func) {
function MODULE_NAME(stdlib) {
"use asm";
var fround = stdlib.Math.fround;
var Math_ceil = stdlib.Math.ceil;
var Math_floor = stdlib.Math.floor;
var Math_sqrt = stdlib.Math.sqrt;
var Math_abs = stdlib.Math.abs;
var Math_min = stdlib.Math.min;
var Math_max = stdlib.Math.max;
FUNC_BODY
return {main: FUNC_NAME};
}
var source = MODULE_NAME.toString()
.replace(/MODULE_NAME/g, func.name + "_module")
.replace(/FUNC_BODY/g, func.toString())
.replace(/FUNC_NAME/g, func.name);
return eval("(" + source + ")");
}
function RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var stdlib = {Math: Math};
var js_module = eval("(" + nonasm_source + ")")(stdlib);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
expect(wasm_module);
}
const fround = Math.fround;
const Math_ceil = Math.ceil;
const Math_floor = Math.floor;
const Math_sqrt = Math.sqrt;
const Math_abs = Math.abs;
const Math_min = Math.min;
const Math_max = Math.max;
function f32_add(a, b) {
a = fround(a);
b = fround(b);
return fround(fround(a) + fround(b));
}
function f32_sub(a, b) {
a = fround(a);
b = fround(b);
return fround(fround(a) - fround(b));
}
function f32_mul(a, b) {
a = fround(a);
b = fround(b);
return fround(fround(a) * fround(b));
}
function f32_div(a, b) {
a = fround(a);
b = fround(b);
return fround(fround(a) / fround(b));
}
function f32_ceil(a) {
a = fround(a);
return fround(Math_ceil(fround(a)));
}
function f32_floor(a) {
a = fround(a);
return fround(Math_floor(fround(a)));
}
function f32_sqrt(a) {
a = fround(a);
return fround(Math_sqrt(fround(a)));
}
function f32_abs(a) {
a = fround(a);
return fround(Math_abs(fround(a)));
}
function f32_min(a, b) {
a = fround(a);
b = fround(b);
return fround(Math_min(fround(a), fround(b)));
}
function f32_max(a, b) {
a = fround(a);
b = fround(b);
return fround(Math_max(fround(a), fround(b)));
}
function f32_eq(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) == fround(b)) {
return 1;
}
return 0;
}
function f32_ne(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) != fround(b)) {
return 1;
}
return 0;
}
function f32_lt(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) < fround(b)) {
return 1;
}
return 0;
}
function f32_lteq(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) <= fround(b)) {
return 1;
}
return 0;
}
function f32_gt(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) > fround(b)) {
return 1;
}
return 0;
}
function f32_gteq(a, b) {
a = fround(a);
b = fround(b);
if (fround(a) >= fround(b)) {
return 1;
}
return 0;
}
var inputs = [
0, 1, 2, 3, 4,
10, 20, 30, 31, 32, 33, 100, 2000,
30000, 400000, 5000000,
100000000, 2000000000,
2147483646,
2147483647,
2147483648,
2147483649,
0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
-0,
-1, -2, -3, -4,
-10, -20, -30, -31, -32, -33, -100, -2000,
-30000, -400000, -5000000,
-100000000, -2000000000,
-2147483646,
-2147483647,
-2147483648,
-2147483649,
0.1,
1.1e-2,
1.2e-4,
1.3e-8,
1.4e-11,
1.5e-12,
1.6e-13
];
var funcs = [
f32_add,
f32_sub,
f32_mul,
f32_div,
// TODO(bradnelson) f32_ceil,
// TODO(bradnelson) f32_floor,
// TODO(bradnelson) f32_sqrt,
// TODO(bradnelson) f32_abs,
// TODO(bradnelson) f32_min is wrong for -0
// TODO(bradnelson) f32_max is wrong for -0
f32_eq,
f32_ne,
f32_lt,
f32_lteq,
f32_gt,
f32_gteq,
];
(function () {
for (func of funcs) {
RunThreeWayTest(WrapInAsmModule(func), function (module) {
for (a of inputs) {
for (b of inputs) {
assertEquals(func(a, b), module.main(a, b));
assertEquals(func(a / 10, b), module.main(a / 10, b));
assertEquals(func(a, b / 440.9), module.main(a, b / 440.9));
assertEquals(func(a / -33.1, b), module.main(a / -33.1, b));
}
}
});
}
})();
// 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 WrapInAsmModule(func) {
function MODULE_NAME(stdlib) {
"use asm";
var Math_ceil = stdlib.Math.ceil;
var Math_floor = stdlib.Math.floor;
var Math_sqrt = stdlib.Math.sqrt;
var Math_abs = stdlib.Math.abs;
var Math_min = stdlib.Math.min;
var Math_max = stdlib.Math.max;
var Math_acos = stdlib.Math.acos;
var Math_asin = stdlib.Math.asin;
var Math_atan = stdlib.Math.atan;
var Math_cos = stdlib.Math.cos;
var Math_sin = stdlib.Math.sin;
var Math_tan = stdlib.Math.tan;
var Math_exp = stdlib.Math.exp;
var Math_log = stdlib.Math.log;
var Math_atan2 = stdlib.Math.atan2;
FUNC_BODY
return {main: FUNC_NAME};
}
var source = MODULE_NAME.toString()
.replace(/MODULE_NAME/g, func.name + "_module")
.replace(/FUNC_BODY/g, func.toString())
.replace(/FUNC_NAME/g, func.name);
return eval("(" + source + ")");
}
function RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var stdlib = {Math: Math};
var js_module = eval("(" + nonasm_source + ")")(stdlib);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
expect(wasm_module);
}
const Math_ceil = Math.ceil;
const Math_floor = Math.floor;
const Math_sqrt = Math.sqrt;
const Math_abs = Math.abs;
const Math_min = Math.min;
const Math_max = Math.max;
const Math_acos = Math.acos;
const Math_asin = Math.asin;
const Math_atan = Math.atan;
const Math_cos = Math.cos;
const Math_sin = Math.sin;
const Math_tan = Math.tan;
const Math_exp = Math.exp;
const Math_log = Math.log;
const Math_atan2 = Math.atan2;
function f64_add(a, b) {
a = +a;
b = +b;
return +(+a + +b);
}
function f64_sub(a, b) {
a = +a;
b = +b;
return +(+a - +b);
}
function f64_mul(a, b) {
a = +a;
b = +b;
return +(+a * +b);
}
function f64_div(a, b) {
a = +a;
b = +b;
return +(+a / +b);
}
function f64_eq(a, b) {
a = +a;
b = +b;
if (+a == +b) {
return 1;
}
return 0;
}
function f64_ne(a, b) {
a = +a;
b = +b;
if (+a != +b) {
return 1;
}
return 0;
}
function f64_lt(a, b) {
a = +a;
b = +b;
if (+a < +b) {
return 1;
}
return 0;
}
function f64_lteq(a, b) {
a = +a;
b = +b;
if (+a <= +b) {
return 1;
}
return 0;
}
function f64_gt(a, b) {
a = +a;
b = +b;
if (+a > +b) {
return 1;
}
return 0;
}
function f64_gteq(a, b) {
a = +a;
b = +b;
if (+a >= +b) {
return 1;
}
return 0;
}
function f64_ceil(a) {
a = +a;
return +(Math_ceil(+a));
}
function f64_floor(a) {
a = +a;
return +(Math_floor(+a));
}
function f64_sqrt(a) {
a = +a;
return +(Math_sqrt(+a));
}
function f64_abs(a) {
a = +a;
return +(Math_abs(+a));
}
function f64_min(a, b) {
a = +a;
b = +b;
return +(Math_min(+a, +b));
}
function f64_max(a, b) {
a = +a;
b = +b;
return +(Math_max(+a, +b));
}
function f64_acos(a) {
a = +a;
return +Math_acos(+a);
}
function f64_asin(a) {
a = +a;
return +Math_asin(+a);
}
function f64_atan(a) {
a = +a;
return +Math_atan(+a);
}
function f64_cos(a) {
a = +a;
return +Math_cos(+a);
}
function f64_sin(a) {
a = +a;
return +Math_sin(+a);
}
function f64_tan(a) {
a = +a;
return +Math_tan(+a);
}
function f64_exp(a, b) {
a = +a;
b = +b;
return +Math_exp(+a, +b);
}
function f64_log(a, b) {
a = +a;
b = +b;
return +Math_log(+a, +b);
}
function f64_atan2(a) {
a = +a;
return +Math_atan2(+a);
}
var inputs = [
0, 1, 2, 3, 4,
10, 20, 30, 31, 32, 33, 100, 2000,
30000, 400000, 5000000,
100000000, 2000000000,
2147483646,
2147483647,
2147483648,
2147483649,
0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
-0,
-1, -2, -3, -4,
-10, -20, -30, -31, -32, -33, -100, -2000,
-30000, -400000, -5000000,
-100000000, -2000000000,
-2147483646,
-2147483647,
-2147483648,
-2147483649,
0.1,
1.1e-2,
1.2e-4,
1.3e-8,
1.4e-11,
1.5e-12,
1.6e-13
];
var funcs = [
f64_add,
f64_sub,
f64_mul,
f64_div,
f64_eq,
f64_ne,
f64_lt,
f64_lteq,
f64_gt,
f64_gteq,
// TODO(bradnelson) f64_ceil,
// TODO(bradnelson) f64_floor,
// TODO(bradnelson) f64_sqrt,
// TODO(bradnelson) f64_abs,
// TODO(bradnelson) f64_min is wrong for -0
// TODO(bradnelson) f64_max is wrong for -0
// TODO(bradnelson) f64_acos,
// TODO(bradnelson) f64_asin,
// TODO(bradnelson) f64_atan,
// TODO(bradnelson) f64_cos,
// TODO(bradnelson) f64_sin,
// TODO(bradnelson) f64_tan,
// TODO(bradnelson) f64_exp,
// TODO(bradnelson) f64_log,
// TODO(bradnelson) f64_atan2,
];
(function () {
for (func of funcs) {
RunThreeWayTest(WrapInAsmModule(func), function (module) {
if (func.length == 1) {
for (a of inputs) {
assertEquals(func(a), module.main(a));
assertEquals(func(a / 10), module.main(a / 10));
assertEquals(func(a / 440.9), module.main(a / 440.9));
assertEquals(func(a / -33.1), module.main(a / -33.1));
}
} else {
for (a of inputs) {
for (b of inputs) {
assertEquals(func(a, b), module.main(a, b));
assertEquals(func(a / 10, b), module.main(a / 10, b));
assertEquals(func(a, b / 440.9), module.main(a, b / 440.9));
assertEquals(func(a / -33.1, b), module.main(a / -33.1, b));
}
}
}
});
}
})();
// 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
const stdlib = {
Math: Math,
Int8Array: Int8Array,
Int16Array: Int16Array,
Int32Array: Int32Array,
Uint8Array: Uint8Array,
Uint16Array: Uint16Array,
Uint32Array: Uint32Array,
Float32Array: Float32Array,
Float64Array: Float64Array,
};
const buffer = new ArrayBuffer(65536);
const BASE = 1000000000;
const OOB_INDEXES = [
buffer.byteLength,
buffer.byteLength + 1,
buffer.byteLength + 2,
buffer.byteLength + 3,
buffer.byteLength + 4,
buffer.byteLength + 5,
buffer.byteLength + 6,
buffer.byteLength + 7,
buffer.byteLength + 8,
buffer.byteLength + 9,
buffer.byteLength + 10,
0x80000000,
0x80000004,
0xF0000000,
0xFFFFFFFF,
0xFFFFFFFE,
-1, -2, -3, -4, -5, -6, -7, -8
];
function resetBuffer() {
var view = new Int32Array(buffer);
for (var i = 0; i < view.length; i++) {
view[i] = BASE | (i << 2);
}
}
resetBuffer();
function checkView(view, load, shift) {
for (var i = 0; i < 300; i++) {
assertEquals(view[i >> shift], load(i));
}
}
function RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var js_module = eval("(" + nonasm_source + ")")(stdlib, {}, buffer);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib, {}, buffer);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, null, buffer);
expect(wasm_module);
}
function LoadAt_i32(stdlib, foreign, buffer) {
"use asm";
var HEAP32 = new stdlib.Int32Array(buffer);
function load(a) {
a = a | 0;
return HEAP32[a >> 2] | 0;
}
return {load: load};
}
RunThreeWayTest(LoadAt_i32, function(module) {
var load = module.load;
assertEquals(BASE, load(0));
assertEquals(BASE | 0x30, load(0x30));
assertEquals(BASE | 0x704, load(0x704));
assertEquals(BASE | 0x704, load(0x705));
assertEquals(BASE | 0x704, load(0x706));
assertEquals(BASE | 0x704, load(0x707));
var length = buffer.byteLength;
assertEquals(BASE | (length - 4), load(length - 4));
assertEquals(BASE | (length - 4), load(length - 4 + 1));
assertEquals(BASE | (length - 4), load(length - 4 + 2));
assertEquals(BASE | (length - 4), load(length - 4 + 3));
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Int32Array(buffer), load, 2);
});
function LoadAt_i16(stdlib, foreign, buffer) {
"use asm";
var HEAP16 = new stdlib.Int16Array(buffer);
function load(a) {
a = a | 0;
return HEAP16[a >> 1] | 0;
}
return {load: load};
}
RunThreeWayTest(LoadAt_i16, function(module) {
var load = module.load;
var LOWER = (BASE << 16) >> 16;
var UPPER = BASE >> 16;
assertEquals(LOWER, load(0));
assertEquals(UPPER, load(2));
assertEquals(LOWER | 0x30, load(0x30));
assertEquals(UPPER, load(0x32));
assertEquals(LOWER | 0x504, load(0x504));
assertEquals(LOWER | 0x504, load(0x505));
assertEquals(UPPER, load(0x706));
assertEquals(UPPER, load(0x707));
var length = buffer.byteLength;
assertEquals(LOWER | (length - 4), load(length - 4));
assertEquals(LOWER | (length - 4), load(length - 4 + 1));
assertEquals(UPPER, load(length - 4 + 2));
assertEquals(UPPER, load(length - 4 + 3));
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Int16Array(buffer), load, 1);
});
function LoadAt_u16(stdlib, foreign, buffer) {
"use asm";
var HEAP16 = new stdlib.Uint16Array(buffer);
function load(a) {
a = a | 0;
return HEAP16[a >> 1] | 0;
}
return {load: load};
}
RunThreeWayTest(LoadAt_u16, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Uint16Array(buffer), load, 1);
});
function LoadAt_i8(stdlib, foreign, buffer) {
"use asm";
var HEAP8 = new stdlib.Int8Array(buffer);
function load(a) {
a = a | 0;
return HEAP8[a >> 0] | 0;
}
return {load: load};
}
RunThreeWayTest(LoadAt_i8, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Int8Array(buffer), load, 0);
});
function LoadAt_u8(stdlib, foreign, buffer) {
"use asm";
var HEAP8 = new stdlib.Uint8Array(buffer);
function load(a) {
a = a | 0;
return HEAP8[a >> 0] | 0;
}
return {load: load};
}
RunThreeWayTest(LoadAt_u8, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Uint8Array(buffer), load, 0);
});
function LoadAt_u32(stdlib, foreign, buffer) {
"use asm";
var HEAP32 = new stdlib.Uint32Array(buffer);
function load(a) {
a = a | 0;
return +(HEAP32[a >> 2] >>> 0);
}
return {load: load};
}
RunThreeWayTest(LoadAt_u32, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(0, load(index));
checkView(new Uint32Array(buffer), load, 2);
});
function LoadAt_f32(stdlib, foreign, buffer) {
"use asm";
var HEAP32 = new stdlib.Float32Array(buffer);
var fround = stdlib.Math.fround;
function load(a) {
a = a | 0;
return fround(HEAP32[a >> 2]);
}
return {load: load};
}
RunThreeWayTest(LoadAt_f32, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(NaN, load(index));
checkView(new Float32Array(buffer), load, 2);
});
function LoadAt_f64(stdlib, foreign, buffer) {
"use asm";
var HEAP64 = new stdlib.Float64Array(buffer);
function load(a) {
a = a | 0;
return +HEAP64[a >> 3];
}
return {load: load};
}
RunThreeWayTest(LoadAt_f64, function(module) {
var load = module.load;
for (index of OOB_INDEXES) assertEquals(NaN, load(index));
checkView(new Float64Array(buffer), load, 3);
});
// TODO(titzer): constant heap indexes
// TODO(titzer): heap accesses with offsets and arithmetic
// TODO(titzer): [i >> K] where K is greater than log(size)
// 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 WrapInAsmModule(func) {
function MODULE_NAME(stdlib) {
"use asm";
var imul = stdlib.Math.imul;
FUNC_BODY
return {main: FUNC_NAME};
}
var source = MODULE_NAME.toString()
.replace(/MODULE_NAME/g, func.name + "_module")
.replace(/FUNC_BODY/g, func.toString())
.replace(/FUNC_NAME/g, func.name);
return eval("(" + source + ")");
}
function RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var stdlib = {Math: Math};
var js_module = eval("(" + nonasm_source + ")")(stdlib);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
expect(wasm_module);
}
const imul = Math.imul;
function i32_add(a, b) {
a = a | 0;
b = b | 0;
return (a + b) | 0;
}
function i32_sub(a, b) {
a = a | 0;
b = b | 0;
return (a - b) | 0;
}
function i32_mul(a, b) {
a = a | 0;
b = b | 0;
return imul(a, b) | 0;
}
function i32_div(a, b) {
a = a | 0;
b = b | 0;
return (a / b) | 0;
}
function i32_mod(a, b) {
a = a | 0;
b = b | 0;
return (a % b) | 0;
}
function i32_and(a, b) {
a = a | 0;
b = b | 0;
return (a & b) | 0;
}
function i32_or(a, b) {
a = a | 0;
b = b | 0;
return (a | b) | 0;
}
function i32_xor(a, b) {
a = a | 0;
b = b | 0;
return (a ^ b) | 0;
}
function i32_shl(a, b) {
a = a | 0;
b = b | 0;
return (a << b) | 0;
}
function i32_shr(a, b) {
a = a | 0;
b = b | 0;
return (a >> b) | 0;
}
function i32_sar(a, b) {
a = a | 0;
b = b | 0;
return (a >>> b) | 0;
}
function i32_eq(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) == (b | 0)) {
return 1;
}
return 0;
}
function i32_ne(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) < (b | 0)) {
return 1;
}
return 0;
}
function i32_lt(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) < (b | 0)) {
return 1;
}
return 0;
}
function i32_lteq(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) <= (b | 0)) {
return 1;
}
return 0;
}
function i32_gt(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) > (b | 0)) {
return 1;
}
return 0;
}
function i32_gteq(a, b) {
a = a | 0;
b = b | 0;
if ((a | 0) >= (b | 0)) {
return 1;
}
return 0;
}
var inputs = [
0, 1, 2, 3, 4,
10, 20, 30, 31, 32, 33, 100, 2000,
30000, 400000, 5000000,
100000000, 2000000000,
2147483646,
2147483647,
2147483648,
2147483649,
0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
-1, -2, -3, -4,
-10, -20, -30, -31, -32, -33, -100, -2000,
-30000, -400000, -5000000,
-100000000, -2000000000,
-2147483646,
-2147483647,
-2147483648,
-2147483649,
];
var funcs = [
i32_add,
i32_sub,
i32_mul,
// TODO(titzer): i32_mul requires Math.imul
// TODO(titzer): i32_div divide by zero is incorrect
// TODO(titzer): i32_mod by zero is incorrect
i32_and,
i32_or,
i32_xor,
// TODO(titzer): i32_shl on arm
// TODO(titzer): i32_shr on arm
// TODO(titzer): i32_sar on arm
i32_eq,
i32_ne,
i32_lt,
i32_lteq,
i32_gt,
i32_gteq,
// TODO(titzer): i32_min
// TODO(titzer): i32_max
// TODO(titzer): i32_abs
];
(function () {
for (func of funcs) {
RunThreeWayTest(WrapInAsmModule(func), function (module) {
for (a of inputs) {
for (b of inputs) {
var expected = func(a, b);
assertEquals(expected, module.main(a, b));
}
}
});
}
})();
// 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 RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var stdlib = {Math: Math};
var js_module = eval("(" + nonasm_source + ")")(stdlib);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
expect(wasm_module);
}
function PositiveIntLiterals() {
"use asm";
function f0() { return 0; }
function f1() { return 1; }
function f4() { return 4; }
function f64() { return 64; }
function f127() { return 127; }
function f128() { return 128; }
function f256() { return 256; }
function f1000() { return 1000; }
function f2000000() { return 2000000; }
function fmax() { return 2147483647; }
return {f0: f0, f1: f1, f4: f4, f64: f64, f127: f127, f128: f128,
f256: f256, f1000: f1000, f2000000, fmax: fmax};
}
RunThreeWayTest(PositiveIntLiterals, function(module) {
assertEquals(0, module.f0());
assertEquals(1, module.f1());
assertEquals(4, module.f4());
assertEquals(64, module.f64());
assertEquals(128, module.f128());
assertEquals(256, module.f256());
assertEquals(1000, module.f1000());
assertEquals(2000000, module.f2000000());
assertEquals(2147483647, module.fmax());
});
function NegativeIntLiterals() {
"use asm";
function f1() { return -1; }
function f4() { return -4; }
function f64() { return -64; }
function f127() { return -127; }
function f128() { return -128; }
function f256() { return -256; }
function f1000() { return -1000; }
function f2000000() { return -2000000; }
function fmin() { return -2147483648; }
return {f1: f1, f4: f4, f64: f64, f127: f127, f128: f128,
f256: f256, f1000: f1000, f2000000, fmin: fmin};
}
RunThreeWayTest(NegativeIntLiterals, function (module) {
assertEquals(-1, module.f1());
assertEquals(-4, module.f4());
assertEquals(-64, module.f64());
assertEquals(-127, module.f127());
assertEquals(-128, module.f128());
assertEquals(-256, module.f256());
assertEquals(-1000, module.f1000());
assertEquals(-2000000, module.f2000000());
assertEquals(-2147483648, module.fmin());
});
function PositiveUnsignedLiterals() {
"use asm";
function f0() { return 0 >>> 0; }
function f1() { return 1 >>> 0; }
function f4() { return 4 >>> 0; }
function f64() { return 64 >>> 0; }
function f127() { return 127 >>> 0; }
function f128() { return 128 >>> 0; }
function f256() { return 256 >>> 0; }
function f1000() { return 1000 >>> 0; }
function f2000000() { return 2000000 >>> 0; }
function fmax() { return 2147483647 >>> 0; }
return {f0: f0, f1: f1, f4: f4, f64: f64, f127: f127, f128: f128,
f256: f256, f1000: f1000, f2000000, fmax: fmax};
}
RunThreeWayTest(PositiveUnsignedLiterals, function (module) {
assertEquals(0, module.f0());
assertEquals(1, module.f1());
assertEquals(4, module.f4());
assertEquals(64, module.f64());
assertEquals(128, module.f128());
assertEquals(256, module.f256());
assertEquals(1000, module.f1000());
assertEquals(2000000, module.f2000000());
assertEquals(2147483647, module.fmax());
});
function LargeUnsignedLiterals() {
"use asm";
function a() {
var x = 2147483648;
return +x;
}
function b() {
var x = 2147483649;
return +x;
}
function c() {
var x = 0x80000000;
return +x;
}
function d() {
var x = 0x80000001;
return +x;
}
function e() {
var x = 0xffffffff;
return +x;
}
return {a: a, b: b, c: c, d: d, e: e};
}
RunThreeWayTest(LargeUnsignedLiterals, function(module) {
return; // TODO(bradnelson): unsigned literals are broken!
assertEquals(2147483648, module.a());
assertEquals(2147483649, module.b());
assertEquals(0x80000000, module.c());
assertEquals(0x80000001, module.d());
assertEquals(0xffffffff, module.e());
});
function ManyI32() {
"use asm";
function main() {
var a = 1 + -2 + 3 + -4 | 0;
var b = 11 + -22 + 33 + -44 | 0;
var c = 111 + -222 + 333 + -444 | 0;
var d = 1111 + -2222 + 3333 + -4444 | 0;
var e = 11111 + -22222 + 33333 + -44444 | 0;
var f = 155555 + -266666 + 377777 + -488888 | 0;
var g = 1155555 + -2266666 + 3377777 + -4488888 | 0;
var h = 11155555 + -22266666 + 33377777 + -44488888 | 0;
var i = 111155555 + -222266666 + 333377777 + -444488888 | 0;
var j = (
0x1 + 0x2 + 0x4 + 0x8 +
0x10 + 0x20 + 0x40 + 0x80 +
0x10F + 0x200 + 0x400 + 0x800 +
0x10E0 + 0x20F0 + 0x4000 + 0x8000 +
0x10D00 + 0x20E00 + 0x400F0 + 0x80002 +
0x10C000 + 0x20D000 + 0x400E00 + 0x800030 +
0x10B0000 + 0x20C0000 + 0x400D000 + 0x8000400 +
0x10A00000 + 0x20B00000 + 0x400C0000 + 0x80005000
) | 0;
return (a + b + c + d + e + f + g + h + i + j) | 0;
}
return {main: main};
}
RunThreeWayTest(ManyI32, function(module) {
assertEquals(-222411306, module.main());
});
function ManyF64a() {
"use asm";
function main() {
var a = +( 0.1 + -0.2 + 0.3 + -0.4);
var b = +( 1.1 + -2.2 + 0.33 + -4.4);
var c = +( 11.1 + -22.2 + 3.33 + -4.44);
var d = +( 111.1 + -222.2 + 33.33 + -4.444);
var e = +( 1111.1 + -2222.2 + 333.33 + -4.4444);
var f = +( 15555.5 + -26666.6 + 3777.77 + -4.88888);
var g = +( 115555.5 + -226666.6 + 33777.77 + -4.488888);
var h = +( 1115555.5 + -2226666.6 + 333777.77 + -4.4488888);
var i = +(11115555.5 + -22226666.6 + 3333777.77 + -4.44488888);
return +(a + b + c + d + e + f + g + h + i);
}
return {main: main};
}
RunThreeWayTest(ManyF64a, function(module) {
assertEquals(-8640233.599945681, module.main());
});
function ManyF64b() {
"use asm";
function k1() { return +(1.0e-25 + 3.0e-25 + 5.0e-25 + 6.0e-25 + 9.0e-25); }
function k2() { return +(1.0e-20 + 3.0e-20 + 5.0e-20 + 6.0e-20 + 9.0e-20); }
function k3() { return +(1.0e-15 + 3.0e-15 + 5.0e-15 + 6.0e-15 + 9.0e-15); }
function k4() { return +(1.0e-10 + 3.0e-10 + 5.0e-10 + 6.0e-10 + 9.0e-10); }
function k5() { return +(1.0e-5 + 3.0e-5 + 5.0e-5 + 6.0e-5 + 9.0e-5); }
function k6() { return +(1.1e+0 + 3.1e+0 + 5.1e+0 + 6.1e+0 + 9.1e+0); }
return {k1: k1, k2: k2, k3: k3, k4: k4, k5: k5, k6: k6};
}
RunThreeWayTest(ManyF64b, function(module) {
assertEquals(2.4e-24, module.k1());
assertEquals(2.4e-19, module.k2());
assertEquals(2.4e-14, module.k3());
assertEquals(2.4e-9, module.k4());
assertEquals(0.00024000000000000003, module.k5());
assertEquals(24.5, module.k6());
});
function ManyF64c() {
"use asm";
function k1() { return +(1.0e+25 + 3.0e+25 + 5.0e+25 + 6.0e+25 + 9.0e+25); }
function k2() { return +(1.0e+20 + 3.0e+20 + 5.0e+20 + 6.0e+20 + 9.0e+20); }
function k3() { return +(1.0e+15 + 3.0e+15 + 5.0e+15 + 6.0e+15 + 9.0e+15); }
function k4() { return +(1.0e+10 + 3.0e+10 + 5.0e+10 + 6.0e+10 + 9.0e+10); }
function k5() { return +(1.0e+5 + 3.0e+5 + 5.0e+5 + 6.0e+5 + 9.0e+5); }
function k6() { return +(1.4e+0 + 3.4e+0 + 5.4e+0 + 6.4e+0 + 9.4e+0); }
return {k1: k1, k2: k2, k3: k3, k4: k4, k5: k5, k6: k6};
}
RunThreeWayTest(ManyF64c, function(module) {
assertEquals(2.4000000000000004e+26, module.k1());
assertEquals(2.4e+21, module.k2());
assertEquals(2.4e+16, module.k3());
assertEquals(2.4e+11, module.k4());
assertEquals(2.4e+6, module.k5());
assertEquals(26, module.k6());
});
function ManyF32a(stdlib) {
"use asm";
var F = stdlib.Math.fround;
function k1() { return F(F(1.0e-25) + F(5.0e-25) + F(6.0e-25) + F(9.0e-25)); }
function k2() { return F(F(1.0e-20) + F(5.0e-20) + F(6.0e-20) + F(9.0e-20)); }
function k3() { return F(F(1.0e-15) + F(5.0e-15) + F(6.0e-15) + F(9.0e-15)); }
function k4() { return F(F(1.0e-10) + F(5.0e-10) + F(6.0e-10) + F(9.0e-10)); }
function k5() { return F(F(1.0e-5) + F(5.0e-5) + F(6.0e-5) + F(9.0e-5)); }
function k6() { return F(F(1.1e+0) + F(5.1e+0) + F(6.1e+0) + F(9.1e+0)); }
return {k1: k1, k2: k2, k3: k3, k4: k4, k5: k5, k6: k6};
}
if (false) {
// TODO(bradnelson): fails validation of F32 literals somehow.
RunThreeWayTest(ManyF32a, function(module) {
assertEquals(2.0999999917333043e-24, module.k1());
assertEquals(2.099999868734112e-19, module.k2());
assertEquals(2.099999997029825e-14, module.k3());
assertEquals(2.099999951710174e-9, module.k4());
assertEquals(0.0002099999983329326, module.k5());
assertEquals(21.399999618530273, module.k6());
});
}
// 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 WrapInAsmModule(func) {
function MODULE_NAME(stdlib) {
"use asm";
var imul = stdlib.Math.imul;
FUNC_BODY
return {main: FUNC_NAME};
}
var source = MODULE_NAME.toString()
.replace(/MODULE_NAME/g, func.name + "_module")
.replace(/FUNC_BODY/g, func.toString())
.replace(/FUNC_NAME/g, func.name);
return eval("(" + source + ")");
}
function RunThreeWayTest(asmfunc, expect) {
var asm_source = asmfunc.toString();
var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
var stdlib = {Math: Math};
var js_module = eval("(" + nonasm_source + ")")(stdlib);
print("Testing " + asmfunc.name + " (js)...");
expect(js_module);
print("Testing " + asmfunc.name + " (asm.js)...");
var asm_module = asmfunc(stdlib);
expect(asm_module);
print("Testing " + asmfunc.name + " (wasm)...");
var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
expect(wasm_module);
}
const imul = Math.imul;
function u32_add(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) + (b >>> 0));
}
function u32_sub(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) - (b >>> 0));
}
function u32_mul(a, b) {
a = a | 0;
b = b | 0;
return +imul(a >>> 0, b >>> 0);
}
function u32_div(a, b) {
a = a | 0;
b = b | 0;
return ((a >>> 0) / (b >>> 0)) | 0;
}
function u32_mod(a, b) {
a = a | 0;
b = b | 0;
return ((a >>> 0) % (b >>> 0)) | 0;
}
function u32_and(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) & (b >>> 0));
}
function u32_or(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) | (b >>> 0));
}
function u32_xor(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) ^ (b >>> 0));
}
function u32_shl(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) << (b >>> 0));
}
function u32_shr(a, b) {
a = a | 0;
b = b | 0;
return +((a >>> 0) >> (b >>> 0));
}
function u32_sar(a, b) {
a = a | 0;
b = b | 0;
return ((a >>> 0) >>> (b >>> 0)) | 0;
}
function u32_eq(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) == (b >>> 0)) {
return 1;
}
return 0;
}
function u32_ne(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) < (b >>> 0)) {
return 1;
}
return 0;
}
function u32_lt(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) < (b >>> 0)) {
return 1;
}
return 0;
}
function u32_lteq(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) <= (b >>> 0)) {
return 1;
}
return 0;
}
function u32_gt(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) > (b >>> 0)) {
return 1;
}
return 0;
}
function u32_gteq(a, b) {
a = a | 0;
b = b | 0;
if ((a >>> 0) >= (b >>> 0)) {
return 1;
}
return 0;
}
var inputs = [
0, 1, 2, 3, 4,
10, 20, 30, 31, 32, 33, 100, 2000,
30000, 400000, 5000000,
100000000, 2000000000,
2147483646,
2147483647,
2147483648,
2147483649,
0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
-1, -2, -3, -4,
-10, -20, -30, -31, -32, -33, -100, -2000,
-30000, -400000, -5000000,
-100000000, -2000000000,
-2147483646,
-2147483647,
-2147483648,
-2147483649,
];
var funcs = [
// TODO(bradnelson): u32_add,
// TODO(bradnelson): u32_sub,
// TODO(titzer): u32_mul requires Math.imul
// TODO(titzer): u32_div by zero is incorrect
// TODO(titzer): u32_mod by zero is incorrect
// TODO(titzer): u32_mul crashes turbofan in asm.js mode
u32_and,
u32_or,
u32_xor,
// TODO(titzer): u32_shl on arm
// TODO(titzer): u32_shr on arm
// TODO(titzer): u32_sar on arm
u32_eq,
u32_ne,
u32_lt,
u32_lteq,
u32_gt,
u32_gteq,
// TODO(titzer): u32_min
// TODO(titzer): u32_max
// TODO(titzer): u32_abs
];
(function () {
for (func of funcs) {
RunThreeWayTest(WrapInAsmModule(func), function (module) {
for (a of inputs) {
for (b of inputs) {
var expected = func(a, b);
assertEquals(expected, module.main(a, b));
}
}
});
}
})();
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment