blob: 70d461b62785391181c5b25a7d847ea75d70ac2e [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
Ben Murdochda12d292016-06-02 14:46:10 +010021// for even shorter tests.
22#define B2(a, b) kExprBlock, 2, a, b
23#define B1(a) kExprBlock, 1, a
24#define RET(x) kExprReturn, x
25#define RET_I8(x) kExprReturn, kExprI8Const, x
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026
27TEST(Run_WasmInt8Const) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010028 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 const byte kExpectedValue = 121;
30 // return(kExpectedValue)
31 BUILD(r, WASM_I8(kExpectedValue));
32 CHECK_EQ(kExpectedValue, r.Call());
33}
34
35
36TEST(Run_WasmInt8Const_fallthru1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010037 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 const byte kExpectedValue = 122;
39 // kExpectedValue
40 BUILD(r, WASM_I8(kExpectedValue));
41 CHECK_EQ(kExpectedValue, r.Call());
42}
43
44
45TEST(Run_WasmInt8Const_fallthru2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010046 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 const byte kExpectedValue = 123;
48 // -99 kExpectedValue
49 BUILD(r, WASM_I8(-99), WASM_I8(kExpectedValue));
50 CHECK_EQ(kExpectedValue, r.Call());
51}
52
53
54TEST(Run_WasmInt8Const_all) {
55 for (int value = -128; value <= 127; value++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010056 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 // return(value)
58 BUILD(r, WASM_I8(value));
Ben Murdoch097c5b22016-05-18 11:27:45 +010059 int32_t result = r.Call();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 CHECK_EQ(value, result);
61 }
62}
63
64
65TEST(Run_WasmInt32Const) {
66 WasmRunner<int32_t> r;
67 const int32_t kExpectedValue = 0x11223344;
68 // return(kExpectedValue)
Ben Murdochda12d292016-06-02 14:46:10 +010069 BUILD(r, WASM_I32V_5(kExpectedValue));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 CHECK_EQ(kExpectedValue, r.Call());
71}
72
73
74TEST(Run_WasmInt32Const_many) {
75 FOR_INT32_INPUTS(i) {
76 WasmRunner<int32_t> r;
77 const int32_t kExpectedValue = *i;
78 // return(kExpectedValue)
Ben Murdochda12d292016-06-02 14:46:10 +010079 BUILD(r, WASM_I32V(kExpectedValue));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 CHECK_EQ(kExpectedValue, r.Call());
81 }
82}
83
84
85TEST(Run_WasmMemorySize) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +010087 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 module.AddMemory(1024);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 BUILD(r, kExprMemorySize);
90 CHECK_EQ(1024, r.Call());
91}
92
93
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000094TEST(Run_WasmInt32Param0) {
95 WasmRunner<int32_t> r(MachineType::Int32());
96 // return(local[0])
97 BUILD(r, WASM_GET_LOCAL(0));
98 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
99}
100
101
102TEST(Run_WasmInt32Param0_fallthru) {
103 WasmRunner<int32_t> r(MachineType::Int32());
104 // local[0]
105 BUILD(r, WASM_GET_LOCAL(0));
106 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
107}
108
109
110TEST(Run_WasmInt32Param1) {
111 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
112 // local[1]
113 BUILD(r, WASM_GET_LOCAL(1));
114 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); }
115}
116
117
118TEST(Run_WasmInt32Add) {
119 WasmRunner<int32_t> r;
120 // 11 + 44
121 BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44)));
122 CHECK_EQ(55, r.Call());
123}
124
125
126TEST(Run_WasmInt32Add_P) {
127 WasmRunner<int32_t> r(MachineType::Int32());
128 // p0 + 13
129 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
130 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
131}
132
133
134TEST(Run_WasmInt32Add_P_fallthru) {
135 WasmRunner<int32_t> r(MachineType::Int32());
136 // p0 + 13
137 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
138 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
139}
140
141
142TEST(Run_WasmInt32Add_P2) {
143 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
144 // p0 + p1
145 BUILD(r, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
146 FOR_INT32_INPUTS(i) {
147 FOR_INT32_INPUTS(j) {
148 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
149 static_cast<uint32_t>(*j));
150 CHECK_EQ(expected, r.Call(*i, *j));
151 }
152 }
153}
154
155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156TEST(Run_WasmFloat32Add) {
157 WasmRunner<int32_t> r;
158 // int(11.5f + 44.5f)
159 BUILD(r,
160 WASM_I32_SCONVERT_F32(WASM_F32_ADD(WASM_F32(11.5f), WASM_F32(44.5f))));
161 CHECK_EQ(56, r.Call());
162}
163
164
165TEST(Run_WasmFloat64Add) {
166 WasmRunner<int32_t> r;
167 // return int(13.5d + 43.5d)
168 BUILD(r, WASM_I32_SCONVERT_F64(WASM_F64_ADD(WASM_F64(13.5), WASM_F64(43.5))));
169 CHECK_EQ(57, r.Call());
170}
171
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172
173void TestInt32Binop(WasmOpcode opcode, int32_t expected, int32_t a, int32_t b) {
174 {
175 WasmRunner<int32_t> r;
176 // K op K
Ben Murdochda12d292016-06-02 14:46:10 +0100177 BUILD(r, WASM_BINOP(opcode, WASM_I32V(a), WASM_I32V(b)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 CHECK_EQ(expected, r.Call());
179 }
180 {
181 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
182 // a op b
183 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
184 CHECK_EQ(expected, r.Call(a, b));
185 }
186}
187
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188TEST(Run_WasmInt32Binops) {
189 TestInt32Binop(kExprI32Add, 88888888, 33333333, 55555555);
190 TestInt32Binop(kExprI32Sub, -1111111, 7777777, 8888888);
191 TestInt32Binop(kExprI32Mul, 65130756, 88734, 734);
192 TestInt32Binop(kExprI32DivS, -66, -4777344, 72384);
193 TestInt32Binop(kExprI32DivU, 805306368, 0xF0000000, 5);
194 TestInt32Binop(kExprI32RemS, -3, -3003, 1000);
195 TestInt32Binop(kExprI32RemU, 4, 4004, 1000);
196 TestInt32Binop(kExprI32And, 0xEE, 0xFFEE, 0xFF0000FF);
197 TestInt32Binop(kExprI32Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
198 TestInt32Binop(kExprI32Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
199 TestInt32Binop(kExprI32Shl, 0xA0000000, 0xA, 28);
200 TestInt32Binop(kExprI32ShrU, 0x07000010, 0x70000100, 4);
201 TestInt32Binop(kExprI32ShrS, 0xFF000000, 0x80000000, 7);
Ben Murdochda12d292016-06-02 14:46:10 +0100202 TestInt32Binop(kExprI32Ror, 0x01000000, 0x80000000, 7);
203 TestInt32Binop(kExprI32Ror, 0x01000000, 0x80000000, 39);
204 TestInt32Binop(kExprI32Rol, 0x00000040, 0x80000000, 7);
205 TestInt32Binop(kExprI32Rol, 0x00000040, 0x80000000, 39);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 TestInt32Binop(kExprI32Eq, 1, -99, -99);
207 TestInt32Binop(kExprI32Ne, 0, -97, -97);
208
209 TestInt32Binop(kExprI32LtS, 1, -4, 4);
210 TestInt32Binop(kExprI32LeS, 0, -2, -3);
211 TestInt32Binop(kExprI32LtU, 1, 0, -6);
212 TestInt32Binop(kExprI32LeU, 1, 98978, 0xF0000000);
213
214 TestInt32Binop(kExprI32GtS, 1, 4, -4);
215 TestInt32Binop(kExprI32GeS, 0, -3, -2);
216 TestInt32Binop(kExprI32GtU, 1, -6, 0);
217 TestInt32Binop(kExprI32GeU, 1, 0xF0000000, 98978);
218}
219
220
221void TestInt32Unop(WasmOpcode opcode, int32_t expected, int32_t a) {
222 {
223 WasmRunner<int32_t> r;
224 // return op K
Ben Murdochda12d292016-06-02 14:46:10 +0100225 BUILD(r, WASM_UNOP(opcode, WASM_I32V(a)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226 CHECK_EQ(expected, r.Call());
227 }
228 {
229 WasmRunner<int32_t> r(MachineType::Int32());
230 // return op a
231 BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0)));
232 CHECK_EQ(expected, r.Call(a));
233 }
234}
235
236
237TEST(Run_WasmInt32Clz) {
238 TestInt32Unop(kExprI32Clz, 0, 0x80001000);
239 TestInt32Unop(kExprI32Clz, 1, 0x40000500);
240 TestInt32Unop(kExprI32Clz, 2, 0x20000300);
241 TestInt32Unop(kExprI32Clz, 3, 0x10000003);
242 TestInt32Unop(kExprI32Clz, 4, 0x08050000);
243 TestInt32Unop(kExprI32Clz, 5, 0x04006000);
244 TestInt32Unop(kExprI32Clz, 6, 0x02000000);
245 TestInt32Unop(kExprI32Clz, 7, 0x010000a0);
246 TestInt32Unop(kExprI32Clz, 8, 0x00800c00);
247 TestInt32Unop(kExprI32Clz, 9, 0x00400000);
248 TestInt32Unop(kExprI32Clz, 10, 0x0020000d);
249 TestInt32Unop(kExprI32Clz, 11, 0x00100f00);
250 TestInt32Unop(kExprI32Clz, 12, 0x00080000);
251 TestInt32Unop(kExprI32Clz, 13, 0x00041000);
252 TestInt32Unop(kExprI32Clz, 14, 0x00020020);
253 TestInt32Unop(kExprI32Clz, 15, 0x00010300);
254 TestInt32Unop(kExprI32Clz, 16, 0x00008040);
255 TestInt32Unop(kExprI32Clz, 17, 0x00004005);
256 TestInt32Unop(kExprI32Clz, 18, 0x00002050);
257 TestInt32Unop(kExprI32Clz, 19, 0x00001700);
258 TestInt32Unop(kExprI32Clz, 20, 0x00000870);
259 TestInt32Unop(kExprI32Clz, 21, 0x00000405);
260 TestInt32Unop(kExprI32Clz, 22, 0x00000203);
261 TestInt32Unop(kExprI32Clz, 23, 0x00000101);
262 TestInt32Unop(kExprI32Clz, 24, 0x00000089);
263 TestInt32Unop(kExprI32Clz, 25, 0x00000041);
264 TestInt32Unop(kExprI32Clz, 26, 0x00000022);
265 TestInt32Unop(kExprI32Clz, 27, 0x00000013);
266 TestInt32Unop(kExprI32Clz, 28, 0x00000008);
267 TestInt32Unop(kExprI32Clz, 29, 0x00000004);
268 TestInt32Unop(kExprI32Clz, 30, 0x00000002);
269 TestInt32Unop(kExprI32Clz, 31, 0x00000001);
270 TestInt32Unop(kExprI32Clz, 32, 0x00000000);
271}
272
273
274TEST(Run_WasmInt32Ctz) {
275 TestInt32Unop(kExprI32Ctz, 32, 0x00000000);
276 TestInt32Unop(kExprI32Ctz, 31, 0x80000000);
277 TestInt32Unop(kExprI32Ctz, 30, 0x40000000);
278 TestInt32Unop(kExprI32Ctz, 29, 0x20000000);
279 TestInt32Unop(kExprI32Ctz, 28, 0x10000000);
280 TestInt32Unop(kExprI32Ctz, 27, 0xa8000000);
281 TestInt32Unop(kExprI32Ctz, 26, 0xf4000000);
282 TestInt32Unop(kExprI32Ctz, 25, 0x62000000);
283 TestInt32Unop(kExprI32Ctz, 24, 0x91000000);
284 TestInt32Unop(kExprI32Ctz, 23, 0xcd800000);
285 TestInt32Unop(kExprI32Ctz, 22, 0x09400000);
286 TestInt32Unop(kExprI32Ctz, 21, 0xaf200000);
287 TestInt32Unop(kExprI32Ctz, 20, 0xac100000);
288 TestInt32Unop(kExprI32Ctz, 19, 0xe0b80000);
289 TestInt32Unop(kExprI32Ctz, 18, 0x9ce40000);
290 TestInt32Unop(kExprI32Ctz, 17, 0xc7920000);
291 TestInt32Unop(kExprI32Ctz, 16, 0xb8f10000);
292 TestInt32Unop(kExprI32Ctz, 15, 0x3b9f8000);
293 TestInt32Unop(kExprI32Ctz, 14, 0xdb4c4000);
294 TestInt32Unop(kExprI32Ctz, 13, 0xe9a32000);
295 TestInt32Unop(kExprI32Ctz, 12, 0xfca61000);
296 TestInt32Unop(kExprI32Ctz, 11, 0x6c8a7800);
297 TestInt32Unop(kExprI32Ctz, 10, 0x8ce5a400);
298 TestInt32Unop(kExprI32Ctz, 9, 0xcb7d0200);
299 TestInt32Unop(kExprI32Ctz, 8, 0xcb4dc100);
300 TestInt32Unop(kExprI32Ctz, 7, 0xdfbec580);
301 TestInt32Unop(kExprI32Ctz, 6, 0x27a9db40);
302 TestInt32Unop(kExprI32Ctz, 5, 0xde3bcb20);
303 TestInt32Unop(kExprI32Ctz, 4, 0xd7e8a610);
304 TestInt32Unop(kExprI32Ctz, 3, 0x9afdbc88);
305 TestInt32Unop(kExprI32Ctz, 2, 0x9afdbc84);
306 TestInt32Unop(kExprI32Ctz, 1, 0x9afdbc82);
307 TestInt32Unop(kExprI32Ctz, 0, 0x9afdbc81);
308}
309
310
311TEST(Run_WasmInt32Popcnt) {
312 TestInt32Unop(kExprI32Popcnt, 32, 0xffffffff);
313 TestInt32Unop(kExprI32Popcnt, 0, 0x00000000);
314 TestInt32Unop(kExprI32Popcnt, 1, 0x00008000);
315 TestInt32Unop(kExprI32Popcnt, 13, 0x12345678);
316 TestInt32Unop(kExprI32Popcnt, 19, 0xfedcba09);
317}
318
Ben Murdochda12d292016-06-02 14:46:10 +0100319TEST(Run_WasmI32Eqz) {
320 TestInt32Unop(kExprI32Eqz, 0, 1);
321 TestInt32Unop(kExprI32Eqz, 0, -1);
322 TestInt32Unop(kExprI32Eqz, 0, -827343);
323 TestInt32Unop(kExprI32Eqz, 0, 8888888);
324 TestInt32Unop(kExprI32Eqz, 1, 0);
325}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326
Ben Murdochda12d292016-06-02 14:46:10 +0100327TEST(Run_WasmI32Shl) {
328 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
329 BUILD(r, WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
330
331 FOR_UINT32_INPUTS(i) {
332 FOR_UINT32_INPUTS(j) {
333 uint32_t expected = (*i) << (*j & 0x1f);
334 CHECK_EQ(expected, r.Call(*i, *j));
335 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336 }
337}
338
Ben Murdochda12d292016-06-02 14:46:10 +0100339TEST(Run_WasmI32Shr) {
340 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
341 BUILD(r, WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342
Ben Murdochda12d292016-06-02 14:46:10 +0100343 FOR_UINT32_INPUTS(i) {
344 FOR_UINT32_INPUTS(j) {
345 uint32_t expected = (*i) >> (*j & 0x1f);
346 CHECK_EQ(expected, r.Call(*i, *j));
347 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348 }
349}
350
Ben Murdochda12d292016-06-02 14:46:10 +0100351TEST(Run_WasmI32Sar) {
352 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
353 BUILD(r, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000354
Ben Murdochda12d292016-06-02 14:46:10 +0100355 FOR_INT32_INPUTS(i) {
356 FOR_INT32_INPUTS(j) {
357 int32_t expected = (*i) >> (*j & 0x1f);
358 CHECK_EQ(expected, r.Call(*i, *j));
359 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 }
361}
362
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000363TEST(Run_WASM_Int32DivS_trap) {
364 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
365 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100366 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000367 CHECK_EQ(0, r.Call(0, 100));
368 CHECK_TRAP(r.Call(100, 0));
369 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100370 CHECK_TRAP(r.Call(kMin, -1));
371 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372}
373
374
375TEST(Run_WASM_Int32RemS_trap) {
376 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
377 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100378 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 CHECK_EQ(33, r.Call(133, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100380 CHECK_EQ(0, r.Call(kMin, -1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 CHECK_TRAP(r.Call(100, 0));
382 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100383 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000384}
385
386
387TEST(Run_WASM_Int32DivU_trap) {
388 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
389 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100390 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 CHECK_EQ(0, r.Call(0, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100392 CHECK_EQ(0, r.Call(kMin, -1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000393 CHECK_TRAP(r.Call(100, 0));
394 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100395 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000396}
397
398
399TEST(Run_WASM_Int32RemU_trap) {
400 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
401 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
402 CHECK_EQ(17, r.Call(217, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100403 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404 CHECK_TRAP(r.Call(100, 0));
405 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100406 CHECK_TRAP(r.Call(kMin, 0));
407 CHECK_EQ(kMin, r.Call(kMin, -1));
408}
409
410TEST(Run_WASM_Int32DivS_asmjs) {
411 TestingModule module;
412 module.origin = kAsmJsOrigin;
413 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
414 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
415 const int32_t kMin = std::numeric_limits<int32_t>::min();
416 CHECK_EQ(0, r.Call(0, 100));
417 CHECK_EQ(0, r.Call(100, 0));
418 CHECK_EQ(0, r.Call(-1001, 0));
419 CHECK_EQ(kMin, r.Call(kMin, -1));
420 CHECK_EQ(0, r.Call(kMin, 0));
421}
422
423TEST(Run_WASM_Int32RemS_asmjs) {
424 TestingModule module;
425 module.origin = kAsmJsOrigin;
426 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
427 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
428 const int32_t kMin = std::numeric_limits<int32_t>::min();
429 CHECK_EQ(33, r.Call(133, 100));
430 CHECK_EQ(0, r.Call(kMin, -1));
431 CHECK_EQ(0, r.Call(100, 0));
432 CHECK_EQ(0, r.Call(-1001, 0));
433 CHECK_EQ(0, r.Call(kMin, 0));
434}
435
436TEST(Run_WASM_Int32DivU_asmjs) {
437 TestingModule module;
438 module.origin = kAsmJsOrigin;
439 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
440 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
441 const int32_t kMin = std::numeric_limits<int32_t>::min();
442 CHECK_EQ(0, r.Call(0, 100));
443 CHECK_EQ(0, r.Call(kMin, -1));
444 CHECK_EQ(0, r.Call(100, 0));
445 CHECK_EQ(0, r.Call(-1001, 0));
446 CHECK_EQ(0, r.Call(kMin, 0));
447}
448
449TEST(Run_WASM_Int32RemU_asmjs) {
450 TestingModule module;
451 module.origin = kAsmJsOrigin;
452 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
453 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
454 const int32_t kMin = std::numeric_limits<int32_t>::min();
455 CHECK_EQ(17, r.Call(217, 100));
456 CHECK_EQ(0, r.Call(100, 0));
457 CHECK_EQ(0, r.Call(-1001, 0));
458 CHECK_EQ(0, r.Call(kMin, 0));
459 CHECK_EQ(kMin, r.Call(kMin, -1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460}
461
462
463TEST(Run_WASM_Int32DivS_byzero_const) {
464 for (int8_t denom = -2; denom < 8; denom++) {
465 WasmRunner<int32_t> r(MachineType::Int32());
466 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
467 for (int32_t val = -7; val < 8; val++) {
468 if (denom == 0) {
469 CHECK_TRAP(r.Call(val));
470 } else {
471 CHECK_EQ(val / denom, r.Call(val));
472 }
473 }
474 }
475}
476
477
478TEST(Run_WASM_Int32DivU_byzero_const) {
479 for (uint32_t denom = 0xfffffffe; denom < 8; denom++) {
480 WasmRunner<uint32_t> r(MachineType::Uint32());
Ben Murdochda12d292016-06-02 14:46:10 +0100481 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482
483 for (uint32_t val = 0xfffffff0; val < 8; val++) {
484 if (denom == 0) {
485 CHECK_TRAP(r.Call(val));
486 } else {
487 CHECK_EQ(val / denom, r.Call(val));
488 }
489 }
490 }
491}
492
493
494TEST(Run_WASM_Int32DivS_trap_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 TestingModule module;
496 module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100497 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000498
499 BUILD(r,
500 WASM_IF_ELSE(WASM_GET_LOCAL(0),
501 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
502 WASM_ZERO, WASM_GET_LOCAL(0)),
503 WASM_GET_LOCAL(1)),
504 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
505 WASM_ZERO, WASM_GET_LOCAL(0)),
506 WASM_GET_LOCAL(1))));
507 CHECK_EQ(0, r.Call(0, 100));
508 CHECK_TRAP(r.Call(8, 0));
509 CHECK_TRAP(r.Call(4, 0));
510 CHECK_TRAP(r.Call(0, 0));
511}
512
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000513void TestFloat32Binop(WasmOpcode opcode, int32_t expected, float a, float b) {
514 {
515 WasmRunner<int32_t> r;
516 // return K op K
517 BUILD(r, WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b)));
518 CHECK_EQ(expected, r.Call());
519 }
520 {
521 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
522 // return a op b
523 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
524 CHECK_EQ(expected, r.Call(a, b));
525 }
526}
527
528
529void TestFloat32BinopWithConvert(WasmOpcode opcode, int32_t expected, float a,
530 float b) {
531 {
532 WasmRunner<int32_t> r;
533 // return int(K op K)
534 BUILD(r,
535 WASM_I32_SCONVERT_F32(WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b))));
536 CHECK_EQ(expected, r.Call());
537 }
538 {
539 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
540 // return int(a op b)
541 BUILD(r, WASM_I32_SCONVERT_F32(
542 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
543 CHECK_EQ(expected, r.Call(a, b));
544 }
545}
546
547
548void TestFloat32UnopWithConvert(WasmOpcode opcode, int32_t expected, float a) {
549 {
550 WasmRunner<int32_t> r;
551 // return int(op(K))
552 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_F32(a))));
553 CHECK_EQ(expected, r.Call());
554 }
555 {
556 WasmRunner<int32_t> r(MachineType::Float32());
557 // return int(op(a))
558 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
559 CHECK_EQ(expected, r.Call(a));
560 }
561}
562
563
564void TestFloat64Binop(WasmOpcode opcode, int32_t expected, double a, double b) {
565 {
566 WasmRunner<int32_t> r;
567 // return K op K
568 BUILD(r, WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b)));
569 CHECK_EQ(expected, r.Call());
570 }
571 {
572 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
573 // return a op b
574 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
575 CHECK_EQ(expected, r.Call(a, b));
576 }
577}
578
579
580void TestFloat64BinopWithConvert(WasmOpcode opcode, int32_t expected, double a,
581 double b) {
582 {
583 WasmRunner<int32_t> r;
584 // return int(K op K)
585 BUILD(r,
586 WASM_I32_SCONVERT_F64(WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b))));
587 CHECK_EQ(expected, r.Call());
588 }
589 {
590 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
591 BUILD(r, WASM_I32_SCONVERT_F64(
592 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
593 CHECK_EQ(expected, r.Call(a, b));
594 }
595}
596
597
598void TestFloat64UnopWithConvert(WasmOpcode opcode, int32_t expected, double a) {
599 {
600 WasmRunner<int32_t> r;
601 // return int(op(K))
602 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_F64(a))));
603 CHECK_EQ(expected, r.Call());
604 }
605 {
606 WasmRunner<int32_t> r(MachineType::Float64());
607 // return int(op(a))
608 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
609 CHECK_EQ(expected, r.Call(a));
610 }
611}
612
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000613TEST(Run_WasmFloat32Binops) {
614 TestFloat32Binop(kExprF32Eq, 1, 8.125f, 8.125f);
615 TestFloat32Binop(kExprF32Ne, 1, 8.125f, 8.127f);
616 TestFloat32Binop(kExprF32Lt, 1, -9.5f, -9.0f);
617 TestFloat32Binop(kExprF32Le, 1, -1111.0f, -1111.0f);
618 TestFloat32Binop(kExprF32Gt, 1, -9.0f, -9.5f);
619 TestFloat32Binop(kExprF32Ge, 1, -1111.0f, -1111.0f);
620
621 TestFloat32BinopWithConvert(kExprF32Add, 10, 3.5f, 6.5f);
622 TestFloat32BinopWithConvert(kExprF32Sub, 2, 44.5f, 42.5f);
623 TestFloat32BinopWithConvert(kExprF32Mul, -66, -132.1f, 0.5f);
624 TestFloat32BinopWithConvert(kExprF32Div, 11, 22.1f, 2.0f);
625}
626
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000627TEST(Run_WasmFloat32Unops) {
628 TestFloat32UnopWithConvert(kExprF32Abs, 8, 8.125f);
629 TestFloat32UnopWithConvert(kExprF32Abs, 9, -9.125f);
630 TestFloat32UnopWithConvert(kExprF32Neg, -213, 213.125f);
631 TestFloat32UnopWithConvert(kExprF32Sqrt, 12, 144.4f);
632}
633
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000634TEST(Run_WasmFloat64Binops) {
635 TestFloat64Binop(kExprF64Eq, 1, 16.25, 16.25);
636 TestFloat64Binop(kExprF64Ne, 1, 16.25, 16.15);
637 TestFloat64Binop(kExprF64Lt, 1, -32.4, 11.7);
638 TestFloat64Binop(kExprF64Le, 1, -88.9, -88.9);
639 TestFloat64Binop(kExprF64Gt, 1, 11.7, -32.4);
640 TestFloat64Binop(kExprF64Ge, 1, -88.9, -88.9);
641
642 TestFloat64BinopWithConvert(kExprF64Add, 100, 43.5, 56.5);
643 TestFloat64BinopWithConvert(kExprF64Sub, 200, 12200.1, 12000.1);
644 TestFloat64BinopWithConvert(kExprF64Mul, -33, 134, -0.25);
645 TestFloat64BinopWithConvert(kExprF64Div, -1111, -2222.3, 2);
646}
647
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648TEST(Run_WasmFloat64Unops) {
649 TestFloat64UnopWithConvert(kExprF64Abs, 108, 108.125);
650 TestFloat64UnopWithConvert(kExprF64Abs, 209, -209.125);
651 TestFloat64UnopWithConvert(kExprF64Neg, -209, 209.125);
652 TestFloat64UnopWithConvert(kExprF64Sqrt, 13, 169.4);
653}
654
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000655TEST(Run_WasmFloat32Neg) {
656 WasmRunner<float> r(MachineType::Float32());
657 BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0)));
658
659 FOR_FLOAT32_INPUTS(i) {
660 CHECK_EQ(0x80000000,
661 bit_cast<uint32_t>(*i) ^ bit_cast<uint32_t>(r.Call(*i)));
662 }
663}
664
665
666TEST(Run_WasmFloat64Neg) {
667 WasmRunner<double> r(MachineType::Float64());
668 BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0)));
669
670 FOR_FLOAT64_INPUTS(i) {
671 CHECK_EQ(0x8000000000000000,
672 bit_cast<uint64_t>(*i) ^ bit_cast<uint64_t>(r.Call(*i)));
673 }
674}
675
676
677TEST(Run_Wasm_IfElse_P) {
678 WasmRunner<int32_t> r(MachineType::Int32());
679 // if (p0) return 11; else return 22;
680 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
681 WASM_I8(11), // --
682 WASM_I8(22))); // --
683 FOR_INT32_INPUTS(i) {
684 int32_t expected = *i ? 11 : 22;
685 CHECK_EQ(expected, r.Call(*i));
686 }
687}
688
689
690TEST(Run_Wasm_IfElse_Unreachable1) {
691 WasmRunner<int32_t> r;
692 // if (0) unreachable; else return 22;
693 BUILD(r, WASM_IF_ELSE(WASM_ZERO, // --
694 WASM_UNREACHABLE, // --
695 WASM_I8(27))); // --
696 CHECK_EQ(27, r.Call());
697}
698
699
700TEST(Run_Wasm_Return12) {
701 WasmRunner<int32_t> r;
702
Ben Murdochda12d292016-06-02 14:46:10 +0100703 BUILD(r, RET_I8(12));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 CHECK_EQ(12, r.Call());
705}
706
707
708TEST(Run_Wasm_Return17) {
709 WasmRunner<int32_t> r;
710
Ben Murdochda12d292016-06-02 14:46:10 +0100711 BUILD(r, B1(RET_I8(17)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000712 CHECK_EQ(17, r.Call());
713}
714
715
716TEST(Run_Wasm_Return_I32) {
717 WasmRunner<int32_t> r(MachineType::Int32());
718
Ben Murdochda12d292016-06-02 14:46:10 +0100719 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000720
721 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
722}
723
724
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725TEST(Run_Wasm_Return_F32) {
726 WasmRunner<float> r(MachineType::Float32());
727
Ben Murdochda12d292016-06-02 14:46:10 +0100728 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729
730 FOR_FLOAT32_INPUTS(i) {
731 float expect = *i;
732 float result = r.Call(expect);
733 if (std::isnan(expect)) {
734 CHECK(std::isnan(result));
735 } else {
736 CHECK_EQ(expect, result);
737 }
738 }
739}
740
741
742TEST(Run_Wasm_Return_F64) {
743 WasmRunner<double> r(MachineType::Float64());
744
Ben Murdochda12d292016-06-02 14:46:10 +0100745 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000746
747 FOR_FLOAT64_INPUTS(i) {
748 double expect = *i;
749 double result = r.Call(expect);
750 if (std::isnan(expect)) {
751 CHECK(std::isnan(result));
752 } else {
753 CHECK_EQ(expect, result);
754 }
755 }
756}
757
758
759TEST(Run_Wasm_Select) {
760 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100761 // return select(11, 22, a);
762 BUILD(r, WASM_SELECT(WASM_I8(11), WASM_I8(22), WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763 FOR_INT32_INPUTS(i) {
764 int32_t expected = *i ? 11 : 22;
765 CHECK_EQ(expected, r.Call(*i));
766 }
767}
768
769
770TEST(Run_Wasm_Select_strict1) {
771 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100772 // select(a=0, a=1, a=2); return a
Ben Murdochda12d292016-06-02 14:46:10 +0100773 BUILD(r, B2(WASM_SELECT(WASM_SET_LOCAL(0, WASM_I8(0)),
774 WASM_SET_LOCAL(0, WASM_I8(1)),
775 WASM_SET_LOCAL(0, WASM_I8(2))),
776 WASM_GET_LOCAL(0)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100777 FOR_INT32_INPUTS(i) { CHECK_EQ(2, r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778}
779
780
781TEST(Run_Wasm_Select_strict2) {
782 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100783 r.AllocateLocal(kAstI32);
784 r.AllocateLocal(kAstI32);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100785 // select(b=5, c=6, a)
786 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
787 WASM_SET_LOCAL(2, WASM_I8(6)), WASM_GET_LOCAL(0)));
788 FOR_INT32_INPUTS(i) {
789 int32_t expected = *i ? 5 : 6;
790 CHECK_EQ(expected, r.Call(*i));
791 }
792}
793
794TEST(Run_Wasm_Select_strict3) {
795 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100796 r.AllocateLocal(kAstI32);
797 r.AllocateLocal(kAstI32);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100798 // select(b=5, c=6, a=b)
799 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
800 WASM_SET_LOCAL(2, WASM_I8(6)),
801 WASM_SET_LOCAL(0, WASM_GET_LOCAL(1))));
802 FOR_INT32_INPUTS(i) {
803 int32_t expected = 5;
804 CHECK_EQ(expected, r.Call(*i));
805 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806}
807
808
809TEST(Run_Wasm_BrIf_strict) {
810 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100811 BUILD(
812 r,
813 B2(B1(WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(99)))),
814 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000815
816 FOR_INT32_INPUTS(i) { CHECK_EQ(99, r.Call(*i)); }
817}
818
Ben Murdochda12d292016-06-02 14:46:10 +0100819TEST(Run_Wasm_BrTable0a) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100820 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100821 BUILD(r,
822 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0))), WASM_I8(91)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100823 FOR_INT32_INPUTS(i) { CHECK_EQ(91, r.Call(*i)); }
824}
825
Ben Murdochda12d292016-06-02 14:46:10 +0100826TEST(Run_Wasm_BrTable0b) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100827 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100828 BUILD(r,
829 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(0))),
830 WASM_I8(92)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100831 FOR_INT32_INPUTS(i) { CHECK_EQ(92, r.Call(*i)); }
832}
833
Ben Murdochda12d292016-06-02 14:46:10 +0100834TEST(Run_Wasm_BrTable0c) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100835 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100836 BUILD(
837 r,
838 B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(1))),
839 RET_I8(76)),
840 WASM_I8(77)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100841 FOR_INT32_INPUTS(i) {
842 int32_t expected = *i == 0 ? 76 : 77;
843 CHECK_EQ(expected, r.Call(*i));
844 }
845}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000846
Ben Murdochda12d292016-06-02 14:46:10 +0100847TEST(Run_Wasm_BrTable1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100849 BUILD(r, B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0))), RET_I8(93));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850 FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); }
851}
852
Ben Murdochda12d292016-06-02 14:46:10 +0100853TEST(Run_Wasm_BrTable_loop) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000854 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100855 BUILD(r,
856 B2(WASM_LOOP(1, WASM_BR_TABLE(WASM_INC_LOCAL_BY(0, 1), 2, BR_TARGET(2),
857 BR_TARGET(1), BR_TARGET(0))),
858 RET_I8(99)),
859 WASM_I8(98));
860 CHECK_EQ(99, r.Call(0));
861 CHECK_EQ(98, r.Call(-1));
862 CHECK_EQ(98, r.Call(-2));
863 CHECK_EQ(98, r.Call(-3));
864 CHECK_EQ(98, r.Call(-100));
865}
866
867TEST(Run_Wasm_BrTable_br) {
868 WasmRunner<int32_t> r(MachineType::Int32());
869 BUILD(r,
870 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(1), BR_TARGET(0))),
871 RET_I8(91)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000872 WASM_I8(99));
873 CHECK_EQ(99, r.Call(0));
874 CHECK_EQ(91, r.Call(1));
875 CHECK_EQ(91, r.Call(2));
876 CHECK_EQ(91, r.Call(3));
877}
878
Ben Murdochda12d292016-06-02 14:46:10 +0100879TEST(Run_Wasm_BrTable_br2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100881
882 BUILD(r, B2(B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 3, BR_TARGET(1),
883 BR_TARGET(2), BR_TARGET(3), BR_TARGET(0))),
884 RET_I8(85)),
885 RET_I8(86)),
886 RET_I8(87)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000887 WASM_I8(88));
888 CHECK_EQ(86, r.Call(0));
889 CHECK_EQ(87, r.Call(1));
890 CHECK_EQ(88, r.Call(2));
891 CHECK_EQ(85, r.Call(3));
892 CHECK_EQ(85, r.Call(4));
893 CHECK_EQ(85, r.Call(5));
894}
895
Ben Murdochda12d292016-06-02 14:46:10 +0100896TEST(Run_Wasm_BrTable4) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000897 for (int i = 0; i < 4; i++) {
Ben Murdochda12d292016-06-02 14:46:10 +0100898 for (int t = 0; t < 4; t++) {
899 uint32_t cases[] = {0, 1, 2, 3};
900 cases[i] = t;
901 byte code[] = {B2(B2(B2(B2(B1(WASM_BR_TABLE(
902 WASM_GET_LOCAL(0), 3, BR_TARGET(cases[0]),
903 BR_TARGET(cases[1]), BR_TARGET(cases[2]),
904 BR_TARGET(cases[3]))),
905 RET_I8(70)),
906 RET_I8(71)),
907 RET_I8(72)),
908 RET_I8(73)),
909 WASM_I8(75)};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000910
Ben Murdochda12d292016-06-02 14:46:10 +0100911 WasmRunner<int32_t> r(MachineType::Int32());
912 r.Build(code, code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000913
Ben Murdochda12d292016-06-02 14:46:10 +0100914 for (int x = -3; x < 50; x++) {
915 int index = (x > 3 || x < 0) ? 3 : x;
916 int32_t expected = 70 + cases[index];
917 CHECK_EQ(expected, r.Call(x));
918 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000919 }
920 }
921}
922
Ben Murdochda12d292016-06-02 14:46:10 +0100923TEST(Run_Wasm_BrTable4x4) {
924 for (byte a = 0; a < 4; a++) {
925 for (byte b = 0; b < 4; b++) {
926 for (byte c = 0; c < 4; c++) {
927 for (byte d = 0; d < 4; d++) {
928 for (int i = 0; i < 4; i++) {
929 uint32_t cases[] = {a, b, c, d};
930 byte code[] = {
931 B2(B2(B2(B2(B1(WASM_BR_TABLE(
932 WASM_GET_LOCAL(0), 3, BR_TARGET(cases[0]),
933 BR_TARGET(cases[1]), BR_TARGET(cases[2]),
934 BR_TARGET(cases[3]))),
935 RET_I8(50)),
936 RET_I8(51)),
937 RET_I8(52)),
938 RET_I8(53)),
939 WASM_I8(55)};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940
Ben Murdochda12d292016-06-02 14:46:10 +0100941 WasmRunner<int32_t> r(MachineType::Int32());
942 r.Build(code, code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000943
Ben Murdochda12d292016-06-02 14:46:10 +0100944 for (int x = -6; x < 47; x++) {
945 int index = (x > 3 || x < 0) ? 3 : x;
946 int32_t expected = 50 + cases[index];
947 CHECK_EQ(expected, r.Call(x));
948 }
949 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 }
951 }
952 }
953 }
954}
955
Ben Murdochda12d292016-06-02 14:46:10 +0100956TEST(Run_Wasm_BrTable4_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 byte code[] = {
Ben Murdochda12d292016-06-02 14:46:10 +0100958 B2(B2(B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 3, BR_TARGET(0),
959 BR_TARGET(1), BR_TARGET(2), BR_TARGET(3))),
960 WASM_INC_LOCAL_BY(1, 1)),
961 WASM_INC_LOCAL_BY(1, 2)),
962 WASM_INC_LOCAL_BY(1, 4)),
963 WASM_INC_LOCAL_BY(1, 8)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964 WASM_GET_LOCAL(1)};
965
966 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
967 r.Build(code, code + arraysize(code));
968
969 CHECK_EQ(15, r.Call(0, 0));
970 CHECK_EQ(14, r.Call(1, 0));
971 CHECK_EQ(12, r.Call(2, 0));
972 CHECK_EQ(8, r.Call(3, 0));
973 CHECK_EQ(8, r.Call(4, 0));
974
975 CHECK_EQ(115, r.Call(0, 100));
976 CHECK_EQ(114, r.Call(1, 100));
977 CHECK_EQ(112, r.Call(2, 100));
978 CHECK_EQ(108, r.Call(3, 100));
979 CHECK_EQ(108, r.Call(4, 100));
980}
981
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000982TEST(Run_Wasm_F32ReinterpretI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000983 TestingModule module;
984 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100985 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000986
987 BUILD(r, WASM_I32_REINTERPRET_F32(
988 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
989
990 FOR_INT32_INPUTS(i) {
991 int32_t expected = *i;
992 memory[0] = expected;
993 CHECK_EQ(expected, r.Call());
994 }
995}
996
997
998TEST(Run_Wasm_I32ReinterpretF32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000999 TestingModule module;
1000 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001001 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001002
1003 BUILD(r, WASM_BLOCK(
1004 2, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
1005 WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))),
1006 WASM_I8(107)));
1007
1008 FOR_INT32_INPUTS(i) {
1009 int32_t expected = *i;
1010 CHECK_EQ(107, r.Call(expected));
1011 CHECK_EQ(expected, memory[0]);
1012 }
1013}
1014
1015
1016TEST(Run_Wasm_ReturnStore) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001017 TestingModule module;
1018 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001019 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001020
1021 BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
1022 WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
1023
1024 FOR_INT32_INPUTS(i) {
1025 int32_t expected = *i;
1026 memory[0] = expected;
1027 CHECK_EQ(expected, r.Call());
1028 }
1029}
1030
1031
1032TEST(Run_Wasm_VoidReturn1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001033 // We use a wrapper function because WasmRunner<void> does not exist.
1034
1035 // Build the test function.
1036 TestSignatures sigs;
1037 TestingModule module;
1038 WasmFunctionCompiler t(sigs.v_v(), &module);
1039 BUILD(t, kExprNop);
1040 uint32_t index = t.CompileAndAdd();
1041
1042 const int32_t kExpected = -414444;
1043 // Build the calling function.
Ben Murdochda12d292016-06-02 14:46:10 +01001044 WasmRunner<int32_t> r(&module);
1045 BUILD(r, B2(WASM_CALL_FUNCTION0(index), WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001046
1047 int32_t result = r.Call();
1048 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001049}
1050
1051
1052TEST(Run_Wasm_VoidReturn2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001053 // We use a wrapper function because WasmRunner<void> does not exist.
1054 // Build the test function.
1055 TestSignatures sigs;
1056 TestingModule module;
1057 WasmFunctionCompiler t(sigs.v_v(), &module);
1058 BUILD(t, WASM_RETURN0);
1059 uint32_t index = t.CompileAndAdd();
1060
1061 const int32_t kExpected = -414444;
1062 // Build the calling function.
Ben Murdochda12d292016-06-02 14:46:10 +01001063 WasmRunner<int32_t> r(&module);
1064 BUILD(r, B2(WASM_CALL_FUNCTION0(index), WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001065
1066 int32_t result = r.Call();
1067 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068}
1069
1070
1071TEST(Run_Wasm_Block_If_P) {
1072 WasmRunner<int32_t> r(MachineType::Int32());
1073 // { if (p0) return 51; return 52; }
Ben Murdochda12d292016-06-02 14:46:10 +01001074 BUILD(r, B2( // --
1075 WASM_IF(WASM_GET_LOCAL(0), // --
1076 WASM_BRV(0, WASM_I8(51))), // --
1077 WASM_I8(52))); // --
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078 FOR_INT32_INPUTS(i) {
1079 int32_t expected = *i ? 51 : 52;
1080 CHECK_EQ(expected, r.Call(*i));
1081 }
1082}
1083
1084
1085TEST(Run_Wasm_Block_BrIf_P) {
1086 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001087 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(51), WASM_GET_LOCAL(0)), WASM_I8(52)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001088 FOR_INT32_INPUTS(i) {
1089 int32_t expected = *i ? 51 : 52;
1090 CHECK_EQ(expected, r.Call(*i));
1091 }
1092}
1093
1094
1095TEST(Run_Wasm_Block_IfElse_P_assign) {
1096 WasmRunner<int32_t> r(MachineType::Int32());
1097 // { if (p0) p0 = 71; else p0 = 72; return p0; }
Ben Murdochda12d292016-06-02 14:46:10 +01001098 BUILD(r, B2( // --
1099 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1100 WASM_SET_LOCAL(0, WASM_I8(71)), // --
1101 WASM_SET_LOCAL(0, WASM_I8(72))), // --
1102 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001103 FOR_INT32_INPUTS(i) {
1104 int32_t expected = *i ? 71 : 72;
1105 CHECK_EQ(expected, r.Call(*i));
1106 }
1107}
1108
1109
1110TEST(Run_Wasm_Block_IfElse_P_return) {
1111 WasmRunner<int32_t> r(MachineType::Int32());
1112 // if (p0) return 81; else return 82;
Ben Murdochda12d292016-06-02 14:46:10 +01001113 BUILD(r, // --
1114 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1115 RET_I8(81), // --
1116 RET_I8(82))); // --
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001117 FOR_INT32_INPUTS(i) {
1118 int32_t expected = *i ? 81 : 82;
1119 CHECK_EQ(expected, r.Call(*i));
1120 }
1121}
1122
1123
1124TEST(Run_Wasm_Block_If_P_assign) {
1125 WasmRunner<int32_t> r(MachineType::Int32());
1126 // { if (p0) p0 = 61; p0; }
1127 BUILD(r, WASM_BLOCK(
1128 2, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))),
1129 WASM_GET_LOCAL(0)));
1130 FOR_INT32_INPUTS(i) {
1131 int32_t expected = *i ? 61 : *i;
1132 CHECK_EQ(expected, r.Call(*i));
1133 }
1134}
1135
1136
1137TEST(Run_Wasm_DanglingAssign) {
1138 WasmRunner<int32_t> r(MachineType::Int32());
1139 // { return 0; p0 = 0; }
Ben Murdochda12d292016-06-02 14:46:10 +01001140 BUILD(r, B2(RET_I8(99), WASM_SET_LOCAL(0, WASM_ZERO)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001141 CHECK_EQ(99, r.Call(1));
1142}
1143
1144
1145TEST(Run_Wasm_ExprIf_P) {
1146 WasmRunner<int32_t> r(MachineType::Int32());
1147 // p0 ? 11 : 22;
1148 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1149 WASM_I8(11), // --
1150 WASM_I8(22))); // --
1151 FOR_INT32_INPUTS(i) {
1152 int32_t expected = *i ? 11 : 22;
1153 CHECK_EQ(expected, r.Call(*i));
1154 }
1155}
1156
1157
1158TEST(Run_Wasm_ExprIf_P_fallthru) {
1159 WasmRunner<int32_t> r(MachineType::Int32());
1160 // p0 ? 11 : 22;
1161 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1162 WASM_I8(11), // --
1163 WASM_I8(22))); // --
1164 FOR_INT32_INPUTS(i) {
1165 int32_t expected = *i ? 11 : 22;
1166 CHECK_EQ(expected, r.Call(*i));
1167 }
1168}
1169
1170
1171TEST(Run_Wasm_CountDown) {
1172 WasmRunner<int32_t> r(MachineType::Int32());
1173 BUILD(r,
1174 WASM_BLOCK(
1175 2, WASM_LOOP(
1176 1, WASM_IF(WASM_GET_LOCAL(0),
1177 WASM_BRV(0, WASM_SET_LOCAL(
1178 0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1179 WASM_I8(1)))))),
1180 WASM_GET_LOCAL(0)));
1181 CHECK_EQ(0, r.Call(1));
1182 CHECK_EQ(0, r.Call(10));
1183 CHECK_EQ(0, r.Call(100));
1184}
1185
1186
1187TEST(Run_Wasm_CountDown_fallthru) {
1188 WasmRunner<int32_t> r(MachineType::Int32());
1189 BUILD(r,
1190 WASM_BLOCK(
1191 2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(0)),
1192 WASM_SET_LOCAL(
1193 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
1194 WASM_CONTINUE(0)),
1195 WASM_GET_LOCAL(0)));
1196 CHECK_EQ(0, r.Call(1));
1197 CHECK_EQ(0, r.Call(10));
1198 CHECK_EQ(0, r.Call(100));
1199}
1200
1201
1202TEST(Run_Wasm_WhileCountDown) {
1203 WasmRunner<int32_t> r(MachineType::Int32());
1204 BUILD(r, WASM_BLOCK(
1205 2, WASM_WHILE(WASM_GET_LOCAL(0),
1206 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1207 WASM_I8(1)))),
1208 WASM_GET_LOCAL(0)));
1209 CHECK_EQ(0, r.Call(1));
1210 CHECK_EQ(0, r.Call(10));
1211 CHECK_EQ(0, r.Call(100));
1212}
1213
1214
1215TEST(Run_Wasm_Loop_if_break1) {
1216 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001217 BUILD(r, B2(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(0)),
1218 WASM_SET_LOCAL(0, WASM_I8(99))),
1219 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001220 CHECK_EQ(99, r.Call(0));
1221 CHECK_EQ(3, r.Call(3));
1222 CHECK_EQ(10000, r.Call(10000));
1223 CHECK_EQ(-29, r.Call(-29));
1224}
1225
1226
1227TEST(Run_Wasm_Loop_if_break2) {
1228 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001229 BUILD(r, B2(WASM_LOOP(2, WASM_BR_IF(1, WASM_GET_LOCAL(0)),
1230 WASM_SET_LOCAL(0, WASM_I8(99))),
1231 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001232 CHECK_EQ(99, r.Call(0));
1233 CHECK_EQ(3, r.Call(3));
1234 CHECK_EQ(10000, r.Call(10000));
1235 CHECK_EQ(-29, r.Call(-29));
1236}
1237
1238
1239TEST(Run_Wasm_Loop_if_break_fallthru) {
1240 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001241 BUILD(r, B1(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
1242 WASM_SET_LOCAL(0, WASM_I8(93)))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001243 WASM_GET_LOCAL(0));
1244 CHECK_EQ(93, r.Call(0));
1245 CHECK_EQ(3, r.Call(3));
1246 CHECK_EQ(10001, r.Call(10001));
1247 CHECK_EQ(-22, r.Call(-22));
1248}
1249
1250
1251TEST(Run_Wasm_LoadMemI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001252 TestingModule module;
1253 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001254 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001255 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001256
1257 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0)));
1258
1259 memory[0] = 99999999;
1260 CHECK_EQ(99999999, r.Call(0));
1261
1262 memory[0] = 88888888;
1263 CHECK_EQ(88888888, r.Call(0));
1264
1265 memory[0] = 77777777;
1266 CHECK_EQ(77777777, r.Call(0));
1267}
1268
1269
1270TEST(Run_Wasm_LoadMemI32_oob) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001271 TestingModule module;
1272 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001274 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001275
1276 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1277
1278 memory[0] = 88888888;
1279 CHECK_EQ(88888888, r.Call(0u));
1280 for (uint32_t offset = 29; offset < 40; offset++) {
1281 CHECK_TRAP(r.Call(offset));
1282 }
1283
1284 for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
1285 CHECK_TRAP(r.Call(offset));
1286 }
1287}
1288
1289
1290TEST(Run_Wasm_LoadMemI32_oob_asm) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291 TestingModule module;
Ben Murdochda12d292016-06-02 14:46:10 +01001292 module.origin = kAsmJsOrigin;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001293 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001294 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295 module.RandomizeMemory(1112);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001296
1297 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1298
1299 memory[0] = 999999;
1300 CHECK_EQ(999999, r.Call(0u));
1301 // TODO(titzer): offset 29-31 should also be OOB.
1302 for (uint32_t offset = 32; offset < 40; offset++) {
1303 CHECK_EQ(0, r.Call(offset));
1304 }
1305
1306 for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
1307 CHECK_EQ(0, r.Call(offset));
1308 }
1309}
1310
1311
1312TEST(Run_Wasm_LoadMem_offset_oob) {
1313 TestingModule module;
1314 module.AddMemoryElems<int32_t>(8);
1315
1316 static const MachineType machineTypes[] = {
1317 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1318 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1319 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1320 MachineType::Float64()};
1321
1322 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1323 module.RandomizeMemory(1116 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001324 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001325 uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]);
1326
1327 BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)),
1328 WASM_ZERO);
1329
1330 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1331
1332 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1333 CHECK_TRAP(r.Call(offset)); // out of bounds.
1334 }
1335 }
1336}
1337
1338
1339TEST(Run_Wasm_LoadMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001340 TestingModule module;
1341 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001342 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001343 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001344
1345 BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0)));
1346
1347 memory[0] = 66666666;
1348 memory[1] = 77777777;
1349 memory[2] = 88888888;
1350 memory[3] = 99999999;
1351 CHECK_EQ(77777777, r.Call(0));
1352 CHECK_EQ(88888888, r.Call(4));
1353 CHECK_EQ(99999999, r.Call(8));
1354
1355 memory[0] = 11111111;
1356 memory[1] = 22222222;
1357 memory[2] = 33333333;
1358 memory[3] = 44444444;
1359 CHECK_EQ(22222222, r.Call(0));
1360 CHECK_EQ(33333333, r.Call(4));
1361 CHECK_EQ(44444444, r.Call(8));
1362}
1363
1364
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001365#if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
1366
Ben Murdoch097c5b22016-05-18 11:27:45 +01001367TEST(Run_Wasm_LoadMemI32_const_oob_misaligned) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001368 const int kMemSize = 12;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001369 // TODO(titzer): Fix misaligned accesses on MIPS and re-enable.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001370 for (int offset = 0; offset < kMemSize + 5; offset++) {
1371 for (int index = 0; index < kMemSize + 5; index++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001372 TestingModule module;
1373 module.AddMemoryElems<byte>(kMemSize);
1374
1375 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001376 module.RandomizeMemory();
1377
1378 BUILD(r,
1379 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1380
1381 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1382 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1383 } else {
1384 CHECK_TRAP(r.Call());
1385 }
1386 }
1387 }
1388}
1389
1390#endif
1391
1392
Ben Murdoch097c5b22016-05-18 11:27:45 +01001393TEST(Run_Wasm_LoadMemI32_const_oob) {
1394 const int kMemSize = 24;
1395 for (int offset = 0; offset < kMemSize + 5; offset += 4) {
1396 for (int index = 0; index < kMemSize + 5; index += 4) {
1397 TestingModule module;
1398 module.AddMemoryElems<byte>(kMemSize);
1399
1400 WasmRunner<int32_t> r(&module);
1401 module.RandomizeMemory();
1402
1403 BUILD(r,
1404 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1405
1406 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1407 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1408 } else {
1409 CHECK_TRAP(r.Call());
1410 }
1411 }
1412 }
1413}
1414
1415
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001416TEST(Run_Wasm_StoreMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417 TestingModule module;
1418 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001419 WasmRunner<int32_t> r(&module, MachineType::Int32());
1420 const int32_t kWritten = 0xaabbccdd;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001421
1422 BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0),
Ben Murdochda12d292016-06-02 14:46:10 +01001423 WASM_I32V_5(kWritten)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001424
1425 for (int i = 0; i < 2; i++) {
1426 module.RandomizeMemory(1111);
1427 memory[0] = 66666666;
1428 memory[1] = 77777777;
1429 memory[2] = 88888888;
1430 memory[3] = 99999999;
1431 CHECK_EQ(kWritten, r.Call(i * 4));
1432 CHECK_EQ(66666666, memory[0]);
1433 CHECK_EQ(i == 0 ? kWritten : 77777777, memory[1]);
1434 CHECK_EQ(i == 1 ? kWritten : 88888888, memory[2]);
1435 CHECK_EQ(i == 2 ? kWritten : 99999999, memory[3]);
1436 }
1437}
1438
1439
1440TEST(Run_Wasm_StoreMem_offset_oob) {
1441 TestingModule module;
1442 byte* memory = module.AddMemoryElems<byte>(32);
1443
1444#if WASM_64
1445 static const MachineType machineTypes[] = {
1446 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1447 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1448 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1449 MachineType::Float64()};
1450#else
1451 static const MachineType machineTypes[] = {
1452 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1453 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1454 MachineType::Float32(), MachineType::Float64()};
1455#endif
1456
1457 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1458 module.RandomizeMemory(1119 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001459 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001460
1461 BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
1462 WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
1463 WASM_ZERO);
1464
1465 byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
1466 uint32_t boundary = 24 - memsize;
1467 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1468 CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
1469
1470 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1471 CHECK_TRAP(r.Call(offset)); // out of bounds.
1472 }
1473 }
1474}
1475
1476
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001477TEST(Run_Wasm_LoadMemI32_P) {
1478 const int kNumElems = 8;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001479 TestingModule module;
1480 int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001481 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001482 module.RandomizeMemory(2222);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001483
1484 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1485
1486 for (int i = 0; i < kNumElems; i++) {
1487 CHECK_EQ(memory[i], r.Call(i * 4));
1488 }
1489}
1490
1491
1492TEST(Run_Wasm_MemI32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001493 const int kNumElems = 20;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494 TestingModule module;
1495 uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001496 WasmRunner<uint32_t> r(&module, MachineType::Int32());
1497 const byte kSum = r.AllocateLocal(kAstI32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001498
1499 BUILD(r, WASM_BLOCK(
1500 2, WASM_WHILE(
1501 WASM_GET_LOCAL(0),
1502 WASM_BLOCK(
1503 2, WASM_SET_LOCAL(
1504 kSum, WASM_I32_ADD(
1505 WASM_GET_LOCAL(kSum),
1506 WASM_LOAD_MEM(MachineType::Int32(),
1507 WASM_GET_LOCAL(0)))),
1508 WASM_SET_LOCAL(
1509 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1510 WASM_GET_LOCAL(1)));
1511
1512 // Run 4 trials.
1513 for (int i = 0; i < 3; i++) {
1514 module.RandomizeMemory(i * 33);
1515 uint32_t expected = 0;
1516 for (size_t j = kNumElems - 1; j > 0; j--) {
1517 expected += memory[j];
1518 }
1519 uint32_t result = r.Call(static_cast<int>(4 * (kNumElems - 1)));
1520 CHECK_EQ(expected, result);
1521 }
1522}
1523
1524
1525TEST(Run_Wasm_CheckMachIntsZero) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001526 const int kNumElems = 55;
1527 TestingModule module;
1528 module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001529 WasmRunner<uint32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001530
1531 BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0,
Ben Murdochda12d292016-06-02 14:46:10 +01001532 kExprIfElse, kExprI32LoadMem, ZERO_ALIGNMENT, ZERO_OFFSET,
1533 kExprGetLocal, 0, kExprBr, 2, kExprI8Const, 255, kExprSetLocal, 0,
1534 kExprI32Sub, kExprGetLocal, 0, kExprI8Const, 4, kExprI8Const, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001535
1536 module.BlankMemory();
1537 CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
1538}
1539
1540
1541TEST(Run_Wasm_MemF32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001542 const int kSize = 5;
1543 TestingModule module;
1544 module.AddMemoryElems<float>(kSize);
1545 float* buffer = module.raw_mem_start<float>();
1546 buffer[0] = -99.25;
1547 buffer[1] = -888.25;
1548 buffer[2] = -77.25;
1549 buffer[3] = 66666.25;
1550 buffer[4] = 5555.25;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001551 WasmRunner<int32_t> r(&module, MachineType::Int32());
1552 const byte kSum = r.AllocateLocal(kAstF32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001553
1554 BUILD(r, WASM_BLOCK(
1555 3, WASM_WHILE(
1556 WASM_GET_LOCAL(0),
1557 WASM_BLOCK(
1558 2, WASM_SET_LOCAL(
1559 kSum, WASM_F32_ADD(
1560 WASM_GET_LOCAL(kSum),
1561 WASM_LOAD_MEM(MachineType::Float32(),
1562 WASM_GET_LOCAL(0)))),
1563 WASM_SET_LOCAL(
1564 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1565 WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
1566 WASM_GET_LOCAL(kSum)),
1567 WASM_GET_LOCAL(0)));
1568
1569 CHECK_EQ(0, r.Call(4 * (kSize - 1)));
1570 CHECK_NE(-99.25, buffer[0]);
1571 CHECK_EQ(71256.0f, buffer[0]);
1572}
1573
1574
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001575template <typename T>
1576T GenerateAndRunFold(WasmOpcode binop, T* buffer, size_t size,
1577 LocalType astType, MachineType memType) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001578 TestingModule module;
1579 module.AddMemoryElems<T>(size);
1580 for (size_t i = 0; i < size; i++) {
1581 module.raw_mem_start<T>()[i] = buffer[i];
1582 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001583 WasmRunner<int32_t> r(&module, MachineType::Int32());
1584 const byte kAccum = r.AllocateLocal(astType);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001585
1586 BUILD(
1587 r,
1588 WASM_BLOCK(
1589 4, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
1590 WASM_WHILE(
1591 WASM_GET_LOCAL(0),
1592 WASM_BLOCK(
1593 2, WASM_SET_LOCAL(
1594 kAccum,
1595 WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
1596 WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))),
1597 WASM_SET_LOCAL(
1598 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(sizeof(T)))))),
1599 WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
1600 WASM_GET_LOCAL(0)));
1601 r.Call(static_cast<int>(sizeof(T) * (size - 1)));
1602 return module.raw_mem_at<double>(0);
1603}
1604
1605
1606TEST(Run_Wasm_MemF64_Mul) {
1607 const size_t kSize = 6;
1608 double buffer[kSize] = {1, 2, 2, 2, 2, 2};
1609 double result = GenerateAndRunFold<double>(kExprF64Mul, buffer, kSize,
1610 kAstF64, MachineType::Float64());
1611 CHECK_EQ(32, result);
1612}
1613
1614
1615TEST(Build_Wasm_Infinite_Loop) {
1616 WasmRunner<int32_t> r(MachineType::Int32());
1617 // Only build the graph and compile, don't run.
1618 BUILD(r, WASM_INFINITE_LOOP);
1619}
1620
1621
1622TEST(Build_Wasm_Infinite_Loop_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623 TestingModule module;
1624 module.AddMemoryElems<int8_t>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001625 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001626
1627 // Only build the graph and compile, don't run.
1628 BUILD(r, WASM_LOOP(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
1629}
1630
1631
1632TEST(Run_Wasm_Unreachable0a) {
1633 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001634 BUILD(r, B2(WASM_BRV(0, WASM_I8(9)), RET(WASM_GET_LOCAL(0))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001635 CHECK_EQ(9, r.Call(0));
1636 CHECK_EQ(9, r.Call(1));
1637}
1638
1639
1640TEST(Run_Wasm_Unreachable0b) {
1641 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001642 BUILD(r, B2(WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001643 CHECK_EQ(7, r.Call(0));
1644 CHECK_EQ(7, r.Call(1));
1645}
1646
1647
1648TEST(Build_Wasm_Unreachable1) {
1649 WasmRunner<int32_t> r(MachineType::Int32());
1650 BUILD(r, WASM_UNREACHABLE);
1651}
1652
1653
1654TEST(Build_Wasm_Unreachable2) {
1655 WasmRunner<int32_t> r(MachineType::Int32());
1656 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE);
1657}
1658
1659
1660TEST(Build_Wasm_Unreachable3) {
1661 WasmRunner<int32_t> r(MachineType::Int32());
1662 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE);
1663}
1664
1665
1666TEST(Build_Wasm_UnreachableIf1) {
1667 WasmRunner<int32_t> r(MachineType::Int32());
1668 BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
1669}
1670
1671
1672TEST(Build_Wasm_UnreachableIf2) {
1673 WasmRunner<int32_t> r(MachineType::Int32());
1674 BUILD(r, WASM_UNREACHABLE,
1675 WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
1676}
1677
1678
1679TEST(Run_Wasm_Unreachable_Load) {
1680 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001681 BUILD(r, B2(WASM_BRV(0, WASM_GET_LOCAL(0)),
1682 WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001683 CHECK_EQ(11, r.Call(11));
1684 CHECK_EQ(21, r.Call(21));
1685}
1686
1687
1688TEST(Run_Wasm_Infinite_Loop_not_taken1) {
1689 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001690 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), WASM_I8(45)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 // Run the code, but don't go into the infinite loop.
1692 CHECK_EQ(45, r.Call(0));
1693}
1694
1695
1696TEST(Run_Wasm_Infinite_Loop_not_taken2) {
1697 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001698 BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(45)),
1699 WASM_INFINITE_LOOP)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001700 // Run the code, but don't go into the infinite loop.
1701 CHECK_EQ(45, r.Call(1));
1702}
1703
1704
1705TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) {
1706 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001707 BUILD(r,
1708 B2(WASM_BRV_IF(0, WASM_I8(45), WASM_GET_LOCAL(0)), WASM_INFINITE_LOOP));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001709 // Run the code, but don't go into the infinite loop.
1710 CHECK_EQ(45, r.Call(1));
1711}
1712
1713
1714static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
1715 if (!WasmOpcodes::IsSupported(opcode)) return;
1716
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001717 Isolate* isolate = CcTest::InitIsolateOnce();
Ben Murdochda12d292016-06-02 14:46:10 +01001718 Zone zone(isolate->allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719 HandleScope scope(isolate);
1720 // Enable all optional operators.
1721 CommonOperatorBuilder common(&zone);
1722 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(),
1723 MachineOperatorBuilder::kAllOptionalOps);
1724 Graph graph(&zone);
1725 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726 FunctionSig* sig = WasmOpcodes::Signature(opcode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001727
1728 if (sig->parameter_count() == 1) {
Ben Murdochda12d292016-06-02 14:46:10 +01001729 byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode), kExprGetLocal, 0};
1730 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code,
1731 code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001732 } else {
1733 CHECK_EQ(2, sig->parameter_count());
Ben Murdochda12d292016-06-02 14:46:10 +01001734 byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode),
1735 kExprGetLocal, 0,
1736 kExprGetLocal, 1};
1737 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code,
1738 code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001739 }
1740}
1741
1742
1743TEST(Build_Wasm_SimpleExprs) {
1744// Test that the decoder can build a graph for all supported simple expressions.
1745#define GRAPH_BUILD_TEST(name, opcode, sig) \
1746 TestBuildGraphForSimpleExpression(kExpr##name);
1747
1748 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST);
1749
1750#undef GRAPH_BUILD_TEST
1751}
1752
1753
1754TEST(Run_Wasm_Int32LoadInt8_signext) {
1755 TestingModule module;
1756 const int kNumElems = 16;
1757 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems);
1758 module.RandomizeMemory();
1759 memory[0] = -1;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001760 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001761 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)));
1762
1763 for (size_t i = 0; i < kNumElems; i++) {
1764 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
1765 }
1766}
1767
1768
1769TEST(Run_Wasm_Int32LoadInt8_zeroext) {
1770 TestingModule module;
1771 const int kNumElems = 16;
1772 byte* memory = module.AddMemory(kNumElems);
1773 module.RandomizeMemory(77);
1774 memory[0] = 255;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001775 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001776 BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0)));
1777
1778 for (size_t i = 0; i < kNumElems; i++) {
1779 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
1780 }
1781}
1782
1783
1784TEST(Run_Wasm_Int32LoadInt16_signext) {
1785 TestingModule module;
1786 const int kNumBytes = 16;
1787 byte* memory = module.AddMemory(kNumBytes);
1788 module.RandomizeMemory(888);
1789 memory[1] = 200;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001790 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001791 BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0)));
1792
1793 for (size_t i = 0; i < kNumBytes; i += 2) {
1794 int32_t expected = memory[i] | (static_cast<int8_t>(memory[i + 1]) << 8);
1795 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
1796 }
1797}
1798
1799
1800TEST(Run_Wasm_Int32LoadInt16_zeroext) {
1801 TestingModule module;
1802 const int kNumBytes = 16;
1803 byte* memory = module.AddMemory(kNumBytes);
1804 module.RandomizeMemory(9999);
1805 memory[1] = 204;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001806 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001807 BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0)));
1808
1809 for (size_t i = 0; i < kNumBytes; i += 2) {
1810 int32_t expected = memory[i] | (memory[i + 1] << 8);
1811 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
1812 }
1813}
1814
1815
1816TEST(Run_WasmInt32Global) {
1817 TestingModule module;
1818 int32_t* global = module.AddGlobal<int32_t>(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001819 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001820 // global = global + p0
1821 BUILD(r, WASM_STORE_GLOBAL(
1822 0, WASM_I32_ADD(WASM_LOAD_GLOBAL(0), WASM_GET_LOCAL(0))));
1823
1824 *global = 116;
1825 for (int i = 9; i < 444444; i += 111111) {
1826 int32_t expected = *global + i;
1827 r.Call(i);
1828 CHECK_EQ(expected, *global);
1829 }
1830}
1831
1832
1833TEST(Run_WasmInt32Globals_DontAlias) {
1834 const int kNumGlobals = 3;
1835 TestingModule module;
1836 int32_t* globals[] = {module.AddGlobal<int32_t>(MachineType::Int32()),
1837 module.AddGlobal<int32_t>(MachineType::Int32()),
1838 module.AddGlobal<int32_t>(MachineType::Int32())};
1839
1840 for (int g = 0; g < kNumGlobals; g++) {
1841 // global = global + p0
Ben Murdoch097c5b22016-05-18 11:27:45 +01001842 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001843 BUILD(r, WASM_STORE_GLOBAL(
1844 g, WASM_I32_ADD(WASM_LOAD_GLOBAL(g), WASM_GET_LOCAL(0))));
1845
1846 // Check that reading/writing global number {g} doesn't alter the others.
1847 *globals[g] = 116 * g;
1848 int32_t before[kNumGlobals];
1849 for (int i = 9; i < 444444; i += 111113) {
1850 int32_t sum = *globals[g] + i;
1851 for (int j = 0; j < kNumGlobals; j++) before[j] = *globals[j];
1852 r.Call(i);
1853 for (int j = 0; j < kNumGlobals; j++) {
1854 int32_t expected = j == g ? sum : before[j];
1855 CHECK_EQ(expected, *globals[j]);
1856 }
1857 }
1858 }
1859}
1860
1861
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001862TEST(Run_WasmFloat32Global) {
1863 TestingModule module;
1864 float* global = module.AddGlobal<float>(MachineType::Float32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001865 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001866 // global = global + p0
Ben Murdochda12d292016-06-02 14:46:10 +01001867 BUILD(r, B2(WASM_STORE_GLOBAL(
1868 0, WASM_F32_ADD(WASM_LOAD_GLOBAL(0),
1869 WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0)))),
1870 WASM_ZERO));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001871
1872 *global = 1.25;
1873 for (int i = 9; i < 4444; i += 1111) {
1874 volatile float expected = *global + i;
1875 r.Call(i);
1876 CHECK_EQ(expected, *global);
1877 }
1878}
1879
1880
1881TEST(Run_WasmFloat64Global) {
1882 TestingModule module;
1883 double* global = module.AddGlobal<double>(MachineType::Float64());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001884 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001885 // global = global + p0
Ben Murdochda12d292016-06-02 14:46:10 +01001886 BUILD(r, B2(WASM_STORE_GLOBAL(
1887 0, WASM_F64_ADD(WASM_LOAD_GLOBAL(0),
1888 WASM_F64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
1889 WASM_ZERO));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001890
1891 *global = 1.25;
1892 for (int i = 9; i < 4444; i += 1111) {
1893 volatile double expected = *global + i;
1894 r.Call(i);
1895 CHECK_EQ(expected, *global);
1896 }
1897}
1898
1899
1900TEST(Run_WasmMixedGlobals) {
1901 TestingModule module;
1902 int32_t* unused = module.AddGlobal<int32_t>(MachineType::Int32());
1903 byte* memory = module.AddMemory(32);
1904
1905 int8_t* var_int8 = module.AddGlobal<int8_t>(MachineType::Int8());
1906 uint8_t* var_uint8 = module.AddGlobal<uint8_t>(MachineType::Uint8());
1907 int16_t* var_int16 = module.AddGlobal<int16_t>(MachineType::Int16());
1908 uint16_t* var_uint16 = module.AddGlobal<uint16_t>(MachineType::Uint16());
1909 int32_t* var_int32 = module.AddGlobal<int32_t>(MachineType::Int32());
1910 uint32_t* var_uint32 = module.AddGlobal<uint32_t>(MachineType::Uint32());
1911 float* var_float = module.AddGlobal<float>(MachineType::Float32());
1912 double* var_double = module.AddGlobal<double>(MachineType::Float64());
1913
Ben Murdoch097c5b22016-05-18 11:27:45 +01001914 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001915
1916 BUILD(
1917 r,
1918 WASM_BLOCK(
1919 9,
1920 WASM_STORE_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int8(), WASM_ZERO)),
1921 WASM_STORE_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint8(), WASM_ZERO)),
1922 WASM_STORE_GLOBAL(3, WASM_LOAD_MEM(MachineType::Int16(), WASM_ZERO)),
1923 WASM_STORE_GLOBAL(4, WASM_LOAD_MEM(MachineType::Uint16(), WASM_ZERO)),
1924 WASM_STORE_GLOBAL(5, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
1925 WASM_STORE_GLOBAL(6, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)),
1926 WASM_STORE_GLOBAL(7,
1927 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)),
1928 WASM_STORE_GLOBAL(8,
1929 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)),
1930 WASM_ZERO));
1931
1932 memory[0] = 0xaa;
1933 memory[1] = 0xcc;
1934 memory[2] = 0x55;
1935 memory[3] = 0xee;
1936 memory[4] = 0x33;
1937 memory[5] = 0x22;
1938 memory[6] = 0x11;
1939 memory[7] = 0x99;
1940 r.Call(1);
1941
1942 CHECK(static_cast<int8_t>(0xaa) == *var_int8);
1943 CHECK(static_cast<uint8_t>(0xaa) == *var_uint8);
1944 CHECK(static_cast<int16_t>(0xccaa) == *var_int16);
1945 CHECK(static_cast<uint16_t>(0xccaa) == *var_uint16);
1946 CHECK(static_cast<int32_t>(0xee55ccaa) == *var_int32);
1947 CHECK(static_cast<uint32_t>(0xee55ccaa) == *var_uint32);
1948 CHECK(bit_cast<float>(0xee55ccaa) == *var_float);
1949 CHECK(bit_cast<double>(0x99112233ee55ccaaULL) == *var_double);
1950
1951 USE(unused);
1952}
1953
1954
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001955TEST(Run_WasmCallEmpty) {
1956 const int32_t kExpected = -414444;
1957 // Build the target function.
1958 TestSignatures sigs;
1959 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001960 WasmFunctionCompiler t(sigs.i_v(), &module);
Ben Murdochda12d292016-06-02 14:46:10 +01001961 BUILD(t, WASM_I32V_3(kExpected));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001962 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001963
1964 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001965 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001966 BUILD(r, WASM_CALL_FUNCTION0(index));
1967
1968 int32_t result = r.Call();
1969 CHECK_EQ(kExpected, result);
1970}
1971
1972
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001973TEST(Run_WasmCallF32StackParameter) {
1974 // Build the target function.
1975 LocalType param_types[20];
1976 for (int i = 0; i < 20; i++) param_types[i] = kAstF32;
1977 FunctionSig sig(1, 19, param_types);
1978 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001979 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001980 BUILD(t, WASM_GET_LOCAL(17));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001981 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001982
1983 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001984 WasmRunner<float> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001985 BUILD(r, WASM_CALL_FUNCTION(
1986 index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
1987 WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
1988 WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
1989 WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
1990 WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f),
1991 WASM_F32(128.5f), WASM_F32(256.5f), WASM_F32(512.5f)));
1992
1993 float result = r.Call();
1994 CHECK_EQ(256.5f, result);
1995}
1996
1997
1998TEST(Run_WasmCallF64StackParameter) {
1999 // Build the target function.
2000 LocalType param_types[20];
2001 for (int i = 0; i < 20; i++) param_types[i] = kAstF64;
2002 FunctionSig sig(1, 19, param_types);
2003 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002004 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002005 BUILD(t, WASM_GET_LOCAL(17));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002006 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002007
2008 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002009 WasmRunner<double> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002010 BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0),
2011 WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
2012 WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
2013 WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
2014 WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
2015 WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
2016 WASM_F64(256.5), WASM_F64(512.5)));
2017
2018 float result = r.Call();
2019 CHECK_EQ(256.5, result);
2020}
2021
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002022TEST(Run_WasmCallVoid) {
2023 const byte kMemOffset = 8;
2024 const int32_t kElemNum = kMemOffset / sizeof(int32_t);
2025 const int32_t kExpected = -414444;
2026 // Build the target function.
2027 TestSignatures sigs;
2028 TestingModule module;
2029 module.AddMemory(16);
2030 module.RandomizeMemory();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002031 WasmFunctionCompiler t(sigs.v_v(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002032 BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset),
Ben Murdochda12d292016-06-02 14:46:10 +01002033 WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002034 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002035
2036 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002037 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002038 BUILD(r, WASM_CALL_FUNCTION0(index),
2039 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset)));
2040
2041 int32_t result = r.Call();
2042 CHECK_EQ(kExpected, result);
2043 CHECK_EQ(kExpected, module.raw_mem_start<int32_t>()[kElemNum]);
2044}
2045
2046
2047TEST(Run_WasmCall_Int32Add) {
2048 // Build the target function.
2049 TestSignatures sigs;
2050 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002051 WasmFunctionCompiler t(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002052 BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002053 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002054
2055 // Build the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002056 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002057 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2058
2059 FOR_INT32_INPUTS(i) {
2060 FOR_INT32_INPUTS(j) {
2061 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
2062 static_cast<uint32_t>(*j));
2063 CHECK_EQ(expected, r.Call(*i, *j));
2064 }
2065 }
2066}
2067
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002068TEST(Run_WasmCall_Float32Sub) {
2069 TestSignatures sigs;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002070 TestingModule module;
2071 WasmFunctionCompiler t(sigs.f_ff(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002072
2073 // Build the target function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002074 BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002075 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002076
2077 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002078 WasmRunner<float> r(&module, MachineType::Float32(), MachineType::Float32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002079 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2080
2081 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002082 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002083 }
2084}
2085
2086
2087TEST(Run_WasmCall_Float64Sub) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002088 TestingModule module;
2089 double* memory = module.AddMemoryElems<double>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002090 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002092 BUILD(r, WASM_BLOCK(
2093 2, WASM_STORE_MEM(
2094 MachineType::Float64(), WASM_ZERO,
2095 WASM_F64_SUB(
2096 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
2097 WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))),
2098 WASM_I8(107)));
2099
2100 FOR_FLOAT64_INPUTS(i) {
2101 FOR_FLOAT64_INPUTS(j) {
2102 memory[0] = *i;
2103 memory[1] = *j;
2104 double expected = *i - *j;
2105 CHECK_EQ(107, r.Call());
2106 if (expected != expected) {
2107 CHECK(memory[0] != memory[0]);
2108 } else {
2109 CHECK_EQ(expected, memory[0]);
2110 }
2111 }
2112 }
2113}
2114
2115#define ADD_CODE(vec, ...) \
2116 do { \
2117 byte __buf[] = {__VA_ARGS__}; \
2118 for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
2119 } while (false)
2120
2121
2122static void Run_WasmMixedCall_N(int start) {
2123 const int kExpected = 6333;
2124 const int kElemSize = 8;
2125 TestSignatures sigs;
2126
2127#if WASM_64
2128 static MachineType mixed[] = {
2129 MachineType::Int32(), MachineType::Float32(), MachineType::Int64(),
2130 MachineType::Float64(), MachineType::Float32(), MachineType::Int64(),
2131 MachineType::Int32(), MachineType::Float64(), MachineType::Float32(),
2132 MachineType::Float64(), MachineType::Int32(), MachineType::Int64(),
2133 MachineType::Int32(), MachineType::Int32()};
2134#else
2135 static MachineType mixed[] = {
2136 MachineType::Int32(), MachineType::Float32(), MachineType::Float64(),
2137 MachineType::Float32(), MachineType::Int32(), MachineType::Float64(),
2138 MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
2139 MachineType::Int32(), MachineType::Int32()};
2140#endif
2141
2142 int num_params = static_cast<int>(arraysize(mixed)) - start;
2143 for (int which = 0; which < num_params; which++) {
Ben Murdochda12d292016-06-02 14:46:10 +01002144 v8::base::AccountingAllocator allocator;
2145 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002146 TestingModule module;
2147 module.AddMemory(1024);
2148 MachineType* memtypes = &mixed[start];
2149 MachineType result = memtypes[which];
2150
2151 // =========================================================================
2152 // Build the selector function.
2153 // =========================================================================
2154 uint32_t index;
2155 FunctionSig::Builder b(&zone, 1, num_params);
2156 b.AddReturn(WasmOpcodes::LocalTypeFor(result));
2157 for (int i = 0; i < num_params; i++) {
2158 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
2159 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002160 WasmFunctionCompiler t(b.Build(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002161 BUILD(t, WASM_GET_LOCAL(which));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002162 index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002163
2164 // =========================================================================
2165 // Build the calling function.
2166 // =========================================================================
Ben Murdoch097c5b22016-05-18 11:27:45 +01002167 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002168
Ben Murdoch097c5b22016-05-18 11:27:45 +01002169 std::vector<byte> code;
2170 ADD_CODE(code,
2171 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
Ben Murdochda12d292016-06-02 14:46:10 +01002172 ZERO_ALIGNMENT, ZERO_OFFSET);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002173 ADD_CODE(code, WASM_ZERO);
2174 ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002175
Ben Murdoch097c5b22016-05-18 11:27:45 +01002176 for (int i = 0; i < num_params; i++) {
2177 int offset = (i + 1) * kElemSize;
2178 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002179 }
2180
Ben Murdochda12d292016-06-02 14:46:10 +01002181 ADD_CODE(code, WASM_I32V_2(kExpected));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002182 size_t end = code.size();
2183 code.push_back(0);
2184 r.Build(&code[0], &code[end]);
2185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002186 // Run the code.
2187 for (int t = 0; t < 10; t++) {
2188 module.RandomizeMemory();
2189 CHECK_EQ(kExpected, r.Call());
2190
2191 int size = WasmOpcodes::MemSize(result);
2192 for (int i = 0; i < size; i++) {
2193 int base = (which + 1) * kElemSize;
2194 byte expected = module.raw_mem_at<byte>(base + i);
2195 byte result = module.raw_mem_at<byte>(i);
2196 CHECK_EQ(expected, result);
2197 }
2198 }
2199 }
2200}
2201
2202
2203TEST(Run_WasmMixedCall_0) { Run_WasmMixedCall_N(0); }
2204TEST(Run_WasmMixedCall_1) { Run_WasmMixedCall_N(1); }
2205TEST(Run_WasmMixedCall_2) { Run_WasmMixedCall_N(2); }
2206TEST(Run_WasmMixedCall_3) { Run_WasmMixedCall_N(3); }
2207
Ben Murdoch097c5b22016-05-18 11:27:45 +01002208TEST(Run_Wasm_AddCall) {
2209 TestSignatures sigs;
2210 TestingModule module;
2211 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2212 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2213 t1.CompileAndAdd();
2214
2215 WasmRunner<int32_t> r(&module, MachineType::Int32());
2216 byte local = r.AllocateLocal(kAstI32);
Ben Murdochda12d292016-06-02 14:46:10 +01002217 BUILD(r, B2(WASM_SET_LOCAL(local, WASM_I8(99)),
2218 WASM_I32_ADD(
2219 WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(0),
2220 WASM_GET_LOCAL(0)),
2221 WASM_CALL_FUNCTION(t1.function_index_, WASM_GET_LOCAL(1),
2222 WASM_GET_LOCAL(local)))));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002223
2224 CHECK_EQ(198, r.Call(0));
2225 CHECK_EQ(200, r.Call(1));
2226 CHECK_EQ(100, r.Call(-49));
2227}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002228
2229TEST(Run_Wasm_CountDown_expr) {
2230 WasmRunner<int32_t> r(MachineType::Int32());
2231 BUILD(r, WASM_LOOP(
2232 3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
2233 WASM_BREAKV(0, WASM_GET_LOCAL(0))),
2234 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
2235 WASM_CONTINUE(0)));
2236 CHECK_EQ(0, r.Call(1));
2237 CHECK_EQ(0, r.Call(10));
2238 CHECK_EQ(0, r.Call(100));
2239}
2240
2241
2242TEST(Run_Wasm_ExprBlock2a) {
2243 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002244 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), WASM_I8(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002245 CHECK_EQ(1, r.Call(0));
2246 CHECK_EQ(1, r.Call(1));
2247}
2248
2249
2250TEST(Run_Wasm_ExprBlock2b) {
2251 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002252 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), WASM_I8(2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002253 CHECK_EQ(2, r.Call(0));
2254 CHECK_EQ(1, r.Call(1));
2255}
2256
2257
2258TEST(Run_Wasm_ExprBlock2c) {
2259 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002260 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)), WASM_I8(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002261 CHECK_EQ(1, r.Call(0));
2262 CHECK_EQ(1, r.Call(1));
2263}
2264
2265
2266TEST(Run_Wasm_ExprBlock2d) {
2267 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002268 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)), WASM_I8(2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002269 CHECK_EQ(2, r.Call(0));
2270 CHECK_EQ(1, r.Call(1));
2271}
2272
2273
2274TEST(Run_Wasm_ExprBlock_ManualSwitch) {
2275 WasmRunner<int32_t> r(MachineType::Int32());
2276 BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
2277 WASM_BRV(0, WASM_I8(11))),
2278 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
2279 WASM_BRV(0, WASM_I8(12))),
2280 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
2281 WASM_BRV(0, WASM_I8(13))),
2282 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
2283 WASM_BRV(0, WASM_I8(14))),
2284 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
2285 WASM_BRV(0, WASM_I8(15))),
2286 WASM_I8(99)));
2287 CHECK_EQ(99, r.Call(0));
2288 CHECK_EQ(11, r.Call(1));
2289 CHECK_EQ(12, r.Call(2));
2290 CHECK_EQ(13, r.Call(3));
2291 CHECK_EQ(14, r.Call(4));
2292 CHECK_EQ(15, r.Call(5));
2293 CHECK_EQ(99, r.Call(6));
2294}
2295
2296
2297TEST(Run_Wasm_ExprBlock_ManualSwitch_brif) {
2298 WasmRunner<int32_t> r(MachineType::Int32());
2299 BUILD(r,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002300 WASM_BLOCK(6, WASM_BRV_IF(0, WASM_I8(11),
2301 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1))),
2302 WASM_BRV_IF(0, WASM_I8(12),
2303 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2))),
2304 WASM_BRV_IF(0, WASM_I8(13),
2305 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3))),
2306 WASM_BRV_IF(0, WASM_I8(14),
2307 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4))),
2308 WASM_BRV_IF(0, WASM_I8(15),
2309 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002310 WASM_I8(99)));
2311 CHECK_EQ(99, r.Call(0));
2312 CHECK_EQ(11, r.Call(1));
2313 CHECK_EQ(12, r.Call(2));
2314 CHECK_EQ(13, r.Call(3));
2315 CHECK_EQ(14, r.Call(4));
2316 CHECK_EQ(15, r.Call(5));
2317 CHECK_EQ(99, r.Call(6));
2318}
2319
2320
2321TEST(Run_Wasm_nested_ifs) {
2322 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2323
2324 BUILD(r, WASM_IF_ELSE(
2325 WASM_GET_LOCAL(0),
2326 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
2327 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
2328
2329
2330 CHECK_EQ(11, r.Call(1, 1));
2331 CHECK_EQ(12, r.Call(1, 0));
2332 CHECK_EQ(13, r.Call(0, 1));
2333 CHECK_EQ(14, r.Call(0, 0));
2334}
2335
2336
2337TEST(Run_Wasm_ExprBlock_if) {
2338 WasmRunner<int32_t> r(MachineType::Int32());
2339
Ben Murdochda12d292016-06-02 14:46:10 +01002340 BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
2341 WASM_BRV(0, WASM_I8(14)))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002342
2343 CHECK_EQ(11, r.Call(1));
2344 CHECK_EQ(14, r.Call(0));
2345}
2346
2347
2348TEST(Run_Wasm_ExprBlock_nested_ifs) {
2349 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2350
2351 BUILD(r, WASM_BLOCK(
2352 1, WASM_IF_ELSE(
2353 WASM_GET_LOCAL(0),
2354 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
2355 WASM_BRV(0, WASM_I8(12))),
2356 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
2357 WASM_BRV(0, WASM_I8(14))))));
2358
2359
2360 CHECK_EQ(11, r.Call(1, 1));
2361 CHECK_EQ(12, r.Call(1, 0));
2362 CHECK_EQ(13, r.Call(0, 1));
2363 CHECK_EQ(14, r.Call(0, 0));
2364}
2365
2366
2367TEST(Run_Wasm_ExprLoop_nested_ifs) {
2368 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2369
2370 BUILD(r, WASM_LOOP(
2371 1, WASM_IF_ELSE(
2372 WASM_GET_LOCAL(0),
2373 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)),
2374 WASM_BRV(1, WASM_I8(12))),
2375 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)),
2376 WASM_BRV(1, WASM_I8(14))))));
2377
2378
2379 CHECK_EQ(11, r.Call(1, 1));
2380 CHECK_EQ(12, r.Call(1, 0));
2381 CHECK_EQ(13, r.Call(0, 1));
2382 CHECK_EQ(14, r.Call(0, 0));
2383}
2384
2385
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002386TEST(Run_Wasm_SimpleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002387 TestSignatures sigs;
2388 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002389
Ben Murdoch097c5b22016-05-18 11:27:45 +01002390 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2391 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2392 t1.CompileAndAdd(/*sig_index*/ 1);
2393
2394 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002395 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002396 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002397
2398 // Signature table.
2399 module.AddSignature(sigs.f_ff());
2400 module.AddSignature(sigs.i_ii());
2401 module.AddSignature(sigs.d_dd());
2402
2403 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002404 int table[] = {0, 1};
2405 module.AddIndirectFunctionTable(table, 2);
2406 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002407
2408 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002409 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002410 BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
2411
2412 CHECK_EQ(88, r.Call(0));
2413 CHECK_EQ(44, r.Call(1));
2414 CHECK_TRAP(r.Call(2));
2415}
2416
2417
2418TEST(Run_Wasm_MultipleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002419 TestSignatures sigs;
2420 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002421
Ben Murdoch097c5b22016-05-18 11:27:45 +01002422 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2423 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2424 t1.CompileAndAdd(/*sig_index*/ 1);
2425
2426 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002427 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002428 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429
2430 // Signature table.
2431 module.AddSignature(sigs.f_ff());
2432 module.AddSignature(sigs.i_ii());
2433 module.AddSignature(sigs.d_dd());
2434
2435 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002436 int table[] = {0, 1};
2437 module.AddIndirectFunctionTable(table, 2);
2438 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002439
2440 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002441 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32(),
2442 MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002443 BUILD(r,
2444 WASM_I32_ADD(WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2445 WASM_GET_LOCAL(2)),
2446 WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
2447 WASM_GET_LOCAL(0))));
2448
2449 CHECK_EQ(5, r.Call(0, 1, 2));
2450 CHECK_EQ(19, r.Call(0, 1, 9));
2451 CHECK_EQ(1, r.Call(1, 0, 2));
2452 CHECK_EQ(1, r.Call(1, 0, 9));
2453
2454 CHECK_TRAP(r.Call(0, 2, 1));
2455 CHECK_TRAP(r.Call(1, 2, 0));
2456 CHECK_TRAP(r.Call(2, 0, 1));
2457 CHECK_TRAP(r.Call(2, 1, 0));
2458}
2459
Ben Murdoch097c5b22016-05-18 11:27:45 +01002460TEST(Run_Wasm_CallIndirect_NoTable) {
2461 TestSignatures sigs;
2462 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002463
Ben Murdoch097c5b22016-05-18 11:27:45 +01002464 // One function.
2465 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2466 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2467 t1.CompileAndAdd(/*sig_index*/ 1);
2468
2469 // Signature table.
2470 module.AddSignature(sigs.f_ff());
2471 module.AddSignature(sigs.i_ii());
2472
2473 // Builder the caller function.
2474 WasmRunner<int32_t> r(&module, MachineType::Int32());
2475 BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
2476
2477 CHECK_TRAP(r.Call(0));
2478 CHECK_TRAP(r.Call(1));
2479 CHECK_TRAP(r.Call(2));
2480}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002481
2482TEST(Run_Wasm_F32Floor) {
2483 WasmRunner<float> r(MachineType::Float32());
2484 BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0)));
2485
Ben Murdochda12d292016-06-02 14:46:10 +01002486 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(floorf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002487}
2488
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002489TEST(Run_Wasm_F32Ceil) {
2490 WasmRunner<float> r(MachineType::Float32());
2491 BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0)));
2492
Ben Murdochda12d292016-06-02 14:46:10 +01002493 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(ceilf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002494}
2495
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002496TEST(Run_Wasm_F32Trunc) {
2497 WasmRunner<float> r(MachineType::Float32());
2498 BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0)));
2499
Ben Murdochda12d292016-06-02 14:46:10 +01002500 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(truncf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002501}
2502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002503TEST(Run_Wasm_F32NearestInt) {
2504 WasmRunner<float> r(MachineType::Float32());
2505 BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0)));
2506
Ben Murdochda12d292016-06-02 14:46:10 +01002507 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyintf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002508}
2509
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002510TEST(Run_Wasm_F64Floor) {
2511 WasmRunner<double> r(MachineType::Float64());
2512 BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0)));
2513
Ben Murdochda12d292016-06-02 14:46:10 +01002514 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(floor(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002515}
2516
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002517TEST(Run_Wasm_F64Ceil) {
2518 WasmRunner<double> r(MachineType::Float64());
2519 BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0)));
2520
Ben Murdochda12d292016-06-02 14:46:10 +01002521 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(ceil(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002522}
2523
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002524TEST(Run_Wasm_F64Trunc) {
2525 WasmRunner<double> r(MachineType::Float64());
2526 BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
2527
Ben Murdochda12d292016-06-02 14:46:10 +01002528 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(trunc(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002529}
2530
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002531TEST(Run_Wasm_F64NearestInt) {
2532 WasmRunner<double> r(MachineType::Float64());
2533 BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
2534
Ben Murdochda12d292016-06-02 14:46:10 +01002535 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002536}
2537
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002538TEST(Run_Wasm_F32Min) {
2539 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2540 BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2541
2542 FOR_FLOAT32_INPUTS(i) {
2543 FOR_FLOAT32_INPUTS(j) {
2544 float expected;
2545 if (*i < *j) {
2546 expected = *i;
2547 } else if (*j < *i) {
2548 expected = *j;
2549 } else if (*i != *i) {
2550 // If *i or *j is NaN, then the result is NaN.
2551 expected = *i;
2552 } else {
2553 expected = *j;
2554 }
2555
Ben Murdochda12d292016-06-02 14:46:10 +01002556 CHECK_FLOAT_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002557 }
2558 }
2559}
2560
2561
2562TEST(Run_Wasm_F64Min) {
2563 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2564 BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2565
2566 FOR_FLOAT64_INPUTS(i) {
2567 FOR_FLOAT64_INPUTS(j) {
2568 double expected;
2569 if (*i < *j) {
2570 expected = *i;
2571 } else if (*j < *i) {
2572 expected = *j;
2573 } else if (*i != *i) {
2574 // If *i or *j is NaN, then the result is NaN.
2575 expected = *i;
2576 } else {
2577 expected = *j;
2578 }
2579
Ben Murdochda12d292016-06-02 14:46:10 +01002580 CHECK_DOUBLE_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002581 }
2582 }
2583}
2584
2585
2586TEST(Run_Wasm_F32Max) {
2587 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2588 BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2589
2590 FOR_FLOAT32_INPUTS(i) {
2591 FOR_FLOAT32_INPUTS(j) {
2592 float expected;
2593 if (*i > *j) {
2594 expected = *i;
2595 } else if (*j > *i) {
2596 expected = *j;
2597 } else if (*i != *i) {
2598 // If *i or *j is NaN, then the result is NaN.
2599 expected = *i;
2600 } else {
2601 expected = *j;
2602 }
2603
Ben Murdochda12d292016-06-02 14:46:10 +01002604 CHECK_FLOAT_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002605 }
2606 }
2607}
2608
2609
2610TEST(Run_Wasm_F64Max) {
2611 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2612 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2613
2614 FOR_FLOAT64_INPUTS(i) {
2615 FOR_FLOAT64_INPUTS(j) {
2616 double expected;
2617 if (*i > *j) {
2618 expected = *i;
2619 } else if (*j > *i) {
2620 expected = *j;
2621 } else if (*i != *i) {
2622 // If *i or *j is NaN, then the result is NaN.
2623 expected = *i;
2624 } else {
2625 expected = *j;
2626 }
2627
Ben Murdochda12d292016-06-02 14:46:10 +01002628 CHECK_DOUBLE_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002629 }
2630 }
2631}
2632
Ben Murdochda12d292016-06-02 14:46:10 +01002633// TODO(ahaas): Fix on arm and mips and reenable.
2634#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && \
2635 !V8_TARGET_ARCH_MIPS64
Ben Murdoch097c5b22016-05-18 11:27:45 +01002636
2637TEST(Run_Wasm_F32Min_Snan) {
2638 // Test that the instruction does not return a signalling NaN.
2639 {
2640 WasmRunner<float> r;
2641 BUILD(r,
2642 WASM_F32_MIN(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
2643 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
2644 }
2645 {
2646 WasmRunner<float> r;
2647 BUILD(r,
2648 WASM_F32_MIN(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
2649 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
2650 }
2651}
2652
2653TEST(Run_Wasm_F32Max_Snan) {
2654 // Test that the instruction does not return a signalling NaN.
2655 {
2656 WasmRunner<float> r;
2657 BUILD(r,
2658 WASM_F32_MAX(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
2659 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
2660 }
2661 {
2662 WasmRunner<float> r;
2663 BUILD(r,
2664 WASM_F32_MAX(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
2665 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
2666 }
2667}
2668
2669TEST(Run_Wasm_F64Min_Snan) {
2670 // Test that the instruction does not return a signalling NaN.
2671 {
2672 WasmRunner<double> r;
2673 BUILD(r, WASM_F64_MIN(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
2674 WASM_F64(57.67)));
2675 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2676 }
2677 {
2678 WasmRunner<double> r;
2679 BUILD(r, WASM_F64_MIN(WASM_F64(45.73),
2680 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
2681 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2682 }
2683}
2684
2685TEST(Run_Wasm_F64Max_Snan) {
2686 // Test that the instruction does not return a signalling NaN.
2687 {
2688 WasmRunner<double> r;
2689 BUILD(r, WASM_F64_MAX(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
2690 WASM_F64(57.67)));
2691 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2692 }
2693 {
2694 WasmRunner<double> r;
2695 BUILD(r, WASM_F64_MAX(WASM_F64(45.73),
2696 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
2697 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2698 }
2699}
2700
2701#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002702
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002703TEST(Run_Wasm_I32SConvertF32) {
2704 WasmRunner<int32_t> r(MachineType::Float32());
2705 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0)));
2706
2707 FOR_FLOAT32_INPUTS(i) {
2708 if (*i < static_cast<float>(INT32_MAX) &&
2709 *i >= static_cast<float>(INT32_MIN)) {
2710 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i));
2711 } else {
2712 CHECK_TRAP32(r.Call(*i));
2713 }
2714 }
2715}
2716
2717
2718TEST(Run_Wasm_I32SConvertF64) {
2719 WasmRunner<int32_t> r(MachineType::Float64());
2720 BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0)));
2721
2722 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002723 if (*i < (static_cast<double>(INT32_MAX) + 1.0) &&
2724 *i > (static_cast<double>(INT32_MIN) - 1.0)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002725 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
2726 } else {
2727 CHECK_TRAP32(r.Call(*i));
2728 }
2729 }
2730}
2731
2732
2733TEST(Run_Wasm_I32UConvertF32) {
2734 WasmRunner<uint32_t> r(MachineType::Float32());
2735 BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0)));
2736
2737 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002738 if (*i < (static_cast<float>(UINT32_MAX) + 1.0) && *i > -1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002739 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
2740 } else {
2741 CHECK_TRAP32(r.Call(*i));
2742 }
2743 }
2744}
2745
2746
2747TEST(Run_Wasm_I32UConvertF64) {
2748 WasmRunner<uint32_t> r(MachineType::Float64());
2749 BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0)));
2750
2751 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002752 if (*i < (static_cast<float>(UINT32_MAX) + 1.0) && *i > -1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002753 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
2754 } else {
2755 CHECK_TRAP32(r.Call(*i));
2756 }
2757 }
2758}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002759
2760TEST(Run_Wasm_F64CopySign) {
2761 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2762 BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2763
2764 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002765 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(copysign(*i, *j), r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002766 }
2767}
2768
2769
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002770TEST(Run_Wasm_F32CopySign) {
2771 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2772 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2773
2774 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002775 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(copysignf(*i, *j), r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002776 }
2777}
2778
Ben Murdoch097c5b22016-05-18 11:27:45 +01002779void CompileCallIndirectMany(LocalType param) {
2780 // Make sure we don't run out of registers when compiling indirect calls
2781 // with many many parameters.
2782 TestSignatures sigs;
2783 for (byte num_params = 0; num_params < 40; num_params++) {
Ben Murdochda12d292016-06-02 14:46:10 +01002784 v8::base::AccountingAllocator allocator;
2785 Zone zone(&allocator);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002786 HandleScope scope(CcTest::InitIsolateOnce());
2787 TestingModule module;
2788 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
2789
2790 module.AddSignature(sig);
2791 module.AddSignature(sig);
2792 module.AddIndirectFunctionTable(nullptr, 0);
2793
2794 WasmFunctionCompiler t(sig, &module);
2795
2796 std::vector<byte> code;
2797 ADD_CODE(code, kExprCallIndirect, 1);
2798 ADD_CODE(code, kExprI8Const, 0);
2799 for (byte p = 0; p < num_params; p++) {
2800 ADD_CODE(code, kExprGetLocal, p);
2801 }
2802
2803 t.Build(&code[0], &code[0] + code.size());
2804 t.Compile();
2805 }
2806}
2807
2808
2809TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); }
2810
2811
2812#if WASM_64
2813TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); }
2814#endif
2815
2816
2817TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); }
2818
2819
2820TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); }
Ben Murdochda12d292016-06-02 14:46:10 +01002821
2822TEST(Run_WASM_Int32RemS_dead) {
2823 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2824 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_ZERO);
2825 const int32_t kMin = std::numeric_limits<int32_t>::min();
2826 CHECK_EQ(0, r.Call(133, 100));
2827 CHECK_EQ(0, r.Call(kMin, -1));
2828 CHECK_EQ(0, r.Call(0, 1));
2829 CHECK_TRAP(r.Call(100, 0));
2830 CHECK_TRAP(r.Call(-1001, 0));
2831 CHECK_TRAP(r.Call(kMin, 0));
2832}