1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --expose-wasm
6
7function WrapInAsmModule(func) {
8  function MODULE_NAME(stdlib) {
9    "use asm";
10    var fround = stdlib.Math.fround;
11    var Math_ceil = stdlib.Math.ceil;
12    var Math_floor = stdlib.Math.floor;
13    var Math_sqrt = stdlib.Math.sqrt;
14    var Math_abs = stdlib.Math.abs;
15    var Math_min = stdlib.Math.min;
16    var Math_max = stdlib.Math.max;
17
18    FUNC_BODY
19    return {main: FUNC_NAME};
20  }
21
22  var source = MODULE_NAME.toString()
23    .replace(/MODULE_NAME/g, func.name + "_module")
24    .replace(/FUNC_BODY/g, func.toString())
25    .replace(/FUNC_NAME/g, func.name);
26  return eval("(" + source + ")");
27}
28
29function RunThreeWayTest(asmfunc, expect) {
30  var asm_source = asmfunc.toString();
31  var nonasm_source = asm_source.replace(new RegExp("use asm"), "");
32  var stdlib = {Math: Math};
33
34  var js_module = eval("(" + nonasm_source + ")")(stdlib);
35  print("Testing " + asmfunc.name + " (js)...");
36  expect(js_module);
37
38  print("Testing " + asmfunc.name + " (asm.js)...");
39  var asm_module = asmfunc(stdlib);
40  expect(asm_module);
41
42  print("Testing " + asmfunc.name + " (wasm)...");
43  var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, stdlib);
44  expect(wasm_module);
45}
46
47const fround = Math.fround;
48const Math_ceil = Math.ceil;
49const Math_floor = Math.floor;
50const Math_sqrt = Math.sqrt;
51const Math_abs = Math.abs;
52const Math_min = Math.min;
53const Math_max = Math.max;
54
55function f32_add(a, b) {
56  a = fround(a);
57  b = fround(b);
58  return fround(fround(a) + fround(b));
59}
60
61function f32_sub(a, b) {
62  a = fround(a);
63  b = fround(b);
64  return fround(fround(a) - fround(b));
65}
66
67function f32_mul(a, b) {
68  a = fround(a);
69  b = fround(b);
70  return fround(fround(a) * fround(b));
71}
72
73function f32_div(a, b) {
74  a = fround(a);
75  b = fround(b);
76  return fround(fround(a) / fround(b));
77}
78
79function f32_ceil(a) {
80  a = fround(a);
81  return fround(Math_ceil(fround(a)));
82}
83
84function f32_floor(a) {
85  a = fround(a);
86  return fround(Math_floor(fround(a)));
87}
88
89function f32_sqrt(a) {
90  a = fround(a);
91  return fround(Math_sqrt(fround(a)));
92}
93
94function f32_abs(a) {
95  a = fround(a);
96  return fround(Math_abs(fround(a)));
97}
98
99function f32_min(a, b) {
100  a = fround(a);
101  b = fround(b);
102  return fround(Math_min(fround(a), fround(b)));
103}
104
105function f32_max(a, b) {
106  a = fround(a);
107  b = fround(b);
108  return fround(Math_max(fround(a), fround(b)));
109}
110
111function f32_eq(a, b) {
112  a = fround(a);
113  b = fround(b);
114  if (fround(a) == fround(b)) {
115    return 1;
116  }
117  return 0;
118}
119
120function f32_ne(a, b) {
121  a = fround(a);
122  b = fround(b);
123  if (fround(a) != fround(b)) {
124    return 1;
125  }
126  return 0;
127}
128
129function f32_lt(a, b) {
130  a = fround(a);
131  b = fround(b);
132  if (fround(a) < fround(b)) {
133    return 1;
134  }
135  return 0;
136}
137
138function f32_lteq(a, b) {
139  a = fround(a);
140  b = fround(b);
141  if (fround(a) <= fround(b)) {
142    return 1;
143  }
144  return 0;
145}
146
147function f32_gt(a, b) {
148  a = fround(a);
149  b = fround(b);
150  if (fround(a) > fround(b)) {
151    return 1;
152  }
153  return 0;
154}
155
156function f32_gteq(a, b) {
157  a = fround(a);
158  b = fround(b);
159  if (fround(a) >= fround(b)) {
160    return 1;
161  }
162  return 0;
163}
164
165
166var inputs = [
167  0, 1, 2, 3, 4,
168  NaN,
169  Infinity,
170  -Infinity,
171  10, 20, 30, 31, 32, 33, 100, 2000,
172  30000, 400000, 5000000,
173  100000000, 2000000000,
174  2147483646,
175  2147483647,
176  2147483648,
177  2147483649,
178  0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
179  0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
180  0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
181  0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
182  -0,
183  -1, -2, -3, -4,
184  -10, -20, -30, -31, -32, -33, -100, -2000,
185  -30000, -400000, -5000000,
186  -100000000, -2000000000,
187  -2147483646,
188  -2147483647,
189  -2147483648,
190  -2147483649,
191  0.1,
192  1.1e-2,
193  1.2e-4,
194  1.3e-8,
195  1.4e-11,
196  1.5e-12,
197  1.6e-13
198];
199
200var funcs = [
201  f32_add,
202  f32_sub,
203  f32_mul,
204  f32_div,
205  f32_ceil,
206  f32_floor,
207// TODO(bradnelson) f32_sqrt,
208// TODO(bradnelson) f32_abs,
209// TODO(bradnelson) f32_min is wrong for -0
210// TODO(bradnelson) f32_max is wrong for -0
211  f32_eq,
212  f32_ne,
213  f32_lt,
214  f32_lteq,
215  f32_gt,
216  f32_gteq,
217];
218
219(function () {
220  for (func of funcs) {
221    RunThreeWayTest(WrapInAsmModule(func), function (module) {
222      if (func.length == 1) {
223        for (a of inputs) {
224          assertEquals(func(a), module.main(a));
225          assertEquals(func(a / 11), module.main(a / 11));
226          assertEquals(func(a / 430.9), module.main(a / 430.9));
227          assertEquals(func(a / -31.1), module.main(a / -31.1));
228        }
229      } else {
230        for (a of inputs) {
231          for (b of inputs) {
232            assertEquals(func(a, b), module.main(a, b));
233            assertEquals(func(a / 11,  b), module.main(a / 11, b));
234            assertEquals(func(a, b / 420.9), module.main(a, b / 420.9));
235            assertEquals(func(a / -31.1, b), module.main(a / -31.1, b));
236          }
237        }
238      }
239    });
240  }
241
242})();
243