• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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/base/bits.h"
10 #include "src/wasm/wasm-macro-gen.h"
11 
12 #include "test/cctest/cctest.h"
13 #include "test/cctest/compiler/value-helper.h"
14 #include "test/cctest/wasm/test-signatures.h"
15 #include "test/cctest/wasm/wasm-run-utils.h"
16 
17 // If the target architecture is 64-bit, enable all tests.
18 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
19 #define WASM_64 1
20 #else
21 #define WASM_64 0
22 #endif
23 
24 #define CHECK_TRAP32(x) \
25   CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF)
26 #define CHECK_TRAP64(x) \
27   CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
28 #define CHECK_TRAP(x) CHECK_TRAP32(x)
29 
30 #define asi64(x) static_cast<int64_t>(x)
31 
32 #define asu64(x) static_cast<uint64_t>(x)
33 
34 #define B2(a, b) kExprBlock, a, b, kExprEnd
35 #define B1(a) kExprBlock, a, kExprEnd
36 
37 // Can't bridge macro land with nested macros.
38 #if V8_TARGET_ARCH_MIPS
39 #define MIPS true
40 #else
41 #define MIPS false
42 #endif
43 
44 #define FOREACH_I64_OPERATOR(V) \
45   V(DepthFirst, true)           \
46   V(I64Phi, true)               \
47   V(I64Const, true)             \
48   V(I64Return, true)            \
49   V(I64Param, true)             \
50   V(I64LoadStore, true)         \
51   V(I64Add, true)               \
52   V(I64Sub, true)               \
53   V(I64Mul, !MIPS)              \
54   V(I64DivS, true)              \
55   V(I64DivU, true)              \
56   V(I64RemS, true)              \
57   V(I64RemU, true)              \
58   V(I64And, true)               \
59   V(I64Ior, true)               \
60   V(I64Xor, true)               \
61   V(I64Shl, true)               \
62   V(I64ShrU, true)              \
63   V(I64ShrS, true)              \
64   V(I64Eq, true)                \
65   V(I64Ne, true)                \
66   V(I64LtS, true)               \
67   V(I64LeS, true)               \
68   V(I64LtU, true)               \
69   V(I64LeU, true)               \
70   V(I64GtS, true)               \
71   V(I64GeS, true)               \
72   V(I64GtU, true)               \
73   V(I64GeU, true)               \
74   V(I64Ctz, true)               \
75   V(I64Clz, true)               \
76   V(I64Popcnt, true)            \
77   V(I32ConvertI64, true)        \
78   V(I64SConvertF32, true)       \
79   V(I64SConvertF64, true)       \
80   V(I64UConvertF32, true)       \
81   V(I64UConvertF64, true)       \
82   V(I64SConvertI32, true)       \
83   V(I64UConvertI32, true)       \
84   V(F32SConvertI64, true)       \
85   V(F32UConvertI64, true)       \
86   V(F64SConvertI64, true)       \
87   V(F64UConvertI64, true)       \
88   V(F64ReinterpretI64, true)    \
89   V(I64ReinterpretF64, true)    \
90   V(I64Ror, true)               \
91   V(I64Rol, true)
92 
93 #define DECLARE_CONST(name, cond) static const bool kSupported_##name = cond;
94 FOREACH_I64_OPERATOR(DECLARE_CONST)
95 #undef DECLARE_CONST
96 
97 #define REQUIRE(name) \
98   if (!WASM_64 && !kSupported_##name) return
99 
WASM_EXEC_TEST(I64Const)100 WASM_EXEC_TEST(I64Const) {
101   REQUIRE(I64Const);
102   WasmRunner<int64_t> r(execution_mode);
103   const int64_t kExpectedValue = 0x1122334455667788LL;
104   // return(kExpectedValue)
105   BUILD(r, WASM_I64V_9(kExpectedValue));
106   CHECK_EQ(kExpectedValue, r.Call());
107 }
108 
WASM_EXEC_TEST(I64Const_many)109 WASM_EXEC_TEST(I64Const_many) {
110   REQUIRE(I64Const);
111   int cntr = 0;
112   FOR_INT32_INPUTS(i) {
113     WasmRunner<int64_t> r(execution_mode);
114     const int64_t kExpectedValue = (static_cast<int64_t>(*i) << 32) | cntr;
115     // return(kExpectedValue)
116     BUILD(r, WASM_I64V(kExpectedValue));
117     CHECK_EQ(kExpectedValue, r.Call());
118     cntr++;
119   }
120 }
121 
WASM_EXEC_TEST(Return_I64)122 WASM_EXEC_TEST(Return_I64) {
123   REQUIRE(I64Return);
124   WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
125 
126   BUILD(r, WASM_RETURN1(WASM_GET_LOCAL(0)));
127 
128   FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
129 }
130 
WASM_EXEC_TEST(I64Add)131 WASM_EXEC_TEST(I64Add) {
132   REQUIRE(I64Add);
133   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
134                         MachineType::Int64());
135   BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
136   FOR_INT64_INPUTS(i) {
137     FOR_INT64_INPUTS(j) { CHECK_EQ(*i + *j, r.Call(*i, *j)); }
138   }
139 }
140 
WASM_EXEC_TEST(I64Sub)141 WASM_EXEC_TEST(I64Sub) {
142   REQUIRE(I64Sub);
143   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
144                         MachineType::Int64());
145   BUILD(r, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
146   FOR_INT64_INPUTS(i) {
147     FOR_INT64_INPUTS(j) { CHECK_EQ(*i - *j, r.Call(*i, *j)); }
148   }
149 }
150 
WASM_EXEC_TEST(I64DivS)151 WASM_EXEC_TEST(I64DivS) {
152   REQUIRE(I64DivS);
153   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
154                         MachineType::Int64());
155   BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
156   FOR_INT64_INPUTS(i) {
157     FOR_INT64_INPUTS(j) {
158       if (*j == 0) {
159         CHECK_TRAP64(r.Call(*i, *j));
160       } else if (*j == -1 && *i == std::numeric_limits<int64_t>::min()) {
161         CHECK_TRAP64(r.Call(*i, *j));
162       } else {
163         CHECK_EQ(*i / *j, r.Call(*i, *j));
164       }
165     }
166   }
167 }
168 
WASM_EXEC_TEST(I64DivS_Trap)169 WASM_EXEC_TEST(I64DivS_Trap) {
170   REQUIRE(I64DivS);
171   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
172                         MachineType::Int64());
173   BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
174   CHECK_EQ(0, r.Call(asi64(0), asi64(100)));
175   CHECK_TRAP64(r.Call(asi64(100), asi64(0)));
176   CHECK_TRAP64(r.Call(asi64(-1001), asi64(0)));
177   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), asi64(-1)));
178   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), asi64(0)));
179 }
180 
WASM_EXEC_TEST(I64DivS_Byzero_Const)181 WASM_EXEC_TEST(I64DivS_Byzero_Const) {
182   REQUIRE(I64DivS);
183   for (int8_t denom = -2; denom < 8; denom++) {
184     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
185     BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(denom)));
186     for (int64_t val = -7; val < 8; val++) {
187       if (denom == 0) {
188         CHECK_TRAP64(r.Call(val));
189       } else {
190         CHECK_EQ(val / denom, r.Call(val));
191       }
192     }
193   }
194 }
195 
WASM_EXEC_TEST(I64DivU)196 WASM_EXEC_TEST(I64DivU) {
197   REQUIRE(I64DivU);
198   WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
199                          MachineType::Uint64());
200   BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
201   FOR_UINT64_INPUTS(i) {
202     FOR_UINT64_INPUTS(j) {
203       if (*j == 0) {
204         CHECK_TRAP64(r.Call(*i, *j));
205       } else {
206         CHECK_EQ(*i / *j, r.Call(*i, *j));
207       }
208     }
209   }
210 }
211 
WASM_EXEC_TEST(I64DivU_Trap)212 WASM_EXEC_TEST(I64DivU_Trap) {
213   REQUIRE(I64DivU);
214   WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
215                          MachineType::Uint64());
216   BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
217   CHECK_EQ(0, r.Call(asu64(0), asu64(100)));
218   CHECK_TRAP64(r.Call(asu64(100), asu64(0)));
219   CHECK_TRAP64(r.Call(asu64(1001), asu64(0)));
220   CHECK_TRAP64(r.Call(std::numeric_limits<uint64_t>::max(), asu64(0)));
221 }
222 
WASM_EXEC_TEST(I64DivU_Byzero_Const)223 WASM_EXEC_TEST(I64DivU_Byzero_Const) {
224   REQUIRE(I64DivU);
225   for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) {
226     WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64());
227     BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(denom)));
228 
229     for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) {
230       if (denom == 0) {
231         CHECK_TRAP64(r.Call(val));
232       } else {
233         CHECK_EQ(val / denom, r.Call(val));
234       }
235     }
236   }
237 }
238 
WASM_EXEC_TEST(I64RemS)239 WASM_EXEC_TEST(I64RemS) {
240   REQUIRE(I64RemS);
241   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
242                         MachineType::Int64());
243   BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
244   FOR_INT64_INPUTS(i) {
245     FOR_INT64_INPUTS(j) {
246       if (*j == 0) {
247         CHECK_TRAP64(r.Call(*i, *j));
248       } else {
249         CHECK_EQ(*i % *j, r.Call(*i, *j));
250       }
251     }
252   }
253 }
254 
WASM_EXEC_TEST(I64RemS_Trap)255 WASM_EXEC_TEST(I64RemS_Trap) {
256   REQUIRE(I64RemS);
257   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
258                         MachineType::Int64());
259   BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
260   CHECK_EQ(33, r.Call(asi64(133), asi64(100)));
261   CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), asi64(-1)));
262   CHECK_TRAP64(r.Call(asi64(100), asi64(0)));
263   CHECK_TRAP64(r.Call(asi64(-1001), asi64(0)));
264   CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), asi64(0)));
265 }
266 
WASM_EXEC_TEST(I64RemU)267 WASM_EXEC_TEST(I64RemU) {
268   REQUIRE(I64RemU);
269   WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
270                          MachineType::Uint64());
271   BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
272   FOR_UINT64_INPUTS(i) {
273     FOR_UINT64_INPUTS(j) {
274       if (*j == 0) {
275         CHECK_TRAP64(r.Call(*i, *j));
276       } else {
277         CHECK_EQ(*i % *j, r.Call(*i, *j));
278       }
279     }
280   }
281 }
282 
WASM_EXEC_TEST(I64RemU_Trap)283 WASM_EXEC_TEST(I64RemU_Trap) {
284   REQUIRE(I64RemU);
285   WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
286                          MachineType::Uint64());
287   BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
288   CHECK_EQ(17, r.Call(asu64(217), asu64(100)));
289   CHECK_TRAP64(r.Call(asu64(100), asu64(0)));
290   CHECK_TRAP64(r.Call(asu64(1001), asu64(0)));
291   CHECK_TRAP64(r.Call(std::numeric_limits<uint64_t>::max(), asu64(0)));
292 }
293 
WASM_EXEC_TEST(I64And)294 WASM_EXEC_TEST(I64And) {
295   REQUIRE(I64And);
296   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
297                         MachineType::Int64());
298   BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
299   FOR_INT64_INPUTS(i) {
300     FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); }
301   }
302 }
303 
WASM_EXEC_TEST(I64Ior)304 WASM_EXEC_TEST(I64Ior) {
305   REQUIRE(I64Ior);
306   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
307                         MachineType::Int64());
308   BUILD(r, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
309   FOR_INT64_INPUTS(i) {
310     FOR_INT64_INPUTS(j) { CHECK_EQ((*i) | (*j), r.Call(*i, *j)); }
311   }
312 }
313 
WASM_EXEC_TEST(I64Xor)314 WASM_EXEC_TEST(I64Xor) {
315   REQUIRE(I64Xor);
316   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
317                         MachineType::Int64());
318   BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
319   FOR_INT64_INPUTS(i) {
320     FOR_INT64_INPUTS(j) { CHECK_EQ((*i) ^ (*j), r.Call(*i, *j)); }
321   }
322 }
323 
WASM_EXEC_TEST(I64Shl)324 WASM_EXEC_TEST(I64Shl) {
325   REQUIRE(I64Shl);
326   {
327     WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
328                            MachineType::Uint64());
329     BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
330 
331     FOR_UINT64_INPUTS(i) {
332       FOR_UINT64_INPUTS(j) {
333         uint64_t expected = (*i) << (*j & 0x3f);
334         CHECK_EQ(expected, r.Call(*i, *j));
335       }
336     }
337   }
338   {
339     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
340     BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
341     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 0, r.Call(*i)); }
342   }
343   {
344     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
345     BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
346     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 32, r.Call(*i)); }
347   }
348   {
349     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
350     BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
351     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 20, r.Call(*i)); }
352   }
353   {
354     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
355     BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
356     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 40, r.Call(*i)); }
357   }
358 }
359 
WASM_EXEC_TEST(I64ShrU)360 WASM_EXEC_TEST(I64ShrU) {
361   REQUIRE(I64ShrU);
362   {
363     WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
364                            MachineType::Uint64());
365     BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
366 
367     FOR_UINT64_INPUTS(i) {
368       FOR_UINT64_INPUTS(j) {
369         uint64_t expected = (*i) >> (*j & 0x3f);
370         CHECK_EQ(expected, r.Call(*i, *j));
371       }
372     }
373   }
374   {
375     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
376     BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
377     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 0, r.Call(*i)); }
378   }
379   {
380     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
381     BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
382     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 32, r.Call(*i)); }
383   }
384   {
385     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
386     BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
387     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); }
388   }
389   {
390     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
391     BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
392     FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); }
393   }
394 }
395 
WASM_EXEC_TEST(I64ShrS)396 WASM_EXEC_TEST(I64ShrS) {
397   REQUIRE(I64ShrS);
398   {
399     WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
400                           MachineType::Int64());
401     BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
402 
403     FOR_INT64_INPUTS(i) {
404       FOR_INT64_INPUTS(j) {
405         int64_t expected = (*i) >> (*j & 0x3f);
406         CHECK_EQ(expected, r.Call(*i, *j));
407       }
408     }
409   }
410   {
411     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
412     BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
413     FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 0, r.Call(*i)); }
414   }
415   {
416     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
417     BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
418     FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 32, r.Call(*i)); }
419   }
420   {
421     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
422     BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
423     FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); }
424   }
425   {
426     WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
427     BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
428     FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); }
429   }
430 }
431 
WASM_EXEC_TEST(I64Eq)432 WASM_EXEC_TEST(I64Eq) {
433   REQUIRE(I64Eq);
434   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
435                         MachineType::Int64());
436   BUILD(r, WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
437   FOR_INT64_INPUTS(i) {
438     FOR_INT64_INPUTS(j) { CHECK_EQ(*i == *j ? 1 : 0, r.Call(*i, *j)); }
439   }
440 }
441 
WASM_EXEC_TEST(I64Ne)442 WASM_EXEC_TEST(I64Ne) {
443   REQUIRE(I64Ne);
444   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
445                         MachineType::Int64());
446   BUILD(r, WASM_I64_NE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
447   FOR_INT64_INPUTS(i) {
448     FOR_INT64_INPUTS(j) { CHECK_EQ(*i != *j ? 1 : 0, r.Call(*i, *j)); }
449   }
450 }
451 
WASM_EXEC_TEST(I64LtS)452 WASM_EXEC_TEST(I64LtS) {
453   REQUIRE(I64LtS);
454   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
455                         MachineType::Int64());
456   BUILD(r, WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
457   FOR_INT64_INPUTS(i) {
458     FOR_INT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); }
459   }
460 }
461 
WASM_EXEC_TEST(I64LeS)462 WASM_EXEC_TEST(I64LeS) {
463   REQUIRE(I64LeS);
464   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
465                         MachineType::Int64());
466   BUILD(r, WASM_I64_LES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
467   FOR_INT64_INPUTS(i) {
468     FOR_INT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); }
469   }
470 }
471 
WASM_EXEC_TEST(I64LtU)472 WASM_EXEC_TEST(I64LtU) {
473   REQUIRE(I64LtU);
474   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
475                         MachineType::Int64());
476   BUILD(r, WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
477   FOR_UINT64_INPUTS(i) {
478     FOR_UINT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); }
479   }
480 }
481 
WASM_EXEC_TEST(I64LeU)482 WASM_EXEC_TEST(I64LeU) {
483   REQUIRE(I64LeU);
484   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
485                         MachineType::Int64());
486   BUILD(r, WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
487   FOR_UINT64_INPUTS(i) {
488     FOR_UINT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); }
489   }
490 }
491 
WASM_EXEC_TEST(I64GtS)492 WASM_EXEC_TEST(I64GtS) {
493   REQUIRE(I64GtS);
494   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
495                         MachineType::Int64());
496   BUILD(r, WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
497   FOR_INT64_INPUTS(i) {
498     FOR_INT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); }
499   }
500 }
501 
WASM_EXEC_TEST(I64GeS)502 WASM_EXEC_TEST(I64GeS) {
503   REQUIRE(I64GeS);
504   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
505                         MachineType::Int64());
506   BUILD(r, WASM_I64_GES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
507   FOR_INT64_INPUTS(i) {
508     FOR_INT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); }
509   }
510 }
511 
WASM_EXEC_TEST(I64GtU)512 WASM_EXEC_TEST(I64GtU) {
513   REQUIRE(I64GtU);
514   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
515                         MachineType::Int64());
516   BUILD(r, WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
517   FOR_UINT64_INPUTS(i) {
518     FOR_UINT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); }
519   }
520 }
521 
WASM_EXEC_TEST(I64GeU)522 WASM_EXEC_TEST(I64GeU) {
523   REQUIRE(I64GeU);
524   WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
525                         MachineType::Int64());
526   BUILD(r, WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
527   FOR_UINT64_INPUTS(i) {
528     FOR_UINT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); }
529   }
530 }
531 
WASM_EXEC_TEST(I32ConvertI64)532 WASM_EXEC_TEST(I32ConvertI64) {
533   REQUIRE(I32ConvertI64);
534   FOR_INT64_INPUTS(i) {
535     WasmRunner<int32_t> r(execution_mode);
536     BUILD(r, WASM_I32_CONVERT_I64(WASM_I64V(*i)));
537     CHECK_EQ(static_cast<int32_t>(*i), r.Call());
538   }
539 }
540 
WASM_EXEC_TEST(I64SConvertI32)541 WASM_EXEC_TEST(I64SConvertI32) {
542   REQUIRE(I64SConvertI32);
543   WasmRunner<int64_t> r(execution_mode, MachineType::Int32());
544   BUILD(r, WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)));
545   FOR_INT32_INPUTS(i) { CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); }
546 }
547 
WASM_EXEC_TEST(I64UConvertI32)548 WASM_EXEC_TEST(I64UConvertI32) {
549   REQUIRE(I64UConvertI32);
550   WasmRunner<int64_t> r(execution_mode, MachineType::Uint32());
551   BUILD(r, WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(0)));
552   FOR_UINT32_INPUTS(i) { CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); }
553 }
554 
WASM_EXEC_TEST(I64Popcnt)555 WASM_EXEC_TEST(I64Popcnt) {
556   struct {
557     int64_t expected;
558     uint64_t input;
559   } values[] = {{64, 0xffffffffffffffff},
560                 {0, 0x0000000000000000},
561                 {2, 0x0000080000008000},
562                 {26, 0x1123456782345678},
563                 {38, 0xffedcba09edcba09}};
564 
565   WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
566   BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
567   for (size_t i = 0; i < arraysize(values); i++) {
568     CHECK_EQ(values[i].expected, r.Call(values[i].input));
569   }
570 }
571 
WASM_EXEC_TEST(F32SConvertI64)572 WASM_EXEC_TEST(F32SConvertI64) {
573   REQUIRE(F32SConvertI64);
574   WasmRunner<float> r(execution_mode, MachineType::Int64());
575   BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0)));
576   FOR_INT64_INPUTS(i) { CHECK_FLOAT_EQ(static_cast<float>(*i), r.Call(*i)); }
577 }
578 
WASM_EXEC_TEST(F32UConvertI64)579 WASM_EXEC_TEST(F32UConvertI64) {
580   REQUIRE(F32UConvertI64);
581   struct {
582     uint64_t input;
583     uint32_t expected;
584   } values[] = {{0x0, 0x0},
585                 {0x1, 0x3f800000},
586                 {0xffffffff, 0x4f800000},
587                 {0x1b09788b, 0x4dd84bc4},
588                 {0x4c5fce8, 0x4c98bf9d},
589                 {0xcc0de5bf, 0x4f4c0de6},
590                 {0x2, 0x40000000},
591                 {0x3, 0x40400000},
592                 {0x4, 0x40800000},
593                 {0x5, 0x40a00000},
594                 {0x8, 0x41000000},
595                 {0x9, 0x41100000},
596                 {0xffffffffffffffff, 0x5f800000},
597                 {0xfffffffffffffffe, 0x5f800000},
598                 {0xfffffffffffffffd, 0x5f800000},
599                 {0x0, 0x0},
600                 {0x100000000, 0x4f800000},
601                 {0xffffffff00000000, 0x5f800000},
602                 {0x1b09788b00000000, 0x5dd84bc4},
603                 {0x4c5fce800000000, 0x5c98bf9d},
604                 {0xcc0de5bf00000000, 0x5f4c0de6},
605                 {0x200000000, 0x50000000},
606                 {0x300000000, 0x50400000},
607                 {0x400000000, 0x50800000},
608                 {0x500000000, 0x50a00000},
609                 {0x800000000, 0x51000000},
610                 {0x900000000, 0x51100000},
611                 {0x273a798e187937a3, 0x5e1ce9e6},
612                 {0xece3af835495a16b, 0x5f6ce3b0},
613                 {0xb668ecc11223344, 0x5d3668ed},
614                 {0x9e, 0x431e0000},
615                 {0x43, 0x42860000},
616                 {0xaf73, 0x472f7300},
617                 {0x116b, 0x458b5800},
618                 {0x658ecc, 0x4acb1d98},
619                 {0x2b3b4c, 0x4a2ced30},
620                 {0x88776655, 0x4f087766},
621                 {0x70000000, 0x4ee00000},
622                 {0x7200000, 0x4ce40000},
623                 {0x7fffffff, 0x4f000000},
624                 {0x56123761, 0x4eac246f},
625                 {0x7fffff00, 0x4efffffe},
626                 {0x761c4761eeeeeeee, 0x5eec388f},
627                 {0x80000000eeeeeeee, 0x5f000000},
628                 {0x88888888dddddddd, 0x5f088889},
629                 {0xa0000000dddddddd, 0x5f200000},
630                 {0xddddddddaaaaaaaa, 0x5f5dddde},
631                 {0xe0000000aaaaaaaa, 0x5f600000},
632                 {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
633                 {0xfffffffdeeeeeeee, 0x5f800000},
634                 {0xf0000000dddddddd, 0x5f700000},
635                 {0x7fffffdddddddd, 0x5b000000},
636                 {0x3fffffaaaaaaaa, 0x5a7fffff},
637                 {0x1fffffaaaaaaaa, 0x59fffffd},
638                 {0xfffff, 0x497ffff0},
639                 {0x7ffff, 0x48ffffe0},
640                 {0x3ffff, 0x487fffc0},
641                 {0x1ffff, 0x47ffff80},
642                 {0xffff, 0x477fff00},
643                 {0x7fff, 0x46fffe00},
644                 {0x3fff, 0x467ffc00},
645                 {0x1fff, 0x45fff800},
646                 {0xfff, 0x457ff000},
647                 {0x7ff, 0x44ffe000},
648                 {0x3ff, 0x447fc000},
649                 {0x1ff, 0x43ff8000},
650                 {0x3fffffffffff, 0x56800000},
651                 {0x1fffffffffff, 0x56000000},
652                 {0xfffffffffff, 0x55800000},
653                 {0x7ffffffffff, 0x55000000},
654                 {0x3ffffffffff, 0x54800000},
655                 {0x1ffffffffff, 0x54000000},
656                 {0x8000008000000000, 0x5f000000},
657                 {0x8000008000000001, 0x5f000001},
658                 {0x8000000000000400, 0x5f000000},
659                 {0x8000000000000401, 0x5f000000}};
660   WasmRunner<float> r(execution_mode, MachineType::Uint64());
661   BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0)));
662   for (size_t i = 0; i < arraysize(values); i++) {
663     CHECK_EQ(bit_cast<float>(values[i].expected), r.Call(values[i].input));
664   }
665 }
666 
WASM_EXEC_TEST(F64SConvertI64)667 WASM_EXEC_TEST(F64SConvertI64) {
668   REQUIRE(F64SConvertI64);
669   WasmRunner<double> r(execution_mode, MachineType::Int64());
670   BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0)));
671   FOR_INT64_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), r.Call(*i)); }
672 }
673 
WASM_EXEC_TEST(F64UConvertI64)674 WASM_EXEC_TEST(F64UConvertI64) {
675   REQUIRE(F64UConvertI64);
676   struct {
677     uint64_t input;
678     uint64_t expected;
679   } values[] = {{0x0, 0x0},
680                 {0x1, 0x3ff0000000000000},
681                 {0xffffffff, 0x41efffffffe00000},
682                 {0x1b09788b, 0x41bb09788b000000},
683                 {0x4c5fce8, 0x419317f3a0000000},
684                 {0xcc0de5bf, 0x41e981bcb7e00000},
685                 {0x2, 0x4000000000000000},
686                 {0x3, 0x4008000000000000},
687                 {0x4, 0x4010000000000000},
688                 {0x5, 0x4014000000000000},
689                 {0x8, 0x4020000000000000},
690                 {0x9, 0x4022000000000000},
691                 {0xffffffffffffffff, 0x43f0000000000000},
692                 {0xfffffffffffffffe, 0x43f0000000000000},
693                 {0xfffffffffffffffd, 0x43f0000000000000},
694                 {0x100000000, 0x41f0000000000000},
695                 {0xffffffff00000000, 0x43efffffffe00000},
696                 {0x1b09788b00000000, 0x43bb09788b000000},
697                 {0x4c5fce800000000, 0x439317f3a0000000},
698                 {0xcc0de5bf00000000, 0x43e981bcb7e00000},
699                 {0x200000000, 0x4200000000000000},
700                 {0x300000000, 0x4208000000000000},
701                 {0x400000000, 0x4210000000000000},
702                 {0x500000000, 0x4214000000000000},
703                 {0x800000000, 0x4220000000000000},
704                 {0x900000000, 0x4222000000000000},
705                 {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
706                 {0xece3af835495a16b, 0x43ed9c75f06a92b4},
707                 {0xb668ecc11223344, 0x43a6cd1d98224467},
708                 {0x9e, 0x4063c00000000000},
709                 {0x43, 0x4050c00000000000},
710                 {0xaf73, 0x40e5ee6000000000},
711                 {0x116b, 0x40b16b0000000000},
712                 {0x658ecc, 0x415963b300000000},
713                 {0x2b3b4c, 0x41459da600000000},
714                 {0x88776655, 0x41e10eeccaa00000},
715                 {0x70000000, 0x41dc000000000000},
716                 {0x7200000, 0x419c800000000000},
717                 {0x7fffffff, 0x41dfffffffc00000},
718                 {0x56123761, 0x41d5848dd8400000},
719                 {0x7fffff00, 0x41dfffffc0000000},
720                 {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
721                 {0x80000000eeeeeeee, 0x43e00000001dddde},
722                 {0x88888888dddddddd, 0x43e11111111bbbbc},
723                 {0xa0000000dddddddd, 0x43e40000001bbbbc},
724                 {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
725                 {0xe0000000aaaaaaaa, 0x43ec000000155555},
726                 {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
727                 {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
728                 {0xf0000000dddddddd, 0x43ee0000001bbbbc},
729                 {0x7fffffdddddddd, 0x435ffffff7777777},
730                 {0x3fffffaaaaaaaa, 0x434fffffd5555555},
731                 {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
732                 {0xfffff, 0x412ffffe00000000},
733                 {0x7ffff, 0x411ffffc00000000},
734                 {0x3ffff, 0x410ffff800000000},
735                 {0x1ffff, 0x40fffff000000000},
736                 {0xffff, 0x40efffe000000000},
737                 {0x7fff, 0x40dfffc000000000},
738                 {0x3fff, 0x40cfff8000000000},
739                 {0x1fff, 0x40bfff0000000000},
740                 {0xfff, 0x40affe0000000000},
741                 {0x7ff, 0x409ffc0000000000},
742                 {0x3ff, 0x408ff80000000000},
743                 {0x1ff, 0x407ff00000000000},
744                 {0x3fffffffffff, 0x42cfffffffffff80},
745                 {0x1fffffffffff, 0x42bfffffffffff00},
746                 {0xfffffffffff, 0x42affffffffffe00},
747                 {0x7ffffffffff, 0x429ffffffffffc00},
748                 {0x3ffffffffff, 0x428ffffffffff800},
749                 {0x1ffffffffff, 0x427ffffffffff000},
750                 {0x8000008000000000, 0x43e0000010000000},
751                 {0x8000008000000001, 0x43e0000010000000},
752                 {0x8000000000000400, 0x43e0000000000000},
753                 {0x8000000000000401, 0x43e0000000000001}};
754   WasmRunner<double> r(execution_mode, MachineType::Uint64());
755   BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0)));
756   for (size_t i = 0; i < arraysize(values); i++) {
757     CHECK_EQ(bit_cast<double>(values[i].expected), r.Call(values[i].input));
758   }
759 }
760 
WASM_EXEC_TEST(I64SConvertF32a)761 WASM_EXEC_TEST(I64SConvertF32a) {
762   WasmRunner<int64_t> r(execution_mode, MachineType::Float32());
763   BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
764 
765   FOR_FLOAT32_INPUTS(i) {
766     if (*i < static_cast<float>(std::numeric_limits<int64_t>::max()) &&
767         *i >= static_cast<float>(std::numeric_limits<int64_t>::min())) {
768       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
769     } else {
770       CHECK_TRAP64(r.Call(*i));
771     }
772   }
773 }
774 
WASM_EXEC_TEST(I64SConvertF64a)775 WASM_EXEC_TEST(I64SConvertF64a) {
776   WasmRunner<int64_t> r(execution_mode, MachineType::Float64());
777   BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
778 
779   FOR_FLOAT64_INPUTS(i) {
780     if (*i < static_cast<double>(std::numeric_limits<int64_t>::max()) &&
781         *i >= static_cast<double>(std::numeric_limits<int64_t>::min())) {
782       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
783     } else {
784       CHECK_TRAP64(r.Call(*i));
785     }
786   }
787 }
788 
WASM_EXEC_TEST(I64UConvertF32a)789 WASM_EXEC_TEST(I64UConvertF32a) {
790   WasmRunner<uint64_t> r(execution_mode, MachineType::Float32());
791   BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
792 
793   FOR_FLOAT32_INPUTS(i) {
794     if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
795         *i > -1) {
796       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
797     } else {
798       CHECK_TRAP64(r.Call(*i));
799     }
800   }
801 }
802 
WASM_EXEC_TEST(I64UConvertF64a)803 WASM_EXEC_TEST(I64UConvertF64a) {
804   WasmRunner<uint64_t> r(execution_mode, MachineType::Float64());
805   BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
806 
807   FOR_FLOAT64_INPUTS(i) {
808     if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
809         *i > -1) {
810       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
811     } else {
812       CHECK_TRAP64(r.Call(*i));
813     }
814   }
815 }
816 
WASM_EXEC_TEST(CallI64Parameter)817 WASM_EXEC_TEST(CallI64Parameter) {
818   // Build the target function.
819   LocalType param_types[20];
820   for (int i = 0; i < 20; i++) param_types[i] = kAstI64;
821   param_types[3] = kAstI32;
822   param_types[4] = kAstI32;
823   FunctionSig sig(1, 19, param_types);
824   for (int i = 0; i < 19; i++) {
825     TestingModule module(execution_mode);
826     WasmFunctionCompiler t(&sig, &module);
827     if (i == 2 || i == 3) {
828       continue;
829     } else {
830       BUILD(t, WASM_GET_LOCAL(i));
831     }
832     uint32_t index = t.CompileAndAdd();
833 
834     // Build the calling function.
835     WasmRunner<int32_t> r(&module);
836     BUILD(
837         r,
838         WASM_I32_CONVERT_I64(WASM_CALL_FUNCTIONN(
839             19, index, WASM_I64V_9(0xbcd12340000000b),
840             WASM_I64V_9(0xbcd12340000000c), WASM_I32V_1(0xd),
841             WASM_I32_CONVERT_I64(WASM_I64V_9(0xbcd12340000000e)),
842             WASM_I64V_9(0xbcd12340000000f), WASM_I64V_10(0xbcd1234000000010),
843             WASM_I64V_10(0xbcd1234000000011), WASM_I64V_10(0xbcd1234000000012),
844             WASM_I64V_10(0xbcd1234000000013), WASM_I64V_10(0xbcd1234000000014),
845             WASM_I64V_10(0xbcd1234000000015), WASM_I64V_10(0xbcd1234000000016),
846             WASM_I64V_10(0xbcd1234000000017), WASM_I64V_10(0xbcd1234000000018),
847             WASM_I64V_10(0xbcd1234000000019), WASM_I64V_10(0xbcd123400000001a),
848             WASM_I64V_10(0xbcd123400000001b), WASM_I64V_10(0xbcd123400000001c),
849             WASM_I64V_10(0xbcd123400000001d))));
850 
851     CHECK_EQ(i + 0xb, r.Call());
852   }
853 }
854 
TestI64Binop(WasmExecutionMode execution_mode,WasmOpcode opcode,int64_t expected,int64_t a,int64_t b)855 void TestI64Binop(WasmExecutionMode execution_mode, WasmOpcode opcode,
856                   int64_t expected, int64_t a, int64_t b) {
857   {
858     WasmRunner<int64_t> r(execution_mode);
859     // return K op K
860     BUILD(r, WASM_BINOP(opcode, WASM_I64V(a), WASM_I64V(b)));
861     CHECK_EQ(expected, r.Call());
862   }
863   {
864     WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
865                           MachineType::Int64());
866     // return a op b
867     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
868     CHECK_EQ(expected, r.Call(a, b));
869   }
870 }
871 
TestI64Cmp(WasmExecutionMode execution_mode,WasmOpcode opcode,int64_t expected,int64_t a,int64_t b)872 void TestI64Cmp(WasmExecutionMode execution_mode, WasmOpcode opcode,
873                 int64_t expected, int64_t a, int64_t b) {
874   {
875     WasmRunner<int32_t> r(execution_mode);
876     // return K op K
877     BUILD(r, WASM_BINOP(opcode, WASM_I64V(a), WASM_I64V(b)));
878     CHECK_EQ(expected, r.Call());
879   }
880   {
881     WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
882                           MachineType::Int64());
883     // return a op b
884     BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
885     CHECK_EQ(expected, r.Call(a, b));
886   }
887 }
888 
889 #define TEST_I64_BINOP(name, expected, a, b)                     \
890   do {                                                           \
891     if (WASM_64 || kSupported_##name)                            \
892       TestI64Binop(execution_mode, kExpr##name, expected, a, b); \
893   } while (false)
894 
WASM_EXEC_TEST(I64Binops)895 WASM_EXEC_TEST(I64Binops) {
896   TEST_I64_BINOP(I64Add, -5586332274295447011, 0x501b72ebabc26847,
897                  0x625de9793d8f79d6);
898   TEST_I64_BINOP(I64Sub, 9001903251710731490, 0xf24fe6474640002e,
899                  0x7562b6f711991b4c);
900   TEST_I64_BINOP(I64Mul, -4569547818546064176, 0x231a263c2cbc6451,
901                  0xead44de6bd3e23d0);
902   TEST_I64_BINOP(I64Mul, -25963122347507043, 0x4da1fa47c9352b73,
903                  0x91fe82317aa035af);
904   TEST_I64_BINOP(I64Mul, 7640290486138131960, 0x185731abe8eea47c,
905                  0x714ec59f1380d4c2);
906   TEST_I64_BINOP(I64DivS, -91517, 0x93b1190a34de56a0, 0x00004d8f68863948);
907   TEST_I64_BINOP(I64DivU, 149016, 0xe15b3727e8a2080a, 0x0000631bfa72db8b);
908   TEST_I64_BINOP(I64RemS, -664128064149968, 0x9a78b4e4fe708692,
909                  0x0003e0b6b3be7609);
910   TEST_I64_BINOP(I64RemU, 1742040017332765, 0x0ce84708c6258c81,
911                  0x000a6fde82016697);
912   TEST_I64_BINOP(I64And, 2531040582801836054, 0xaf257d1602644a16,
913                  0x33b290a91a10d997);
914   TEST_I64_BINOP(I64Ior, 8556201506536114940, 0x169d9be7bd3f0a5c,
915                  0x66bca28d77af40e8);
916   TEST_I64_BINOP(I64Xor, -4605655183785456377, 0xb6ea20a5d48e85b8,
917                  0x76ff4da6c80688bf);
918   TEST_I64_BINOP(I64Shl, -7240704056088331264, 0xef4dc1ed030e8ffe, 9);
919   TEST_I64_BINOP(I64ShrU, 12500673744059159, 0xb1a52fa7deec5d14, 10);
920   TEST_I64_BINOP(I64ShrS, 1725103446999874, 0x3107c791461a112b, 11);
921   TEST_I64_BINOP(I64Ror, -8960135652432576946, 0x73418d1717e4e83a, 12);
922   TEST_I64_BINOP(I64Ror, 7617662827409989779, 0xebff67cf0c126d36, 13);
923   TEST_I64_BINOP(I64Rol, -2097714064174346012, 0x43938b8db0b0f230, 14);
924   TEST_I64_BINOP(I64Rol, 8728493013947314237, 0xe07af243ac4d219d, 15);
925 }
926 
927 #define TEST_I64_CMP(name, expected, a, b)                     \
928   do {                                                         \
929     if (WASM_64 || kSupported_##name)                          \
930       TestI64Cmp(execution_mode, kExpr##name, expected, a, b); \
931   } while (false)
932 
WASM_EXEC_TEST(I64Compare)933 WASM_EXEC_TEST(I64Compare) {
934   TEST_I64_CMP(I64Eq, 0, 0xB915D8FA494064F0, 0x04D700B2536019A3);
935   TEST_I64_CMP(I64Ne, 1, 0xC2FAFAAAB0446CDC, 0x52A3328F780C97A3);
936   TEST_I64_CMP(I64LtS, 0, 0x673636E6306B0578, 0x028EC9ECA78F7227);
937   TEST_I64_CMP(I64LeS, 1, 0xAE5214114B86A0FA, 0x7C1D21DA3DFD0CCF);
938   TEST_I64_CMP(I64LtU, 0, 0x7D52166381EC1CE0, 0x59F4A6A9E78CD3D8);
939   TEST_I64_CMP(I64LeU, 1, 0xE4169A385C7EA0E0, 0xFBDBED2C8781E5BC);
940   TEST_I64_CMP(I64GtS, 0, 0x9D08FF8FB5F42E81, 0xD4E5C9D7FE09F621);
941   TEST_I64_CMP(I64GeS, 1, 0x78DA3B2F73264E0F, 0x6FE5E2A67C501CBE);
942   TEST_I64_CMP(I64GtU, 0, 0x8F691284E44F7DA9, 0xD5EA9BC1EE149192);
943   TEST_I64_CMP(I64GeU, 0, 0x0886A0C58C7AA224, 0x5DDBE5A81FD7EE47);
944 }
945 
WASM_EXEC_TEST(I64Clz)946 WASM_EXEC_TEST(I64Clz) {
947   REQUIRE(I64Clz);
948   struct {
949     int64_t expected;
950     uint64_t input;
951   } values[] = {{0, 0x8000100000000000},  {1, 0x4000050000000000},
952                 {2, 0x2000030000000000},  {3, 0x1000000300000000},
953                 {4, 0x0805000000000000},  {5, 0x0400600000000000},
954                 {6, 0x0200000000000000},  {7, 0x010000a000000000},
955                 {8, 0x00800c0000000000},  {9, 0x0040000000000000},
956                 {10, 0x0020000d00000000}, {11, 0x00100f0000000000},
957                 {12, 0x0008000000000000}, {13, 0x0004100000000000},
958                 {14, 0x0002002000000000}, {15, 0x0001030000000000},
959                 {16, 0x0000804000000000}, {17, 0x0000400500000000},
960                 {18, 0x0000205000000000}, {19, 0x0000170000000000},
961                 {20, 0x0000087000000000}, {21, 0x0000040500000000},
962                 {22, 0x0000020300000000}, {23, 0x0000010100000000},
963                 {24, 0x0000008900000000}, {25, 0x0000004100000000},
964                 {26, 0x0000002200000000}, {27, 0x0000001300000000},
965                 {28, 0x0000000800000000}, {29, 0x0000000400000000},
966                 {30, 0x0000000200000000}, {31, 0x0000000100000000},
967                 {32, 0x0000000080001000}, {33, 0x0000000040000500},
968                 {34, 0x0000000020000300}, {35, 0x0000000010000003},
969                 {36, 0x0000000008050000}, {37, 0x0000000004006000},
970                 {38, 0x0000000002000000}, {39, 0x00000000010000a0},
971                 {40, 0x0000000000800c00}, {41, 0x0000000000400000},
972                 {42, 0x000000000020000d}, {43, 0x0000000000100f00},
973                 {44, 0x0000000000080000}, {45, 0x0000000000041000},
974                 {46, 0x0000000000020020}, {47, 0x0000000000010300},
975                 {48, 0x0000000000008040}, {49, 0x0000000000004005},
976                 {50, 0x0000000000002050}, {51, 0x0000000000001700},
977                 {52, 0x0000000000000870}, {53, 0x0000000000000405},
978                 {54, 0x0000000000000203}, {55, 0x0000000000000101},
979                 {56, 0x0000000000000089}, {57, 0x0000000000000041},
980                 {58, 0x0000000000000022}, {59, 0x0000000000000013},
981                 {60, 0x0000000000000008}, {61, 0x0000000000000004},
982                 {62, 0x0000000000000002}, {63, 0x0000000000000001},
983                 {64, 0x0000000000000000}};
984 
985   WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
986   BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0)));
987   for (size_t i = 0; i < arraysize(values); i++) {
988     CHECK_EQ(values[i].expected, r.Call(values[i].input));
989   }
990 }
991 
WASM_EXEC_TEST(I64Ctz)992 WASM_EXEC_TEST(I64Ctz) {
993   REQUIRE(I64Ctz);
994   struct {
995     int64_t expected;
996     uint64_t input;
997   } values[] = {{64, 0x0000000000000000}, {63, 0x8000000000000000},
998                 {62, 0x4000000000000000}, {61, 0x2000000000000000},
999                 {60, 0x1000000000000000}, {59, 0xa800000000000000},
1000                 {58, 0xf400000000000000}, {57, 0x6200000000000000},
1001                 {56, 0x9100000000000000}, {55, 0xcd80000000000000},
1002                 {54, 0x0940000000000000}, {53, 0xaf20000000000000},
1003                 {52, 0xac10000000000000}, {51, 0xe0b8000000000000},
1004                 {50, 0x9ce4000000000000}, {49, 0xc792000000000000},
1005                 {48, 0xb8f1000000000000}, {47, 0x3b9f800000000000},
1006                 {46, 0xdb4c400000000000}, {45, 0xe9a3200000000000},
1007                 {44, 0xfca6100000000000}, {43, 0x6c8a780000000000},
1008                 {42, 0x8ce5a40000000000}, {41, 0xcb7d020000000000},
1009                 {40, 0xcb4dc10000000000}, {39, 0xdfbec58000000000},
1010                 {38, 0x27a9db4000000000}, {37, 0xde3bcb2000000000},
1011                 {36, 0xd7e8a61000000000}, {35, 0x9afdbc8800000000},
1012                 {34, 0x9afdbc8400000000}, {33, 0x9afdbc8200000000},
1013                 {32, 0x9afdbc8100000000}, {31, 0x0000000080000000},
1014                 {30, 0x0000000040000000}, {29, 0x0000000020000000},
1015                 {28, 0x0000000010000000}, {27, 0x00000000a8000000},
1016                 {26, 0x00000000f4000000}, {25, 0x0000000062000000},
1017                 {24, 0x0000000091000000}, {23, 0x00000000cd800000},
1018                 {22, 0x0000000009400000}, {21, 0x00000000af200000},
1019                 {20, 0x00000000ac100000}, {19, 0x00000000e0b80000},
1020                 {18, 0x000000009ce40000}, {17, 0x00000000c7920000},
1021                 {16, 0x00000000b8f10000}, {15, 0x000000003b9f8000},
1022                 {14, 0x00000000db4c4000}, {13, 0x00000000e9a32000},
1023                 {12, 0x00000000fca61000}, {11, 0x000000006c8a7800},
1024                 {10, 0x000000008ce5a400}, {9, 0x00000000cb7d0200},
1025                 {8, 0x00000000cb4dc100},  {7, 0x00000000dfbec580},
1026                 {6, 0x0000000027a9db40},  {5, 0x00000000de3bcb20},
1027                 {4, 0x00000000d7e8a610},  {3, 0x000000009afdbc88},
1028                 {2, 0x000000009afdbc84},  {1, 0x000000009afdbc82},
1029                 {0, 0x000000009afdbc81}};
1030 
1031   WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
1032   BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0)));
1033   for (size_t i = 0; i < arraysize(values); i++) {
1034     CHECK_EQ(values[i].expected, r.Call(values[i].input));
1035   }
1036 }
1037 
WASM_EXEC_TEST(I64Popcnt2)1038 WASM_EXEC_TEST(I64Popcnt2) {
1039   REQUIRE(I64Popcnt);
1040   struct {
1041     int64_t expected;
1042     uint64_t input;
1043   } values[] = {{64, 0xffffffffffffffff},
1044                 {0, 0x0000000000000000},
1045                 {2, 0x0000080000008000},
1046                 {26, 0x1123456782345678},
1047                 {38, 0xffedcba09edcba09}};
1048 
1049   WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
1050   BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
1051   for (size_t i = 0; i < arraysize(values); i++) {
1052     CHECK_EQ(values[i].expected, r.Call(values[i].input));
1053   }
1054 }
1055 
1056 // Test the WasmRunner with an Int64 return value and different numbers of
1057 // Int64 parameters.
WASM_EXEC_TEST(I64WasmRunner)1058 WASM_EXEC_TEST(I64WasmRunner) {
1059   REQUIRE(I64Param);
1060   REQUIRE(I64Xor);
1061   {FOR_INT64_INPUTS(i){WasmRunner<int64_t> r(execution_mode);
1062   BUILD(r, WASM_I64V(*i));
1063   CHECK_EQ(*i, r.Call());
1064 }
1065 }
1066 {
1067   WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
1068   BUILD(r, WASM_GET_LOCAL(0));
1069   FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1070 }
1071 {
1072   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
1073                         MachineType::Int64());
1074   BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
1075   FOR_INT64_INPUTS(i) {
1076     FOR_INT64_INPUTS(j) { CHECK_EQ(*i ^ *j, r.Call(*i, *j)); }
1077   }
1078 }
1079 {
1080   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
1081                         MachineType::Int64(), MachineType::Int64());
1082   BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0),
1083                         WASM_I64_XOR(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2))));
1084   FOR_INT64_INPUTS(i) {
1085     FOR_INT64_INPUTS(j) {
1086       CHECK_EQ(*i ^ *j ^ *j, r.Call(*i, *j, *j));
1087       CHECK_EQ(*j ^ *i ^ *j, r.Call(*j, *i, *j));
1088       CHECK_EQ(*j ^ *j ^ *i, r.Call(*j, *j, *i));
1089     }
1090   }
1091 }
1092 {
1093   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
1094                         MachineType::Int64(), MachineType::Int64(),
1095                         MachineType::Int64());
1096   BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0),
1097                         WASM_I64_XOR(WASM_GET_LOCAL(1),
1098                                      WASM_I64_XOR(WASM_GET_LOCAL(2),
1099                                                   WASM_GET_LOCAL(3)))));
1100   FOR_INT64_INPUTS(i) {
1101     FOR_INT64_INPUTS(j) {
1102       CHECK_EQ(*i ^ *j ^ *j ^ *j, r.Call(*i, *j, *j, *j));
1103       CHECK_EQ(*j ^ *i ^ *j ^ *j, r.Call(*j, *i, *j, *j));
1104       CHECK_EQ(*j ^ *j ^ *i ^ *j, r.Call(*j, *j, *i, *j));
1105       CHECK_EQ(*j ^ *j ^ *j ^ *i, r.Call(*j, *j, *j, *i));
1106     }
1107   }
1108 }
1109 }
1110 
WASM_EXEC_TEST(Call_Int64Sub)1111 WASM_EXEC_TEST(Call_Int64Sub) {
1112   REQUIRE(I64Sub);
1113   // Build the target function.
1114   TestSignatures sigs;
1115   TestingModule module(execution_mode);
1116   WasmFunctionCompiler t(sigs.l_ll(), &module);
1117   BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
1118   uint32_t index = t.CompileAndAdd();
1119 
1120   // Build the caller function.
1121   WasmRunner<int64_t> r(&module, MachineType::Int64(), MachineType::Int64());
1122   BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
1123 
1124   FOR_INT32_INPUTS(i) {
1125     FOR_INT32_INPUTS(j) {
1126       int64_t a = static_cast<int64_t>(*i) << 32 |
1127                   (static_cast<int64_t>(*j) | 0xFFFFFFFF);
1128       int64_t b = static_cast<int64_t>(*j) << 32 |
1129                   (static_cast<int64_t>(*i) | 0xFFFFFFFF);
1130 
1131       int64_t expected = static_cast<int64_t>(static_cast<uint64_t>(a) -
1132                                               static_cast<uint64_t>(b));
1133       CHECK_EQ(expected, r.Call(a, b));
1134     }
1135   }
1136 }
1137 
WASM_EXEC_TEST(LoadStoreI64_sx)1138 WASM_EXEC_TEST(LoadStoreI64_sx) {
1139   REQUIRE(I64LoadStore);
1140   REQUIRE(DepthFirst);
1141   byte loads[] = {kExprI64LoadMem8S, kExprI64LoadMem16S, kExprI64LoadMem32S,
1142                   kExprI64LoadMem};
1143 
1144   for (size_t m = 0; m < arraysize(loads); m++) {
1145     TestingModule module(execution_mode);
1146     byte* memory = module.AddMemoryElems<byte>(16);
1147     WasmRunner<int64_t> r(&module);
1148 
1149     byte code[] = {
1150         kExprI8Const,     8,  // --
1151         kExprI8Const,     0,  // --
1152         loads[m],             // --
1153         ZERO_ALIGNMENT,       // --
1154         ZERO_OFFSET,          // --
1155         kExprI64StoreMem,     // --
1156         ZERO_ALIGNMENT,       // --
1157         ZERO_OFFSET           // --
1158     };
1159 
1160     r.Build(code, code + arraysize(code));
1161 
1162     // Try a bunch of different negative values.
1163     for (int i = -1; i >= -128; i -= 11) {
1164       int size = 1 << m;
1165       module.BlankMemory();
1166       memory[size - 1] = static_cast<byte>(i);  // set the high order byte.
1167 
1168       int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8);
1169 
1170       CHECK_EQ(expected, r.Call());
1171       CHECK_EQ(static_cast<byte>(i), memory[8 + size - 1]);
1172       for (int j = size; j < 8; j++) {
1173         CHECK_EQ(255, memory[8 + j]);
1174       }
1175     }
1176   }
1177 }
1178 
WASM_EXEC_TEST(I64SConvertF32b)1179 WASM_EXEC_TEST(I64SConvertF32b) {
1180   REQUIRE(I64SConvertF32);
1181   WasmRunner<int64_t> r(execution_mode, MachineType::Float32());
1182   BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
1183 
1184   FOR_FLOAT32_INPUTS(i) {
1185     if (*i < static_cast<float>(INT64_MAX) &&
1186         *i >= static_cast<float>(INT64_MIN)) {
1187       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
1188     } else {
1189       CHECK_TRAP64(r.Call(*i));
1190     }
1191   }
1192 }
1193 
WASM_EXEC_TEST(I64SConvertF64b)1194 WASM_EXEC_TEST(I64SConvertF64b) {
1195   REQUIRE(I64SConvertF64);
1196   WasmRunner<int64_t> r(execution_mode, MachineType::Float64());
1197   BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
1198 
1199   FOR_FLOAT64_INPUTS(i) {
1200     if (*i < static_cast<double>(INT64_MAX) &&
1201         *i >= static_cast<double>(INT64_MIN)) {
1202       CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
1203     } else {
1204       CHECK_TRAP64(r.Call(*i));
1205     }
1206   }
1207 }
1208 
WASM_EXEC_TEST(I64UConvertF32b)1209 WASM_EXEC_TEST(I64UConvertF32b) {
1210   REQUIRE(I64UConvertF32);
1211   WasmRunner<uint64_t> r(execution_mode, MachineType::Float32());
1212   BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
1213 
1214   FOR_FLOAT32_INPUTS(i) {
1215     if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
1216       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
1217     } else {
1218       CHECK_TRAP64(r.Call(*i));
1219     }
1220   }
1221 }
1222 
WASM_EXEC_TEST(I64UConvertF64b)1223 WASM_EXEC_TEST(I64UConvertF64b) {
1224   REQUIRE(I64UConvertF64);
1225   WasmRunner<uint64_t> r(execution_mode, MachineType::Float64());
1226   BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
1227 
1228   FOR_FLOAT64_INPUTS(i) {
1229     if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
1230       CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
1231     } else {
1232       CHECK_TRAP64(r.Call(*i));
1233     }
1234   }
1235 }
1236 
WASM_EXEC_TEST(I64ReinterpretF64)1237 WASM_EXEC_TEST(I64ReinterpretF64) {
1238   REQUIRE(I64ReinterpretF64);
1239   TestingModule module(execution_mode);
1240   int64_t* memory = module.AddMemoryElems<int64_t>(8);
1241   WasmRunner<int64_t> r(&module);
1242 
1243   BUILD(r, WASM_I64_REINTERPRET_F64(
1244                WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)));
1245 
1246   FOR_INT32_INPUTS(i) {
1247     int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
1248     memory[0] = expected;
1249     CHECK_EQ(expected, r.Call());
1250   }
1251 }
1252 
WASM_EXEC_TEST(F64ReinterpretI64)1253 WASM_EXEC_TEST(F64ReinterpretI64) {
1254   REQUIRE(F64ReinterpretI64);
1255   TestingModule module(execution_mode);
1256   int64_t* memory = module.AddMemoryElems<int64_t>(8);
1257   WasmRunner<int64_t> r(&module, MachineType::Int64());
1258 
1259   BUILD(r, WASM_BLOCK(
1260                2, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO,
1261                                  WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))),
1262                WASM_GET_LOCAL(0)));
1263 
1264   FOR_INT32_INPUTS(i) {
1265     int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
1266     CHECK_EQ(expected, r.Call(expected));
1267     CHECK_EQ(expected, memory[0]);
1268   }
1269 }
1270 
WASM_EXEC_TEST(LoadMemI64)1271 WASM_EXEC_TEST(LoadMemI64) {
1272   REQUIRE(I64LoadStore);
1273   TestingModule module(execution_mode);
1274   int64_t* memory = module.AddMemoryElems<int64_t>(8);
1275   module.RandomizeMemory(1111);
1276   WasmRunner<int64_t> r(&module);
1277 
1278   BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0)));
1279 
1280   memory[0] = 0xaabbccdd00112233LL;
1281   CHECK_EQ(0xaabbccdd00112233LL, r.Call());
1282 
1283   memory[0] = 0x33aabbccdd001122LL;
1284   CHECK_EQ(0x33aabbccdd001122LL, r.Call());
1285 
1286   memory[0] = 77777777;
1287   CHECK_EQ(77777777, r.Call());
1288 }
1289 
WASM_EXEC_TEST(LoadMemI64_alignment)1290 WASM_EXEC_TEST(LoadMemI64_alignment) {
1291   REQUIRE(I64LoadStore);
1292   TestingModule module(execution_mode);
1293   int64_t* memory = module.AddMemoryElems<int64_t>(8);
1294   for (byte alignment = 0; alignment <= 3; alignment++) {
1295     module.RandomizeMemory(1111);
1296     WasmRunner<int64_t> r(&module);
1297 
1298     BUILD(r,
1299           WASM_LOAD_MEM_ALIGNMENT(MachineType::Int64(), WASM_I8(0), alignment));
1300 
1301     memory[0] = 0xaabbccdd00112233LL;
1302     CHECK_EQ(0xaabbccdd00112233LL, r.Call());
1303 
1304     memory[0] = 0x33aabbccdd001122LL;
1305     CHECK_EQ(0x33aabbccdd001122LL, r.Call());
1306 
1307     memory[0] = 77777777;
1308     CHECK_EQ(77777777, r.Call());
1309   }
1310 }
1311 
WASM_EXEC_TEST(MemI64_Sum)1312 WASM_EXEC_TEST(MemI64_Sum) {
1313   REQUIRE(I64LoadStore);
1314   REQUIRE(I64Add);
1315   REQUIRE(I64Sub);
1316   REQUIRE(I64Phi);
1317   const int kNumElems = 20;
1318   TestingModule module(execution_mode);
1319   uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems);
1320   WasmRunner<uint64_t> r(&module, MachineType::Int32());
1321   const byte kSum = r.AllocateLocal(kAstI64);
1322 
1323   BUILD(r, WASM_BLOCK(
1324                2, WASM_WHILE(
1325                       WASM_GET_LOCAL(0),
1326                       WASM_BLOCK(
1327                           2, WASM_SET_LOCAL(
1328                                  kSum, WASM_I64_ADD(
1329                                            WASM_GET_LOCAL(kSum),
1330                                            WASM_LOAD_MEM(MachineType::Int64(),
1331                                                          WASM_GET_LOCAL(0)))),
1332                           WASM_SET_LOCAL(
1333                               0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))),
1334                WASM_GET_LOCAL(1)));
1335 
1336   // Run 4 trials.
1337   for (int i = 0; i < 3; i++) {
1338     module.RandomizeMemory(i * 33);
1339     uint64_t expected = 0;
1340     for (size_t j = kNumElems - 1; j > 0; j--) {
1341       expected += memory[j];
1342     }
1343     uint64_t result = r.Call(8 * (kNumElems - 1));
1344     CHECK_EQ(expected, result);
1345   }
1346 }
1347 
WASM_EXEC_TEST(StoreMemI64_alignment)1348 WASM_EXEC_TEST(StoreMemI64_alignment) {
1349   TestingModule module(execution_mode);
1350   int64_t* memory = module.AddMemoryElems<int64_t>(4);
1351   const int64_t kWritten = 0x12345678abcd0011ll;
1352 
1353   for (byte i = 0; i <= 3; i++) {
1354     WasmRunner<int64_t> r(&module, MachineType::Int64());
1355     BUILD(r, WASM_STORE_MEM_ALIGNMENT(MachineType::Int64(), WASM_ZERO, i,
1356                                       WASM_GET_LOCAL(0)));
1357     module.RandomizeMemory(1111);
1358     memory[0] = 0;
1359 
1360     CHECK_EQ(kWritten, r.Call(kWritten));
1361     CHECK_EQ(kWritten, memory[0]);
1362   }
1363 }
1364 
WASM_EXEC_TEST(I64Global)1365 WASM_EXEC_TEST(I64Global) {
1366   REQUIRE(I64LoadStore);
1367   REQUIRE(I64SConvertI32);
1368   REQUIRE(I64And);
1369   REQUIRE(DepthFirst);
1370   TestingModule module(execution_mode);
1371   int64_t* global = module.AddGlobal<int64_t>(MachineType::Int64());
1372   WasmRunner<int32_t> r(&module, MachineType::Int32());
1373   // global = global + p0
1374   BUILD(r, B2(WASM_STORE_GLOBAL(
1375                   0, WASM_I64_AND(WASM_LOAD_GLOBAL(0),
1376                                   WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
1377               WASM_ZERO));
1378 
1379   *global = 0xFFFFFFFFFFFFFFFFLL;
1380   for (int i = 9; i < 444444; i += 111111) {
1381     int64_t expected = *global & i;
1382     r.Call(i);
1383     CHECK_EQ(expected, *global);
1384   }
1385 }
1386 
WASM_EXEC_TEST(I64Eqz)1387 WASM_EXEC_TEST(I64Eqz) {
1388   REQUIRE(I64Eq);
1389 
1390   WasmRunner<int32_t> r(execution_mode, MachineType::Int64());
1391   BUILD(r, WASM_I64_EQZ(WASM_GET_LOCAL(0)));
1392 
1393   FOR_INT64_INPUTS(i) {
1394     int32_t result = *i == 0 ? 1 : 0;
1395     CHECK_EQ(result, r.Call(*i));
1396   }
1397 }
1398 
WASM_EXEC_TEST(I64Ror)1399 WASM_EXEC_TEST(I64Ror) {
1400   REQUIRE(I64Ror);
1401   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
1402                         MachineType::Int64());
1403   BUILD(r, WASM_I64_ROR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
1404 
1405   FOR_UINT64_INPUTS(i) {
1406     FOR_UINT64_INPUTS(j) {
1407       int64_t expected = bits::RotateRight64(*i, *j & 0x3f);
1408       CHECK_EQ(expected, r.Call(*i, *j));
1409     }
1410   }
1411 }
1412 
WASM_EXEC_TEST(I64Rol)1413 WASM_EXEC_TEST(I64Rol) {
1414   REQUIRE(I64Rol);
1415   WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
1416                         MachineType::Int64());
1417   BUILD(r, WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
1418 
1419   FOR_UINT64_INPUTS(i) {
1420     FOR_UINT64_INPUTS(j) {
1421       int64_t expected = bits::RotateLeft64(*i, *j & 0x3f);
1422       CHECK_EQ(expected, r.Call(*i, *j));
1423     }
1424   }
1425 }
1426 
WASM_EXEC_TEST(StoreMem_offset_oob_i64)1427 WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
1428   TestingModule module(execution_mode);
1429   byte* memory = module.AddMemoryElems<byte>(32);
1430 
1431   static const MachineType machineTypes[] = {
1432       MachineType::Int8(),   MachineType::Uint8(),  MachineType::Int16(),
1433       MachineType::Uint16(), MachineType::Int32(),  MachineType::Uint32(),
1434       MachineType::Int64(),  MachineType::Uint64(), MachineType::Float32(),
1435       MachineType::Float64()};
1436 
1437   for (size_t m = 0; m < arraysize(machineTypes); m++) {
1438     module.RandomizeMemory(1119 + static_cast<int>(m));
1439     WasmRunner<int32_t> r(&module, MachineType::Uint32());
1440 
1441     BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
1442                                    WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
1443           WASM_ZERO);
1444 
1445     byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
1446     uint32_t boundary = 24 - memsize;
1447     CHECK_EQ(0, r.Call(boundary));  // in bounds.
1448     CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
1449 
1450     for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1451       CHECK_TRAP(r.Call(offset));  // out of bounds.
1452     }
1453   }
1454 }
1455 
1456 #define ADD_CODE(vec, ...)                                              \
1457   do {                                                                  \
1458     byte __buf[] = {__VA_ARGS__};                                       \
1459     for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
1460   } while (false)
1461 
CompileCallIndirectMany(LocalType param)1462 static void CompileCallIndirectMany(LocalType param) {
1463   // Make sure we don't run out of registers when compiling indirect calls
1464   // with many many parameters.
1465   TestSignatures sigs;
1466   for (byte num_params = 0; num_params < 40; num_params++) {
1467     v8::base::AccountingAllocator allocator;
1468     Zone zone(&allocator);
1469     HandleScope scope(CcTest::InitIsolateOnce());
1470     TestingModule module(kExecuteCompiled);
1471     FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
1472 
1473     module.AddSignature(sig);
1474     module.AddSignature(sig);
1475     module.AddIndirectFunctionTable(nullptr, 0);
1476 
1477     WasmFunctionCompiler t(sig, &module);
1478 
1479     std::vector<byte> code;
1480     ADD_CODE(code, kExprI8Const, 0);
1481     for (byte p = 0; p < num_params; p++) {
1482       ADD_CODE(code, kExprGetLocal, p);
1483     }
1484     ADD_CODE(code, kExprCallIndirect, static_cast<byte>(num_params), 1);
1485 
1486     t.Build(&code[0], &code[0] + code.size());
1487     t.Compile();
1488   }
1489 }
1490 
TEST(Compile_Wasm_CallIndirect_Many_i64)1491 TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); }
1492 
Run_WasmMixedCall_N(WasmExecutionMode execution_mode,int start)1493 static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
1494   const int kExpected = 6333;
1495   const int kElemSize = 8;
1496   TestSignatures sigs;
1497 
1498   static MachineType mixed[] = {
1499       MachineType::Int32(),   MachineType::Float32(), MachineType::Int64(),
1500       MachineType::Float64(), MachineType::Float32(), MachineType::Int64(),
1501       MachineType::Int32(),   MachineType::Float64(), MachineType::Float32(),
1502       MachineType::Float64(), MachineType::Int32(),   MachineType::Int64(),
1503       MachineType::Int32(),   MachineType::Int32()};
1504 
1505   int num_params = static_cast<int>(arraysize(mixed)) - start;
1506   for (int which = 0; which < num_params; which++) {
1507     v8::base::AccountingAllocator allocator;
1508     Zone zone(&allocator);
1509     TestingModule module(execution_mode);
1510     module.AddMemory(1024);
1511     MachineType* memtypes = &mixed[start];
1512     MachineType result = memtypes[which];
1513 
1514     // =========================================================================
1515     // Build the selector function.
1516     // =========================================================================
1517     uint32_t index;
1518     FunctionSig::Builder b(&zone, 1, num_params);
1519     b.AddReturn(WasmOpcodes::LocalTypeFor(result));
1520     for (int i = 0; i < num_params; i++) {
1521       b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
1522     }
1523     WasmFunctionCompiler t(b.Build(), &module);
1524     BUILD(t, WASM_GET_LOCAL(which));
1525     index = t.CompileAndAdd();
1526 
1527     // =========================================================================
1528     // Build the calling function.
1529     // =========================================================================
1530     WasmRunner<int32_t> r(&module);
1531     std::vector<byte> code;
1532 
1533     // Load the offset for the store.
1534     ADD_CODE(code, WASM_ZERO);
1535 
1536     // Load the arguments.
1537     for (int i = 0; i < num_params; i++) {
1538       int offset = (i + 1) * kElemSize;
1539       ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
1540     }
1541 
1542     // Call the selector function.
1543     ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params),
1544              static_cast<byte>(index));
1545 
1546     // Store the result in memory.
1547     ADD_CODE(code,
1548              static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
1549              ZERO_ALIGNMENT, ZERO_OFFSET);
1550 
1551     // Return the expected value.
1552     ADD_CODE(code, WASM_I32V_2(kExpected));
1553 
1554     r.Build(&code[0], &code[0] + code.size());
1555 
1556     // Run the code.
1557     for (int t = 0; t < 10; t++) {
1558       module.RandomizeMemory();
1559       CHECK_EQ(kExpected, r.Call());
1560 
1561       int size = WasmOpcodes::MemSize(result);
1562       for (int i = 0; i < size; i++) {
1563         int base = (which + 1) * kElemSize;
1564         byte expected = module.raw_mem_at<byte>(base + i);
1565         byte result = module.raw_mem_at<byte>(i);
1566         CHECK_EQ(expected, result);
1567       }
1568     }
1569   }
1570 }
1571 
WASM_EXEC_TEST(MixedCall_i64_0)1572 WASM_EXEC_TEST(MixedCall_i64_0) { Run_WasmMixedCall_N(execution_mode, 0); }
WASM_EXEC_TEST(MixedCall_i64_1)1573 WASM_EXEC_TEST(MixedCall_i64_1) { Run_WasmMixedCall_N(execution_mode, 1); }
WASM_EXEC_TEST(MixedCall_i64_2)1574 WASM_EXEC_TEST(MixedCall_i64_2) { Run_WasmMixedCall_N(execution_mode, 2); }
WASM_EXEC_TEST(MixedCall_i64_3)1575 WASM_EXEC_TEST(MixedCall_i64_3) { Run_WasmMixedCall_N(execution_mode, 3); }
1576