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