blob: a6f07f7af028e9fb849f1195ff8d9961cf447518 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 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#include <stdint.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "src/wasm/wasm-macro-gen.h"
10
11#include "test/cctest/cctest.h"
12#include "test/cctest/compiler/value-helper.h"
13#include "test/cctest/wasm/test-signatures.h"
14#include "test/cctest/wasm/wasm-run-utils.h"
15
16using namespace v8::base;
17using namespace v8::internal;
18using namespace v8::internal::compiler;
19using namespace v8::internal::wasm;
20
21#define BUILD(r, ...) \
22 do { \
23 byte code[] = {__VA_ARGS__}; \
24 r.Build(code, code + arraysize(code)); \
25 } while (false)
26
27
28TEST(Run_WasmInt8Const) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010029 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030 const byte kExpectedValue = 121;
31 // return(kExpectedValue)
32 BUILD(r, WASM_I8(kExpectedValue));
33 CHECK_EQ(kExpectedValue, r.Call());
34}
35
36
37TEST(Run_WasmInt8Const_fallthru1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010038 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 const byte kExpectedValue = 122;
40 // kExpectedValue
41 BUILD(r, WASM_I8(kExpectedValue));
42 CHECK_EQ(kExpectedValue, r.Call());
43}
44
45
46TEST(Run_WasmInt8Const_fallthru2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010047 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 const byte kExpectedValue = 123;
49 // -99 kExpectedValue
50 BUILD(r, WASM_I8(-99), WASM_I8(kExpectedValue));
51 CHECK_EQ(kExpectedValue, r.Call());
52}
53
54
55TEST(Run_WasmInt8Const_all) {
56 for (int value = -128; value <= 127; value++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010057 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 // return(value)
59 BUILD(r, WASM_I8(value));
Ben Murdoch097c5b22016-05-18 11:27:45 +010060 int32_t result = r.Call();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 CHECK_EQ(value, result);
62 }
63}
64
65
66TEST(Run_WasmInt32Const) {
67 WasmRunner<int32_t> r;
68 const int32_t kExpectedValue = 0x11223344;
69 // return(kExpectedValue)
70 BUILD(r, WASM_I32(kExpectedValue));
71 CHECK_EQ(kExpectedValue, r.Call());
72}
73
74
75TEST(Run_WasmInt32Const_many) {
76 FOR_INT32_INPUTS(i) {
77 WasmRunner<int32_t> r;
78 const int32_t kExpectedValue = *i;
79 // return(kExpectedValue)
80 BUILD(r, WASM_I32(kExpectedValue));
81 CHECK_EQ(kExpectedValue, r.Call());
82 }
83}
84
85
86TEST(Run_WasmMemorySize) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +010088 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 module.AddMemory(1024);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 BUILD(r, kExprMemorySize);
91 CHECK_EQ(1024, r.Call());
92}
93
94
95#if WASM_64
96TEST(Run_WasmInt64Const) {
97 WasmRunner<int64_t> r;
98 const int64_t kExpectedValue = 0x1122334455667788LL;
99 // return(kExpectedValue)
100 BUILD(r, WASM_I64(kExpectedValue));
101 CHECK_EQ(kExpectedValue, r.Call());
102}
103
104
105TEST(Run_WasmInt64Const_many) {
106 int cntr = 0;
107 FOR_INT32_INPUTS(i) {
108 WasmRunner<int64_t> r;
109 const int64_t kExpectedValue = (static_cast<int64_t>(*i) << 32) | cntr;
110 // return(kExpectedValue)
111 BUILD(r, WASM_I64(kExpectedValue));
112 CHECK_EQ(kExpectedValue, r.Call());
113 cntr++;
114 }
115}
116#endif
117
Ben Murdoch097c5b22016-05-18 11:27:45 +0100118TEST(Run_WasmI32ConvertI64) {
119 FOR_INT64_INPUTS(i) {
120 WasmRunner<int32_t> r;
121 BUILD(r, WASM_I32_CONVERT_I64(WASM_I64(*i)));
122 CHECK_EQ(static_cast<int32_t>(*i), r.Call());
123 }
124}
125
126TEST(Run_WasmI64AndConstants) {
127 FOR_INT64_INPUTS(i) {
128 FOR_INT64_INPUTS(j) {
129 WasmRunner<int32_t> r;
130 BUILD(r, WASM_I32_CONVERT_I64(WASM_I64_AND(WASM_I64(*i), WASM_I64(*j))));
131 CHECK_EQ(static_cast<int32_t>(*i & *j), r.Call());
132 }
133 }
134}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135
136TEST(Run_WasmInt32Param0) {
137 WasmRunner<int32_t> r(MachineType::Int32());
138 // return(local[0])
139 BUILD(r, WASM_GET_LOCAL(0));
140 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
141}
142
143
144TEST(Run_WasmInt32Param0_fallthru) {
145 WasmRunner<int32_t> r(MachineType::Int32());
146 // local[0]
147 BUILD(r, WASM_GET_LOCAL(0));
148 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
149}
150
151
152TEST(Run_WasmInt32Param1) {
153 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
154 // local[1]
155 BUILD(r, WASM_GET_LOCAL(1));
156 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); }
157}
158
159
160TEST(Run_WasmInt32Add) {
161 WasmRunner<int32_t> r;
162 // 11 + 44
163 BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44)));
164 CHECK_EQ(55, r.Call());
165}
166
167
168TEST(Run_WasmInt32Add_P) {
169 WasmRunner<int32_t> r(MachineType::Int32());
170 // p0 + 13
171 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
172 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
173}
174
175
176TEST(Run_WasmInt32Add_P_fallthru) {
177 WasmRunner<int32_t> r(MachineType::Int32());
178 // p0 + 13
179 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
180 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
181}
182
183
184TEST(Run_WasmInt32Add_P2) {
185 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
186 // p0 + p1
187 BUILD(r, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
188 FOR_INT32_INPUTS(i) {
189 FOR_INT32_INPUTS(j) {
190 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
191 static_cast<uint32_t>(*j));
192 CHECK_EQ(expected, r.Call(*i, *j));
193 }
194 }
195}
196
197
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198TEST(Run_WasmFloat32Add) {
199 WasmRunner<int32_t> r;
200 // int(11.5f + 44.5f)
201 BUILD(r,
202 WASM_I32_SCONVERT_F32(WASM_F32_ADD(WASM_F32(11.5f), WASM_F32(44.5f))));
203 CHECK_EQ(56, r.Call());
204}
205
206
207TEST(Run_WasmFloat64Add) {
208 WasmRunner<int32_t> r;
209 // return int(13.5d + 43.5d)
210 BUILD(r, WASM_I32_SCONVERT_F64(WASM_F64_ADD(WASM_F64(13.5), WASM_F64(43.5))));
211 CHECK_EQ(57, r.Call());
212}
213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214
215void TestInt32Binop(WasmOpcode opcode, int32_t expected, int32_t a, int32_t b) {
216 {
217 WasmRunner<int32_t> r;
218 // K op K
219 BUILD(r, WASM_BINOP(opcode, WASM_I32(a), WASM_I32(b)));
220 CHECK_EQ(expected, r.Call());
221 }
222 {
223 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
224 // a op b
225 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
226 CHECK_EQ(expected, r.Call(a, b));
227 }
228}
229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230TEST(Run_WasmInt32Binops) {
231 TestInt32Binop(kExprI32Add, 88888888, 33333333, 55555555);
232 TestInt32Binop(kExprI32Sub, -1111111, 7777777, 8888888);
233 TestInt32Binop(kExprI32Mul, 65130756, 88734, 734);
234 TestInt32Binop(kExprI32DivS, -66, -4777344, 72384);
235 TestInt32Binop(kExprI32DivU, 805306368, 0xF0000000, 5);
236 TestInt32Binop(kExprI32RemS, -3, -3003, 1000);
237 TestInt32Binop(kExprI32RemU, 4, 4004, 1000);
238 TestInt32Binop(kExprI32And, 0xEE, 0xFFEE, 0xFF0000FF);
239 TestInt32Binop(kExprI32Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
240 TestInt32Binop(kExprI32Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
241 TestInt32Binop(kExprI32Shl, 0xA0000000, 0xA, 28);
242 TestInt32Binop(kExprI32ShrU, 0x07000010, 0x70000100, 4);
243 TestInt32Binop(kExprI32ShrS, 0xFF000000, 0x80000000, 7);
244 TestInt32Binop(kExprI32Eq, 1, -99, -99);
245 TestInt32Binop(kExprI32Ne, 0, -97, -97);
246
247 TestInt32Binop(kExprI32LtS, 1, -4, 4);
248 TestInt32Binop(kExprI32LeS, 0, -2, -3);
249 TestInt32Binop(kExprI32LtU, 1, 0, -6);
250 TestInt32Binop(kExprI32LeU, 1, 98978, 0xF0000000);
251
252 TestInt32Binop(kExprI32GtS, 1, 4, -4);
253 TestInt32Binop(kExprI32GeS, 0, -3, -2);
254 TestInt32Binop(kExprI32GtU, 1, -6, 0);
255 TestInt32Binop(kExprI32GeU, 1, 0xF0000000, 98978);
256}
257
258
259void TestInt32Unop(WasmOpcode opcode, int32_t expected, int32_t a) {
260 {
261 WasmRunner<int32_t> r;
262 // return op K
263 BUILD(r, WASM_UNOP(opcode, WASM_I32(a)));
264 CHECK_EQ(expected, r.Call());
265 }
266 {
267 WasmRunner<int32_t> r(MachineType::Int32());
268 // return op a
269 BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0)));
270 CHECK_EQ(expected, r.Call(a));
271 }
272}
273
274
275TEST(Run_WasmInt32Clz) {
276 TestInt32Unop(kExprI32Clz, 0, 0x80001000);
277 TestInt32Unop(kExprI32Clz, 1, 0x40000500);
278 TestInt32Unop(kExprI32Clz, 2, 0x20000300);
279 TestInt32Unop(kExprI32Clz, 3, 0x10000003);
280 TestInt32Unop(kExprI32Clz, 4, 0x08050000);
281 TestInt32Unop(kExprI32Clz, 5, 0x04006000);
282 TestInt32Unop(kExprI32Clz, 6, 0x02000000);
283 TestInt32Unop(kExprI32Clz, 7, 0x010000a0);
284 TestInt32Unop(kExprI32Clz, 8, 0x00800c00);
285 TestInt32Unop(kExprI32Clz, 9, 0x00400000);
286 TestInt32Unop(kExprI32Clz, 10, 0x0020000d);
287 TestInt32Unop(kExprI32Clz, 11, 0x00100f00);
288 TestInt32Unop(kExprI32Clz, 12, 0x00080000);
289 TestInt32Unop(kExprI32Clz, 13, 0x00041000);
290 TestInt32Unop(kExprI32Clz, 14, 0x00020020);
291 TestInt32Unop(kExprI32Clz, 15, 0x00010300);
292 TestInt32Unop(kExprI32Clz, 16, 0x00008040);
293 TestInt32Unop(kExprI32Clz, 17, 0x00004005);
294 TestInt32Unop(kExprI32Clz, 18, 0x00002050);
295 TestInt32Unop(kExprI32Clz, 19, 0x00001700);
296 TestInt32Unop(kExprI32Clz, 20, 0x00000870);
297 TestInt32Unop(kExprI32Clz, 21, 0x00000405);
298 TestInt32Unop(kExprI32Clz, 22, 0x00000203);
299 TestInt32Unop(kExprI32Clz, 23, 0x00000101);
300 TestInt32Unop(kExprI32Clz, 24, 0x00000089);
301 TestInt32Unop(kExprI32Clz, 25, 0x00000041);
302 TestInt32Unop(kExprI32Clz, 26, 0x00000022);
303 TestInt32Unop(kExprI32Clz, 27, 0x00000013);
304 TestInt32Unop(kExprI32Clz, 28, 0x00000008);
305 TestInt32Unop(kExprI32Clz, 29, 0x00000004);
306 TestInt32Unop(kExprI32Clz, 30, 0x00000002);
307 TestInt32Unop(kExprI32Clz, 31, 0x00000001);
308 TestInt32Unop(kExprI32Clz, 32, 0x00000000);
309}
310
311
312TEST(Run_WasmInt32Ctz) {
313 TestInt32Unop(kExprI32Ctz, 32, 0x00000000);
314 TestInt32Unop(kExprI32Ctz, 31, 0x80000000);
315 TestInt32Unop(kExprI32Ctz, 30, 0x40000000);
316 TestInt32Unop(kExprI32Ctz, 29, 0x20000000);
317 TestInt32Unop(kExprI32Ctz, 28, 0x10000000);
318 TestInt32Unop(kExprI32Ctz, 27, 0xa8000000);
319 TestInt32Unop(kExprI32Ctz, 26, 0xf4000000);
320 TestInt32Unop(kExprI32Ctz, 25, 0x62000000);
321 TestInt32Unop(kExprI32Ctz, 24, 0x91000000);
322 TestInt32Unop(kExprI32Ctz, 23, 0xcd800000);
323 TestInt32Unop(kExprI32Ctz, 22, 0x09400000);
324 TestInt32Unop(kExprI32Ctz, 21, 0xaf200000);
325 TestInt32Unop(kExprI32Ctz, 20, 0xac100000);
326 TestInt32Unop(kExprI32Ctz, 19, 0xe0b80000);
327 TestInt32Unop(kExprI32Ctz, 18, 0x9ce40000);
328 TestInt32Unop(kExprI32Ctz, 17, 0xc7920000);
329 TestInt32Unop(kExprI32Ctz, 16, 0xb8f10000);
330 TestInt32Unop(kExprI32Ctz, 15, 0x3b9f8000);
331 TestInt32Unop(kExprI32Ctz, 14, 0xdb4c4000);
332 TestInt32Unop(kExprI32Ctz, 13, 0xe9a32000);
333 TestInt32Unop(kExprI32Ctz, 12, 0xfca61000);
334 TestInt32Unop(kExprI32Ctz, 11, 0x6c8a7800);
335 TestInt32Unop(kExprI32Ctz, 10, 0x8ce5a400);
336 TestInt32Unop(kExprI32Ctz, 9, 0xcb7d0200);
337 TestInt32Unop(kExprI32Ctz, 8, 0xcb4dc100);
338 TestInt32Unop(kExprI32Ctz, 7, 0xdfbec580);
339 TestInt32Unop(kExprI32Ctz, 6, 0x27a9db40);
340 TestInt32Unop(kExprI32Ctz, 5, 0xde3bcb20);
341 TestInt32Unop(kExprI32Ctz, 4, 0xd7e8a610);
342 TestInt32Unop(kExprI32Ctz, 3, 0x9afdbc88);
343 TestInt32Unop(kExprI32Ctz, 2, 0x9afdbc84);
344 TestInt32Unop(kExprI32Ctz, 1, 0x9afdbc82);
345 TestInt32Unop(kExprI32Ctz, 0, 0x9afdbc81);
346}
347
348
349TEST(Run_WasmInt32Popcnt) {
350 TestInt32Unop(kExprI32Popcnt, 32, 0xffffffff);
351 TestInt32Unop(kExprI32Popcnt, 0, 0x00000000);
352 TestInt32Unop(kExprI32Popcnt, 1, 0x00008000);
353 TestInt32Unop(kExprI32Popcnt, 13, 0x12345678);
354 TestInt32Unop(kExprI32Popcnt, 19, 0xfedcba09);
355}
356
357
358#if WASM_64
359void TestInt64Binop(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) {
360 if (!WasmOpcodes::IsSupported(opcode)) return;
361 {
362 WasmRunner<int64_t> r;
363 // return K op K
364 BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b)));
365 CHECK_EQ(expected, r.Call());
366 }
367 {
368 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
369 // return a op b
370 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
371 CHECK_EQ(expected, r.Call(a, b));
372 }
373}
374
375
376void TestInt64Cmp(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) {
377 if (!WasmOpcodes::IsSupported(opcode)) return;
378 {
379 WasmRunner<int32_t> r;
380 // return K op K
381 BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b)));
382 CHECK_EQ(expected, r.Call());
383 }
384 {
385 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64());
386 // return a op b
387 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
388 CHECK_EQ(expected, r.Call(a, b));
389 }
390}
391
392
393TEST(Run_WasmInt64Binops) {
394 // TODO(titzer): real 64-bit numbers
395 TestInt64Binop(kExprI64Add, 8888888888888LL, 3333333333333LL,
396 5555555555555LL);
397 TestInt64Binop(kExprI64Sub, -111111111111LL, 777777777777LL, 888888888888LL);
398 TestInt64Binop(kExprI64Mul, 65130756, 88734, 734);
399 TestInt64Binop(kExprI64DivS, -66, -4777344, 72384);
400 TestInt64Binop(kExprI64DivU, 805306368, 0xF0000000, 5);
401 TestInt64Binop(kExprI64RemS, -3, -3003, 1000);
402 TestInt64Binop(kExprI64RemU, 4, 4004, 1000);
403 TestInt64Binop(kExprI64And, 0xEE, 0xFFEE, 0xFF0000FF);
404 TestInt64Binop(kExprI64Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
405 TestInt64Binop(kExprI64Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
406 TestInt64Binop(kExprI64Shl, 0xA0000000, 0xA, 28);
407 TestInt64Binop(kExprI64ShrU, 0x0700001000123456LL, 0x7000010001234567LL, 4);
408 TestInt64Binop(kExprI64ShrS, 0xFF00000000000000LL, 0x8000000000000000LL, 7);
409 TestInt64Cmp(kExprI64Eq, 1, -9999, -9999);
410 TestInt64Cmp(kExprI64Ne, 1, -9199, -9999);
411 TestInt64Cmp(kExprI64LtS, 1, -4, 4);
412 TestInt64Cmp(kExprI64LeS, 0, -2, -3);
413 TestInt64Cmp(kExprI64LtU, 1, 0, -6);
414 TestInt64Cmp(kExprI64LeU, 1, 98978, 0xF0000000);
415}
416
417
418TEST(Run_WasmInt64Clz) {
419 struct {
420 int64_t expected;
421 uint64_t input;
422 } values[] = {{0, 0x8000100000000000}, {1, 0x4000050000000000},
423 {2, 0x2000030000000000}, {3, 0x1000000300000000},
424 {4, 0x0805000000000000}, {5, 0x0400600000000000},
425 {6, 0x0200000000000000}, {7, 0x010000a000000000},
426 {8, 0x00800c0000000000}, {9, 0x0040000000000000},
427 {10, 0x0020000d00000000}, {11, 0x00100f0000000000},
428 {12, 0x0008000000000000}, {13, 0x0004100000000000},
429 {14, 0x0002002000000000}, {15, 0x0001030000000000},
430 {16, 0x0000804000000000}, {17, 0x0000400500000000},
431 {18, 0x0000205000000000}, {19, 0x0000170000000000},
432 {20, 0x0000087000000000}, {21, 0x0000040500000000},
433 {22, 0x0000020300000000}, {23, 0x0000010100000000},
434 {24, 0x0000008900000000}, {25, 0x0000004100000000},
435 {26, 0x0000002200000000}, {27, 0x0000001300000000},
436 {28, 0x0000000800000000}, {29, 0x0000000400000000},
437 {30, 0x0000000200000000}, {31, 0x0000000100000000},
438 {32, 0x0000000080001000}, {33, 0x0000000040000500},
439 {34, 0x0000000020000300}, {35, 0x0000000010000003},
440 {36, 0x0000000008050000}, {37, 0x0000000004006000},
441 {38, 0x0000000002000000}, {39, 0x00000000010000a0},
442 {40, 0x0000000000800c00}, {41, 0x0000000000400000},
443 {42, 0x000000000020000d}, {43, 0x0000000000100f00},
444 {44, 0x0000000000080000}, {45, 0x0000000000041000},
445 {46, 0x0000000000020020}, {47, 0x0000000000010300},
446 {48, 0x0000000000008040}, {49, 0x0000000000004005},
447 {50, 0x0000000000002050}, {51, 0x0000000000001700},
448 {52, 0x0000000000000870}, {53, 0x0000000000000405},
449 {54, 0x0000000000000203}, {55, 0x0000000000000101},
450 {56, 0x0000000000000089}, {57, 0x0000000000000041},
451 {58, 0x0000000000000022}, {59, 0x0000000000000013},
452 {60, 0x0000000000000008}, {61, 0x0000000000000004},
453 {62, 0x0000000000000002}, {63, 0x0000000000000001},
454 {64, 0x0000000000000000}};
455
456 WasmRunner<int64_t> r(MachineType::Uint64());
457 BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0)));
458 for (size_t i = 0; i < arraysize(values); i++) {
459 CHECK_EQ(values[i].expected, r.Call(values[i].input));
460 }
461}
462
463
464TEST(Run_WasmInt64Ctz) {
465 struct {
466 int64_t expected;
467 uint64_t input;
468 } values[] = {{64, 0x0000000000000000}, {63, 0x8000000000000000},
469 {62, 0x4000000000000000}, {61, 0x2000000000000000},
470 {60, 0x1000000000000000}, {59, 0xa800000000000000},
471 {58, 0xf400000000000000}, {57, 0x6200000000000000},
472 {56, 0x9100000000000000}, {55, 0xcd80000000000000},
473 {54, 0x0940000000000000}, {53, 0xaf20000000000000},
474 {52, 0xac10000000000000}, {51, 0xe0b8000000000000},
475 {50, 0x9ce4000000000000}, {49, 0xc792000000000000},
476 {48, 0xb8f1000000000000}, {47, 0x3b9f800000000000},
477 {46, 0xdb4c400000000000}, {45, 0xe9a3200000000000},
478 {44, 0xfca6100000000000}, {43, 0x6c8a780000000000},
479 {42, 0x8ce5a40000000000}, {41, 0xcb7d020000000000},
480 {40, 0xcb4dc10000000000}, {39, 0xdfbec58000000000},
481 {38, 0x27a9db4000000000}, {37, 0xde3bcb2000000000},
482 {36, 0xd7e8a61000000000}, {35, 0x9afdbc8800000000},
483 {34, 0x9afdbc8400000000}, {33, 0x9afdbc8200000000},
484 {32, 0x9afdbc8100000000}, {31, 0x0000000080000000},
485 {30, 0x0000000040000000}, {29, 0x0000000020000000},
486 {28, 0x0000000010000000}, {27, 0x00000000a8000000},
487 {26, 0x00000000f4000000}, {25, 0x0000000062000000},
488 {24, 0x0000000091000000}, {23, 0x00000000cd800000},
489 {22, 0x0000000009400000}, {21, 0x00000000af200000},
490 {20, 0x00000000ac100000}, {19, 0x00000000e0b80000},
491 {18, 0x000000009ce40000}, {17, 0x00000000c7920000},
492 {16, 0x00000000b8f10000}, {15, 0x000000003b9f8000},
493 {14, 0x00000000db4c4000}, {13, 0x00000000e9a32000},
494 {12, 0x00000000fca61000}, {11, 0x000000006c8a7800},
495 {10, 0x000000008ce5a400}, {9, 0x00000000cb7d0200},
496 {8, 0x00000000cb4dc100}, {7, 0x00000000dfbec580},
497 {6, 0x0000000027a9db40}, {5, 0x00000000de3bcb20},
498 {4, 0x00000000d7e8a610}, {3, 0x000000009afdbc88},
499 {2, 0x000000009afdbc84}, {1, 0x000000009afdbc82},
500 {0, 0x000000009afdbc81}};
501
502 WasmRunner<int64_t> r(MachineType::Uint64());
503 BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0)));
504 for (size_t i = 0; i < arraysize(values); i++) {
505 CHECK_EQ(values[i].expected, r.Call(values[i].input));
506 }
507}
508
509
510TEST(Run_WasmInt64Popcnt) {
511 struct {
512 int64_t expected;
513 uint64_t input;
514 } values[] = {{64, 0xffffffffffffffff},
515 {0, 0x0000000000000000},
516 {2, 0x0000080000008000},
517 {26, 0x1123456782345678},
518 {38, 0xffedcba09edcba09}};
519
520 WasmRunner<int64_t> r(MachineType::Uint64());
521 BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
522 for (size_t i = 0; i < arraysize(values); i++) {
523 CHECK_EQ(values[i].expected, r.Call(values[i].input));
524 }
525}
526
527
528#endif
529
530TEST(Run_WASM_Int32DivS_trap) {
531 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
532 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
533 CHECK_EQ(0, r.Call(0, 100));
534 CHECK_TRAP(r.Call(100, 0));
535 CHECK_TRAP(r.Call(-1001, 0));
536 CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), -1));
537 CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
538}
539
540
541TEST(Run_WASM_Int32RemS_trap) {
542 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
543 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
544 CHECK_EQ(33, r.Call(133, 100));
545 CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1));
546 CHECK_TRAP(r.Call(100, 0));
547 CHECK_TRAP(r.Call(-1001, 0));
548 CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
549}
550
551
552TEST(Run_WASM_Int32DivU_trap) {
553 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
554 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
555 CHECK_EQ(0, r.Call(0, 100));
556 CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1));
557 CHECK_TRAP(r.Call(100, 0));
558 CHECK_TRAP(r.Call(-1001, 0));
559 CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
560}
561
562
563TEST(Run_WASM_Int32RemU_trap) {
564 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
565 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
566 CHECK_EQ(17, r.Call(217, 100));
567 CHECK_TRAP(r.Call(100, 0));
568 CHECK_TRAP(r.Call(-1001, 0));
569 CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0));
570 CHECK_EQ(std::numeric_limits<int32_t>::min(),
571 r.Call(std::numeric_limits<int32_t>::min(), -1));
572}
573
574
575TEST(Run_WASM_Int32DivS_byzero_const) {
576 for (int8_t denom = -2; denom < 8; denom++) {
577 WasmRunner<int32_t> r(MachineType::Int32());
578 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
579 for (int32_t val = -7; val < 8; val++) {
580 if (denom == 0) {
581 CHECK_TRAP(r.Call(val));
582 } else {
583 CHECK_EQ(val / denom, r.Call(val));
584 }
585 }
586 }
587}
588
589
590TEST(Run_WASM_Int32DivU_byzero_const) {
591 for (uint32_t denom = 0xfffffffe; denom < 8; denom++) {
592 WasmRunner<uint32_t> r(MachineType::Uint32());
593 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32(denom)));
594
595 for (uint32_t val = 0xfffffff0; val < 8; val++) {
596 if (denom == 0) {
597 CHECK_TRAP(r.Call(val));
598 } else {
599 CHECK_EQ(val / denom, r.Call(val));
600 }
601 }
602 }
603}
604
605
606TEST(Run_WASM_Int32DivS_trap_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000607 TestingModule module;
608 module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100609 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610
611 BUILD(r,
612 WASM_IF_ELSE(WASM_GET_LOCAL(0),
613 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
614 WASM_ZERO, WASM_GET_LOCAL(0)),
615 WASM_GET_LOCAL(1)),
616 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
617 WASM_ZERO, WASM_GET_LOCAL(0)),
618 WASM_GET_LOCAL(1))));
619 CHECK_EQ(0, r.Call(0, 100));
620 CHECK_TRAP(r.Call(8, 0));
621 CHECK_TRAP(r.Call(4, 0));
622 CHECK_TRAP(r.Call(0, 0));
623}
624
625
626#if WASM_64
627#define as64(x) static_cast<int64_t>(x)
628TEST(Run_WASM_Int64DivS_trap) {
629 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
630 BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
631 CHECK_EQ(0, r.Call(as64(0), as64(100)));
632 CHECK_TRAP64(r.Call(as64(100), as64(0)));
633 CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
634 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
635 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
636}
637
638
639TEST(Run_WASM_Int64RemS_trap) {
640 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
641 BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
642 CHECK_EQ(33, r.Call(as64(133), as64(100)));
643 CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
644 CHECK_TRAP64(r.Call(as64(100), as64(0)));
645 CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
646 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
647}
648
649
650TEST(Run_WASM_Int64DivU_trap) {
651 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
652 BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
653 CHECK_EQ(0, r.Call(as64(0), as64(100)));
654 CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
655 CHECK_TRAP64(r.Call(as64(100), as64(0)));
656 CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
657 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
658}
659
660
661TEST(Run_WASM_Int64RemU_trap) {
662 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
663 BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
664 CHECK_EQ(17, r.Call(as64(217), as64(100)));
665 CHECK_TRAP64(r.Call(as64(100), as64(0)));
666 CHECK_TRAP64(r.Call(as64(-1001), as64(0)));
667 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0)));
668 CHECK_EQ(std::numeric_limits<int64_t>::min(),
669 r.Call(std::numeric_limits<int64_t>::min(), as64(-1)));
670}
671
672
673TEST(Run_WASM_Int64DivS_byzero_const) {
674 for (int8_t denom = -2; denom < 8; denom++) {
675 WasmRunner<int64_t> r(MachineType::Int64());
676 BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64(denom)));
677 for (int64_t val = -7; val < 8; val++) {
678 if (denom == 0) {
679 CHECK_TRAP64(r.Call(val));
680 } else {
681 CHECK_EQ(val / denom, r.Call(val));
682 }
683 }
684 }
685}
686
687
688TEST(Run_WASM_Int64DivU_byzero_const) {
689 for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) {
690 WasmRunner<uint64_t> r(MachineType::Uint64());
691 BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64(denom)));
692
693 for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) {
694 if (denom == 0) {
695 CHECK_TRAP64(r.Call(val));
696 } else {
697 CHECK_EQ(val / denom, r.Call(val));
698 }
699 }
700 }
701}
702#endif
703
704
705void TestFloat32Binop(WasmOpcode opcode, int32_t expected, float a, float b) {
706 {
707 WasmRunner<int32_t> r;
708 // return K op K
709 BUILD(r, WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b)));
710 CHECK_EQ(expected, r.Call());
711 }
712 {
713 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
714 // return a op b
715 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
716 CHECK_EQ(expected, r.Call(a, b));
717 }
718}
719
720
721void TestFloat32BinopWithConvert(WasmOpcode opcode, int32_t expected, float a,
722 float b) {
723 {
724 WasmRunner<int32_t> r;
725 // return int(K op K)
726 BUILD(r,
727 WASM_I32_SCONVERT_F32(WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b))));
728 CHECK_EQ(expected, r.Call());
729 }
730 {
731 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
732 // return int(a op b)
733 BUILD(r, WASM_I32_SCONVERT_F32(
734 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
735 CHECK_EQ(expected, r.Call(a, b));
736 }
737}
738
739
740void TestFloat32UnopWithConvert(WasmOpcode opcode, int32_t expected, float a) {
741 {
742 WasmRunner<int32_t> r;
743 // return int(op(K))
744 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_F32(a))));
745 CHECK_EQ(expected, r.Call());
746 }
747 {
748 WasmRunner<int32_t> r(MachineType::Float32());
749 // return int(op(a))
750 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
751 CHECK_EQ(expected, r.Call(a));
752 }
753}
754
755
756void TestFloat64Binop(WasmOpcode opcode, int32_t expected, double a, double b) {
757 {
758 WasmRunner<int32_t> r;
759 // return K op K
760 BUILD(r, WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b)));
761 CHECK_EQ(expected, r.Call());
762 }
763 {
764 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
765 // return a op b
766 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
767 CHECK_EQ(expected, r.Call(a, b));
768 }
769}
770
771
772void TestFloat64BinopWithConvert(WasmOpcode opcode, int32_t expected, double a,
773 double b) {
774 {
775 WasmRunner<int32_t> r;
776 // return int(K op K)
777 BUILD(r,
778 WASM_I32_SCONVERT_F64(WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b))));
779 CHECK_EQ(expected, r.Call());
780 }
781 {
782 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
783 BUILD(r, WASM_I32_SCONVERT_F64(
784 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
785 CHECK_EQ(expected, r.Call(a, b));
786 }
787}
788
789
790void TestFloat64UnopWithConvert(WasmOpcode opcode, int32_t expected, double a) {
791 {
792 WasmRunner<int32_t> r;
793 // return int(op(K))
794 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_F64(a))));
795 CHECK_EQ(expected, r.Call());
796 }
797 {
798 WasmRunner<int32_t> r(MachineType::Float64());
799 // return int(op(a))
800 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
801 CHECK_EQ(expected, r.Call(a));
802 }
803}
804
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805TEST(Run_WasmFloat32Binops) {
806 TestFloat32Binop(kExprF32Eq, 1, 8.125f, 8.125f);
807 TestFloat32Binop(kExprF32Ne, 1, 8.125f, 8.127f);
808 TestFloat32Binop(kExprF32Lt, 1, -9.5f, -9.0f);
809 TestFloat32Binop(kExprF32Le, 1, -1111.0f, -1111.0f);
810 TestFloat32Binop(kExprF32Gt, 1, -9.0f, -9.5f);
811 TestFloat32Binop(kExprF32Ge, 1, -1111.0f, -1111.0f);
812
813 TestFloat32BinopWithConvert(kExprF32Add, 10, 3.5f, 6.5f);
814 TestFloat32BinopWithConvert(kExprF32Sub, 2, 44.5f, 42.5f);
815 TestFloat32BinopWithConvert(kExprF32Mul, -66, -132.1f, 0.5f);
816 TestFloat32BinopWithConvert(kExprF32Div, 11, 22.1f, 2.0f);
817}
818
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000819TEST(Run_WasmFloat32Unops) {
820 TestFloat32UnopWithConvert(kExprF32Abs, 8, 8.125f);
821 TestFloat32UnopWithConvert(kExprF32Abs, 9, -9.125f);
822 TestFloat32UnopWithConvert(kExprF32Neg, -213, 213.125f);
823 TestFloat32UnopWithConvert(kExprF32Sqrt, 12, 144.4f);
824}
825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000826TEST(Run_WasmFloat64Binops) {
827 TestFloat64Binop(kExprF64Eq, 1, 16.25, 16.25);
828 TestFloat64Binop(kExprF64Ne, 1, 16.25, 16.15);
829 TestFloat64Binop(kExprF64Lt, 1, -32.4, 11.7);
830 TestFloat64Binop(kExprF64Le, 1, -88.9, -88.9);
831 TestFloat64Binop(kExprF64Gt, 1, 11.7, -32.4);
832 TestFloat64Binop(kExprF64Ge, 1, -88.9, -88.9);
833
834 TestFloat64BinopWithConvert(kExprF64Add, 100, 43.5, 56.5);
835 TestFloat64BinopWithConvert(kExprF64Sub, 200, 12200.1, 12000.1);
836 TestFloat64BinopWithConvert(kExprF64Mul, -33, 134, -0.25);
837 TestFloat64BinopWithConvert(kExprF64Div, -1111, -2222.3, 2);
838}
839
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000840TEST(Run_WasmFloat64Unops) {
841 TestFloat64UnopWithConvert(kExprF64Abs, 108, 108.125);
842 TestFloat64UnopWithConvert(kExprF64Abs, 209, -209.125);
843 TestFloat64UnopWithConvert(kExprF64Neg, -209, 209.125);
844 TestFloat64UnopWithConvert(kExprF64Sqrt, 13, 169.4);
845}
846
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000847TEST(Run_WasmFloat32Neg) {
848 WasmRunner<float> r(MachineType::Float32());
849 BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0)));
850
851 FOR_FLOAT32_INPUTS(i) {
852 CHECK_EQ(0x80000000,
853 bit_cast<uint32_t>(*i) ^ bit_cast<uint32_t>(r.Call(*i)));
854 }
855}
856
857
858TEST(Run_WasmFloat64Neg) {
859 WasmRunner<double> r(MachineType::Float64());
860 BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0)));
861
862 FOR_FLOAT64_INPUTS(i) {
863 CHECK_EQ(0x8000000000000000,
864 bit_cast<uint64_t>(*i) ^ bit_cast<uint64_t>(r.Call(*i)));
865 }
866}
867
868
869TEST(Run_Wasm_IfElse_P) {
870 WasmRunner<int32_t> r(MachineType::Int32());
871 // if (p0) return 11; else return 22;
872 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
873 WASM_I8(11), // --
874 WASM_I8(22))); // --
875 FOR_INT32_INPUTS(i) {
876 int32_t expected = *i ? 11 : 22;
877 CHECK_EQ(expected, r.Call(*i));
878 }
879}
880
881
882TEST(Run_Wasm_IfElse_Unreachable1) {
883 WasmRunner<int32_t> r;
884 // if (0) unreachable; else return 22;
885 BUILD(r, WASM_IF_ELSE(WASM_ZERO, // --
886 WASM_UNREACHABLE, // --
887 WASM_I8(27))); // --
888 CHECK_EQ(27, r.Call());
889}
890
891
892TEST(Run_Wasm_Return12) {
893 WasmRunner<int32_t> r;
894
895 BUILD(r, WASM_RETURN(WASM_I8(12)));
896 CHECK_EQ(12, r.Call());
897}
898
899
900TEST(Run_Wasm_Return17) {
901 WasmRunner<int32_t> r;
902
903 BUILD(r, WASM_BLOCK(1, WASM_RETURN(WASM_I8(17))));
904 CHECK_EQ(17, r.Call());
905}
906
907
908TEST(Run_Wasm_Return_I32) {
909 WasmRunner<int32_t> r(MachineType::Int32());
910
911 BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
912
913 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
914}
915
916
917#if WASM_64
918TEST(Run_Wasm_Return_I64) {
919 WasmRunner<int64_t> r(MachineType::Int64());
920
921 BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
922
923 FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
924}
925#endif
926
927
928TEST(Run_Wasm_Return_F32) {
929 WasmRunner<float> r(MachineType::Float32());
930
931 BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
932
933 FOR_FLOAT32_INPUTS(i) {
934 float expect = *i;
935 float result = r.Call(expect);
936 if (std::isnan(expect)) {
937 CHECK(std::isnan(result));
938 } else {
939 CHECK_EQ(expect, result);
940 }
941 }
942}
943
944
945TEST(Run_Wasm_Return_F64) {
946 WasmRunner<double> r(MachineType::Float64());
947
948 BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0)));
949
950 FOR_FLOAT64_INPUTS(i) {
951 double expect = *i;
952 double result = r.Call(expect);
953 if (std::isnan(expect)) {
954 CHECK(std::isnan(result));
955 } else {
956 CHECK_EQ(expect, result);
957 }
958 }
959}
960
961
962TEST(Run_Wasm_Select) {
963 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100964 // return select(11, 22, a);
965 BUILD(r, WASM_SELECT(WASM_I8(11), WASM_I8(22), WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 FOR_INT32_INPUTS(i) {
967 int32_t expected = *i ? 11 : 22;
968 CHECK_EQ(expected, r.Call(*i));
969 }
970}
971
972
973TEST(Run_Wasm_Select_strict1) {
974 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100975 // select(a=0, a=1, a=2); return a
976 BUILD(r, WASM_BLOCK(2, WASM_SELECT(WASM_SET_LOCAL(0, WASM_I8(0)),
977 WASM_SET_LOCAL(0, WASM_I8(1)),
978 WASM_SET_LOCAL(0, WASM_I8(2))),
979 WASM_GET_LOCAL(0)));
980 FOR_INT32_INPUTS(i) { CHECK_EQ(2, r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000981}
982
983
984TEST(Run_Wasm_Select_strict2) {
985 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100986 r.env()->AddLocals(kAstI32, 2);
987 // select(b=5, c=6, a)
988 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
989 WASM_SET_LOCAL(2, WASM_I8(6)), WASM_GET_LOCAL(0)));
990 FOR_INT32_INPUTS(i) {
991 int32_t expected = *i ? 5 : 6;
992 CHECK_EQ(expected, r.Call(*i));
993 }
994}
995
996TEST(Run_Wasm_Select_strict3) {
997 WasmRunner<int32_t> r(MachineType::Int32());
998 r.env()->AddLocals(kAstI32, 2);
999 // select(b=5, c=6, a=b)
1000 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
1001 WASM_SET_LOCAL(2, WASM_I8(6)),
1002 WASM_SET_LOCAL(0, WASM_GET_LOCAL(1))));
1003 FOR_INT32_INPUTS(i) {
1004 int32_t expected = 5;
1005 CHECK_EQ(expected, r.Call(*i));
1006 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001007}
1008
1009
1010TEST(Run_Wasm_BrIf_strict) {
1011 WasmRunner<int32_t> r(MachineType::Int32());
1012 BUILD(r, WASM_BLOCK(
1013 2, WASM_BLOCK(1, WASM_BRV_IF(0, WASM_GET_LOCAL(0),
1014 WASM_SET_LOCAL(0, WASM_I8(99)))),
1015 WASM_GET_LOCAL(0)));
1016
1017 FOR_INT32_INPUTS(i) { CHECK_EQ(99, r.Call(*i)); }
1018}
1019
Ben Murdoch097c5b22016-05-18 11:27:45 +01001020TEST(Run_Wasm_TableSwitch0a) {
1021 WasmRunner<int32_t> r(MachineType::Int32());
1022 BUILD(r, WASM_BLOCK(2, WASM_TABLESWITCH_OP(0, 1, WASM_CASE_BR(0)),
1023 WASM_TABLESWITCH_BODY0(WASM_GET_LOCAL(0)), WASM_I8(91)));
1024 FOR_INT32_INPUTS(i) { CHECK_EQ(91, r.Call(*i)); }
1025}
1026
1027TEST(Run_Wasm_TableSwitch0b) {
1028 WasmRunner<int32_t> r(MachineType::Int32());
1029 BUILD(r, WASM_BLOCK(
1030 2, WASM_TABLESWITCH_OP(0, 2, WASM_CASE_BR(0), WASM_CASE_BR(0)),
1031 WASM_TABLESWITCH_BODY0(WASM_GET_LOCAL(0)), WASM_I8(92)));
1032 FOR_INT32_INPUTS(i) { CHECK_EQ(92, r.Call(*i)); }
1033}
1034
1035TEST(Run_Wasm_TableSwitch0c) {
1036 WasmRunner<int32_t> r(MachineType::Int32());
1037 BUILD(r,
1038 WASM_BLOCK(2, WASM_BLOCK(2, WASM_TABLESWITCH_OP(0, 2, WASM_CASE_BR(0),
1039 WASM_CASE_BR(1)),
1040 WASM_TABLESWITCH_BODY0(WASM_GET_LOCAL(0)),
1041 WASM_RETURN(WASM_I8(76))),
1042 WASM_I8(77)));
1043 FOR_INT32_INPUTS(i) {
1044 int32_t expected = *i == 0 ? 76 : 77;
1045 CHECK_EQ(expected, r.Call(*i));
1046 }
1047}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001048
1049TEST(Run_Wasm_TableSwitch1) {
1050 WasmRunner<int32_t> r(MachineType::Int32());
1051 BUILD(r, WASM_TABLESWITCH_OP(1, 1, WASM_CASE(0)),
1052 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(93))));
1053 FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); }
1054}
1055
1056
1057TEST(Run_Wasm_TableSwitch_br) {
1058 WasmRunner<int32_t> r(MachineType::Int32());
1059 BUILD(r, WASM_TABLESWITCH_OP(1, 2, WASM_CASE_BR(0), WASM_CASE(0)),
1060 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91))),
1061 WASM_I8(99));
1062 CHECK_EQ(99, r.Call(0));
1063 CHECK_EQ(91, r.Call(1));
1064 CHECK_EQ(91, r.Call(2));
1065 CHECK_EQ(91, r.Call(3));
1066}
1067
1068
1069TEST(Run_Wasm_TableSwitch_br2) {
1070 WasmRunner<int32_t> r(MachineType::Int32());
1071 BUILD(r, WASM_BLOCK(
1072 2, WASM_BLOCK(2, WASM_TABLESWITCH_OP(
1073 1, 4, WASM_CASE_BR(0), WASM_CASE_BR(1),
1074 WASM_CASE_BR(2), WASM_CASE(0)),
1075 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0),
1076 WASM_RETURN(WASM_I8(85))),
1077 WASM_RETURN(WASM_I8(86))),
1078 WASM_RETURN(WASM_I8(87))),
1079 WASM_I8(88));
1080 CHECK_EQ(86, r.Call(0));
1081 CHECK_EQ(87, r.Call(1));
1082 CHECK_EQ(88, r.Call(2));
1083 CHECK_EQ(85, r.Call(3));
1084 CHECK_EQ(85, r.Call(4));
1085 CHECK_EQ(85, r.Call(5));
1086}
1087
1088
1089TEST(Run_Wasm_TableSwitch2) {
1090 WasmRunner<int32_t> r(MachineType::Int32());
1091 BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(0), WASM_CASE(1)),
1092 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91)),
1093 WASM_RETURN(WASM_I8(92))));
1094 FOR_INT32_INPUTS(i) {
1095 int32_t expected = *i == 0 ? 91 : 92;
1096 CHECK_EQ(expected, r.Call(*i));
1097 }
1098}
1099
1100
1101TEST(Run_Wasm_TableSwitch2b) {
1102 WasmRunner<int32_t> r(MachineType::Int32());
1103 BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(1), WASM_CASE(0)),
1104 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(81)),
1105 WASM_RETURN(WASM_I8(82))));
1106 FOR_INT32_INPUTS(i) {
1107 int32_t expected = *i == 0 ? 82 : 81;
1108 CHECK_EQ(expected, r.Call(*i));
1109 }
1110}
1111
1112
1113TEST(Run_Wasm_TableSwitch4) {
1114 for (int i = 0; i < 4; i++) {
1115 const uint16_t br = 0x8000u;
1116 uint16_t c = 0;
1117 uint16_t cases[] = {i == 0 ? br : c++, i == 1 ? br : c++, i == 2 ? br : c++,
1118 i == 3 ? br : c++};
1119 byte code[] = {
1120 WASM_BLOCK(1, WASM_TABLESWITCH_OP(
1121 3, 4, WASM_CASE(cases[0]), WASM_CASE(cases[1]),
1122 WASM_CASE(cases[2]), WASM_CASE(cases[3])),
1123 WASM_TABLESWITCH_BODY(
1124 WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(71)),
1125 WASM_RETURN(WASM_I8(72)), WASM_RETURN(WASM_I8(73)))),
1126 WASM_RETURN(WASM_I8(74))};
1127
1128 WasmRunner<int32_t> r(MachineType::Int32());
1129 r.Build(code, code + arraysize(code));
1130
1131 FOR_INT32_INPUTS(i) {
1132 int index = (*i < 0 || *i > 3) ? 3 : *i;
1133 int32_t expected = 71 + cases[index];
1134 if (expected >= 0x8000) expected = 74;
1135 CHECK_EQ(expected, r.Call(*i));
1136 }
1137 }
1138}
1139
1140
1141TEST(Run_Wasm_TableSwitch4b) {
1142 for (int a = 0; a < 2; a++) {
1143 for (int b = 0; b < 2; b++) {
1144 for (int c = 0; c < 2; c++) {
1145 for (int d = 0; d < 2; d++) {
1146 if (a + b + c + d == 0) continue;
1147 if (a + b + c + d == 4) continue;
1148
1149 byte code[] = {
1150 WASM_TABLESWITCH_OP(2, 4, WASM_CASE(a), WASM_CASE(b),
1151 WASM_CASE(c), WASM_CASE(d)),
1152 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(61)),
1153 WASM_RETURN(WASM_I8(62)))};
1154
1155 WasmRunner<int32_t> r(MachineType::Int32());
1156 r.Build(code, code + arraysize(code));
1157
1158 CHECK_EQ(61 + a, r.Call(0));
1159 CHECK_EQ(61 + b, r.Call(1));
1160 CHECK_EQ(61 + c, r.Call(2));
1161 CHECK_EQ(61 + d, r.Call(3));
1162 CHECK_EQ(61 + d, r.Call(4));
1163 }
1164 }
1165 }
1166 }
1167}
1168
1169
1170TEST(Run_Wasm_TableSwitch4_fallthru) {
1171 byte code[] = {
1172 WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2),
1173 WASM_CASE(3)),
1174 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1),
1175 WASM_INC_LOCAL_BY(1, 2), WASM_INC_LOCAL_BY(1, 4),
1176 WASM_INC_LOCAL_BY(1, 8)),
1177 WASM_GET_LOCAL(1)};
1178
1179 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
1180 r.Build(code, code + arraysize(code));
1181
1182 CHECK_EQ(15, r.Call(0, 0));
1183 CHECK_EQ(14, r.Call(1, 0));
1184 CHECK_EQ(12, r.Call(2, 0));
1185 CHECK_EQ(8, r.Call(3, 0));
1186 CHECK_EQ(8, r.Call(4, 0));
1187
1188 CHECK_EQ(115, r.Call(0, 100));
1189 CHECK_EQ(114, r.Call(1, 100));
1190 CHECK_EQ(112, r.Call(2, 100));
1191 CHECK_EQ(108, r.Call(3, 100));
1192 CHECK_EQ(108, r.Call(4, 100));
1193}
1194
1195
1196TEST(Run_Wasm_TableSwitch4_fallthru_br) {
1197 byte code[] = {
1198 WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2),
1199 WASM_CASE(3)),
1200 WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1),
1201 WASM_BRV(0, WASM_INC_LOCAL_BY(1, 2)),
1202 WASM_INC_LOCAL_BY(1, 4),
1203 WASM_BRV(0, WASM_INC_LOCAL_BY(1, 8))),
1204 WASM_GET_LOCAL(1)};
1205
1206 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
1207 r.Build(code, code + arraysize(code));
1208
1209 CHECK_EQ(3, r.Call(0, 0));
1210 CHECK_EQ(2, r.Call(1, 0));
1211 CHECK_EQ(12, r.Call(2, 0));
1212 CHECK_EQ(8, r.Call(3, 0));
1213 CHECK_EQ(8, r.Call(4, 0));
1214
1215 CHECK_EQ(203, r.Call(0, 200));
1216 CHECK_EQ(202, r.Call(1, 200));
1217 CHECK_EQ(212, r.Call(2, 200));
1218 CHECK_EQ(208, r.Call(3, 200));
1219 CHECK_EQ(208, r.Call(4, 200));
1220}
1221
1222
1223TEST(Run_Wasm_F32ReinterpretI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224 TestingModule module;
1225 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227
1228 BUILD(r, WASM_I32_REINTERPRET_F32(
1229 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
1230
1231 FOR_INT32_INPUTS(i) {
1232 int32_t expected = *i;
1233 memory[0] = expected;
1234 CHECK_EQ(expected, r.Call());
1235 }
1236}
1237
1238
1239TEST(Run_Wasm_I32ReinterpretF32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001240 TestingModule module;
1241 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001242 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001243
1244 BUILD(r, WASM_BLOCK(
1245 2, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
1246 WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))),
1247 WASM_I8(107)));
1248
1249 FOR_INT32_INPUTS(i) {
1250 int32_t expected = *i;
1251 CHECK_EQ(107, r.Call(expected));
1252 CHECK_EQ(expected, memory[0]);
1253 }
1254}
1255
1256
1257TEST(Run_Wasm_ReturnStore) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258 TestingModule module;
1259 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001260 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001261
1262 BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
1263 WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
1264
1265 FOR_INT32_INPUTS(i) {
1266 int32_t expected = *i;
1267 memory[0] = expected;
1268 CHECK_EQ(expected, r.Call());
1269 }
1270}
1271
1272
1273TEST(Run_Wasm_VoidReturn1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001274 // We use a wrapper function because WasmRunner<void> does not exist.
1275
1276 // Build the test function.
1277 TestSignatures sigs;
1278 TestingModule module;
1279 WasmFunctionCompiler t(sigs.v_v(), &module);
1280 BUILD(t, kExprNop);
1281 uint32_t index = t.CompileAndAdd();
1282
1283 const int32_t kExpected = -414444;
1284 // Build the calling function.
1285 WasmRunner<int32_t> r;
1286 r.env()->module = &module;
1287 BUILD(r, WASM_BLOCK(2, WASM_CALL_FUNCTION0(index), WASM_I32(kExpected)));
1288
1289 int32_t result = r.Call();
1290 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291}
1292
1293
1294TEST(Run_Wasm_VoidReturn2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001295 // We use a wrapper function because WasmRunner<void> does not exist.
1296 // Build the test function.
1297 TestSignatures sigs;
1298 TestingModule module;
1299 WasmFunctionCompiler t(sigs.v_v(), &module);
1300 BUILD(t, WASM_RETURN0);
1301 uint32_t index = t.CompileAndAdd();
1302
1303 const int32_t kExpected = -414444;
1304 // Build the calling function.
1305 WasmRunner<int32_t> r;
1306 r.env()->module = &module;
1307 BUILD(r, WASM_BLOCK(2, WASM_CALL_FUNCTION0(index), WASM_I32(kExpected)));
1308
1309 int32_t result = r.Call();
1310 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001311}
1312
1313
1314TEST(Run_Wasm_Block_If_P) {
1315 WasmRunner<int32_t> r(MachineType::Int32());
1316 // { if (p0) return 51; return 52; }
1317 BUILD(r, WASM_BLOCK(2, // --
1318 WASM_IF(WASM_GET_LOCAL(0), // --
1319 WASM_BRV(0, WASM_I8(51))), // --
1320 WASM_I8(52))); // --
1321 FOR_INT32_INPUTS(i) {
1322 int32_t expected = *i ? 51 : 52;
1323 CHECK_EQ(expected, r.Call(*i));
1324 }
1325}
1326
1327
1328TEST(Run_Wasm_Block_BrIf_P) {
1329 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001330 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_I8(51), WASM_GET_LOCAL(0)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001331 WASM_I8(52)));
1332 FOR_INT32_INPUTS(i) {
1333 int32_t expected = *i ? 51 : 52;
1334 CHECK_EQ(expected, r.Call(*i));
1335 }
1336}
1337
1338
1339TEST(Run_Wasm_Block_IfElse_P_assign) {
1340 WasmRunner<int32_t> r(MachineType::Int32());
1341 // { if (p0) p0 = 71; else p0 = 72; return p0; }
1342 BUILD(r, WASM_BLOCK(2, // --
1343 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1344 WASM_SET_LOCAL(0, WASM_I8(71)), // --
1345 WASM_SET_LOCAL(0, WASM_I8(72))), // --
1346 WASM_GET_LOCAL(0)));
1347 FOR_INT32_INPUTS(i) {
1348 int32_t expected = *i ? 71 : 72;
1349 CHECK_EQ(expected, r.Call(*i));
1350 }
1351}
1352
1353
1354TEST(Run_Wasm_Block_IfElse_P_return) {
1355 WasmRunner<int32_t> r(MachineType::Int32());
1356 // if (p0) return 81; else return 82;
1357 BUILD(r, // --
1358 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1359 WASM_RETURN(WASM_I8(81)), // --
1360 WASM_RETURN(WASM_I8(82)))); // --
1361 FOR_INT32_INPUTS(i) {
1362 int32_t expected = *i ? 81 : 82;
1363 CHECK_EQ(expected, r.Call(*i));
1364 }
1365}
1366
1367
1368TEST(Run_Wasm_Block_If_P_assign) {
1369 WasmRunner<int32_t> r(MachineType::Int32());
1370 // { if (p0) p0 = 61; p0; }
1371 BUILD(r, WASM_BLOCK(
1372 2, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))),
1373 WASM_GET_LOCAL(0)));
1374 FOR_INT32_INPUTS(i) {
1375 int32_t expected = *i ? 61 : *i;
1376 CHECK_EQ(expected, r.Call(*i));
1377 }
1378}
1379
1380
1381TEST(Run_Wasm_DanglingAssign) {
1382 WasmRunner<int32_t> r(MachineType::Int32());
1383 // { return 0; p0 = 0; }
1384 BUILD(r,
1385 WASM_BLOCK(2, WASM_RETURN(WASM_I8(99)), WASM_SET_LOCAL(0, WASM_ZERO)));
1386 CHECK_EQ(99, r.Call(1));
1387}
1388
1389
1390TEST(Run_Wasm_ExprIf_P) {
1391 WasmRunner<int32_t> r(MachineType::Int32());
1392 // p0 ? 11 : 22;
1393 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1394 WASM_I8(11), // --
1395 WASM_I8(22))); // --
1396 FOR_INT32_INPUTS(i) {
1397 int32_t expected = *i ? 11 : 22;
1398 CHECK_EQ(expected, r.Call(*i));
1399 }
1400}
1401
1402
1403TEST(Run_Wasm_ExprIf_P_fallthru) {
1404 WasmRunner<int32_t> r(MachineType::Int32());
1405 // p0 ? 11 : 22;
1406 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1407 WASM_I8(11), // --
1408 WASM_I8(22))); // --
1409 FOR_INT32_INPUTS(i) {
1410 int32_t expected = *i ? 11 : 22;
1411 CHECK_EQ(expected, r.Call(*i));
1412 }
1413}
1414
1415
1416TEST(Run_Wasm_CountDown) {
1417 WasmRunner<int32_t> r(MachineType::Int32());
1418 BUILD(r,
1419 WASM_BLOCK(
1420 2, WASM_LOOP(
1421 1, WASM_IF(WASM_GET_LOCAL(0),
1422 WASM_BRV(0, WASM_SET_LOCAL(
1423 0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1424 WASM_I8(1)))))),
1425 WASM_GET_LOCAL(0)));
1426 CHECK_EQ(0, r.Call(1));
1427 CHECK_EQ(0, r.Call(10));
1428 CHECK_EQ(0, r.Call(100));
1429}
1430
1431
1432TEST(Run_Wasm_CountDown_fallthru) {
1433 WasmRunner<int32_t> r(MachineType::Int32());
1434 BUILD(r,
1435 WASM_BLOCK(
1436 2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(0)),
1437 WASM_SET_LOCAL(
1438 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
1439 WASM_CONTINUE(0)),
1440 WASM_GET_LOCAL(0)));
1441 CHECK_EQ(0, r.Call(1));
1442 CHECK_EQ(0, r.Call(10));
1443 CHECK_EQ(0, r.Call(100));
1444}
1445
1446
1447TEST(Run_Wasm_WhileCountDown) {
1448 WasmRunner<int32_t> r(MachineType::Int32());
1449 BUILD(r, WASM_BLOCK(
1450 2, WASM_WHILE(WASM_GET_LOCAL(0),
1451 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1452 WASM_I8(1)))),
1453 WASM_GET_LOCAL(0)));
1454 CHECK_EQ(0, r.Call(1));
1455 CHECK_EQ(0, r.Call(10));
1456 CHECK_EQ(0, r.Call(100));
1457}
1458
1459
1460TEST(Run_Wasm_Loop_if_break1) {
1461 WasmRunner<int32_t> r(MachineType::Int32());
1462 BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(0)),
1463 WASM_SET_LOCAL(0, WASM_I8(99))),
1464 WASM_GET_LOCAL(0)));
1465 CHECK_EQ(99, r.Call(0));
1466 CHECK_EQ(3, r.Call(3));
1467 CHECK_EQ(10000, r.Call(10000));
1468 CHECK_EQ(-29, r.Call(-29));
1469}
1470
1471
1472TEST(Run_Wasm_Loop_if_break2) {
1473 WasmRunner<int32_t> r(MachineType::Int32());
1474 BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_BR_IF(1, WASM_GET_LOCAL(0)),
1475 WASM_SET_LOCAL(0, WASM_I8(99))),
1476 WASM_GET_LOCAL(0)));
1477 CHECK_EQ(99, r.Call(0));
1478 CHECK_EQ(3, r.Call(3));
1479 CHECK_EQ(10000, r.Call(10000));
1480 CHECK_EQ(-29, r.Call(-29));
1481}
1482
1483
1484TEST(Run_Wasm_Loop_if_break_fallthru) {
1485 WasmRunner<int32_t> r(MachineType::Int32());
1486 BUILD(r, WASM_BLOCK(1, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
1487 WASM_SET_LOCAL(0, WASM_I8(93)))),
1488 WASM_GET_LOCAL(0));
1489 CHECK_EQ(93, r.Call(0));
1490 CHECK_EQ(3, r.Call(3));
1491 CHECK_EQ(10001, r.Call(10001));
1492 CHECK_EQ(-22, r.Call(-22));
1493}
1494
1495
1496TEST(Run_Wasm_LoadMemI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001497 TestingModule module;
1498 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001499 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001500 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001501
1502 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0)));
1503
1504 memory[0] = 99999999;
1505 CHECK_EQ(99999999, r.Call(0));
1506
1507 memory[0] = 88888888;
1508 CHECK_EQ(88888888, r.Call(0));
1509
1510 memory[0] = 77777777;
1511 CHECK_EQ(77777777, r.Call(0));
1512}
1513
1514
1515TEST(Run_Wasm_LoadMemI32_oob) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001516 TestingModule module;
1517 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001518 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001519 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001520
1521 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1522
1523 memory[0] = 88888888;
1524 CHECK_EQ(88888888, r.Call(0u));
1525 for (uint32_t offset = 29; offset < 40; offset++) {
1526 CHECK_TRAP(r.Call(offset));
1527 }
1528
1529 for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
1530 CHECK_TRAP(r.Call(offset));
1531 }
1532}
1533
1534
1535TEST(Run_Wasm_LoadMemI32_oob_asm) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001536 TestingModule module;
1537 module.asm_js = true;
1538 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001539 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001540 module.RandomizeMemory(1112);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001541
1542 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1543
1544 memory[0] = 999999;
1545 CHECK_EQ(999999, r.Call(0u));
1546 // TODO(titzer): offset 29-31 should also be OOB.
1547 for (uint32_t offset = 32; offset < 40; offset++) {
1548 CHECK_EQ(0, r.Call(offset));
1549 }
1550
1551 for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
1552 CHECK_EQ(0, r.Call(offset));
1553 }
1554}
1555
1556
1557TEST(Run_Wasm_LoadMem_offset_oob) {
1558 TestingModule module;
1559 module.AddMemoryElems<int32_t>(8);
1560
1561 static const MachineType machineTypes[] = {
1562 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1563 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1564 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1565 MachineType::Float64()};
1566
1567 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1568 module.RandomizeMemory(1116 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001569 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001570 uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]);
1571
1572 BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)),
1573 WASM_ZERO);
1574
1575 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1576
1577 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1578 CHECK_TRAP(r.Call(offset)); // out of bounds.
1579 }
1580 }
1581}
1582
1583
1584TEST(Run_Wasm_LoadMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001585 TestingModule module;
1586 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001587 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001588 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001589
1590 BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0)));
1591
1592 memory[0] = 66666666;
1593 memory[1] = 77777777;
1594 memory[2] = 88888888;
1595 memory[3] = 99999999;
1596 CHECK_EQ(77777777, r.Call(0));
1597 CHECK_EQ(88888888, r.Call(4));
1598 CHECK_EQ(99999999, r.Call(8));
1599
1600 memory[0] = 11111111;
1601 memory[1] = 22222222;
1602 memory[2] = 33333333;
1603 memory[3] = 44444444;
1604 CHECK_EQ(22222222, r.Call(0));
1605 CHECK_EQ(33333333, r.Call(4));
1606 CHECK_EQ(44444444, r.Call(8));
1607}
1608
1609
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001610#if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
1611
Ben Murdoch097c5b22016-05-18 11:27:45 +01001612TEST(Run_Wasm_LoadMemI32_const_oob_misaligned) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001613 const int kMemSize = 12;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001614 // TODO(titzer): Fix misaligned accesses on MIPS and re-enable.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001615 for (int offset = 0; offset < kMemSize + 5; offset++) {
1616 for (int index = 0; index < kMemSize + 5; index++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001617 TestingModule module;
1618 module.AddMemoryElems<byte>(kMemSize);
1619
1620 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001621 module.RandomizeMemory();
1622
1623 BUILD(r,
1624 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1625
1626 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1627 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1628 } else {
1629 CHECK_TRAP(r.Call());
1630 }
1631 }
1632 }
1633}
1634
1635#endif
1636
1637
Ben Murdoch097c5b22016-05-18 11:27:45 +01001638TEST(Run_Wasm_LoadMemI32_const_oob) {
1639 const int kMemSize = 24;
1640 for (int offset = 0; offset < kMemSize + 5; offset += 4) {
1641 for (int index = 0; index < kMemSize + 5; index += 4) {
1642 TestingModule module;
1643 module.AddMemoryElems<byte>(kMemSize);
1644
1645 WasmRunner<int32_t> r(&module);
1646 module.RandomizeMemory();
1647
1648 BUILD(r,
1649 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1650
1651 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1652 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1653 } else {
1654 CHECK_TRAP(r.Call());
1655 }
1656 }
1657 }
1658}
1659
1660
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001661TEST(Run_Wasm_StoreMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001662 TestingModule module;
1663 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001664 WasmRunner<int32_t> r(&module, MachineType::Int32());
1665 const int32_t kWritten = 0xaabbccdd;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001666
1667 BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0),
1668 WASM_I32(kWritten)));
1669
1670 for (int i = 0; i < 2; i++) {
1671 module.RandomizeMemory(1111);
1672 memory[0] = 66666666;
1673 memory[1] = 77777777;
1674 memory[2] = 88888888;
1675 memory[3] = 99999999;
1676 CHECK_EQ(kWritten, r.Call(i * 4));
1677 CHECK_EQ(66666666, memory[0]);
1678 CHECK_EQ(i == 0 ? kWritten : 77777777, memory[1]);
1679 CHECK_EQ(i == 1 ? kWritten : 88888888, memory[2]);
1680 CHECK_EQ(i == 2 ? kWritten : 99999999, memory[3]);
1681 }
1682}
1683
1684
1685TEST(Run_Wasm_StoreMem_offset_oob) {
1686 TestingModule module;
1687 byte* memory = module.AddMemoryElems<byte>(32);
1688
1689#if WASM_64
1690 static const MachineType machineTypes[] = {
1691 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1692 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1693 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1694 MachineType::Float64()};
1695#else
1696 static const MachineType machineTypes[] = {
1697 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1698 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1699 MachineType::Float32(), MachineType::Float64()};
1700#endif
1701
1702 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1703 module.RandomizeMemory(1119 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001704 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001705
1706 BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
1707 WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
1708 WASM_ZERO);
1709
1710 byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
1711 uint32_t boundary = 24 - memsize;
1712 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1713 CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
1714
1715 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1716 CHECK_TRAP(r.Call(offset)); // out of bounds.
1717 }
1718 }
1719}
1720
1721
1722#if WASM_64
1723TEST(Run_Wasm_F64ReinterpretI64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001724 TestingModule module;
1725 int64_t* memory = module.AddMemoryElems<int64_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001726 WasmRunner<int64_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001727
1728 BUILD(r, WASM_I64_REINTERPRET_F64(
1729 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)));
1730
1731 FOR_INT32_INPUTS(i) {
1732 int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
1733 memory[0] = expected;
1734 CHECK_EQ(expected, r.Call());
1735 }
1736}
1737
1738
1739TEST(Run_Wasm_I64ReinterpretF64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001740 TestingModule module;
1741 int64_t* memory = module.AddMemoryElems<int64_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001742 WasmRunner<int64_t> r(&module, MachineType::Int64());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001743
1744 BUILD(r, WASM_BLOCK(
1745 2, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO,
1746 WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))),
1747 WASM_GET_LOCAL(0)));
1748
1749 FOR_INT32_INPUTS(i) {
1750 int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
1751 CHECK_EQ(expected, r.Call(expected));
1752 CHECK_EQ(expected, memory[0]);
1753 }
1754}
1755
1756
1757TEST(Run_Wasm_LoadMemI64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001758 TestingModule module;
1759 int64_t* memory = module.AddMemoryElems<int64_t>(8);
1760 module.RandomizeMemory(1111);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001761 WasmRunner<int64_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001762
1763 BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0)));
1764
1765 memory[0] = 0xaabbccdd00112233LL;
1766 CHECK_EQ(0xaabbccdd00112233LL, r.Call());
1767
1768 memory[0] = 0x33aabbccdd001122LL;
1769 CHECK_EQ(0x33aabbccdd001122LL, r.Call());
1770
1771 memory[0] = 77777777;
1772 CHECK_EQ(77777777, r.Call());
1773}
1774#endif
1775
1776
1777TEST(Run_Wasm_LoadMemI32_P) {
1778 const int kNumElems = 8;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001779 TestingModule module;
1780 int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001781 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001782 module.RandomizeMemory(2222);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783
1784 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1785
1786 for (int i = 0; i < kNumElems; i++) {
1787 CHECK_EQ(memory[i], r.Call(i * 4));
1788 }
1789}
1790
1791
1792TEST(Run_Wasm_MemI32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001793 const int kNumElems = 20;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001794 TestingModule module;
1795 uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001796 WasmRunner<uint32_t> r(&module, MachineType::Int32());
1797 const byte kSum = r.AllocateLocal(kAstI32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798
1799 BUILD(r, WASM_BLOCK(
1800 2, WASM_WHILE(
1801 WASM_GET_LOCAL(0),
1802 WASM_BLOCK(
1803 2, WASM_SET_LOCAL(
1804 kSum, WASM_I32_ADD(
1805 WASM_GET_LOCAL(kSum),
1806 WASM_LOAD_MEM(MachineType::Int32(),
1807 WASM_GET_LOCAL(0)))),
1808 WASM_SET_LOCAL(
1809 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1810 WASM_GET_LOCAL(1)));
1811
1812 // Run 4 trials.
1813 for (int i = 0; i < 3; i++) {
1814 module.RandomizeMemory(i * 33);
1815 uint32_t expected = 0;
1816 for (size_t j = kNumElems - 1; j > 0; j--) {
1817 expected += memory[j];
1818 }
1819 uint32_t result = r.Call(static_cast<int>(4 * (kNumElems - 1)));
1820 CHECK_EQ(expected, result);
1821 }
1822}
1823
1824
1825TEST(Run_Wasm_CheckMachIntsZero) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001826 const int kNumElems = 55;
1827 TestingModule module;
1828 module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001829 WasmRunner<uint32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001830
1831 BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0,
1832 kExprIfElse, kExprI32LoadMem, 0, kExprGetLocal, 0, kExprBr, 2,
1833 kExprI8Const, 255, kExprSetLocal, 0, kExprI32Sub, kExprGetLocal, 0,
1834 kExprI8Const, 4, kExprI8Const, 0);
1835
1836 module.BlankMemory();
1837 CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
1838}
1839
1840
1841TEST(Run_Wasm_MemF32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001842 const int kSize = 5;
1843 TestingModule module;
1844 module.AddMemoryElems<float>(kSize);
1845 float* buffer = module.raw_mem_start<float>();
1846 buffer[0] = -99.25;
1847 buffer[1] = -888.25;
1848 buffer[2] = -77.25;
1849 buffer[3] = 66666.25;
1850 buffer[4] = 5555.25;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001851 WasmRunner<int32_t> r(&module, MachineType::Int32());
1852 const byte kSum = r.AllocateLocal(kAstF32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001853
1854 BUILD(r, WASM_BLOCK(
1855 3, WASM_WHILE(
1856 WASM_GET_LOCAL(0),
1857 WASM_BLOCK(
1858 2, WASM_SET_LOCAL(
1859 kSum, WASM_F32_ADD(
1860 WASM_GET_LOCAL(kSum),
1861 WASM_LOAD_MEM(MachineType::Float32(),
1862 WASM_GET_LOCAL(0)))),
1863 WASM_SET_LOCAL(
1864 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1865 WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
1866 WASM_GET_LOCAL(kSum)),
1867 WASM_GET_LOCAL(0)));
1868
1869 CHECK_EQ(0, r.Call(4 * (kSize - 1)));
1870 CHECK_NE(-99.25, buffer[0]);
1871 CHECK_EQ(71256.0f, buffer[0]);
1872}
1873
1874
1875#if WASM_64
1876TEST(Run_Wasm_MemI64_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001877 const int kNumElems = 20;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001878 TestingModule module;
1879 uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001880 WasmRunner<uint64_t> r(&module, MachineType::Int32());
1881 const byte kSum = r.AllocateLocal(kAstI64);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001882
1883 BUILD(r, WASM_BLOCK(
1884 2, WASM_WHILE(
1885 WASM_GET_LOCAL(0),
1886 WASM_BLOCK(
1887 2, WASM_SET_LOCAL(
1888 kSum, WASM_I64_ADD(
1889 WASM_GET_LOCAL(kSum),
1890 WASM_LOAD_MEM(MachineType::Int64(),
1891 WASM_GET_LOCAL(0)))),
1892 WASM_SET_LOCAL(
1893 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))),
1894 WASM_GET_LOCAL(1)));
1895
1896 // Run 4 trials.
1897 for (int i = 0; i < 3; i++) {
1898 module.RandomizeMemory(i * 33);
1899 uint64_t expected = 0;
1900 for (size_t j = kNumElems - 1; j > 0; j--) {
1901 expected += memory[j];
1902 }
1903 uint64_t result = r.Call(8 * (kNumElems - 1));
1904 CHECK_EQ(expected, result);
1905 }
1906}
1907#endif
1908
1909
1910template <typename T>
1911T GenerateAndRunFold(WasmOpcode binop, T* buffer, size_t size,
1912 LocalType astType, MachineType memType) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001913 TestingModule module;
1914 module.AddMemoryElems<T>(size);
1915 for (size_t i = 0; i < size; i++) {
1916 module.raw_mem_start<T>()[i] = buffer[i];
1917 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001918 WasmRunner<int32_t> r(&module, MachineType::Int32());
1919 const byte kAccum = r.AllocateLocal(astType);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001920
1921 BUILD(
1922 r,
1923 WASM_BLOCK(
1924 4, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
1925 WASM_WHILE(
1926 WASM_GET_LOCAL(0),
1927 WASM_BLOCK(
1928 2, WASM_SET_LOCAL(
1929 kAccum,
1930 WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
1931 WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))),
1932 WASM_SET_LOCAL(
1933 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(sizeof(T)))))),
1934 WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
1935 WASM_GET_LOCAL(0)));
1936 r.Call(static_cast<int>(sizeof(T) * (size - 1)));
1937 return module.raw_mem_at<double>(0);
1938}
1939
1940
1941TEST(Run_Wasm_MemF64_Mul) {
1942 const size_t kSize = 6;
1943 double buffer[kSize] = {1, 2, 2, 2, 2, 2};
1944 double result = GenerateAndRunFold<double>(kExprF64Mul, buffer, kSize,
1945 kAstF64, MachineType::Float64());
1946 CHECK_EQ(32, result);
1947}
1948
1949
1950TEST(Build_Wasm_Infinite_Loop) {
1951 WasmRunner<int32_t> r(MachineType::Int32());
1952 // Only build the graph and compile, don't run.
1953 BUILD(r, WASM_INFINITE_LOOP);
1954}
1955
1956
1957TEST(Build_Wasm_Infinite_Loop_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001958 TestingModule module;
1959 module.AddMemoryElems<int8_t>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001960 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001961
1962 // Only build the graph and compile, don't run.
1963 BUILD(r, WASM_LOOP(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
1964}
1965
1966
1967TEST(Run_Wasm_Unreachable0a) {
1968 WasmRunner<int32_t> r(MachineType::Int32());
1969 BUILD(r,
1970 WASM_BLOCK(2, WASM_BRV(0, WASM_I8(9)), WASM_RETURN(WASM_GET_LOCAL(0))));
1971 CHECK_EQ(9, r.Call(0));
1972 CHECK_EQ(9, r.Call(1));
1973}
1974
1975
1976TEST(Run_Wasm_Unreachable0b) {
1977 WasmRunner<int32_t> r(MachineType::Int32());
1978 BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE));
1979 CHECK_EQ(7, r.Call(0));
1980 CHECK_EQ(7, r.Call(1));
1981}
1982
1983
1984TEST(Build_Wasm_Unreachable1) {
1985 WasmRunner<int32_t> r(MachineType::Int32());
1986 BUILD(r, WASM_UNREACHABLE);
1987}
1988
1989
1990TEST(Build_Wasm_Unreachable2) {
1991 WasmRunner<int32_t> r(MachineType::Int32());
1992 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE);
1993}
1994
1995
1996TEST(Build_Wasm_Unreachable3) {
1997 WasmRunner<int32_t> r(MachineType::Int32());
1998 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE);
1999}
2000
2001
2002TEST(Build_Wasm_UnreachableIf1) {
2003 WasmRunner<int32_t> r(MachineType::Int32());
2004 BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
2005}
2006
2007
2008TEST(Build_Wasm_UnreachableIf2) {
2009 WasmRunner<int32_t> r(MachineType::Int32());
2010 BUILD(r, WASM_UNREACHABLE,
2011 WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
2012}
2013
2014
2015TEST(Run_Wasm_Unreachable_Load) {
2016 WasmRunner<int32_t> r(MachineType::Int32());
2017 BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_GET_LOCAL(0)),
2018 WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
2019 CHECK_EQ(11, r.Call(11));
2020 CHECK_EQ(21, r.Call(21));
2021}
2022
2023
2024TEST(Run_Wasm_Infinite_Loop_not_taken1) {
2025 WasmRunner<int32_t> r(MachineType::Int32());
2026 BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP),
2027 WASM_I8(45)));
2028 // Run the code, but don't go into the infinite loop.
2029 CHECK_EQ(45, r.Call(0));
2030}
2031
2032
2033TEST(Run_Wasm_Infinite_Loop_not_taken2) {
2034 WasmRunner<int32_t> r(MachineType::Int32());
2035 BUILD(r,
2036 WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(45)),
2037 WASM_INFINITE_LOOP)));
2038 // Run the code, but don't go into the infinite loop.
2039 CHECK_EQ(45, r.Call(1));
2040}
2041
2042
2043TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) {
2044 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002045 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_I8(45), WASM_GET_LOCAL(0)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002046 WASM_INFINITE_LOOP));
2047 // Run the code, but don't go into the infinite loop.
2048 CHECK_EQ(45, r.Call(1));
2049}
2050
2051
2052static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
2053 if (!WasmOpcodes::IsSupported(opcode)) return;
2054
2055 Zone zone;
2056 Isolate* isolate = CcTest::InitIsolateOnce();
2057 HandleScope scope(isolate);
2058 // Enable all optional operators.
2059 CommonOperatorBuilder common(&zone);
2060 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(),
2061 MachineOperatorBuilder::kAllOptionalOps);
2062 Graph graph(&zone);
2063 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
2064 FunctionEnv env;
2065 FunctionSig* sig = WasmOpcodes::Signature(opcode);
2066 init_env(&env, sig);
2067
2068 if (sig->parameter_count() == 1) {
2069 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0};
2070 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code));
2071 } else {
2072 CHECK_EQ(2, sig->parameter_count());
2073 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal,
2074 1};
2075 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code));
2076 }
2077}
2078
2079
2080TEST(Build_Wasm_SimpleExprs) {
2081// Test that the decoder can build a graph for all supported simple expressions.
2082#define GRAPH_BUILD_TEST(name, opcode, sig) \
2083 TestBuildGraphForSimpleExpression(kExpr##name);
2084
2085 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST);
2086
2087#undef GRAPH_BUILD_TEST
2088}
2089
2090
2091TEST(Run_Wasm_Int32LoadInt8_signext) {
2092 TestingModule module;
2093 const int kNumElems = 16;
2094 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems);
2095 module.RandomizeMemory();
2096 memory[0] = -1;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002097 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002098 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)));
2099
2100 for (size_t i = 0; i < kNumElems; i++) {
2101 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
2102 }
2103}
2104
2105
2106TEST(Run_Wasm_Int32LoadInt8_zeroext) {
2107 TestingModule module;
2108 const int kNumElems = 16;
2109 byte* memory = module.AddMemory(kNumElems);
2110 module.RandomizeMemory(77);
2111 memory[0] = 255;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002112 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002113 BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0)));
2114
2115 for (size_t i = 0; i < kNumElems; i++) {
2116 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
2117 }
2118}
2119
2120
2121TEST(Run_Wasm_Int32LoadInt16_signext) {
2122 TestingModule module;
2123 const int kNumBytes = 16;
2124 byte* memory = module.AddMemory(kNumBytes);
2125 module.RandomizeMemory(888);
2126 memory[1] = 200;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002127 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002128 BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0)));
2129
2130 for (size_t i = 0; i < kNumBytes; i += 2) {
2131 int32_t expected = memory[i] | (static_cast<int8_t>(memory[i + 1]) << 8);
2132 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
2133 }
2134}
2135
2136
2137TEST(Run_Wasm_Int32LoadInt16_zeroext) {
2138 TestingModule module;
2139 const int kNumBytes = 16;
2140 byte* memory = module.AddMemory(kNumBytes);
2141 module.RandomizeMemory(9999);
2142 memory[1] = 204;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002143 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002144 BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0)));
2145
2146 for (size_t i = 0; i < kNumBytes; i += 2) {
2147 int32_t expected = memory[i] | (memory[i + 1] << 8);
2148 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
2149 }
2150}
2151
2152
2153TEST(Run_WasmInt32Global) {
2154 TestingModule module;
2155 int32_t* global = module.AddGlobal<int32_t>(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002156 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002157 // global = global + p0
2158 BUILD(r, WASM_STORE_GLOBAL(
2159 0, WASM_I32_ADD(WASM_LOAD_GLOBAL(0), WASM_GET_LOCAL(0))));
2160
2161 *global = 116;
2162 for (int i = 9; i < 444444; i += 111111) {
2163 int32_t expected = *global + i;
2164 r.Call(i);
2165 CHECK_EQ(expected, *global);
2166 }
2167}
2168
2169
2170TEST(Run_WasmInt32Globals_DontAlias) {
2171 const int kNumGlobals = 3;
2172 TestingModule module;
2173 int32_t* globals[] = {module.AddGlobal<int32_t>(MachineType::Int32()),
2174 module.AddGlobal<int32_t>(MachineType::Int32()),
2175 module.AddGlobal<int32_t>(MachineType::Int32())};
2176
2177 for (int g = 0; g < kNumGlobals; g++) {
2178 // global = global + p0
Ben Murdoch097c5b22016-05-18 11:27:45 +01002179 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002180 BUILD(r, WASM_STORE_GLOBAL(
2181 g, WASM_I32_ADD(WASM_LOAD_GLOBAL(g), WASM_GET_LOCAL(0))));
2182
2183 // Check that reading/writing global number {g} doesn't alter the others.
2184 *globals[g] = 116 * g;
2185 int32_t before[kNumGlobals];
2186 for (int i = 9; i < 444444; i += 111113) {
2187 int32_t sum = *globals[g] + i;
2188 for (int j = 0; j < kNumGlobals; j++) before[j] = *globals[j];
2189 r.Call(i);
2190 for (int j = 0; j < kNumGlobals; j++) {
2191 int32_t expected = j == g ? sum : before[j];
2192 CHECK_EQ(expected, *globals[j]);
2193 }
2194 }
2195 }
2196}
2197
2198
2199#if WASM_64
2200TEST(Run_WasmInt64Global) {
2201 TestingModule module;
2202 int64_t* global = module.AddGlobal<int64_t>(MachineType::Int64());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002203 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002204 // global = global + p0
2205 BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
2206 0, WASM_I64_ADD(
2207 WASM_LOAD_GLOBAL(0),
2208 WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
2209 WASM_ZERO));
2210
2211 *global = 0xFFFFFFFFFFFFFFFFLL;
2212 for (int i = 9; i < 444444; i += 111111) {
2213 int64_t expected = *global + i;
2214 r.Call(i);
2215 CHECK_EQ(expected, *global);
2216 }
2217}
2218#endif
2219
2220
2221TEST(Run_WasmFloat32Global) {
2222 TestingModule module;
2223 float* global = module.AddGlobal<float>(MachineType::Float32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002224 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002225 // global = global + p0
2226 BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
2227 0, WASM_F32_ADD(
2228 WASM_LOAD_GLOBAL(0),
2229 WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0)))),
2230 WASM_ZERO));
2231
2232 *global = 1.25;
2233 for (int i = 9; i < 4444; i += 1111) {
2234 volatile float expected = *global + i;
2235 r.Call(i);
2236 CHECK_EQ(expected, *global);
2237 }
2238}
2239
2240
2241TEST(Run_WasmFloat64Global) {
2242 TestingModule module;
2243 double* global = module.AddGlobal<double>(MachineType::Float64());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002244 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002245 // global = global + p0
2246 BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL(
2247 0, WASM_F64_ADD(
2248 WASM_LOAD_GLOBAL(0),
2249 WASM_F64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
2250 WASM_ZERO));
2251
2252 *global = 1.25;
2253 for (int i = 9; i < 4444; i += 1111) {
2254 volatile double expected = *global + i;
2255 r.Call(i);
2256 CHECK_EQ(expected, *global);
2257 }
2258}
2259
2260
2261TEST(Run_WasmMixedGlobals) {
2262 TestingModule module;
2263 int32_t* unused = module.AddGlobal<int32_t>(MachineType::Int32());
2264 byte* memory = module.AddMemory(32);
2265
2266 int8_t* var_int8 = module.AddGlobal<int8_t>(MachineType::Int8());
2267 uint8_t* var_uint8 = module.AddGlobal<uint8_t>(MachineType::Uint8());
2268 int16_t* var_int16 = module.AddGlobal<int16_t>(MachineType::Int16());
2269 uint16_t* var_uint16 = module.AddGlobal<uint16_t>(MachineType::Uint16());
2270 int32_t* var_int32 = module.AddGlobal<int32_t>(MachineType::Int32());
2271 uint32_t* var_uint32 = module.AddGlobal<uint32_t>(MachineType::Uint32());
2272 float* var_float = module.AddGlobal<float>(MachineType::Float32());
2273 double* var_double = module.AddGlobal<double>(MachineType::Float64());
2274
Ben Murdoch097c5b22016-05-18 11:27:45 +01002275 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002276
2277 BUILD(
2278 r,
2279 WASM_BLOCK(
2280 9,
2281 WASM_STORE_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int8(), WASM_ZERO)),
2282 WASM_STORE_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint8(), WASM_ZERO)),
2283 WASM_STORE_GLOBAL(3, WASM_LOAD_MEM(MachineType::Int16(), WASM_ZERO)),
2284 WASM_STORE_GLOBAL(4, WASM_LOAD_MEM(MachineType::Uint16(), WASM_ZERO)),
2285 WASM_STORE_GLOBAL(5, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
2286 WASM_STORE_GLOBAL(6, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)),
2287 WASM_STORE_GLOBAL(7,
2288 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)),
2289 WASM_STORE_GLOBAL(8,
2290 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)),
2291 WASM_ZERO));
2292
2293 memory[0] = 0xaa;
2294 memory[1] = 0xcc;
2295 memory[2] = 0x55;
2296 memory[3] = 0xee;
2297 memory[4] = 0x33;
2298 memory[5] = 0x22;
2299 memory[6] = 0x11;
2300 memory[7] = 0x99;
2301 r.Call(1);
2302
2303 CHECK(static_cast<int8_t>(0xaa) == *var_int8);
2304 CHECK(static_cast<uint8_t>(0xaa) == *var_uint8);
2305 CHECK(static_cast<int16_t>(0xccaa) == *var_int16);
2306 CHECK(static_cast<uint16_t>(0xccaa) == *var_uint16);
2307 CHECK(static_cast<int32_t>(0xee55ccaa) == *var_int32);
2308 CHECK(static_cast<uint32_t>(0xee55ccaa) == *var_uint32);
2309 CHECK(bit_cast<float>(0xee55ccaa) == *var_float);
2310 CHECK(bit_cast<double>(0x99112233ee55ccaaULL) == *var_double);
2311
2312 USE(unused);
2313}
2314
2315
2316#if WASM_64
2317// Test the WasmRunner with an Int64 return value and different numbers of
2318// Int64 parameters.
2319TEST(Run_TestI64WasmRunner) {
2320 {
2321 FOR_INT64_INPUTS(i) {
2322 WasmRunner<int64_t> r;
2323 BUILD(r, WASM_I64(*i));
2324 CHECK_EQ(*i, r.Call());
2325 }
2326 }
2327 {
2328 WasmRunner<int64_t> r(MachineType::Int64());
2329 BUILD(r, WASM_GET_LOCAL(0));
2330 FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
2331 }
2332 {
2333 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
2334 BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2335 FOR_INT64_INPUTS(i) {
2336 FOR_INT64_INPUTS(j) { CHECK_EQ(*i + *j, r.Call(*i, *j)); }
2337 }
2338 }
2339 {
2340 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(),
2341 MachineType::Int64());
2342 BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0),
2343 WASM_I64_ADD(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2))));
2344 FOR_INT64_INPUTS(i) {
2345 FOR_INT64_INPUTS(j) {
2346 CHECK_EQ(*i + *j + *j, r.Call(*i, *j, *j));
2347 CHECK_EQ(*j + *i + *j, r.Call(*j, *i, *j));
2348 CHECK_EQ(*j + *j + *i, r.Call(*j, *j, *i));
2349 }
2350 }
2351 }
2352 {
2353 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(),
2354 MachineType::Int64(), MachineType::Int64());
2355 BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0),
2356 WASM_I64_ADD(WASM_GET_LOCAL(1),
2357 WASM_I64_ADD(WASM_GET_LOCAL(2),
2358 WASM_GET_LOCAL(3)))));
2359 FOR_INT64_INPUTS(i) {
2360 FOR_INT64_INPUTS(j) {
2361 CHECK_EQ(*i + *j + *j + *j, r.Call(*i, *j, *j, *j));
2362 CHECK_EQ(*j + *i + *j + *j, r.Call(*j, *i, *j, *j));
2363 CHECK_EQ(*j + *j + *i + *j, r.Call(*j, *j, *i, *j));
2364 CHECK_EQ(*j + *j + *j + *i, r.Call(*j, *j, *j, *i));
2365 }
2366 }
2367 }
2368}
2369#endif
2370
2371
2372TEST(Run_WasmCallEmpty) {
2373 const int32_t kExpected = -414444;
2374 // Build the target function.
2375 TestSignatures sigs;
2376 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002377 WasmFunctionCompiler t(sigs.i_v(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002378 BUILD(t, WASM_I32(kExpected));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002379 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002380
2381 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002382 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002383 BUILD(r, WASM_CALL_FUNCTION0(index));
2384
2385 int32_t result = r.Call();
2386 CHECK_EQ(kExpected, result);
2387}
2388
2389
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002390TEST(Run_WasmCallF32StackParameter) {
2391 // Build the target function.
2392 LocalType param_types[20];
2393 for (int i = 0; i < 20; i++) param_types[i] = kAstF32;
2394 FunctionSig sig(1, 19, param_types);
2395 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002396 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002397 BUILD(t, WASM_GET_LOCAL(17));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002398 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002399
2400 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002401 WasmRunner<float> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002402 BUILD(r, WASM_CALL_FUNCTION(
2403 index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
2404 WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
2405 WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
2406 WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
2407 WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f),
2408 WASM_F32(128.5f), WASM_F32(256.5f), WASM_F32(512.5f)));
2409
2410 float result = r.Call();
2411 CHECK_EQ(256.5f, result);
2412}
2413
2414
2415TEST(Run_WasmCallF64StackParameter) {
2416 // Build the target function.
2417 LocalType param_types[20];
2418 for (int i = 0; i < 20; i++) param_types[i] = kAstF64;
2419 FunctionSig sig(1, 19, param_types);
2420 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002421 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002422 BUILD(t, WASM_GET_LOCAL(17));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002423 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002424
2425 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002426 WasmRunner<double> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002427 BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0),
2428 WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
2429 WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
2430 WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
2431 WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
2432 WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
2433 WASM_F64(256.5), WASM_F64(512.5)));
2434
2435 float result = r.Call();
2436 CHECK_EQ(256.5, result);
2437}
2438
Ben Murdoch097c5b22016-05-18 11:27:45 +01002439TEST(Run_WasmCallI64Parameter) {
2440 // Build the target function.
2441 LocalType param_types[20];
2442 for (int i = 0; i < 20; i++) param_types[i] = kAstI64;
2443 param_types[3] = kAstI32;
2444 param_types[4] = kAstI32;
2445 FunctionSig sig(1, 19, param_types);
2446 for (int i = 0; i < 19; i++) {
2447 TestingModule module;
2448 WasmFunctionCompiler t(&sig, &module);
2449 if (i == 2 || i == 3) {
2450 continue;
2451 } else {
2452 BUILD(t, WASM_GET_LOCAL(i));
2453 }
2454 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002455
Ben Murdoch097c5b22016-05-18 11:27:45 +01002456 // Build the calling function.
2457 WasmRunner<int32_t> r;
2458 r.env()->module = &module;
2459 BUILD(r,
2460 WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION(
2461 index, WASM_I64(0xbcd12340000000b), WASM_I64(0xbcd12340000000c),
2462 WASM_I32(0xd), WASM_I32_CONVERT_I64(WASM_I64(0xbcd12340000000e)),
2463 WASM_I64(0xbcd12340000000f), WASM_I64(0xbcd1234000000010),
2464 WASM_I64(0xbcd1234000000011), WASM_I64(0xbcd1234000000012),
2465 WASM_I64(0xbcd1234000000013), WASM_I64(0xbcd1234000000014),
2466 WASM_I64(0xbcd1234000000015), WASM_I64(0xbcd1234000000016),
2467 WASM_I64(0xbcd1234000000017), WASM_I64(0xbcd1234000000018),
2468 WASM_I64(0xbcd1234000000019), WASM_I64(0xbcd123400000001a),
2469 WASM_I64(0xbcd123400000001b), WASM_I64(0xbcd123400000001c),
2470 WASM_I64(0xbcd123400000001d))));
2471
2472 CHECK_EQ(i + 0xb, r.Call());
2473 }
2474}
2475
2476TEST(Run_WasmI64And) {
2477 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
2478 BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2479 FOR_INT64_INPUTS(i) {
2480 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); }
2481 }
2482}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002483
2484TEST(Run_WasmCallVoid) {
2485 const byte kMemOffset = 8;
2486 const int32_t kElemNum = kMemOffset / sizeof(int32_t);
2487 const int32_t kExpected = -414444;
2488 // Build the target function.
2489 TestSignatures sigs;
2490 TestingModule module;
2491 module.AddMemory(16);
2492 module.RandomizeMemory();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002493 WasmFunctionCompiler t(sigs.v_v(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002494 BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset),
2495 WASM_I32(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002496 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002497
2498 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002499 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002500 BUILD(r, WASM_CALL_FUNCTION0(index),
2501 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset)));
2502
2503 int32_t result = r.Call();
2504 CHECK_EQ(kExpected, result);
2505 CHECK_EQ(kExpected, module.raw_mem_start<int32_t>()[kElemNum]);
2506}
2507
2508
2509TEST(Run_WasmCall_Int32Add) {
2510 // Build the target function.
2511 TestSignatures sigs;
2512 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002513 WasmFunctionCompiler t(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002514 BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002515 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002516
2517 // Build the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002518 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002519 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2520
2521 FOR_INT32_INPUTS(i) {
2522 FOR_INT32_INPUTS(j) {
2523 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
2524 static_cast<uint32_t>(*j));
2525 CHECK_EQ(expected, r.Call(*i, *j));
2526 }
2527 }
2528}
2529
2530
2531#if WASM_64
2532TEST(Run_WasmCall_Int64Sub) {
2533 // Build the target function.
2534 TestSignatures sigs;
2535 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002536 WasmFunctionCompiler t(sigs.l_ll(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002537 BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002538 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002539
2540 // Build the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002541 WasmRunner<int64_t> r(&module, MachineType::Int64(), MachineType::Int64());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002542 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2543
2544 FOR_INT32_INPUTS(i) {
2545 FOR_INT32_INPUTS(j) {
2546 int64_t a = static_cast<int64_t>(*i) << 32 |
2547 (static_cast<int64_t>(*j) | 0xFFFFFFFF);
2548 int64_t b = static_cast<int64_t>(*j) << 32 |
2549 (static_cast<int64_t>(*i) | 0xFFFFFFFF);
2550
2551 int64_t expected = static_cast<int64_t>(static_cast<uint64_t>(a) -
2552 static_cast<uint64_t>(b));
2553 CHECK_EQ(expected, r.Call(a, b));
2554 }
2555 }
2556}
2557#endif
2558
2559
2560TEST(Run_WasmCall_Float32Sub) {
2561 TestSignatures sigs;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002562 TestingModule module;
2563 WasmFunctionCompiler t(sigs.f_ff(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002564
2565 // Build the target function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002566 BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002567 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002568
2569 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002570 WasmRunner<float> r(&module, MachineType::Float32(), MachineType::Float32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002571 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2572
2573 FOR_FLOAT32_INPUTS(i) {
2574 FOR_FLOAT32_INPUTS(j) {
2575 volatile float expected = *i - *j;
2576 CheckFloatEq(expected, r.Call(*i, *j));
2577 }
2578 }
2579}
2580
2581
2582TEST(Run_WasmCall_Float64Sub) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002583 TestingModule module;
2584 double* memory = module.AddMemoryElems<double>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002585 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002586
2587 // TODO(titzer): convert to a binop test.
2588 BUILD(r, WASM_BLOCK(
2589 2, WASM_STORE_MEM(
2590 MachineType::Float64(), WASM_ZERO,
2591 WASM_F64_SUB(
2592 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
2593 WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))),
2594 WASM_I8(107)));
2595
2596 FOR_FLOAT64_INPUTS(i) {
2597 FOR_FLOAT64_INPUTS(j) {
2598 memory[0] = *i;
2599 memory[1] = *j;
2600 double expected = *i - *j;
2601 CHECK_EQ(107, r.Call());
2602 if (expected != expected) {
2603 CHECK(memory[0] != memory[0]);
2604 } else {
2605 CHECK_EQ(expected, memory[0]);
2606 }
2607 }
2608 }
2609}
2610
2611#define ADD_CODE(vec, ...) \
2612 do { \
2613 byte __buf[] = {__VA_ARGS__}; \
2614 for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
2615 } while (false)
2616
2617
2618static void Run_WasmMixedCall_N(int start) {
2619 const int kExpected = 6333;
2620 const int kElemSize = 8;
2621 TestSignatures sigs;
2622
2623#if WASM_64
2624 static MachineType mixed[] = {
2625 MachineType::Int32(), MachineType::Float32(), MachineType::Int64(),
2626 MachineType::Float64(), MachineType::Float32(), MachineType::Int64(),
2627 MachineType::Int32(), MachineType::Float64(), MachineType::Float32(),
2628 MachineType::Float64(), MachineType::Int32(), MachineType::Int64(),
2629 MachineType::Int32(), MachineType::Int32()};
2630#else
2631 static MachineType mixed[] = {
2632 MachineType::Int32(), MachineType::Float32(), MachineType::Float64(),
2633 MachineType::Float32(), MachineType::Int32(), MachineType::Float64(),
2634 MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
2635 MachineType::Int32(), MachineType::Int32()};
2636#endif
2637
2638 int num_params = static_cast<int>(arraysize(mixed)) - start;
2639 for (int which = 0; which < num_params; which++) {
2640 Zone zone;
2641 TestingModule module;
2642 module.AddMemory(1024);
2643 MachineType* memtypes = &mixed[start];
2644 MachineType result = memtypes[which];
2645
2646 // =========================================================================
2647 // Build the selector function.
2648 // =========================================================================
2649 uint32_t index;
2650 FunctionSig::Builder b(&zone, 1, num_params);
2651 b.AddReturn(WasmOpcodes::LocalTypeFor(result));
2652 for (int i = 0; i < num_params; i++) {
2653 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
2654 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002655 WasmFunctionCompiler t(b.Build(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002656 BUILD(t, WASM_GET_LOCAL(which));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002657 index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002658
2659 // =========================================================================
2660 // Build the calling function.
2661 // =========================================================================
Ben Murdoch097c5b22016-05-18 11:27:45 +01002662 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002663
Ben Murdoch097c5b22016-05-18 11:27:45 +01002664 std::vector<byte> code;
2665 ADD_CODE(code,
2666 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
2667 WasmOpcodes::LoadStoreAccessOf(false));
2668 ADD_CODE(code, WASM_ZERO);
2669 ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002670
Ben Murdoch097c5b22016-05-18 11:27:45 +01002671 for (int i = 0; i < num_params; i++) {
2672 int offset = (i + 1) * kElemSize;
2673 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002674 }
2675
Ben Murdoch097c5b22016-05-18 11:27:45 +01002676 ADD_CODE(code, WASM_I32(kExpected));
2677 size_t end = code.size();
2678 code.push_back(0);
2679 r.Build(&code[0], &code[end]);
2680
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002681 // Run the code.
2682 for (int t = 0; t < 10; t++) {
2683 module.RandomizeMemory();
2684 CHECK_EQ(kExpected, r.Call());
2685
2686 int size = WasmOpcodes::MemSize(result);
2687 for (int i = 0; i < size; i++) {
2688 int base = (which + 1) * kElemSize;
2689 byte expected = module.raw_mem_at<byte>(base + i);
2690 byte result = module.raw_mem_at<byte>(i);
2691 CHECK_EQ(expected, result);
2692 }
2693 }
2694 }
2695}
2696
2697
2698TEST(Run_WasmMixedCall_0) { Run_WasmMixedCall_N(0); }
2699TEST(Run_WasmMixedCall_1) { Run_WasmMixedCall_N(1); }
2700TEST(Run_WasmMixedCall_2) { Run_WasmMixedCall_N(2); }
2701TEST(Run_WasmMixedCall_3) { Run_WasmMixedCall_N(3); }
2702
Ben Murdoch097c5b22016-05-18 11:27:45 +01002703TEST(Run_Wasm_AddCall) {
2704 TestSignatures sigs;
2705 TestingModule module;
2706 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2707 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2708 t1.CompileAndAdd();
2709
2710 WasmRunner<int32_t> r(&module, MachineType::Int32());
2711 byte local = r.AllocateLocal(kAstI32);
2712 BUILD(r,
2713 WASM_BLOCK(2, WASM_SET_LOCAL(local, WASM_I8(99)),
2714 WASM_I32_ADD(
2715 WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(0),
2716 WASM_GET_LOCAL(0)),
2717 WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(1),
2718 WASM_GET_LOCAL(local)))));
2719
2720 CHECK_EQ(198, r.Call(0));
2721 CHECK_EQ(200, r.Call(1));
2722 CHECK_EQ(100, r.Call(-49));
2723}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002724
2725TEST(Run_Wasm_CountDown_expr) {
2726 WasmRunner<int32_t> r(MachineType::Int32());
2727 BUILD(r, WASM_LOOP(
2728 3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
2729 WASM_BREAKV(0, WASM_GET_LOCAL(0))),
2730 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
2731 WASM_CONTINUE(0)));
2732 CHECK_EQ(0, r.Call(1));
2733 CHECK_EQ(0, r.Call(10));
2734 CHECK_EQ(0, r.Call(100));
2735}
2736
2737
2738TEST(Run_Wasm_ExprBlock2a) {
2739 WasmRunner<int32_t> r(MachineType::Int32());
2740 BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))),
2741 WASM_I8(1)));
2742 CHECK_EQ(1, r.Call(0));
2743 CHECK_EQ(1, r.Call(1));
2744}
2745
2746
2747TEST(Run_Wasm_ExprBlock2b) {
2748 WasmRunner<int32_t> r(MachineType::Int32());
2749 BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))),
2750 WASM_I8(2)));
2751 CHECK_EQ(2, r.Call(0));
2752 CHECK_EQ(1, r.Call(1));
2753}
2754
2755
2756TEST(Run_Wasm_ExprBlock2c) {
2757 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002758 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002759 WASM_I8(1)));
2760 CHECK_EQ(1, r.Call(0));
2761 CHECK_EQ(1, r.Call(1));
2762}
2763
2764
2765TEST(Run_Wasm_ExprBlock2d) {
2766 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002767 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002768 WASM_I8(2)));
2769 CHECK_EQ(2, r.Call(0));
2770 CHECK_EQ(1, r.Call(1));
2771}
2772
2773
2774TEST(Run_Wasm_ExprBlock_ManualSwitch) {
2775 WasmRunner<int32_t> r(MachineType::Int32());
2776 BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
2777 WASM_BRV(0, WASM_I8(11))),
2778 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
2779 WASM_BRV(0, WASM_I8(12))),
2780 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
2781 WASM_BRV(0, WASM_I8(13))),
2782 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
2783 WASM_BRV(0, WASM_I8(14))),
2784 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
2785 WASM_BRV(0, WASM_I8(15))),
2786 WASM_I8(99)));
2787 CHECK_EQ(99, r.Call(0));
2788 CHECK_EQ(11, r.Call(1));
2789 CHECK_EQ(12, r.Call(2));
2790 CHECK_EQ(13, r.Call(3));
2791 CHECK_EQ(14, r.Call(4));
2792 CHECK_EQ(15, r.Call(5));
2793 CHECK_EQ(99, r.Call(6));
2794}
2795
2796
2797TEST(Run_Wasm_ExprBlock_ManualSwitch_brif) {
2798 WasmRunner<int32_t> r(MachineType::Int32());
2799 BUILD(r,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002800 WASM_BLOCK(6, WASM_BRV_IF(0, WASM_I8(11),
2801 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1))),
2802 WASM_BRV_IF(0, WASM_I8(12),
2803 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2))),
2804 WASM_BRV_IF(0, WASM_I8(13),
2805 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3))),
2806 WASM_BRV_IF(0, WASM_I8(14),
2807 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4))),
2808 WASM_BRV_IF(0, WASM_I8(15),
2809 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002810 WASM_I8(99)));
2811 CHECK_EQ(99, r.Call(0));
2812 CHECK_EQ(11, r.Call(1));
2813 CHECK_EQ(12, r.Call(2));
2814 CHECK_EQ(13, r.Call(3));
2815 CHECK_EQ(14, r.Call(4));
2816 CHECK_EQ(15, r.Call(5));
2817 CHECK_EQ(99, r.Call(6));
2818}
2819
2820
2821TEST(Run_Wasm_nested_ifs) {
2822 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2823
2824 BUILD(r, WASM_IF_ELSE(
2825 WASM_GET_LOCAL(0),
2826 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
2827 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
2828
2829
2830 CHECK_EQ(11, r.Call(1, 1));
2831 CHECK_EQ(12, r.Call(1, 0));
2832 CHECK_EQ(13, r.Call(0, 1));
2833 CHECK_EQ(14, r.Call(0, 0));
2834}
2835
2836
2837TEST(Run_Wasm_ExprBlock_if) {
2838 WasmRunner<int32_t> r(MachineType::Int32());
2839
2840 BUILD(r,
2841 WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
2842 WASM_BRV(0, WASM_I8(14)))));
2843
2844 CHECK_EQ(11, r.Call(1));
2845 CHECK_EQ(14, r.Call(0));
2846}
2847
2848
2849TEST(Run_Wasm_ExprBlock_nested_ifs) {
2850 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2851
2852 BUILD(r, WASM_BLOCK(
2853 1, WASM_IF_ELSE(
2854 WASM_GET_LOCAL(0),
2855 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
2856 WASM_BRV(0, WASM_I8(12))),
2857 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
2858 WASM_BRV(0, WASM_I8(14))))));
2859
2860
2861 CHECK_EQ(11, r.Call(1, 1));
2862 CHECK_EQ(12, r.Call(1, 0));
2863 CHECK_EQ(13, r.Call(0, 1));
2864 CHECK_EQ(14, r.Call(0, 0));
2865}
2866
2867
2868TEST(Run_Wasm_ExprLoop_nested_ifs) {
2869 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2870
2871 BUILD(r, WASM_LOOP(
2872 1, WASM_IF_ELSE(
2873 WASM_GET_LOCAL(0),
2874 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)),
2875 WASM_BRV(1, WASM_I8(12))),
2876 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)),
2877 WASM_BRV(1, WASM_I8(14))))));
2878
2879
2880 CHECK_EQ(11, r.Call(1, 1));
2881 CHECK_EQ(12, r.Call(1, 0));
2882 CHECK_EQ(13, r.Call(0, 1));
2883 CHECK_EQ(14, r.Call(0, 0));
2884}
2885
2886
2887#if WASM_64
2888TEST(Run_Wasm_LoadStoreI64_sx) {
2889 byte loads[] = {kExprI64LoadMem8S, kExprI64LoadMem16S, kExprI64LoadMem32S,
2890 kExprI64LoadMem};
2891
2892 for (size_t m = 0; m < arraysize(loads); m++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002893 TestingModule module;
2894 byte* memory = module.AddMemoryElems<byte>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002895 WasmRunner<int64_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002896
2897 byte code[] = {kExprI64StoreMem, 0, kExprI8Const, 8,
2898 loads[m], 0, kExprI8Const, 0};
2899
2900 r.Build(code, code + arraysize(code));
2901
2902 // Try a bunch of different negative values.
2903 for (int i = -1; i >= -128; i -= 11) {
2904 int size = 1 << m;
2905 module.BlankMemory();
2906 memory[size - 1] = static_cast<byte>(i); // set the high order byte.
2907
2908 int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8);
2909
2910 CHECK_EQ(expected, r.Call());
2911 CHECK_EQ(static_cast<byte>(i), memory[8 + size - 1]);
2912 for (int j = size; j < 8; j++) {
2913 CHECK_EQ(255, memory[8 + j]);
2914 }
2915 }
2916 }
2917}
2918
2919
2920#endif
2921
2922
2923TEST(Run_Wasm_SimpleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002924 TestSignatures sigs;
2925 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002926
Ben Murdoch097c5b22016-05-18 11:27:45 +01002927 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2928 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2929 t1.CompileAndAdd(/*sig_index*/ 1);
2930
2931 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002932 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002933 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002934
2935 // Signature table.
2936 module.AddSignature(sigs.f_ff());
2937 module.AddSignature(sigs.i_ii());
2938 module.AddSignature(sigs.d_dd());
2939
2940 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002941 int table[] = {0, 1};
2942 module.AddIndirectFunctionTable(table, 2);
2943 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002944
2945 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002946 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002947 BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
2948
2949 CHECK_EQ(88, r.Call(0));
2950 CHECK_EQ(44, r.Call(1));
2951 CHECK_TRAP(r.Call(2));
2952}
2953
2954
2955TEST(Run_Wasm_MultipleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002956 TestSignatures sigs;
2957 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002958
Ben Murdoch097c5b22016-05-18 11:27:45 +01002959 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2960 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2961 t1.CompileAndAdd(/*sig_index*/ 1);
2962
2963 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002964 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002965 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002966
2967 // Signature table.
2968 module.AddSignature(sigs.f_ff());
2969 module.AddSignature(sigs.i_ii());
2970 module.AddSignature(sigs.d_dd());
2971
2972 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002973 int table[] = {0, 1};
2974 module.AddIndirectFunctionTable(table, 2);
2975 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002976
2977 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002978 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32(),
2979 MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002980 BUILD(r,
2981 WASM_I32_ADD(WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2982 WASM_GET_LOCAL(2)),
2983 WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
2984 WASM_GET_LOCAL(0))));
2985
2986 CHECK_EQ(5, r.Call(0, 1, 2));
2987 CHECK_EQ(19, r.Call(0, 1, 9));
2988 CHECK_EQ(1, r.Call(1, 0, 2));
2989 CHECK_EQ(1, r.Call(1, 0, 9));
2990
2991 CHECK_TRAP(r.Call(0, 2, 1));
2992 CHECK_TRAP(r.Call(1, 2, 0));
2993 CHECK_TRAP(r.Call(2, 0, 1));
2994 CHECK_TRAP(r.Call(2, 1, 0));
2995}
2996
Ben Murdoch097c5b22016-05-18 11:27:45 +01002997TEST(Run_Wasm_CallIndirect_NoTable) {
2998 TestSignatures sigs;
2999 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003000
Ben Murdoch097c5b22016-05-18 11:27:45 +01003001 // One function.
3002 WasmFunctionCompiler t1(sigs.i_ii(), &module);
3003 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3004 t1.CompileAndAdd(/*sig_index*/ 1);
3005
3006 // Signature table.
3007 module.AddSignature(sigs.f_ff());
3008 module.AddSignature(sigs.i_ii());
3009
3010 // Builder the caller function.
3011 WasmRunner<int32_t> r(&module, MachineType::Int32());
3012 BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
3013
3014 CHECK_TRAP(r.Call(0));
3015 CHECK_TRAP(r.Call(1));
3016 CHECK_TRAP(r.Call(2));
3017}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003018
3019TEST(Run_Wasm_F32Floor) {
3020 WasmRunner<float> r(MachineType::Float32());
3021 BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0)));
3022
Ben Murdoch097c5b22016-05-18 11:27:45 +01003023 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003024}
3025
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003026TEST(Run_Wasm_F32Ceil) {
3027 WasmRunner<float> r(MachineType::Float32());
3028 BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0)));
3029
Ben Murdoch097c5b22016-05-18 11:27:45 +01003030 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003031}
3032
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003033TEST(Run_Wasm_F32Trunc) {
3034 WasmRunner<float> r(MachineType::Float32());
3035 BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0)));
3036
Ben Murdoch097c5b22016-05-18 11:27:45 +01003037 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003038}
3039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003040TEST(Run_Wasm_F32NearestInt) {
3041 WasmRunner<float> r(MachineType::Float32());
3042 BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0)));
3043
Ben Murdoch097c5b22016-05-18 11:27:45 +01003044 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyintf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003045}
3046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003047TEST(Run_Wasm_F64Floor) {
3048 WasmRunner<double> r(MachineType::Float64());
3049 BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0)));
3050
3051 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), r.Call(*i)); }
3052}
3053
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003054TEST(Run_Wasm_F64Ceil) {
3055 WasmRunner<double> r(MachineType::Float64());
3056 BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0)));
3057
3058 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), r.Call(*i)); }
3059}
3060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003061TEST(Run_Wasm_F64Trunc) {
3062 WasmRunner<double> r(MachineType::Float64());
3063 BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
3064
3065 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), r.Call(*i)); }
3066}
3067
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003068TEST(Run_Wasm_F64NearestInt) {
3069 WasmRunner<double> r(MachineType::Float64());
3070 BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
3071
3072 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), r.Call(*i)); }
3073}
3074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003075TEST(Run_Wasm_F32Min) {
3076 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
3077 BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3078
3079 FOR_FLOAT32_INPUTS(i) {
3080 FOR_FLOAT32_INPUTS(j) {
3081 float expected;
3082 if (*i < *j) {
3083 expected = *i;
3084 } else if (*j < *i) {
3085 expected = *j;
3086 } else if (*i != *i) {
3087 // If *i or *j is NaN, then the result is NaN.
3088 expected = *i;
3089 } else {
3090 expected = *j;
3091 }
3092
3093 CheckFloatEq(expected, r.Call(*i, *j));
3094 }
3095 }
3096}
3097
3098
3099TEST(Run_Wasm_F64Min) {
3100 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
3101 BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3102
3103 FOR_FLOAT64_INPUTS(i) {
3104 FOR_FLOAT64_INPUTS(j) {
3105 double expected;
3106 if (*i < *j) {
3107 expected = *i;
3108 } else if (*j < *i) {
3109 expected = *j;
3110 } else if (*i != *i) {
3111 // If *i or *j is NaN, then the result is NaN.
3112 expected = *i;
3113 } else {
3114 expected = *j;
3115 }
3116
3117 CheckDoubleEq(expected, r.Call(*i, *j));
3118 }
3119 }
3120}
3121
3122
3123TEST(Run_Wasm_F32Max) {
3124 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
3125 BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3126
3127 FOR_FLOAT32_INPUTS(i) {
3128 FOR_FLOAT32_INPUTS(j) {
3129 float expected;
3130 if (*i > *j) {
3131 expected = *i;
3132 } else if (*j > *i) {
3133 expected = *j;
3134 } else if (*i != *i) {
3135 // If *i or *j is NaN, then the result is NaN.
3136 expected = *i;
3137 } else {
3138 expected = *j;
3139 }
3140
3141 CheckFloatEq(expected, r.Call(*i, *j));
3142 }
3143 }
3144}
3145
3146
3147TEST(Run_Wasm_F64Max) {
3148 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
3149 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3150
3151 FOR_FLOAT64_INPUTS(i) {
3152 FOR_FLOAT64_INPUTS(j) {
3153 double expected;
3154 if (*i > *j) {
3155 expected = *i;
3156 } else if (*j > *i) {
3157 expected = *j;
3158 } else if (*i != *i) {
3159 // If *i or *j is NaN, then the result is NaN.
3160 expected = *i;
3161 } else {
3162 expected = *j;
3163 }
3164
3165 CheckDoubleEq(expected, r.Call(*i, *j));
3166 }
3167 }
3168}
3169
Ben Murdoch097c5b22016-05-18 11:27:45 +01003170// TODO(ahaas): Fix on arm and reenable.
3171#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
3172
3173TEST(Run_Wasm_F32Min_Snan) {
3174 // Test that the instruction does not return a signalling NaN.
3175 {
3176 WasmRunner<float> r;
3177 BUILD(r,
3178 WASM_F32_MIN(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
3179 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
3180 }
3181 {
3182 WasmRunner<float> r;
3183 BUILD(r,
3184 WASM_F32_MIN(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
3185 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
3186 }
3187}
3188
3189TEST(Run_Wasm_F32Max_Snan) {
3190 // Test that the instruction does not return a signalling NaN.
3191 {
3192 WasmRunner<float> r;
3193 BUILD(r,
3194 WASM_F32_MAX(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
3195 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
3196 }
3197 {
3198 WasmRunner<float> r;
3199 BUILD(r,
3200 WASM_F32_MAX(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
3201 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
3202 }
3203}
3204
3205TEST(Run_Wasm_F64Min_Snan) {
3206 // Test that the instruction does not return a signalling NaN.
3207 {
3208 WasmRunner<double> r;
3209 BUILD(r, WASM_F64_MIN(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
3210 WASM_F64(57.67)));
3211 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
3212 }
3213 {
3214 WasmRunner<double> r;
3215 BUILD(r, WASM_F64_MIN(WASM_F64(45.73),
3216 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
3217 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
3218 }
3219}
3220
3221TEST(Run_Wasm_F64Max_Snan) {
3222 // Test that the instruction does not return a signalling NaN.
3223 {
3224 WasmRunner<double> r;
3225 BUILD(r, WASM_F64_MAX(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
3226 WASM_F64(57.67)));
3227 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
3228 }
3229 {
3230 WasmRunner<double> r;
3231 BUILD(r, WASM_F64_MAX(WASM_F64(45.73),
3232 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
3233 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
3234 }
3235}
3236
3237#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003238
3239#if WASM_64
3240TEST(Run_Wasm_F32SConvertI64) {
3241 WasmRunner<float> r(MachineType::Int64());
3242 BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0)));
3243 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); }
3244}
3245
3246
3247#if !defined(_WIN64)
3248// TODO(ahaas): Fix this failure.
3249TEST(Run_Wasm_F32UConvertI64) {
3250 WasmRunner<float> r(MachineType::Uint64());
3251 BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0)));
3252 FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); }
3253}
3254#endif
3255
3256
3257TEST(Run_Wasm_F64SConvertI64) {
3258 WasmRunner<double> r(MachineType::Int64());
3259 BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0)));
3260 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); }
3261}
3262
3263
3264#if !defined(_WIN64)
3265// TODO(ahaas): Fix this failure.
3266TEST(Run_Wasm_F64UConvertI64) {
3267 WasmRunner<double> r(MachineType::Uint64());
3268 BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0)));
3269 FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); }
3270}
3271#endif
3272
3273
3274TEST(Run_Wasm_I64SConvertF32) {
3275 WasmRunner<int64_t> r(MachineType::Float32());
3276 BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
3277
3278 FOR_FLOAT32_INPUTS(i) {
3279 if (*i < static_cast<float>(INT64_MAX) &&
3280 *i >= static_cast<float>(INT64_MIN)) {
3281 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
3282 } else {
3283 CHECK_TRAP64(r.Call(*i));
3284 }
3285 }
3286}
3287
3288
3289TEST(Run_Wasm_I64SConvertF64) {
3290 WasmRunner<int64_t> r(MachineType::Float64());
3291 BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
3292
3293 FOR_FLOAT64_INPUTS(i) {
3294 if (*i < static_cast<double>(INT64_MAX) &&
3295 *i >= static_cast<double>(INT64_MIN)) {
3296 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
3297 } else {
3298 CHECK_TRAP64(r.Call(*i));
3299 }
3300 }
3301}
3302
3303
3304TEST(Run_Wasm_I64UConvertF32) {
3305 WasmRunner<uint64_t> r(MachineType::Float32());
3306 BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
3307
3308 FOR_FLOAT32_INPUTS(i) {
3309 if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
3310 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
3311 } else {
3312 CHECK_TRAP64(r.Call(*i));
3313 }
3314 }
3315}
3316
3317
3318TEST(Run_Wasm_I64UConvertF64) {
3319 WasmRunner<uint64_t> r(MachineType::Float64());
3320 BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
3321
3322 FOR_FLOAT64_INPUTS(i) {
3323 if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
3324 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
3325 } else {
3326 CHECK_TRAP64(r.Call(*i));
3327 }
3328 }
3329}
3330#endif
3331
3332
3333// TODO(titzer): Fix and re-enable.
3334#if 0
3335TEST(Run_Wasm_I32SConvertF32) {
3336 WasmRunner<int32_t> r(MachineType::Float32());
3337 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0)));
3338
3339 FOR_FLOAT32_INPUTS(i) {
3340 if (*i < static_cast<float>(INT32_MAX) &&
3341 *i >= static_cast<float>(INT32_MIN)) {
3342 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i));
3343 } else {
3344 CHECK_TRAP32(r.Call(*i));
3345 }
3346 }
3347}
3348
3349
3350TEST(Run_Wasm_I32SConvertF64) {
3351 WasmRunner<int32_t> r(MachineType::Float64());
3352 BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0)));
3353
3354 FOR_FLOAT64_INPUTS(i) {
3355 if (*i < static_cast<double>(INT32_MAX) &&
3356 *i >= static_cast<double>(INT32_MIN)) {
3357 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
3358 } else {
3359 CHECK_TRAP32(r.Call(*i));
3360 }
3361 }
3362}
3363
3364
3365TEST(Run_Wasm_I32UConvertF32) {
3366 WasmRunner<uint32_t> r(MachineType::Float32());
3367 BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0)));
3368
3369 FOR_FLOAT32_INPUTS(i) {
3370 if (*i < static_cast<float>(UINT32_MAX) && *i > -1) {
3371 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
3372 } else {
3373 CHECK_TRAP32(r.Call(*i));
3374 }
3375 }
3376}
3377
3378
3379TEST(Run_Wasm_I32UConvertF64) {
3380 WasmRunner<uint32_t> r(MachineType::Float64());
3381 BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0)));
3382
3383 FOR_FLOAT64_INPUTS(i) {
3384 if (*i < static_cast<float>(UINT32_MAX) && *i > -1) {
3385 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
3386 } else {
3387 CHECK_TRAP32(r.Call(*i));
3388 }
3389 }
3390}
3391#endif
3392
3393
3394TEST(Run_Wasm_F64CopySign) {
3395 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
3396 BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3397
3398 FOR_FLOAT64_INPUTS(i) {
3399 FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(copysign(*i, *j), r.Call(*i, *j)); }
3400 }
3401}
3402
3403
3404// TODO(tizer): Fix on arm and reenable.
3405#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
3406
3407TEST(Run_Wasm_F32CopySign) {
3408 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
3409 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
3410
3411 FOR_FLOAT32_INPUTS(i) {
3412 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); }
3413 }
3414}
3415
Ben Murdoch097c5b22016-05-18 11:27:45 +01003416
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003417#endif
Ben Murdoch097c5b22016-05-18 11:27:45 +01003418
3419
3420void CompileCallIndirectMany(LocalType param) {
3421 // Make sure we don't run out of registers when compiling indirect calls
3422 // with many many parameters.
3423 TestSignatures sigs;
3424 for (byte num_params = 0; num_params < 40; num_params++) {
3425 Zone zone;
3426 HandleScope scope(CcTest::InitIsolateOnce());
3427 TestingModule module;
3428 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
3429
3430 module.AddSignature(sig);
3431 module.AddSignature(sig);
3432 module.AddIndirectFunctionTable(nullptr, 0);
3433
3434 WasmFunctionCompiler t(sig, &module);
3435
3436 std::vector<byte> code;
3437 ADD_CODE(code, kExprCallIndirect, 1);
3438 ADD_CODE(code, kExprI8Const, 0);
3439 for (byte p = 0; p < num_params; p++) {
3440 ADD_CODE(code, kExprGetLocal, p);
3441 }
3442
3443 t.Build(&code[0], &code[0] + code.size());
3444 t.Compile();
3445 }
3446}
3447
3448
3449TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); }
3450
3451
3452#if WASM_64
3453TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); }
3454#endif
3455
3456
3457TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); }
3458
3459
3460TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); }