blob: 236624f5f0c0b29d343915b6256a0f9f297a1a4f [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
Ben Murdochc5610432016-08-08 18:44:38 +01009#include "src/base/platform/elapsed-timer.h"
10
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/wasm/wasm-macro-gen.h"
12
13#include "test/cctest/cctest.h"
14#include "test/cctest/compiler/value-helper.h"
15#include "test/cctest/wasm/test-signatures.h"
16#include "test/cctest/wasm/wasm-run-utils.h"
17
18using namespace v8::base;
19using namespace v8::internal;
20using namespace v8::internal::compiler;
21using namespace v8::internal::wasm;
22
Ben Murdochda12d292016-06-02 14:46:10 +010023// for even shorter tests.
Ben Murdochc5610432016-08-08 18:44:38 +010024#define B2(a, b) kExprBlock, a, b, kExprEnd
25#define B1(a) kExprBlock, a, kExprEnd
26#define RET(x) x, kExprReturn, 1
27#define RET_I8(x) kExprI8Const, x, kExprReturn, 1
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028
Ben Murdochc5610432016-08-08 18:44:38 +010029WASM_EXEC_TEST(Int8Const) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010030 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031 const byte kExpectedValue = 121;
32 // return(kExpectedValue)
33 BUILD(r, WASM_I8(kExpectedValue));
34 CHECK_EQ(kExpectedValue, r.Call());
35}
36
Ben Murdochc5610432016-08-08 18:44:38 +010037WASM_EXEC_TEST(Int8Const_fallthru1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010038 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 const byte kExpectedValue = 122;
40 // kExpectedValue
41 BUILD(r, WASM_I8(kExpectedValue));
42 CHECK_EQ(kExpectedValue, r.Call());
43}
44
Ben Murdochc5610432016-08-08 18:44:38 +010045WASM_EXEC_TEST(Int8Const_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
Ben Murdochc5610432016-08-08 18:44:38 +010053WASM_EXEC_TEST(Int8Const_all) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 for (int value = -128; value <= 127; value++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010055 WasmRunner<int32_t> r;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056 // return(value)
57 BUILD(r, WASM_I8(value));
Ben Murdoch097c5b22016-05-18 11:27:45 +010058 int32_t result = r.Call();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059 CHECK_EQ(value, result);
60 }
61}
62
Ben Murdochc5610432016-08-08 18:44:38 +010063WASM_EXEC_TEST(Int32Const) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 WasmRunner<int32_t> r;
65 const int32_t kExpectedValue = 0x11223344;
66 // return(kExpectedValue)
Ben Murdochda12d292016-06-02 14:46:10 +010067 BUILD(r, WASM_I32V_5(kExpectedValue));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 CHECK_EQ(kExpectedValue, r.Call());
69}
70
Ben Murdochc5610432016-08-08 18:44:38 +010071WASM_EXEC_TEST(Int32Const_many) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072 FOR_INT32_INPUTS(i) {
73 WasmRunner<int32_t> r;
74 const int32_t kExpectedValue = *i;
75 // return(kExpectedValue)
Ben Murdochda12d292016-06-02 14:46:10 +010076 BUILD(r, WASM_I32V(kExpectedValue));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077 CHECK_EQ(kExpectedValue, r.Call());
78 }
79}
80
Ben Murdochc5610432016-08-08 18:44:38 +010081WASM_EXEC_TEST(MemorySize) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +010083 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 module.AddMemory(1024);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 BUILD(r, kExprMemorySize);
86 CHECK_EQ(1024, r.Call());
87}
88
Ben Murdochc5610432016-08-08 18:44:38 +010089WASM_EXEC_TEST(Int32Param0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 WasmRunner<int32_t> r(MachineType::Int32());
91 // return(local[0])
92 BUILD(r, WASM_GET_LOCAL(0));
93 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
94}
95
Ben Murdochc5610432016-08-08 18:44:38 +010096WASM_EXEC_TEST(Int32Param0_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 WasmRunner<int32_t> r(MachineType::Int32());
98 // local[0]
99 BUILD(r, WASM_GET_LOCAL(0));
100 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
101}
102
Ben Murdochc5610432016-08-08 18:44:38 +0100103WASM_EXEC_TEST(Int32Param1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
105 // local[1]
106 BUILD(r, WASM_GET_LOCAL(1));
107 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); }
108}
109
Ben Murdochc5610432016-08-08 18:44:38 +0100110WASM_EXEC_TEST(Int32Add) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 WasmRunner<int32_t> r;
112 // 11 + 44
113 BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44)));
114 CHECK_EQ(55, r.Call());
115}
116
Ben Murdochc5610432016-08-08 18:44:38 +0100117WASM_EXEC_TEST(Int32Add_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 WasmRunner<int32_t> r(MachineType::Int32());
119 // p0 + 13
120 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
121 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
122}
123
Ben Murdochc5610432016-08-08 18:44:38 +0100124WASM_EXEC_TEST(Int32Add_P_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 WasmRunner<int32_t> r(MachineType::Int32());
126 // p0 + 13
127 BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
128 FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
129}
130
Ben Murdochc5610432016-08-08 18:44:38 +0100131WASM_EXEC_TEST(Int32Add_P2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
133 // p0 + p1
134 BUILD(r, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
135 FOR_INT32_INPUTS(i) {
136 FOR_INT32_INPUTS(j) {
137 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
138 static_cast<uint32_t>(*j));
139 CHECK_EQ(expected, r.Call(*i, *j));
140 }
141 }
142}
143
Ben Murdochc5610432016-08-08 18:44:38 +0100144WASM_EXEC_TEST(Float32Add) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145 WasmRunner<int32_t> r;
146 // int(11.5f + 44.5f)
147 BUILD(r,
148 WASM_I32_SCONVERT_F32(WASM_F32_ADD(WASM_F32(11.5f), WASM_F32(44.5f))));
149 CHECK_EQ(56, r.Call());
150}
151
Ben Murdochc5610432016-08-08 18:44:38 +0100152WASM_EXEC_TEST(Float64Add) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153 WasmRunner<int32_t> r;
154 // return int(13.5d + 43.5d)
155 BUILD(r, WASM_I32_SCONVERT_F64(WASM_F64_ADD(WASM_F64(13.5), WASM_F64(43.5))));
156 CHECK_EQ(57, r.Call());
157}
158
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159void TestInt32Binop(WasmOpcode opcode, int32_t expected, int32_t a, int32_t b) {
160 {
161 WasmRunner<int32_t> r;
162 // K op K
Ben Murdochda12d292016-06-02 14:46:10 +0100163 BUILD(r, WASM_BINOP(opcode, WASM_I32V(a), WASM_I32V(b)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 CHECK_EQ(expected, r.Call());
165 }
166 {
167 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
168 // a op b
169 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
170 CHECK_EQ(expected, r.Call(a, b));
171 }
172}
173
Ben Murdochc5610432016-08-08 18:44:38 +0100174WASM_EXEC_TEST(Int32Binops) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175 TestInt32Binop(kExprI32Add, 88888888, 33333333, 55555555);
176 TestInt32Binop(kExprI32Sub, -1111111, 7777777, 8888888);
177 TestInt32Binop(kExprI32Mul, 65130756, 88734, 734);
178 TestInt32Binop(kExprI32DivS, -66, -4777344, 72384);
179 TestInt32Binop(kExprI32DivU, 805306368, 0xF0000000, 5);
180 TestInt32Binop(kExprI32RemS, -3, -3003, 1000);
181 TestInt32Binop(kExprI32RemU, 4, 4004, 1000);
182 TestInt32Binop(kExprI32And, 0xEE, 0xFFEE, 0xFF0000FF);
183 TestInt32Binop(kExprI32Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011);
184 TestInt32Binop(kExprI32Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE);
185 TestInt32Binop(kExprI32Shl, 0xA0000000, 0xA, 28);
186 TestInt32Binop(kExprI32ShrU, 0x07000010, 0x70000100, 4);
187 TestInt32Binop(kExprI32ShrS, 0xFF000000, 0x80000000, 7);
Ben Murdochda12d292016-06-02 14:46:10 +0100188 TestInt32Binop(kExprI32Ror, 0x01000000, 0x80000000, 7);
189 TestInt32Binop(kExprI32Ror, 0x01000000, 0x80000000, 39);
190 TestInt32Binop(kExprI32Rol, 0x00000040, 0x80000000, 7);
191 TestInt32Binop(kExprI32Rol, 0x00000040, 0x80000000, 39);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 TestInt32Binop(kExprI32Eq, 1, -99, -99);
193 TestInt32Binop(kExprI32Ne, 0, -97, -97);
194
195 TestInt32Binop(kExprI32LtS, 1, -4, 4);
196 TestInt32Binop(kExprI32LeS, 0, -2, -3);
197 TestInt32Binop(kExprI32LtU, 1, 0, -6);
198 TestInt32Binop(kExprI32LeU, 1, 98978, 0xF0000000);
199
200 TestInt32Binop(kExprI32GtS, 1, 4, -4);
201 TestInt32Binop(kExprI32GeS, 0, -3, -2);
202 TestInt32Binop(kExprI32GtU, 1, -6, 0);
203 TestInt32Binop(kExprI32GeU, 1, 0xF0000000, 98978);
204}
205
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206void TestInt32Unop(WasmOpcode opcode, int32_t expected, int32_t a) {
207 {
208 WasmRunner<int32_t> r;
209 // return op K
Ben Murdochda12d292016-06-02 14:46:10 +0100210 BUILD(r, WASM_UNOP(opcode, WASM_I32V(a)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 CHECK_EQ(expected, r.Call());
212 }
213 {
214 WasmRunner<int32_t> r(MachineType::Int32());
215 // return op a
216 BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0)));
217 CHECK_EQ(expected, r.Call(a));
218 }
219}
220
Ben Murdochc5610432016-08-08 18:44:38 +0100221WASM_EXEC_TEST(Int32Clz) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 TestInt32Unop(kExprI32Clz, 0, 0x80001000);
223 TestInt32Unop(kExprI32Clz, 1, 0x40000500);
224 TestInt32Unop(kExprI32Clz, 2, 0x20000300);
225 TestInt32Unop(kExprI32Clz, 3, 0x10000003);
226 TestInt32Unop(kExprI32Clz, 4, 0x08050000);
227 TestInt32Unop(kExprI32Clz, 5, 0x04006000);
228 TestInt32Unop(kExprI32Clz, 6, 0x02000000);
229 TestInt32Unop(kExprI32Clz, 7, 0x010000a0);
230 TestInt32Unop(kExprI32Clz, 8, 0x00800c00);
231 TestInt32Unop(kExprI32Clz, 9, 0x00400000);
232 TestInt32Unop(kExprI32Clz, 10, 0x0020000d);
233 TestInt32Unop(kExprI32Clz, 11, 0x00100f00);
234 TestInt32Unop(kExprI32Clz, 12, 0x00080000);
235 TestInt32Unop(kExprI32Clz, 13, 0x00041000);
236 TestInt32Unop(kExprI32Clz, 14, 0x00020020);
237 TestInt32Unop(kExprI32Clz, 15, 0x00010300);
238 TestInt32Unop(kExprI32Clz, 16, 0x00008040);
239 TestInt32Unop(kExprI32Clz, 17, 0x00004005);
240 TestInt32Unop(kExprI32Clz, 18, 0x00002050);
241 TestInt32Unop(kExprI32Clz, 19, 0x00001700);
242 TestInt32Unop(kExprI32Clz, 20, 0x00000870);
243 TestInt32Unop(kExprI32Clz, 21, 0x00000405);
244 TestInt32Unop(kExprI32Clz, 22, 0x00000203);
245 TestInt32Unop(kExprI32Clz, 23, 0x00000101);
246 TestInt32Unop(kExprI32Clz, 24, 0x00000089);
247 TestInt32Unop(kExprI32Clz, 25, 0x00000041);
248 TestInt32Unop(kExprI32Clz, 26, 0x00000022);
249 TestInt32Unop(kExprI32Clz, 27, 0x00000013);
250 TestInt32Unop(kExprI32Clz, 28, 0x00000008);
251 TestInt32Unop(kExprI32Clz, 29, 0x00000004);
252 TestInt32Unop(kExprI32Clz, 30, 0x00000002);
253 TestInt32Unop(kExprI32Clz, 31, 0x00000001);
254 TestInt32Unop(kExprI32Clz, 32, 0x00000000);
255}
256
Ben Murdochc5610432016-08-08 18:44:38 +0100257WASM_EXEC_TEST(Int32Ctz) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258 TestInt32Unop(kExprI32Ctz, 32, 0x00000000);
259 TestInt32Unop(kExprI32Ctz, 31, 0x80000000);
260 TestInt32Unop(kExprI32Ctz, 30, 0x40000000);
261 TestInt32Unop(kExprI32Ctz, 29, 0x20000000);
262 TestInt32Unop(kExprI32Ctz, 28, 0x10000000);
263 TestInt32Unop(kExprI32Ctz, 27, 0xa8000000);
264 TestInt32Unop(kExprI32Ctz, 26, 0xf4000000);
265 TestInt32Unop(kExprI32Ctz, 25, 0x62000000);
266 TestInt32Unop(kExprI32Ctz, 24, 0x91000000);
267 TestInt32Unop(kExprI32Ctz, 23, 0xcd800000);
268 TestInt32Unop(kExprI32Ctz, 22, 0x09400000);
269 TestInt32Unop(kExprI32Ctz, 21, 0xaf200000);
270 TestInt32Unop(kExprI32Ctz, 20, 0xac100000);
271 TestInt32Unop(kExprI32Ctz, 19, 0xe0b80000);
272 TestInt32Unop(kExprI32Ctz, 18, 0x9ce40000);
273 TestInt32Unop(kExprI32Ctz, 17, 0xc7920000);
274 TestInt32Unop(kExprI32Ctz, 16, 0xb8f10000);
275 TestInt32Unop(kExprI32Ctz, 15, 0x3b9f8000);
276 TestInt32Unop(kExprI32Ctz, 14, 0xdb4c4000);
277 TestInt32Unop(kExprI32Ctz, 13, 0xe9a32000);
278 TestInt32Unop(kExprI32Ctz, 12, 0xfca61000);
279 TestInt32Unop(kExprI32Ctz, 11, 0x6c8a7800);
280 TestInt32Unop(kExprI32Ctz, 10, 0x8ce5a400);
281 TestInt32Unop(kExprI32Ctz, 9, 0xcb7d0200);
282 TestInt32Unop(kExprI32Ctz, 8, 0xcb4dc100);
283 TestInt32Unop(kExprI32Ctz, 7, 0xdfbec580);
284 TestInt32Unop(kExprI32Ctz, 6, 0x27a9db40);
285 TestInt32Unop(kExprI32Ctz, 5, 0xde3bcb20);
286 TestInt32Unop(kExprI32Ctz, 4, 0xd7e8a610);
287 TestInt32Unop(kExprI32Ctz, 3, 0x9afdbc88);
288 TestInt32Unop(kExprI32Ctz, 2, 0x9afdbc84);
289 TestInt32Unop(kExprI32Ctz, 1, 0x9afdbc82);
290 TestInt32Unop(kExprI32Ctz, 0, 0x9afdbc81);
291}
292
Ben Murdochc5610432016-08-08 18:44:38 +0100293WASM_EXEC_TEST(Int32Popcnt) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000294 TestInt32Unop(kExprI32Popcnt, 32, 0xffffffff);
295 TestInt32Unop(kExprI32Popcnt, 0, 0x00000000);
296 TestInt32Unop(kExprI32Popcnt, 1, 0x00008000);
297 TestInt32Unop(kExprI32Popcnt, 13, 0x12345678);
298 TestInt32Unop(kExprI32Popcnt, 19, 0xfedcba09);
299}
300
Ben Murdochc5610432016-08-08 18:44:38 +0100301WASM_EXEC_TEST(I32Eqz) {
Ben Murdochda12d292016-06-02 14:46:10 +0100302 TestInt32Unop(kExprI32Eqz, 0, 1);
303 TestInt32Unop(kExprI32Eqz, 0, -1);
304 TestInt32Unop(kExprI32Eqz, 0, -827343);
305 TestInt32Unop(kExprI32Eqz, 0, 8888888);
306 TestInt32Unop(kExprI32Eqz, 1, 0);
307}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308
Ben Murdochc5610432016-08-08 18:44:38 +0100309WASM_EXEC_TEST(I32Shl) {
Ben Murdochda12d292016-06-02 14:46:10 +0100310 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
311 BUILD(r, WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
312
313 FOR_UINT32_INPUTS(i) {
314 FOR_UINT32_INPUTS(j) {
315 uint32_t expected = (*i) << (*j & 0x1f);
316 CHECK_EQ(expected, r.Call(*i, *j));
317 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318 }
319}
320
Ben Murdochc5610432016-08-08 18:44:38 +0100321WASM_EXEC_TEST(I32Shr) {
Ben Murdochda12d292016-06-02 14:46:10 +0100322 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
323 BUILD(r, WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324
Ben Murdochda12d292016-06-02 14:46:10 +0100325 FOR_UINT32_INPUTS(i) {
326 FOR_UINT32_INPUTS(j) {
327 uint32_t expected = (*i) >> (*j & 0x1f);
328 CHECK_EQ(expected, r.Call(*i, *j));
329 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 }
331}
332
Ben Murdochc5610432016-08-08 18:44:38 +0100333WASM_EXEC_TEST(I32Sar) {
Ben Murdochda12d292016-06-02 14:46:10 +0100334 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
335 BUILD(r, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336
Ben Murdochda12d292016-06-02 14:46:10 +0100337 FOR_INT32_INPUTS(i) {
338 FOR_INT32_INPUTS(j) {
339 int32_t expected = (*i) >> (*j & 0x1f);
340 CHECK_EQ(expected, r.Call(*i, *j));
341 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342 }
343}
344
Ben Murdochc5610432016-08-08 18:44:38 +0100345WASM_EXEC_TEST(Int32DivS_trap) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000346 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
347 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100348 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000349 CHECK_EQ(0, r.Call(0, 100));
350 CHECK_TRAP(r.Call(100, 0));
351 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100352 CHECK_TRAP(r.Call(kMin, -1));
353 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000354}
355
Ben Murdochc5610432016-08-08 18:44:38 +0100356WASM_EXEC_TEST(Int32RemS_trap) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000357 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
358 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100359 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 CHECK_EQ(33, r.Call(133, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100361 CHECK_EQ(0, r.Call(kMin, -1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 CHECK_TRAP(r.Call(100, 0));
363 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100364 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000365}
366
Ben Murdochc5610432016-08-08 18:44:38 +0100367WASM_EXEC_TEST(Int32DivU_trap) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
369 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdochda12d292016-06-02 14:46:10 +0100370 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371 CHECK_EQ(0, r.Call(0, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100372 CHECK_EQ(0, r.Call(kMin, -1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373 CHECK_TRAP(r.Call(100, 0));
374 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100375 CHECK_TRAP(r.Call(kMin, 0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376}
377
Ben Murdochc5610432016-08-08 18:44:38 +0100378WASM_EXEC_TEST(Int32RemU_trap) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
380 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
381 CHECK_EQ(17, r.Call(217, 100));
Ben Murdochda12d292016-06-02 14:46:10 +0100382 const int32_t kMin = std::numeric_limits<int32_t>::min();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 CHECK_TRAP(r.Call(100, 0));
384 CHECK_TRAP(r.Call(-1001, 0));
Ben Murdochda12d292016-06-02 14:46:10 +0100385 CHECK_TRAP(r.Call(kMin, 0));
386 CHECK_EQ(kMin, r.Call(kMin, -1));
387}
388
Ben Murdochc5610432016-08-08 18:44:38 +0100389WASM_EXEC_TEST(Int32DivS_byzero_const) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 for (int8_t denom = -2; denom < 8; denom++) {
391 WasmRunner<int32_t> r(MachineType::Int32());
392 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
393 for (int32_t val = -7; val < 8; val++) {
394 if (denom == 0) {
395 CHECK_TRAP(r.Call(val));
396 } else {
397 CHECK_EQ(val / denom, r.Call(val));
398 }
399 }
400 }
401}
402
Ben Murdochc5610432016-08-08 18:44:38 +0100403WASM_EXEC_TEST(Int32DivU_byzero_const) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404 for (uint32_t denom = 0xfffffffe; denom < 8; denom++) {
405 WasmRunner<uint32_t> r(MachineType::Uint32());
Ben Murdochda12d292016-06-02 14:46:10 +0100406 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000407
408 for (uint32_t val = 0xfffffff0; val < 8; val++) {
409 if (denom == 0) {
410 CHECK_TRAP(r.Call(val));
411 } else {
412 CHECK_EQ(val / denom, r.Call(val));
413 }
414 }
415 }
416}
417
Ben Murdochc5610432016-08-08 18:44:38 +0100418WASM_EXEC_TEST(Int32DivS_trap_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000419 TestingModule module;
420 module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100421 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000422
423 BUILD(r,
424 WASM_IF_ELSE(WASM_GET_LOCAL(0),
425 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
426 WASM_ZERO, WASM_GET_LOCAL(0)),
427 WASM_GET_LOCAL(1)),
428 WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(),
429 WASM_ZERO, WASM_GET_LOCAL(0)),
430 WASM_GET_LOCAL(1))));
431 CHECK_EQ(0, r.Call(0, 100));
432 CHECK_TRAP(r.Call(8, 0));
433 CHECK_TRAP(r.Call(4, 0));
434 CHECK_TRAP(r.Call(0, 0));
435}
436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437void TestFloat32Binop(WasmOpcode opcode, int32_t expected, float a, float b) {
438 {
439 WasmRunner<int32_t> r;
440 // return K op K
441 BUILD(r, WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b)));
442 CHECK_EQ(expected, r.Call());
443 }
444 {
445 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
446 // return a op b
447 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
448 CHECK_EQ(expected, r.Call(a, b));
449 }
450}
451
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452void TestFloat32BinopWithConvert(WasmOpcode opcode, int32_t expected, float a,
453 float b) {
454 {
455 WasmRunner<int32_t> r;
456 // return int(K op K)
457 BUILD(r,
458 WASM_I32_SCONVERT_F32(WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b))));
459 CHECK_EQ(expected, r.Call());
460 }
461 {
462 WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32());
463 // return int(a op b)
464 BUILD(r, WASM_I32_SCONVERT_F32(
465 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
466 CHECK_EQ(expected, r.Call(a, b));
467 }
468}
469
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000470void TestFloat32UnopWithConvert(WasmOpcode opcode, int32_t expected, float a) {
471 {
472 WasmRunner<int32_t> r;
473 // return int(op(K))
474 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_F32(a))));
475 CHECK_EQ(expected, r.Call());
476 }
477 {
478 WasmRunner<int32_t> r(MachineType::Float32());
479 // return int(op(a))
480 BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
481 CHECK_EQ(expected, r.Call(a));
482 }
483}
484
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485void TestFloat64Binop(WasmOpcode opcode, int32_t expected, double a, double b) {
486 {
487 WasmRunner<int32_t> r;
488 // return K op K
489 BUILD(r, WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b)));
490 CHECK_EQ(expected, r.Call());
491 }
492 {
493 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
494 // return a op b
495 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
496 CHECK_EQ(expected, r.Call(a, b));
497 }
498}
499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500void TestFloat64BinopWithConvert(WasmOpcode opcode, int32_t expected, double a,
501 double b) {
502 {
503 WasmRunner<int32_t> r;
504 // return int(K op K)
505 BUILD(r,
506 WASM_I32_SCONVERT_F64(WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b))));
507 CHECK_EQ(expected, r.Call());
508 }
509 {
510 WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64());
511 BUILD(r, WASM_I32_SCONVERT_F64(
512 WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
513 CHECK_EQ(expected, r.Call(a, b));
514 }
515}
516
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000517void TestFloat64UnopWithConvert(WasmOpcode opcode, int32_t expected, double a) {
518 {
519 WasmRunner<int32_t> r;
520 // return int(op(K))
521 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_F64(a))));
522 CHECK_EQ(expected, r.Call());
523 }
524 {
525 WasmRunner<int32_t> r(MachineType::Float64());
526 // return int(op(a))
527 BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
528 CHECK_EQ(expected, r.Call(a));
529 }
530}
531
Ben Murdochc5610432016-08-08 18:44:38 +0100532WASM_EXEC_TEST(Float32Binops) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000533 TestFloat32Binop(kExprF32Eq, 1, 8.125f, 8.125f);
534 TestFloat32Binop(kExprF32Ne, 1, 8.125f, 8.127f);
535 TestFloat32Binop(kExprF32Lt, 1, -9.5f, -9.0f);
536 TestFloat32Binop(kExprF32Le, 1, -1111.0f, -1111.0f);
537 TestFloat32Binop(kExprF32Gt, 1, -9.0f, -9.5f);
538 TestFloat32Binop(kExprF32Ge, 1, -1111.0f, -1111.0f);
539
540 TestFloat32BinopWithConvert(kExprF32Add, 10, 3.5f, 6.5f);
541 TestFloat32BinopWithConvert(kExprF32Sub, 2, 44.5f, 42.5f);
542 TestFloat32BinopWithConvert(kExprF32Mul, -66, -132.1f, 0.5f);
543 TestFloat32BinopWithConvert(kExprF32Div, 11, 22.1f, 2.0f);
544}
545
Ben Murdochc5610432016-08-08 18:44:38 +0100546WASM_EXEC_TEST(Float32Unops) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000547 TestFloat32UnopWithConvert(kExprF32Abs, 8, 8.125f);
548 TestFloat32UnopWithConvert(kExprF32Abs, 9, -9.125f);
549 TestFloat32UnopWithConvert(kExprF32Neg, -213, 213.125f);
550 TestFloat32UnopWithConvert(kExprF32Sqrt, 12, 144.4f);
551}
552
Ben Murdochc5610432016-08-08 18:44:38 +0100553WASM_EXEC_TEST(Float64Binops) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000554 TestFloat64Binop(kExprF64Eq, 1, 16.25, 16.25);
555 TestFloat64Binop(kExprF64Ne, 1, 16.25, 16.15);
556 TestFloat64Binop(kExprF64Lt, 1, -32.4, 11.7);
557 TestFloat64Binop(kExprF64Le, 1, -88.9, -88.9);
558 TestFloat64Binop(kExprF64Gt, 1, 11.7, -32.4);
559 TestFloat64Binop(kExprF64Ge, 1, -88.9, -88.9);
560
561 TestFloat64BinopWithConvert(kExprF64Add, 100, 43.5, 56.5);
562 TestFloat64BinopWithConvert(kExprF64Sub, 200, 12200.1, 12000.1);
563 TestFloat64BinopWithConvert(kExprF64Mul, -33, 134, -0.25);
564 TestFloat64BinopWithConvert(kExprF64Div, -1111, -2222.3, 2);
565}
566
Ben Murdochc5610432016-08-08 18:44:38 +0100567WASM_EXEC_TEST(Float64Unops) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 TestFloat64UnopWithConvert(kExprF64Abs, 108, 108.125);
569 TestFloat64UnopWithConvert(kExprF64Abs, 209, -209.125);
570 TestFloat64UnopWithConvert(kExprF64Neg, -209, 209.125);
571 TestFloat64UnopWithConvert(kExprF64Sqrt, 13, 169.4);
572}
573
Ben Murdochc5610432016-08-08 18:44:38 +0100574WASM_EXEC_TEST(Float32Neg) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 WasmRunner<float> r(MachineType::Float32());
576 BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0)));
577
578 FOR_FLOAT32_INPUTS(i) {
579 CHECK_EQ(0x80000000,
580 bit_cast<uint32_t>(*i) ^ bit_cast<uint32_t>(r.Call(*i)));
581 }
582}
583
Ben Murdochc5610432016-08-08 18:44:38 +0100584WASM_EXEC_TEST(Float32SubMinusZero) {
585 WasmRunner<float> r(MachineType::Float32());
586 BUILD(r, WASM_F32_SUB(WASM_F32(-0.0), WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587
Ben Murdochc5610432016-08-08 18:44:38 +0100588 CHECK_EQ(0x7fe00000, bit_cast<uint32_t>(r.Call(bit_cast<float>(0x7fa00000))));
589}
590
591WASM_EXEC_TEST(Float64SubMinusZero) {
592 WasmRunner<double> r(MachineType::Float64());
593 BUILD(r, WASM_F64_SUB(WASM_F64(-0.0), WASM_GET_LOCAL(0)));
594
595 CHECK_EQ(0x7ff8123456789abc,
596 bit_cast<uint64_t>(r.Call(bit_cast<double>(0x7ff0123456789abc))));
597}
598
599WASM_EXEC_TEST(Float64Neg) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000600 WasmRunner<double> r(MachineType::Float64());
601 BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0)));
602
603 FOR_FLOAT64_INPUTS(i) {
604 CHECK_EQ(0x8000000000000000,
605 bit_cast<uint64_t>(*i) ^ bit_cast<uint64_t>(r.Call(*i)));
606 }
607}
608
Ben Murdochc5610432016-08-08 18:44:38 +0100609WASM_EXEC_TEST(IfElse_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610 WasmRunner<int32_t> r(MachineType::Int32());
611 // if (p0) return 11; else return 22;
612 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
613 WASM_I8(11), // --
614 WASM_I8(22))); // --
615 FOR_INT32_INPUTS(i) {
616 int32_t expected = *i ? 11 : 22;
617 CHECK_EQ(expected, r.Call(*i));
618 }
619}
620
Ben Murdochc5610432016-08-08 18:44:38 +0100621WASM_EXEC_TEST(If_empty1) {
622 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
623 BUILD(r, WASM_GET_LOCAL(0), kExprIf, kExprEnd, WASM_GET_LOCAL(1));
624 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 9, *i)); }
625}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626
Ben Murdochc5610432016-08-08 18:44:38 +0100627WASM_EXEC_TEST(IfElse_empty1) {
628 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
629 BUILD(r, WASM_GET_LOCAL(0), kExprIf, kExprElse, kExprEnd, WASM_GET_LOCAL(1));
630 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 8, *i)); }
631}
632
633WASM_EXEC_TEST(IfElse_empty2) {
634 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
635 BUILD(r, WASM_GET_LOCAL(0), kExprIf, WASM_ZERO, kExprElse, kExprEnd,
636 WASM_GET_LOCAL(1));
637 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 7, *i)); }
638}
639
640WASM_EXEC_TEST(IfElse_empty3) {
641 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
642 BUILD(r, WASM_GET_LOCAL(0), kExprIf, kExprElse, WASM_ZERO, kExprEnd,
643 WASM_GET_LOCAL(1));
644 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 6, *i)); }
645}
646
647WASM_EXEC_TEST(If_chain) {
648 WasmRunner<int32_t> r(MachineType::Int32());
649 // if (p0) 13; if (p0) 14; 15
650 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_I8(13)),
651 WASM_IF(WASM_GET_LOCAL(0), WASM_I8(14)), WASM_I8(15));
652 FOR_INT32_INPUTS(i) { CHECK_EQ(15, r.Call(*i)); }
653}
654
655WASM_EXEC_TEST(If_chain_set) {
656 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
657 // if (p0) p1 = 73; if (p0) p1 = 74; p1
658 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(73))),
659 WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(74))),
660 WASM_GET_LOCAL(1));
661 FOR_INT32_INPUTS(i) {
662 int32_t expected = *i ? 74 : *i;
663 CHECK_EQ(expected, r.Call(*i, *i));
664 }
665}
666
667WASM_EXEC_TEST(IfElse_Unreachable1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000668 WasmRunner<int32_t> r;
669 // if (0) unreachable; else return 22;
670 BUILD(r, WASM_IF_ELSE(WASM_ZERO, // --
671 WASM_UNREACHABLE, // --
672 WASM_I8(27))); // --
673 CHECK_EQ(27, r.Call());
674}
675
Ben Murdochc5610432016-08-08 18:44:38 +0100676WASM_EXEC_TEST(Return12) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677 WasmRunner<int32_t> r;
678
Ben Murdochda12d292016-06-02 14:46:10 +0100679 BUILD(r, RET_I8(12));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 CHECK_EQ(12, r.Call());
681}
682
Ben Murdochc5610432016-08-08 18:44:38 +0100683WASM_EXEC_TEST(Return17) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000684 WasmRunner<int32_t> r;
685
Ben Murdochda12d292016-06-02 14:46:10 +0100686 BUILD(r, B1(RET_I8(17)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000687 CHECK_EQ(17, r.Call());
688}
689
Ben Murdochc5610432016-08-08 18:44:38 +0100690WASM_EXEC_TEST(Return_I32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000691 WasmRunner<int32_t> r(MachineType::Int32());
692
Ben Murdochda12d292016-06-02 14:46:10 +0100693 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694
695 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
696}
697
Ben Murdochc5610432016-08-08 18:44:38 +0100698WASM_EXEC_TEST(Return_F32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000699 WasmRunner<float> r(MachineType::Float32());
700
Ben Murdochda12d292016-06-02 14:46:10 +0100701 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000702
703 FOR_FLOAT32_INPUTS(i) {
704 float expect = *i;
705 float result = r.Call(expect);
706 if (std::isnan(expect)) {
707 CHECK(std::isnan(result));
708 } else {
709 CHECK_EQ(expect, result);
710 }
711 }
712}
713
Ben Murdochc5610432016-08-08 18:44:38 +0100714WASM_EXEC_TEST(Return_F64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715 WasmRunner<double> r(MachineType::Float64());
716
Ben Murdochda12d292016-06-02 14:46:10 +0100717 BUILD(r, RET(WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000718
719 FOR_FLOAT64_INPUTS(i) {
720 double expect = *i;
721 double result = r.Call(expect);
722 if (std::isnan(expect)) {
723 CHECK(std::isnan(result));
724 } else {
725 CHECK_EQ(expect, result);
726 }
727 }
728}
729
Ben Murdochc5610432016-08-08 18:44:38 +0100730WASM_EXEC_TEST(Select) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000731 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100732 // return select(11, 22, a);
733 BUILD(r, WASM_SELECT(WASM_I8(11), WASM_I8(22), WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734 FOR_INT32_INPUTS(i) {
735 int32_t expected = *i ? 11 : 22;
736 CHECK_EQ(expected, r.Call(*i));
737 }
738}
739
Ben Murdochc5610432016-08-08 18:44:38 +0100740WASM_EXEC_TEST(Select_strict1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100742 // select(a=0, a=1, a=2); return a
Ben Murdochda12d292016-06-02 14:46:10 +0100743 BUILD(r, B2(WASM_SELECT(WASM_SET_LOCAL(0, WASM_I8(0)),
744 WASM_SET_LOCAL(0, WASM_I8(1)),
745 WASM_SET_LOCAL(0, WASM_I8(2))),
746 WASM_GET_LOCAL(0)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100747 FOR_INT32_INPUTS(i) { CHECK_EQ(2, r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748}
749
Ben Murdochc5610432016-08-08 18:44:38 +0100750WASM_EXEC_TEST(Select_strict2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000751 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100752 r.AllocateLocal(kAstI32);
753 r.AllocateLocal(kAstI32);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100754 // select(b=5, c=6, a)
755 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
756 WASM_SET_LOCAL(2, WASM_I8(6)), WASM_GET_LOCAL(0)));
757 FOR_INT32_INPUTS(i) {
758 int32_t expected = *i ? 5 : 6;
759 CHECK_EQ(expected, r.Call(*i));
760 }
761}
762
Ben Murdochc5610432016-08-08 18:44:38 +0100763WASM_EXEC_TEST(Select_strict3) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100764 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100765 r.AllocateLocal(kAstI32);
766 r.AllocateLocal(kAstI32);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100767 // select(b=5, c=6, a=b)
768 BUILD(r, WASM_SELECT(WASM_SET_LOCAL(1, WASM_I8(5)),
769 WASM_SET_LOCAL(2, WASM_I8(6)),
770 WASM_SET_LOCAL(0, WASM_GET_LOCAL(1))));
771 FOR_INT32_INPUTS(i) {
772 int32_t expected = 5;
773 CHECK_EQ(expected, r.Call(*i));
774 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775}
776
Ben Murdochc5610432016-08-08 18:44:38 +0100777WASM_EXEC_TEST(BrIf_strict) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100779 BUILD(
780 r,
781 B2(B1(WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(99)))),
782 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000783
784 FOR_INT32_INPUTS(i) { CHECK_EQ(99, r.Call(*i)); }
785}
786
Ben Murdochc5610432016-08-08 18:44:38 +0100787WASM_EXEC_TEST(BrTable0a) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100788 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100789 BUILD(r,
790 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0))), WASM_I8(91)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100791 FOR_INT32_INPUTS(i) { CHECK_EQ(91, r.Call(*i)); }
792}
793
Ben Murdochc5610432016-08-08 18:44:38 +0100794WASM_EXEC_TEST(BrTable0b) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100795 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100796 BUILD(r,
797 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(0))),
798 WASM_I8(92)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100799 FOR_INT32_INPUTS(i) { CHECK_EQ(92, r.Call(*i)); }
800}
801
Ben Murdochc5610432016-08-08 18:44:38 +0100802WASM_EXEC_TEST(BrTable0c) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100803 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100804 BUILD(
805 r,
806 B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(1))),
807 RET_I8(76)),
808 WASM_I8(77)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100809 FOR_INT32_INPUTS(i) {
810 int32_t expected = *i == 0 ? 76 : 77;
811 CHECK_EQ(expected, r.Call(*i));
812 }
813}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000814
Ben Murdochc5610432016-08-08 18:44:38 +0100815WASM_EXEC_TEST(BrTable1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000816 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100817 BUILD(r, B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0))), RET_I8(93));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); }
819}
820
Ben Murdochc5610432016-08-08 18:44:38 +0100821WASM_EXEC_TEST(BrTable_loop) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000822 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100823 BUILD(r,
824 B2(WASM_LOOP(1, WASM_BR_TABLE(WASM_INC_LOCAL_BY(0, 1), 2, BR_TARGET(2),
825 BR_TARGET(1), BR_TARGET(0))),
826 RET_I8(99)),
827 WASM_I8(98));
828 CHECK_EQ(99, r.Call(0));
829 CHECK_EQ(98, r.Call(-1));
830 CHECK_EQ(98, r.Call(-2));
831 CHECK_EQ(98, r.Call(-3));
832 CHECK_EQ(98, r.Call(-100));
833}
834
Ben Murdochc5610432016-08-08 18:44:38 +0100835WASM_EXEC_TEST(BrTable_br) {
Ben Murdochda12d292016-06-02 14:46:10 +0100836 WasmRunner<int32_t> r(MachineType::Int32());
837 BUILD(r,
838 B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(1), BR_TARGET(0))),
839 RET_I8(91)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000840 WASM_I8(99));
841 CHECK_EQ(99, r.Call(0));
842 CHECK_EQ(91, r.Call(1));
843 CHECK_EQ(91, r.Call(2));
844 CHECK_EQ(91, r.Call(3));
845}
846
Ben Murdochc5610432016-08-08 18:44:38 +0100847WASM_EXEC_TEST(BrTable_br2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +0100849
850 BUILD(r, B2(B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 3, BR_TARGET(1),
851 BR_TARGET(2), BR_TARGET(3), BR_TARGET(0))),
852 RET_I8(85)),
853 RET_I8(86)),
854 RET_I8(87)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 WASM_I8(88));
856 CHECK_EQ(86, r.Call(0));
857 CHECK_EQ(87, r.Call(1));
858 CHECK_EQ(88, r.Call(2));
859 CHECK_EQ(85, r.Call(3));
860 CHECK_EQ(85, r.Call(4));
861 CHECK_EQ(85, r.Call(5));
862}
863
Ben Murdochc5610432016-08-08 18:44:38 +0100864WASM_EXEC_TEST(BrTable4) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 for (int i = 0; i < 4; i++) {
Ben Murdochda12d292016-06-02 14:46:10 +0100866 for (int t = 0; t < 4; t++) {
867 uint32_t cases[] = {0, 1, 2, 3};
868 cases[i] = t;
869 byte code[] = {B2(B2(B2(B2(B1(WASM_BR_TABLE(
870 WASM_GET_LOCAL(0), 3, BR_TARGET(cases[0]),
871 BR_TARGET(cases[1]), BR_TARGET(cases[2]),
872 BR_TARGET(cases[3]))),
873 RET_I8(70)),
874 RET_I8(71)),
875 RET_I8(72)),
876 RET_I8(73)),
877 WASM_I8(75)};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878
Ben Murdochda12d292016-06-02 14:46:10 +0100879 WasmRunner<int32_t> r(MachineType::Int32());
880 r.Build(code, code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000881
Ben Murdochda12d292016-06-02 14:46:10 +0100882 for (int x = -3; x < 50; x++) {
883 int index = (x > 3 || x < 0) ? 3 : x;
884 int32_t expected = 70 + cases[index];
885 CHECK_EQ(expected, r.Call(x));
886 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000887 }
888 }
889}
890
Ben Murdochc5610432016-08-08 18:44:38 +0100891WASM_EXEC_TEST(BrTable4x4) {
Ben Murdochda12d292016-06-02 14:46:10 +0100892 for (byte a = 0; a < 4; a++) {
893 for (byte b = 0; b < 4; b++) {
894 for (byte c = 0; c < 4; c++) {
895 for (byte d = 0; d < 4; d++) {
896 for (int i = 0; i < 4; i++) {
897 uint32_t cases[] = {a, b, c, d};
898 byte code[] = {
899 B2(B2(B2(B2(B1(WASM_BR_TABLE(
900 WASM_GET_LOCAL(0), 3, BR_TARGET(cases[0]),
901 BR_TARGET(cases[1]), BR_TARGET(cases[2]),
902 BR_TARGET(cases[3]))),
903 RET_I8(50)),
904 RET_I8(51)),
905 RET_I8(52)),
906 RET_I8(53)),
907 WASM_I8(55)};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000908
Ben Murdochda12d292016-06-02 14:46:10 +0100909 WasmRunner<int32_t> r(MachineType::Int32());
910 r.Build(code, code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000911
Ben Murdochda12d292016-06-02 14:46:10 +0100912 for (int x = -6; x < 47; x++) {
913 int index = (x > 3 || x < 0) ? 3 : x;
914 int32_t expected = 50 + cases[index];
915 CHECK_EQ(expected, r.Call(x));
916 }
917 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 }
919 }
920 }
921 }
922}
923
Ben Murdochc5610432016-08-08 18:44:38 +0100924WASM_EXEC_TEST(BrTable4_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 byte code[] = {
Ben Murdochda12d292016-06-02 14:46:10 +0100926 B2(B2(B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 3, BR_TARGET(0),
927 BR_TARGET(1), BR_TARGET(2), BR_TARGET(3))),
928 WASM_INC_LOCAL_BY(1, 1)),
929 WASM_INC_LOCAL_BY(1, 2)),
930 WASM_INC_LOCAL_BY(1, 4)),
931 WASM_INC_LOCAL_BY(1, 8)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000932 WASM_GET_LOCAL(1)};
933
934 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
935 r.Build(code, code + arraysize(code));
936
937 CHECK_EQ(15, r.Call(0, 0));
938 CHECK_EQ(14, r.Call(1, 0));
939 CHECK_EQ(12, r.Call(2, 0));
940 CHECK_EQ(8, r.Call(3, 0));
941 CHECK_EQ(8, r.Call(4, 0));
942
943 CHECK_EQ(115, r.Call(0, 100));
944 CHECK_EQ(114, r.Call(1, 100));
945 CHECK_EQ(112, r.Call(2, 100));
946 CHECK_EQ(108, r.Call(3, 100));
947 CHECK_EQ(108, r.Call(4, 100));
948}
949
Ben Murdochc5610432016-08-08 18:44:38 +0100950WASM_EXEC_TEST(F32ReinterpretI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000951 TestingModule module;
952 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100953 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954
955 BUILD(r, WASM_I32_REINTERPRET_F32(
956 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
957
958 FOR_INT32_INPUTS(i) {
959 int32_t expected = *i;
960 memory[0] = expected;
961 CHECK_EQ(expected, r.Call());
962 }
963}
964
Ben Murdochc5610432016-08-08 18:44:38 +0100965WASM_EXEC_TEST(I32ReinterpretF32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 TestingModule module;
967 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100968 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000969
970 BUILD(r, WASM_BLOCK(
971 2, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
972 WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))),
973 WASM_I8(107)));
974
975 FOR_INT32_INPUTS(i) {
976 int32_t expected = *i;
977 CHECK_EQ(107, r.Call(expected));
978 CHECK_EQ(expected, memory[0]);
979 }
980}
981
Ben Murdochc5610432016-08-08 18:44:38 +0100982WASM_EXEC_TEST(ReturnStore) {
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_STORE_MEM(MachineType::Int32(), WASM_ZERO,
988 WASM_LOAD_MEM(MachineType::Int32(), 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
Ben Murdochc5610432016-08-08 18:44:38 +0100997WASM_EXEC_TEST(VoidReturn1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100998 // We use a wrapper function because WasmRunner<void> does not exist.
999
1000 // Build the test function.
1001 TestSignatures sigs;
1002 TestingModule module;
1003 WasmFunctionCompiler t(sigs.v_v(), &module);
1004 BUILD(t, kExprNop);
1005 uint32_t index = t.CompileAndAdd();
1006
1007 const int32_t kExpected = -414444;
1008 // Build the calling function.
Ben Murdochda12d292016-06-02 14:46:10 +01001009 WasmRunner<int32_t> r(&module);
1010 BUILD(r, B2(WASM_CALL_FUNCTION0(index), WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001011
1012 int32_t result = r.Call();
1013 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014}
1015
Ben Murdochc5610432016-08-08 18:44:38 +01001016WASM_EXEC_TEST(VoidReturn2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001017 // We use a wrapper function because WasmRunner<void> does not exist.
1018 // Build the test function.
1019 TestSignatures sigs;
1020 TestingModule module;
1021 WasmFunctionCompiler t(sigs.v_v(), &module);
1022 BUILD(t, WASM_RETURN0);
1023 uint32_t index = t.CompileAndAdd();
1024
1025 const int32_t kExpected = -414444;
1026 // Build the calling function.
Ben Murdochda12d292016-06-02 14:46:10 +01001027 WasmRunner<int32_t> r(&module);
1028 BUILD(r, B2(WASM_CALL_FUNCTION0(index), WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001029
1030 int32_t result = r.Call();
1031 CHECK_EQ(kExpected, result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001032}
1033
Ben Murdochc5610432016-08-08 18:44:38 +01001034WASM_EXEC_TEST(Block_empty) {
1035 WasmRunner<int32_t> r(MachineType::Int32());
1036 BUILD(r, kExprBlock, kExprEnd, WASM_GET_LOCAL(0));
1037 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1038}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001039
Ben Murdochc5610432016-08-08 18:44:38 +01001040WASM_EXEC_TEST(Block_empty_br1) {
1041 WasmRunner<int32_t> r(MachineType::Int32());
1042 BUILD(r, B1(WASM_BR(0)), WASM_GET_LOCAL(0));
1043 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1044}
1045
1046WASM_EXEC_TEST(Block_empty_brif1) {
1047 WasmRunner<int32_t> r(MachineType::Int32());
1048 BUILD(r, B1(WASM_BR_IF(0, WASM_ZERO)), WASM_GET_LOCAL(0));
1049 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1050}
1051
1052WASM_EXEC_TEST(Block_empty_brif2) {
1053 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
1054 BUILD(r, B1(WASM_BR_IF(0, WASM_GET_LOCAL(1))), WASM_GET_LOCAL(0));
1055 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i, *i + 1)); }
1056}
1057
1058WASM_EXEC_TEST(Block_br2) {
1059 WasmRunner<int32_t> r(MachineType::Int32());
1060 BUILD(r, B1(WASM_BRV(0, WASM_GET_LOCAL(0))));
1061 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1062}
1063
1064WASM_EXEC_TEST(Block_If_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001065 WasmRunner<int32_t> r(MachineType::Int32());
1066 // { if (p0) return 51; return 52; }
Ben Murdochda12d292016-06-02 14:46:10 +01001067 BUILD(r, B2( // --
1068 WASM_IF(WASM_GET_LOCAL(0), // --
Ben Murdochc5610432016-08-08 18:44:38 +01001069 WASM_BRV(1, WASM_I8(51))), // --
Ben Murdochda12d292016-06-02 14:46:10 +01001070 WASM_I8(52))); // --
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001071 FOR_INT32_INPUTS(i) {
1072 int32_t expected = *i ? 51 : 52;
1073 CHECK_EQ(expected, r.Call(*i));
1074 }
1075}
1076
Ben Murdochc5610432016-08-08 18:44:38 +01001077WASM_EXEC_TEST(Loop_empty) {
1078 WasmRunner<int32_t> r(MachineType::Int32());
1079 BUILD(r, kExprLoop, kExprEnd, WASM_GET_LOCAL(0));
1080 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1081}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001082
Ben Murdochc5610432016-08-08 18:44:38 +01001083WASM_EXEC_TEST(Loop_empty_br1) {
1084 WasmRunner<int32_t> r(MachineType::Int32());
1085 BUILD(r, WASM_LOOP(1, WASM_BR(1)), WASM_GET_LOCAL(0));
1086 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1087}
1088
1089WASM_EXEC_TEST(Loop_empty_brif1) {
1090 WasmRunner<int32_t> r(MachineType::Int32());
1091 BUILD(r, WASM_LOOP(1, WASM_BR_IF(1, WASM_ZERO)), WASM_GET_LOCAL(0));
1092 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
1093}
1094
1095WASM_EXEC_TEST(Loop_empty_brif2) {
1096 WasmRunner<uint32_t> r(MachineType::Uint32(), MachineType::Uint32());
1097 BUILD(r, WASM_LOOP(1, WASM_BR_IF(1, WASM_GET_LOCAL(1))), WASM_GET_LOCAL(0));
1098 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i, *i + 1)); }
1099}
1100
1101WASM_EXEC_TEST(Block_BrIf_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001102 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001103 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(51), WASM_GET_LOCAL(0)), WASM_I8(52)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 FOR_INT32_INPUTS(i) {
1105 int32_t expected = *i ? 51 : 52;
1106 CHECK_EQ(expected, r.Call(*i));
1107 }
1108}
1109
Ben Murdochc5610432016-08-08 18:44:38 +01001110WASM_EXEC_TEST(Block_IfElse_P_assign) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001111 WasmRunner<int32_t> r(MachineType::Int32());
1112 // { if (p0) p0 = 71; else p0 = 72; return p0; }
Ben Murdochda12d292016-06-02 14:46:10 +01001113 BUILD(r, B2( // --
1114 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1115 WASM_SET_LOCAL(0, WASM_I8(71)), // --
1116 WASM_SET_LOCAL(0, WASM_I8(72))), // --
1117 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001118 FOR_INT32_INPUTS(i) {
1119 int32_t expected = *i ? 71 : 72;
1120 CHECK_EQ(expected, r.Call(*i));
1121 }
1122}
1123
Ben Murdochc5610432016-08-08 18:44:38 +01001124WASM_EXEC_TEST(Block_IfElse_P_return) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001125 WasmRunner<int32_t> r(MachineType::Int32());
1126 // if (p0) return 81; else return 82;
Ben Murdochda12d292016-06-02 14:46:10 +01001127 BUILD(r, // --
1128 WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1129 RET_I8(81), // --
1130 RET_I8(82))); // --
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131 FOR_INT32_INPUTS(i) {
1132 int32_t expected = *i ? 81 : 82;
1133 CHECK_EQ(expected, r.Call(*i));
1134 }
1135}
1136
Ben Murdochc5610432016-08-08 18:44:38 +01001137WASM_EXEC_TEST(Block_If_P_assign) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001138 WasmRunner<int32_t> r(MachineType::Int32());
1139 // { if (p0) p0 = 61; p0; }
1140 BUILD(r, WASM_BLOCK(
1141 2, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))),
1142 WASM_GET_LOCAL(0)));
1143 FOR_INT32_INPUTS(i) {
1144 int32_t expected = *i ? 61 : *i;
1145 CHECK_EQ(expected, r.Call(*i));
1146 }
1147}
1148
Ben Murdochc5610432016-08-08 18:44:38 +01001149WASM_EXEC_TEST(DanglingAssign) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001150 WasmRunner<int32_t> r(MachineType::Int32());
1151 // { return 0; p0 = 0; }
Ben Murdochda12d292016-06-02 14:46:10 +01001152 BUILD(r, B2(RET_I8(99), WASM_SET_LOCAL(0, WASM_ZERO)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001153 CHECK_EQ(99, r.Call(1));
1154}
1155
Ben Murdochc5610432016-08-08 18:44:38 +01001156WASM_EXEC_TEST(ExprIf_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001157 WasmRunner<int32_t> r(MachineType::Int32());
1158 // p0 ? 11 : 22;
1159 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1160 WASM_I8(11), // --
1161 WASM_I8(22))); // --
1162 FOR_INT32_INPUTS(i) {
1163 int32_t expected = *i ? 11 : 22;
1164 CHECK_EQ(expected, r.Call(*i));
1165 }
1166}
1167
Ben Murdochc5610432016-08-08 18:44:38 +01001168WASM_EXEC_TEST(ExprIf_P_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001169 WasmRunner<int32_t> r(MachineType::Int32());
1170 // p0 ? 11 : 22;
1171 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
1172 WASM_I8(11), // --
1173 WASM_I8(22))); // --
1174 FOR_INT32_INPUTS(i) {
1175 int32_t expected = *i ? 11 : 22;
1176 CHECK_EQ(expected, r.Call(*i));
1177 }
1178}
1179
Ben Murdochc5610432016-08-08 18:44:38 +01001180WASM_EXEC_TEST(CountDown) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001181 WasmRunner<int32_t> r(MachineType::Int32());
1182 BUILD(r,
1183 WASM_BLOCK(
1184 2, WASM_LOOP(
1185 1, WASM_IF(WASM_GET_LOCAL(0),
Ben Murdochc5610432016-08-08 18:44:38 +01001186 WASM_BRV(1, WASM_SET_LOCAL(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001187 0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1188 WASM_I8(1)))))),
1189 WASM_GET_LOCAL(0)));
1190 CHECK_EQ(0, r.Call(1));
1191 CHECK_EQ(0, r.Call(10));
1192 CHECK_EQ(0, r.Call(100));
1193}
1194
Ben Murdochc5610432016-08-08 18:44:38 +01001195WASM_EXEC_TEST(CountDown_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001196 WasmRunner<int32_t> r(MachineType::Int32());
1197 BUILD(r,
1198 WASM_BLOCK(
Ben Murdochc5610432016-08-08 18:44:38 +01001199 2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(1)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001200 WASM_SET_LOCAL(
1201 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
1202 WASM_CONTINUE(0)),
1203 WASM_GET_LOCAL(0)));
1204 CHECK_EQ(0, r.Call(1));
1205 CHECK_EQ(0, r.Call(10));
1206 CHECK_EQ(0, r.Call(100));
1207}
1208
Ben Murdochc5610432016-08-08 18:44:38 +01001209WASM_EXEC_TEST(WhileCountDown) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001210 WasmRunner<int32_t> r(MachineType::Int32());
1211 BUILD(r, WASM_BLOCK(
1212 2, WASM_WHILE(WASM_GET_LOCAL(0),
1213 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
1214 WASM_I8(1)))),
1215 WASM_GET_LOCAL(0)));
1216 CHECK_EQ(0, r.Call(1));
1217 CHECK_EQ(0, r.Call(10));
1218 CHECK_EQ(0, r.Call(100));
1219}
1220
Ben Murdochc5610432016-08-08 18:44:38 +01001221WASM_EXEC_TEST(Loop_if_break1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001222 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01001223 BUILD(r, B2(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
Ben Murdochda12d292016-06-02 14:46:10 +01001224 WASM_SET_LOCAL(0, WASM_I8(99))),
1225 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226 CHECK_EQ(99, r.Call(0));
1227 CHECK_EQ(3, r.Call(3));
1228 CHECK_EQ(10000, r.Call(10000));
1229 CHECK_EQ(-29, r.Call(-29));
1230}
1231
Ben Murdochc5610432016-08-08 18:44:38 +01001232WASM_EXEC_TEST(Loop_if_break2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001233 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001234 BUILD(r, B2(WASM_LOOP(2, WASM_BR_IF(1, WASM_GET_LOCAL(0)),
1235 WASM_SET_LOCAL(0, WASM_I8(99))),
1236 WASM_GET_LOCAL(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001237 CHECK_EQ(99, r.Call(0));
1238 CHECK_EQ(3, r.Call(3));
1239 CHECK_EQ(10000, r.Call(10000));
1240 CHECK_EQ(-29, r.Call(-29));
1241}
1242
Ben Murdochc5610432016-08-08 18:44:38 +01001243WASM_EXEC_TEST(Loop_if_break_fallthru) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001245 BUILD(r, B1(WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)),
1246 WASM_SET_LOCAL(0, WASM_I8(93)))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001247 WASM_GET_LOCAL(0));
1248 CHECK_EQ(93, r.Call(0));
1249 CHECK_EQ(3, r.Call(3));
1250 CHECK_EQ(10001, r.Call(10001));
1251 CHECK_EQ(-22, r.Call(-22));
1252}
1253
Ben Murdochc5610432016-08-08 18:44:38 +01001254WASM_EXEC_TEST(IfBreak1) {
1255 WasmRunner<int32_t> r(MachineType::Int32());
1256 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), WASM_UNREACHABLE)),
1257 WASM_I8(91));
1258 CHECK_EQ(91, r.Call(0));
1259 CHECK_EQ(91, r.Call(1));
1260 CHECK_EQ(91, r.Call(-8734));
1261}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001262
Ben Murdochc5610432016-08-08 18:44:38 +01001263WASM_EXEC_TEST(IfBreak2) {
1264 WasmRunner<int32_t> r(MachineType::Int32());
1265 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), RET_I8(77))),
1266 WASM_I8(81));
1267 CHECK_EQ(81, r.Call(0));
1268 CHECK_EQ(81, r.Call(1));
1269 CHECK_EQ(81, r.Call(-8734));
1270}
1271
1272WASM_EXEC_TEST(LoadMemI32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001273 TestingModule module;
1274 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001275 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001276 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001277
1278 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0)));
1279
1280 memory[0] = 99999999;
1281 CHECK_EQ(99999999, r.Call(0));
1282
1283 memory[0] = 88888888;
1284 CHECK_EQ(88888888, r.Call(0));
1285
1286 memory[0] = 77777777;
1287 CHECK_EQ(77777777, r.Call(0));
1288}
1289
Ben Murdochc5610432016-08-08 18:44:38 +01001290WASM_EXEC_TEST(LoadMemI32_oob) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291 TestingModule module;
1292 int32_t* memory = module.AddMemoryElems<int32_t>(8);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001293 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001294 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295
1296 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1297
1298 memory[0] = 88888888;
1299 CHECK_EQ(88888888, r.Call(0u));
1300 for (uint32_t offset = 29; offset < 40; offset++) {
1301 CHECK_TRAP(r.Call(offset));
1302 }
1303
1304 for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
1305 CHECK_TRAP(r.Call(offset));
1306 }
1307}
1308
Ben Murdochc5610432016-08-08 18:44:38 +01001309WASM_EXEC_TEST(LoadMem_offset_oob) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001310 TestingModule module;
1311 module.AddMemoryElems<int32_t>(8);
1312
1313 static const MachineType machineTypes[] = {
1314 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1315 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1316 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1317 MachineType::Float64()};
1318
1319 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1320 module.RandomizeMemory(1116 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001321 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001322 uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]);
1323
1324 BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)),
1325 WASM_ZERO);
1326
1327 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1328
1329 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1330 CHECK_TRAP(r.Call(offset)); // out of bounds.
1331 }
1332 }
1333}
1334
Ben Murdochc5610432016-08-08 18:44:38 +01001335WASM_EXEC_TEST(LoadMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001336 TestingModule module;
1337 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001338 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001339 module.RandomizeMemory(1111);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001340
1341 BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0)));
1342
1343 memory[0] = 66666666;
1344 memory[1] = 77777777;
1345 memory[2] = 88888888;
1346 memory[3] = 99999999;
1347 CHECK_EQ(77777777, r.Call(0));
1348 CHECK_EQ(88888888, r.Call(4));
1349 CHECK_EQ(99999999, r.Call(8));
1350
1351 memory[0] = 11111111;
1352 memory[1] = 22222222;
1353 memory[2] = 33333333;
1354 memory[3] = 44444444;
1355 CHECK_EQ(22222222, r.Call(0));
1356 CHECK_EQ(33333333, r.Call(4));
1357 CHECK_EQ(44444444, r.Call(8));
1358}
1359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001360#if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
1361
Ben Murdochc5610432016-08-08 18:44:38 +01001362WASM_EXEC_TEST(LoadMemI32_const_oob_misaligned) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001363 const int kMemSize = 12;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001364 // TODO(titzer): Fix misaligned accesses on MIPS and re-enable.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001365 for (int offset = 0; offset < kMemSize + 5; offset++) {
1366 for (int index = 0; index < kMemSize + 5; index++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001367 TestingModule module;
1368 module.AddMemoryElems<byte>(kMemSize);
1369
1370 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001371 module.RandomizeMemory();
1372
1373 BUILD(r,
1374 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1375
1376 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1377 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1378 } else {
1379 CHECK_TRAP(r.Call());
1380 }
1381 }
1382 }
1383}
1384
1385#endif
1386
Ben Murdochc5610432016-08-08 18:44:38 +01001387WASM_EXEC_TEST(LoadMemI32_const_oob) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001388 const int kMemSize = 24;
1389 for (int offset = 0; offset < kMemSize + 5; offset += 4) {
1390 for (int index = 0; index < kMemSize + 5; index += 4) {
1391 TestingModule module;
1392 module.AddMemoryElems<byte>(kMemSize);
1393
1394 WasmRunner<int32_t> r(&module);
1395 module.RandomizeMemory();
1396
1397 BUILD(r,
1398 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
1399
1400 if ((offset + index) <= (kMemSize - sizeof(int32_t))) {
1401 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
1402 } else {
1403 CHECK_TRAP(r.Call());
1404 }
1405 }
1406 }
1407}
1408
Ben Murdochc5610432016-08-08 18:44:38 +01001409WASM_EXEC_TEST(StoreMemI32_offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001410 TestingModule module;
1411 int32_t* memory = module.AddMemoryElems<int32_t>(4);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001412 WasmRunner<int32_t> r(&module, MachineType::Int32());
1413 const int32_t kWritten = 0xaabbccdd;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001414
1415 BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0),
Ben Murdochda12d292016-06-02 14:46:10 +01001416 WASM_I32V_5(kWritten)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417
1418 for (int i = 0; i < 2; i++) {
1419 module.RandomizeMemory(1111);
1420 memory[0] = 66666666;
1421 memory[1] = 77777777;
1422 memory[2] = 88888888;
1423 memory[3] = 99999999;
1424 CHECK_EQ(kWritten, r.Call(i * 4));
1425 CHECK_EQ(66666666, memory[0]);
1426 CHECK_EQ(i == 0 ? kWritten : 77777777, memory[1]);
1427 CHECK_EQ(i == 1 ? kWritten : 88888888, memory[2]);
1428 CHECK_EQ(i == 2 ? kWritten : 99999999, memory[3]);
1429 }
1430}
1431
Ben Murdochc5610432016-08-08 18:44:38 +01001432WASM_EXEC_TEST(StoreMem_offset_oob) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001433 TestingModule module;
1434 byte* memory = module.AddMemoryElems<byte>(32);
1435
1436#if WASM_64
1437 static const MachineType machineTypes[] = {
1438 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1439 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1440 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
1441 MachineType::Float64()};
1442#else
1443 static const MachineType machineTypes[] = {
1444 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
1445 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
1446 MachineType::Float32(), MachineType::Float64()};
1447#endif
1448
1449 for (size_t m = 0; m < arraysize(machineTypes); m++) {
1450 module.RandomizeMemory(1119 + static_cast<int>(m));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001451 WasmRunner<int32_t> r(&module, MachineType::Uint32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001452
1453 BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
1454 WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
1455 WASM_ZERO);
1456
1457 byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
1458 uint32_t boundary = 24 - memsize;
1459 CHECK_EQ(0, r.Call(boundary)); // in bounds.
1460 CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
1461
1462 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) {
1463 CHECK_TRAP(r.Call(offset)); // out of bounds.
1464 }
1465 }
1466}
1467
Ben Murdochc5610432016-08-08 18:44:38 +01001468WASM_EXEC_TEST(LoadMemI32_P) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001469 const int kNumElems = 8;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001470 TestingModule module;
1471 int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001472 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001473 module.RandomizeMemory(2222);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001474
1475 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
1476
1477 for (int i = 0; i < kNumElems; i++) {
1478 CHECK_EQ(memory[i], r.Call(i * 4));
1479 }
1480}
1481
Ben Murdochc5610432016-08-08 18:44:38 +01001482WASM_EXEC_TEST(MemI32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001483 const int kNumElems = 20;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001484 TestingModule module;
1485 uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001486 WasmRunner<uint32_t> r(&module, MachineType::Int32());
1487 const byte kSum = r.AllocateLocal(kAstI32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001488
1489 BUILD(r, WASM_BLOCK(
1490 2, WASM_WHILE(
1491 WASM_GET_LOCAL(0),
1492 WASM_BLOCK(
1493 2, WASM_SET_LOCAL(
1494 kSum, WASM_I32_ADD(
1495 WASM_GET_LOCAL(kSum),
1496 WASM_LOAD_MEM(MachineType::Int32(),
1497 WASM_GET_LOCAL(0)))),
1498 WASM_SET_LOCAL(
1499 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1500 WASM_GET_LOCAL(1)));
1501
1502 // Run 4 trials.
1503 for (int i = 0; i < 3; i++) {
1504 module.RandomizeMemory(i * 33);
1505 uint32_t expected = 0;
1506 for (size_t j = kNumElems - 1; j > 0; j--) {
1507 expected += memory[j];
1508 }
1509 uint32_t result = r.Call(static_cast<int>(4 * (kNumElems - 1)));
1510 CHECK_EQ(expected, result);
1511 }
1512}
1513
Ben Murdochc5610432016-08-08 18:44:38 +01001514WASM_EXEC_TEST(CheckMachIntsZero) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001515 const int kNumElems = 55;
1516 TestingModule module;
1517 module.AddMemoryElems<uint32_t>(kNumElems);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001518 WasmRunner<uint32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001519
Ben Murdochc5610432016-08-08 18:44:38 +01001520 BUILD(r, kExprLoop, kExprGetLocal, 0, kExprIf, kExprGetLocal, 0,
1521 kExprI32LoadMem, 0, 0, kExprIf, kExprI8Const, 255, kExprReturn, ARITY_1,
1522 kExprEnd, kExprGetLocal, 0, kExprI8Const, 4, kExprI32Sub, kExprSetLocal,
1523 0, kExprBr, ARITY_1, DEPTH_0, kExprEnd, kExprEnd, kExprI8Const, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001524
1525 module.BlankMemory();
1526 CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
1527}
1528
Ben Murdochc5610432016-08-08 18:44:38 +01001529WASM_EXEC_TEST(MemF32_Sum) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001530 const int kSize = 5;
1531 TestingModule module;
1532 module.AddMemoryElems<float>(kSize);
1533 float* buffer = module.raw_mem_start<float>();
1534 buffer[0] = -99.25;
1535 buffer[1] = -888.25;
1536 buffer[2] = -77.25;
1537 buffer[3] = 66666.25;
1538 buffer[4] = 5555.25;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001539 WasmRunner<int32_t> r(&module, MachineType::Int32());
1540 const byte kSum = r.AllocateLocal(kAstF32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001541
1542 BUILD(r, WASM_BLOCK(
1543 3, WASM_WHILE(
1544 WASM_GET_LOCAL(0),
1545 WASM_BLOCK(
1546 2, WASM_SET_LOCAL(
1547 kSum, WASM_F32_ADD(
1548 WASM_GET_LOCAL(kSum),
1549 WASM_LOAD_MEM(MachineType::Float32(),
1550 WASM_GET_LOCAL(0)))),
1551 WASM_SET_LOCAL(
1552 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
1553 WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
1554 WASM_GET_LOCAL(kSum)),
1555 WASM_GET_LOCAL(0)));
1556
1557 CHECK_EQ(0, r.Call(4 * (kSize - 1)));
1558 CHECK_NE(-99.25, buffer[0]);
1559 CHECK_EQ(71256.0f, buffer[0]);
1560}
1561
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001562template <typename T>
1563T GenerateAndRunFold(WasmOpcode binop, T* buffer, size_t size,
1564 LocalType astType, MachineType memType) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001565 TestingModule module;
1566 module.AddMemoryElems<T>(size);
1567 for (size_t i = 0; i < size; i++) {
1568 module.raw_mem_start<T>()[i] = buffer[i];
1569 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001570 WasmRunner<int32_t> r(&module, MachineType::Int32());
1571 const byte kAccum = r.AllocateLocal(astType);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001572
1573 BUILD(
1574 r,
1575 WASM_BLOCK(
1576 4, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
1577 WASM_WHILE(
1578 WASM_GET_LOCAL(0),
1579 WASM_BLOCK(
1580 2, WASM_SET_LOCAL(
1581 kAccum,
1582 WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
1583 WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))),
1584 WASM_SET_LOCAL(
1585 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(sizeof(T)))))),
1586 WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
1587 WASM_GET_LOCAL(0)));
1588 r.Call(static_cast<int>(sizeof(T) * (size - 1)));
1589 return module.raw_mem_at<double>(0);
1590}
1591
Ben Murdochc5610432016-08-08 18:44:38 +01001592WASM_EXEC_TEST(MemF64_Mul) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001593 const size_t kSize = 6;
1594 double buffer[kSize] = {1, 2, 2, 2, 2, 2};
1595 double result = GenerateAndRunFold<double>(kExprF64Mul, buffer, kSize,
1596 kAstF64, MachineType::Float64());
1597 CHECK_EQ(32, result);
1598}
1599
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001600TEST(Build_Wasm_Infinite_Loop) {
1601 WasmRunner<int32_t> r(MachineType::Int32());
1602 // Only build the graph and compile, don't run.
1603 BUILD(r, WASM_INFINITE_LOOP);
1604}
1605
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001606TEST(Build_Wasm_Infinite_Loop_effect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607 TestingModule module;
1608 module.AddMemoryElems<int8_t>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001609 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001610
1611 // Only build the graph and compile, don't run.
1612 BUILD(r, WASM_LOOP(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)));
1613}
1614
Ben Murdochc5610432016-08-08 18:44:38 +01001615WASM_EXEC_TEST(Unreachable0a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001617 BUILD(r, B2(WASM_BRV(0, WASM_I8(9)), RET(WASM_GET_LOCAL(0))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001618 CHECK_EQ(9, r.Call(0));
1619 CHECK_EQ(9, r.Call(1));
1620}
1621
Ben Murdochc5610432016-08-08 18:44:38 +01001622WASM_EXEC_TEST(Unreachable0b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001624 BUILD(r, B2(WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001625 CHECK_EQ(7, r.Call(0));
1626 CHECK_EQ(7, r.Call(1));
1627}
1628
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001629TEST(Build_Wasm_Unreachable1) {
1630 WasmRunner<int32_t> r(MachineType::Int32());
1631 BUILD(r, WASM_UNREACHABLE);
1632}
1633
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001634TEST(Build_Wasm_Unreachable2) {
1635 WasmRunner<int32_t> r(MachineType::Int32());
1636 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE);
1637}
1638
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001639TEST(Build_Wasm_Unreachable3) {
1640 WasmRunner<int32_t> r(MachineType::Int32());
1641 BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE);
1642}
1643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001644TEST(Build_Wasm_UnreachableIf1) {
1645 WasmRunner<int32_t> r(MachineType::Int32());
1646 BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
1647}
1648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001649TEST(Build_Wasm_UnreachableIf2) {
1650 WasmRunner<int32_t> r(MachineType::Int32());
1651 BUILD(r, WASM_UNREACHABLE,
1652 WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
1653}
1654
Ben Murdochc5610432016-08-08 18:44:38 +01001655WASM_EXEC_TEST(Unreachable_Load) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001656 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001657 BUILD(r, B2(WASM_BRV(0, WASM_GET_LOCAL(0)),
1658 WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001659 CHECK_EQ(11, r.Call(11));
1660 CHECK_EQ(21, r.Call(21));
1661}
1662
Ben Murdochc5610432016-08-08 18:44:38 +01001663WASM_EXEC_TEST(Infinite_Loop_not_taken1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001664 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001665 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), WASM_I8(45)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001666 // Run the code, but don't go into the infinite loop.
1667 CHECK_EQ(45, r.Call(0));
1668}
1669
Ben Murdochc5610432016-08-08 18:44:38 +01001670WASM_EXEC_TEST(Infinite_Loop_not_taken2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001671 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01001672 BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(45)),
Ben Murdochda12d292016-06-02 14:46:10 +01001673 WASM_INFINITE_LOOP)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001674 // Run the code, but don't go into the infinite loop.
1675 CHECK_EQ(45, r.Call(1));
1676}
1677
Ben Murdochc5610432016-08-08 18:44:38 +01001678WASM_EXEC_TEST(Infinite_Loop_not_taken2_brif) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001679 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01001680 BUILD(r,
1681 B2(WASM_BRV_IF(0, WASM_I8(45), WASM_GET_LOCAL(0)), WASM_INFINITE_LOOP));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001682 // Run the code, but don't go into the infinite loop.
1683 CHECK_EQ(45, r.Call(1));
1684}
1685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001686static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001687 Isolate* isolate = CcTest::InitIsolateOnce();
Ben Murdochda12d292016-06-02 14:46:10 +01001688 Zone zone(isolate->allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001689 HandleScope scope(isolate);
1690 // Enable all optional operators.
1691 CommonOperatorBuilder common(&zone);
1692 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(),
1693 MachineOperatorBuilder::kAllOptionalOps);
1694 Graph graph(&zone);
1695 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001696 FunctionSig* sig = WasmOpcodes::Signature(opcode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001697
1698 if (sig->parameter_count() == 1) {
Ben Murdochc5610432016-08-08 18:44:38 +01001699 byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode)};
1700 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
Ben Murdochda12d292016-06-02 14:46:10 +01001701 code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001702 } else {
1703 CHECK_EQ(2, sig->parameter_count());
Ben Murdochc5610432016-08-08 18:44:38 +01001704 byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, kExprGetLocal, 1,
1705 static_cast<byte>(opcode)};
1706 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
Ben Murdochda12d292016-06-02 14:46:10 +01001707 code + arraysize(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001708 }
1709}
1710
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001711TEST(Build_Wasm_SimpleExprs) {
1712// Test that the decoder can build a graph for all supported simple expressions.
1713#define GRAPH_BUILD_TEST(name, opcode, sig) \
1714 TestBuildGraphForSimpleExpression(kExpr##name);
1715
1716 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST);
1717
1718#undef GRAPH_BUILD_TEST
1719}
1720
Ben Murdochc5610432016-08-08 18:44:38 +01001721WASM_EXEC_TEST(Int32LoadInt8_signext) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001722 TestingModule module;
1723 const int kNumElems = 16;
1724 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems);
1725 module.RandomizeMemory();
1726 memory[0] = -1;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001727 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001728 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)));
1729
1730 for (size_t i = 0; i < kNumElems; i++) {
1731 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
1732 }
1733}
1734
Ben Murdochc5610432016-08-08 18:44:38 +01001735WASM_EXEC_TEST(Int32LoadInt8_zeroext) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001736 TestingModule module;
1737 const int kNumElems = 16;
1738 byte* memory = module.AddMemory(kNumElems);
1739 module.RandomizeMemory(77);
1740 memory[0] = 255;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001741 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001742 BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0)));
1743
1744 for (size_t i = 0; i < kNumElems; i++) {
1745 CHECK_EQ(memory[i], r.Call(static_cast<int>(i)));
1746 }
1747}
1748
Ben Murdochc5610432016-08-08 18:44:38 +01001749WASM_EXEC_TEST(Int32LoadInt16_signext) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001750 TestingModule module;
1751 const int kNumBytes = 16;
1752 byte* memory = module.AddMemory(kNumBytes);
1753 module.RandomizeMemory(888);
1754 memory[1] = 200;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001755 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001756 BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0)));
1757
1758 for (size_t i = 0; i < kNumBytes; i += 2) {
1759 int32_t expected = memory[i] | (static_cast<int8_t>(memory[i + 1]) << 8);
1760 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
1761 }
1762}
1763
Ben Murdochc5610432016-08-08 18:44:38 +01001764WASM_EXEC_TEST(Int32LoadInt16_zeroext) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001765 TestingModule module;
1766 const int kNumBytes = 16;
1767 byte* memory = module.AddMemory(kNumBytes);
1768 module.RandomizeMemory(9999);
1769 memory[1] = 204;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001770 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001771 BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0)));
1772
1773 for (size_t i = 0; i < kNumBytes; i += 2) {
1774 int32_t expected = memory[i] | (memory[i + 1] << 8);
1775 CHECK_EQ(expected, r.Call(static_cast<int>(i)));
1776 }
1777}
1778
Ben Murdochc5610432016-08-08 18:44:38 +01001779WASM_EXEC_TEST(Int32Global) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001780 TestingModule module;
1781 int32_t* global = module.AddGlobal<int32_t>(MachineType::Int32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001782 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783 // global = global + p0
1784 BUILD(r, WASM_STORE_GLOBAL(
1785 0, WASM_I32_ADD(WASM_LOAD_GLOBAL(0), WASM_GET_LOCAL(0))));
1786
1787 *global = 116;
1788 for (int i = 9; i < 444444; i += 111111) {
1789 int32_t expected = *global + i;
1790 r.Call(i);
1791 CHECK_EQ(expected, *global);
1792 }
1793}
1794
Ben Murdochc5610432016-08-08 18:44:38 +01001795WASM_EXEC_TEST(Int32Globals_DontAlias) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001796 const int kNumGlobals = 3;
1797 TestingModule module;
1798 int32_t* globals[] = {module.AddGlobal<int32_t>(MachineType::Int32()),
1799 module.AddGlobal<int32_t>(MachineType::Int32()),
1800 module.AddGlobal<int32_t>(MachineType::Int32())};
1801
1802 for (int g = 0; g < kNumGlobals; g++) {
1803 // global = global + p0
Ben Murdoch097c5b22016-05-18 11:27:45 +01001804 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001805 BUILD(r, WASM_STORE_GLOBAL(
1806 g, WASM_I32_ADD(WASM_LOAD_GLOBAL(g), WASM_GET_LOCAL(0))));
1807
1808 // Check that reading/writing global number {g} doesn't alter the others.
1809 *globals[g] = 116 * g;
1810 int32_t before[kNumGlobals];
1811 for (int i = 9; i < 444444; i += 111113) {
1812 int32_t sum = *globals[g] + i;
1813 for (int j = 0; j < kNumGlobals; j++) before[j] = *globals[j];
1814 r.Call(i);
1815 for (int j = 0; j < kNumGlobals; j++) {
1816 int32_t expected = j == g ? sum : before[j];
1817 CHECK_EQ(expected, *globals[j]);
1818 }
1819 }
1820 }
1821}
1822
Ben Murdochc5610432016-08-08 18:44:38 +01001823WASM_EXEC_TEST(Float32Global) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001824 TestingModule module;
1825 float* global = module.AddGlobal<float>(MachineType::Float32());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001826 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001827 // global = global + p0
Ben Murdochda12d292016-06-02 14:46:10 +01001828 BUILD(r, B2(WASM_STORE_GLOBAL(
1829 0, WASM_F32_ADD(WASM_LOAD_GLOBAL(0),
1830 WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0)))),
1831 WASM_ZERO));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001832
1833 *global = 1.25;
1834 for (int i = 9; i < 4444; i += 1111) {
1835 volatile float expected = *global + i;
1836 r.Call(i);
1837 CHECK_EQ(expected, *global);
1838 }
1839}
1840
Ben Murdochc5610432016-08-08 18:44:38 +01001841WASM_EXEC_TEST(Float64Global) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001842 TestingModule module;
1843 double* global = module.AddGlobal<double>(MachineType::Float64());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001844 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001845 // global = global + p0
Ben Murdochda12d292016-06-02 14:46:10 +01001846 BUILD(r, B2(WASM_STORE_GLOBAL(
1847 0, WASM_F64_ADD(WASM_LOAD_GLOBAL(0),
1848 WASM_F64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
1849 WASM_ZERO));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001850
1851 *global = 1.25;
1852 for (int i = 9; i < 4444; i += 1111) {
1853 volatile double expected = *global + i;
1854 r.Call(i);
1855 CHECK_EQ(expected, *global);
1856 }
1857}
1858
Ben Murdochc5610432016-08-08 18:44:38 +01001859WASM_EXEC_TEST(MixedGlobals) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001860 TestingModule module;
1861 int32_t* unused = module.AddGlobal<int32_t>(MachineType::Int32());
1862 byte* memory = module.AddMemory(32);
1863
1864 int8_t* var_int8 = module.AddGlobal<int8_t>(MachineType::Int8());
1865 uint8_t* var_uint8 = module.AddGlobal<uint8_t>(MachineType::Uint8());
1866 int16_t* var_int16 = module.AddGlobal<int16_t>(MachineType::Int16());
1867 uint16_t* var_uint16 = module.AddGlobal<uint16_t>(MachineType::Uint16());
1868 int32_t* var_int32 = module.AddGlobal<int32_t>(MachineType::Int32());
1869 uint32_t* var_uint32 = module.AddGlobal<uint32_t>(MachineType::Uint32());
1870 float* var_float = module.AddGlobal<float>(MachineType::Float32());
1871 double* var_double = module.AddGlobal<double>(MachineType::Float64());
1872
Ben Murdoch097c5b22016-05-18 11:27:45 +01001873 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001874
1875 BUILD(
1876 r,
1877 WASM_BLOCK(
1878 9,
1879 WASM_STORE_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int8(), WASM_ZERO)),
1880 WASM_STORE_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint8(), WASM_ZERO)),
1881 WASM_STORE_GLOBAL(3, WASM_LOAD_MEM(MachineType::Int16(), WASM_ZERO)),
1882 WASM_STORE_GLOBAL(4, WASM_LOAD_MEM(MachineType::Uint16(), WASM_ZERO)),
1883 WASM_STORE_GLOBAL(5, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
1884 WASM_STORE_GLOBAL(6, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)),
1885 WASM_STORE_GLOBAL(7,
1886 WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)),
1887 WASM_STORE_GLOBAL(8,
1888 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)),
1889 WASM_ZERO));
1890
1891 memory[0] = 0xaa;
1892 memory[1] = 0xcc;
1893 memory[2] = 0x55;
1894 memory[3] = 0xee;
1895 memory[4] = 0x33;
1896 memory[5] = 0x22;
1897 memory[6] = 0x11;
1898 memory[7] = 0x99;
1899 r.Call(1);
1900
1901 CHECK(static_cast<int8_t>(0xaa) == *var_int8);
1902 CHECK(static_cast<uint8_t>(0xaa) == *var_uint8);
1903 CHECK(static_cast<int16_t>(0xccaa) == *var_int16);
1904 CHECK(static_cast<uint16_t>(0xccaa) == *var_uint16);
1905 CHECK(static_cast<int32_t>(0xee55ccaa) == *var_int32);
1906 CHECK(static_cast<uint32_t>(0xee55ccaa) == *var_uint32);
1907 CHECK(bit_cast<float>(0xee55ccaa) == *var_float);
1908 CHECK(bit_cast<double>(0x99112233ee55ccaaULL) == *var_double);
1909
1910 USE(unused);
1911}
1912
Ben Murdochc5610432016-08-08 18:44:38 +01001913WASM_EXEC_TEST(CallEmpty) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001914 const int32_t kExpected = -414444;
1915 // Build the target function.
1916 TestSignatures sigs;
1917 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001918 WasmFunctionCompiler t(sigs.i_v(), &module);
Ben Murdochda12d292016-06-02 14:46:10 +01001919 BUILD(t, WASM_I32V_3(kExpected));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001920 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001921
1922 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001923 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001924 BUILD(r, WASM_CALL_FUNCTION0(index));
1925
1926 int32_t result = r.Call();
1927 CHECK_EQ(kExpected, result);
1928}
1929
Ben Murdochc5610432016-08-08 18:44:38 +01001930WASM_EXEC_TEST(CallF32StackParameter) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001931 // Build the target function.
1932 LocalType param_types[20];
1933 for (int i = 0; i < 20; i++) param_types[i] = kAstF32;
1934 FunctionSig sig(1, 19, param_types);
1935 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001936 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001937 BUILD(t, WASM_GET_LOCAL(17));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001938 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001939
1940 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001941 WasmRunner<float> r(&module);
Ben Murdochc5610432016-08-08 18:44:38 +01001942 BUILD(r, WASM_CALL_FUNCTIONN(
1943 19, index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001944 WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
1945 WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
1946 WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
1947 WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f),
1948 WASM_F32(128.5f), WASM_F32(256.5f), WASM_F32(512.5f)));
1949
1950 float result = r.Call();
1951 CHECK_EQ(256.5f, result);
1952}
1953
Ben Murdochc5610432016-08-08 18:44:38 +01001954WASM_EXEC_TEST(CallF64StackParameter) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001955 // Build the target function.
1956 LocalType param_types[20];
1957 for (int i = 0; i < 20; i++) param_types[i] = kAstF64;
1958 FunctionSig sig(1, 19, param_types);
1959 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001960 WasmFunctionCompiler t(&sig, &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001961 BUILD(t, WASM_GET_LOCAL(17));
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<double> r(&module);
Ben Murdochc5610432016-08-08 18:44:38 +01001966 BUILD(r, WASM_CALL_FUNCTIONN(19, index, WASM_F64(1.0), WASM_F64(2.0),
1967 WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
1968 WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
1969 WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
1970 WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5),
1971 WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5),
1972 WASM_F64(256.5), WASM_F64(512.5)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001973
1974 float result = r.Call();
1975 CHECK_EQ(256.5, result);
1976}
1977
Ben Murdochc5610432016-08-08 18:44:38 +01001978WASM_EXEC_TEST(CallVoid) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001979 const byte kMemOffset = 8;
1980 const int32_t kElemNum = kMemOffset / sizeof(int32_t);
1981 const int32_t kExpected = -414444;
1982 // Build the target function.
1983 TestSignatures sigs;
1984 TestingModule module;
1985 module.AddMemory(16);
1986 module.RandomizeMemory();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001987 WasmFunctionCompiler t(sigs.v_v(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001988 BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset),
Ben Murdochda12d292016-06-02 14:46:10 +01001989 WASM_I32V_3(kExpected)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001990 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001991
1992 // Build the calling function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001993 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001994 BUILD(r, WASM_CALL_FUNCTION0(index),
1995 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset)));
1996
1997 int32_t result = r.Call();
1998 CHECK_EQ(kExpected, result);
1999 CHECK_EQ(kExpected, module.raw_mem_start<int32_t>()[kElemNum]);
2000}
2001
Ben Murdochc5610432016-08-08 18:44:38 +01002002WASM_EXEC_TEST(Call_Int32Add) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002003 // Build the target function.
2004 TestSignatures sigs;
2005 TestingModule module;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002006 WasmFunctionCompiler t(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002007 BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002008 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002009
2010 // Build the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002011 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002012 BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002013
2014 FOR_INT32_INPUTS(i) {
2015 FOR_INT32_INPUTS(j) {
2016 int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) +
2017 static_cast<uint32_t>(*j));
2018 CHECK_EQ(expected, r.Call(*i, *j));
2019 }
2020 }
2021}
2022
Ben Murdochc5610432016-08-08 18:44:38 +01002023WASM_EXEC_TEST(Call_Float32Sub) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002024 TestSignatures sigs;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002025 TestingModule module;
2026 WasmFunctionCompiler t(sigs.f_ff(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002027
2028 // Build the target function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002029 BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002030 uint32_t index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002031
2032 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002033 WasmRunner<float> r(&module, MachineType::Float32(), MachineType::Float32());
Ben Murdochc5610432016-08-08 18:44:38 +01002034 BUILD(r, WASM_CALL_FUNCTION2(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002035
2036 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002037 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002038 }
2039}
2040
Ben Murdochc5610432016-08-08 18:44:38 +01002041WASM_EXEC_TEST(Call_Float64Sub) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002042 TestingModule module;
2043 double* memory = module.AddMemoryElems<double>(16);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002044 WasmRunner<int32_t> r(&module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002045
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002046 BUILD(r, WASM_BLOCK(
2047 2, WASM_STORE_MEM(
2048 MachineType::Float64(), WASM_ZERO,
2049 WASM_F64_SUB(
2050 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
2051 WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))),
2052 WASM_I8(107)));
2053
2054 FOR_FLOAT64_INPUTS(i) {
2055 FOR_FLOAT64_INPUTS(j) {
2056 memory[0] = *i;
2057 memory[1] = *j;
2058 double expected = *i - *j;
2059 CHECK_EQ(107, r.Call());
2060 if (expected != expected) {
2061 CHECK(memory[0] != memory[0]);
2062 } else {
2063 CHECK_EQ(expected, memory[0]);
2064 }
2065 }
2066 }
2067}
2068
2069#define ADD_CODE(vec, ...) \
2070 do { \
2071 byte __buf[] = {__VA_ARGS__}; \
2072 for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
2073 } while (false)
2074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002075static void Run_WasmMixedCall_N(int start) {
2076 const int kExpected = 6333;
2077 const int kElemSize = 8;
2078 TestSignatures sigs;
2079
2080#if WASM_64
2081 static MachineType mixed[] = {
2082 MachineType::Int32(), MachineType::Float32(), MachineType::Int64(),
2083 MachineType::Float64(), MachineType::Float32(), MachineType::Int64(),
2084 MachineType::Int32(), MachineType::Float64(), MachineType::Float32(),
2085 MachineType::Float64(), MachineType::Int32(), MachineType::Int64(),
2086 MachineType::Int32(), MachineType::Int32()};
2087#else
2088 static MachineType mixed[] = {
2089 MachineType::Int32(), MachineType::Float32(), MachineType::Float64(),
2090 MachineType::Float32(), MachineType::Int32(), MachineType::Float64(),
2091 MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
2092 MachineType::Int32(), MachineType::Int32()};
2093#endif
2094
2095 int num_params = static_cast<int>(arraysize(mixed)) - start;
2096 for (int which = 0; which < num_params; which++) {
Ben Murdochda12d292016-06-02 14:46:10 +01002097 v8::base::AccountingAllocator allocator;
2098 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002099 TestingModule module;
2100 module.AddMemory(1024);
2101 MachineType* memtypes = &mixed[start];
2102 MachineType result = memtypes[which];
2103
2104 // =========================================================================
2105 // Build the selector function.
2106 // =========================================================================
2107 uint32_t index;
2108 FunctionSig::Builder b(&zone, 1, num_params);
2109 b.AddReturn(WasmOpcodes::LocalTypeFor(result));
2110 for (int i = 0; i < num_params; i++) {
2111 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
2112 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002113 WasmFunctionCompiler t(b.Build(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002114 BUILD(t, WASM_GET_LOCAL(which));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002115 index = t.CompileAndAdd();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002116
2117 // =========================================================================
2118 // Build the calling function.
2119 // =========================================================================
Ben Murdoch097c5b22016-05-18 11:27:45 +01002120 WasmRunner<int32_t> r(&module);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002121 std::vector<byte> code;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002122
Ben Murdochc5610432016-08-08 18:44:38 +01002123 // Load the offset for the store.
2124 ADD_CODE(code, WASM_ZERO);
2125
2126 // Load the arguments.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002127 for (int i = 0; i < num_params; i++) {
2128 int offset = (i + 1) * kElemSize;
2129 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002130 }
2131
Ben Murdochc5610432016-08-08 18:44:38 +01002132 // Call the selector function.
2133 ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params),
2134 static_cast<byte>(index));
2135
2136 // Store the result in memory.
2137 ADD_CODE(code,
2138 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)),
2139 ZERO_ALIGNMENT, ZERO_OFFSET);
2140
2141 // Return the expected value.
Ben Murdochda12d292016-06-02 14:46:10 +01002142 ADD_CODE(code, WASM_I32V_2(kExpected));
Ben Murdochc5610432016-08-08 18:44:38 +01002143
2144 r.Build(&code[0], &code[0] + code.size());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002145
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002146 // Run the code.
2147 for (int t = 0; t < 10; t++) {
2148 module.RandomizeMemory();
2149 CHECK_EQ(kExpected, r.Call());
2150
2151 int size = WasmOpcodes::MemSize(result);
2152 for (int i = 0; i < size; i++) {
2153 int base = (which + 1) * kElemSize;
2154 byte expected = module.raw_mem_at<byte>(base + i);
2155 byte result = module.raw_mem_at<byte>(i);
2156 CHECK_EQ(expected, result);
2157 }
2158 }
2159 }
2160}
2161
Ben Murdochc5610432016-08-08 18:44:38 +01002162WASM_EXEC_TEST(MixedCall_0) { Run_WasmMixedCall_N(0); }
2163WASM_EXEC_TEST(MixedCall_1) { Run_WasmMixedCall_N(1); }
2164WASM_EXEC_TEST(MixedCall_2) { Run_WasmMixedCall_N(2); }
2165WASM_EXEC_TEST(MixedCall_3) { Run_WasmMixedCall_N(3); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002166
Ben Murdochc5610432016-08-08 18:44:38 +01002167WASM_EXEC_TEST(AddCall) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002168 TestSignatures sigs;
2169 TestingModule module;
2170 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2171 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2172 t1.CompileAndAdd();
2173
2174 WasmRunner<int32_t> r(&module, MachineType::Int32());
2175 byte local = r.AllocateLocal(kAstI32);
Ben Murdochda12d292016-06-02 14:46:10 +01002176 BUILD(r, B2(WASM_SET_LOCAL(local, WASM_I8(99)),
2177 WASM_I32_ADD(
Ben Murdochc5610432016-08-08 18:44:38 +01002178 WASM_CALL_FUNCTION2(t1.function_index_, WASM_GET_LOCAL(0),
2179 WASM_GET_LOCAL(0)),
2180 WASM_CALL_FUNCTION2(t1.function_index_, WASM_GET_LOCAL(1),
2181 WASM_GET_LOCAL(local)))));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002182
2183 CHECK_EQ(198, r.Call(0));
2184 CHECK_EQ(200, r.Call(1));
2185 CHECK_EQ(100, r.Call(-49));
2186}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002187
Ben Murdochc5610432016-08-08 18:44:38 +01002188WASM_EXEC_TEST(CountDown_expr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002189 WasmRunner<int32_t> r(MachineType::Int32());
2190 BUILD(r, WASM_LOOP(
2191 3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
Ben Murdochc5610432016-08-08 18:44:38 +01002192 WASM_BREAKV(1, WASM_GET_LOCAL(0))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002193 WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
2194 WASM_CONTINUE(0)));
2195 CHECK_EQ(0, r.Call(1));
2196 CHECK_EQ(0, r.Call(10));
2197 CHECK_EQ(0, r.Call(100));
2198}
2199
Ben Murdochc5610432016-08-08 18:44:38 +01002200WASM_EXEC_TEST(ExprBlock2a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002201 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002202 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))), WASM_I8(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002203 CHECK_EQ(1, r.Call(0));
2204 CHECK_EQ(1, r.Call(1));
2205}
2206
Ben Murdochc5610432016-08-08 18:44:38 +01002207WASM_EXEC_TEST(ExprBlock2b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002208 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002209 BUILD(r, B2(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))), WASM_I8(2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002210 CHECK_EQ(2, r.Call(0));
2211 CHECK_EQ(1, r.Call(1));
2212}
2213
Ben Murdochc5610432016-08-08 18:44:38 +01002214WASM_EXEC_TEST(ExprBlock2c) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002215 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002216 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)), WASM_I8(1)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002217 CHECK_EQ(1, r.Call(0));
2218 CHECK_EQ(1, r.Call(1));
2219}
2220
Ben Murdochc5610432016-08-08 18:44:38 +01002221WASM_EXEC_TEST(ExprBlock2d) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002222 WasmRunner<int32_t> r(MachineType::Int32());
Ben Murdochda12d292016-06-02 14:46:10 +01002223 BUILD(r, B2(WASM_BRV_IF(0, WASM_I8(1), WASM_GET_LOCAL(0)), WASM_I8(2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002224 CHECK_EQ(2, r.Call(0));
2225 CHECK_EQ(1, r.Call(1));
2226}
2227
Ben Murdochc5610432016-08-08 18:44:38 +01002228WASM_EXEC_TEST(ExprBlock_ManualSwitch) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002229 WasmRunner<int32_t> r(MachineType::Int32());
2230 BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
Ben Murdochc5610432016-08-08 18:44:38 +01002231 WASM_BRV(1, WASM_I8(11))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002232 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
Ben Murdochc5610432016-08-08 18:44:38 +01002233 WASM_BRV(1, WASM_I8(12))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002234 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
Ben Murdochc5610432016-08-08 18:44:38 +01002235 WASM_BRV(1, WASM_I8(13))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002236 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
Ben Murdochc5610432016-08-08 18:44:38 +01002237 WASM_BRV(1, WASM_I8(14))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002238 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
Ben Murdochc5610432016-08-08 18:44:38 +01002239 WASM_BRV(1, WASM_I8(15))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002240 WASM_I8(99)));
2241 CHECK_EQ(99, r.Call(0));
2242 CHECK_EQ(11, r.Call(1));
2243 CHECK_EQ(12, r.Call(2));
2244 CHECK_EQ(13, r.Call(3));
2245 CHECK_EQ(14, r.Call(4));
2246 CHECK_EQ(15, r.Call(5));
2247 CHECK_EQ(99, r.Call(6));
2248}
2249
Ben Murdochc5610432016-08-08 18:44:38 +01002250WASM_EXEC_TEST(ExprBlock_ManualSwitch_brif) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002251 WasmRunner<int32_t> r(MachineType::Int32());
2252 BUILD(r,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002253 WASM_BLOCK(6, WASM_BRV_IF(0, WASM_I8(11),
2254 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1))),
2255 WASM_BRV_IF(0, WASM_I8(12),
2256 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2))),
2257 WASM_BRV_IF(0, WASM_I8(13),
2258 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3))),
2259 WASM_BRV_IF(0, WASM_I8(14),
2260 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4))),
2261 WASM_BRV_IF(0, WASM_I8(15),
2262 WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002263 WASM_I8(99)));
2264 CHECK_EQ(99, r.Call(0));
2265 CHECK_EQ(11, r.Call(1));
2266 CHECK_EQ(12, r.Call(2));
2267 CHECK_EQ(13, r.Call(3));
2268 CHECK_EQ(14, r.Call(4));
2269 CHECK_EQ(15, r.Call(5));
2270 CHECK_EQ(99, r.Call(6));
2271}
2272
Ben Murdochc5610432016-08-08 18:44:38 +01002273WASM_EXEC_TEST(nested_ifs) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002274 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2275
2276 BUILD(r, WASM_IF_ELSE(
2277 WASM_GET_LOCAL(0),
2278 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
2279 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
2280
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002281 CHECK_EQ(11, r.Call(1, 1));
2282 CHECK_EQ(12, r.Call(1, 0));
2283 CHECK_EQ(13, r.Call(0, 1));
2284 CHECK_EQ(14, r.Call(0, 0));
2285}
2286
Ben Murdochc5610432016-08-08 18:44:38 +01002287WASM_EXEC_TEST(ExprBlock_if) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002288 WasmRunner<int32_t> r(MachineType::Int32());
2289
Ben Murdochda12d292016-06-02 14:46:10 +01002290 BUILD(r, B1(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
Ben Murdochc5610432016-08-08 18:44:38 +01002291 WASM_BRV(1, WASM_I8(14)))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002292
2293 CHECK_EQ(11, r.Call(1));
2294 CHECK_EQ(14, r.Call(0));
2295}
2296
Ben Murdochc5610432016-08-08 18:44:38 +01002297WASM_EXEC_TEST(ExprBlock_nested_ifs) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002298 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2299
2300 BUILD(r, WASM_BLOCK(
2301 1, WASM_IF_ELSE(
2302 WASM_GET_LOCAL(0),
2303 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
Ben Murdochc5610432016-08-08 18:44:38 +01002304 WASM_BRV(1, WASM_I8(12))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002305 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
Ben Murdochc5610432016-08-08 18:44:38 +01002306 WASM_BRV(1, WASM_I8(14))))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002307
2308 CHECK_EQ(11, r.Call(1, 1));
2309 CHECK_EQ(12, r.Call(1, 0));
2310 CHECK_EQ(13, r.Call(0, 1));
2311 CHECK_EQ(14, r.Call(0, 0));
2312}
2313
Ben Murdochc5610432016-08-08 18:44:38 +01002314WASM_EXEC_TEST(ExprLoop_nested_ifs) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002315 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2316
2317 BUILD(r, WASM_LOOP(
2318 1, WASM_IF_ELSE(
2319 WASM_GET_LOCAL(0),
2320 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)),
Ben Murdochc5610432016-08-08 18:44:38 +01002321 WASM_BRV(3, WASM_I8(12))),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002322 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)),
Ben Murdochc5610432016-08-08 18:44:38 +01002323 WASM_BRV(3, WASM_I8(14))))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002324
2325 CHECK_EQ(11, r.Call(1, 1));
2326 CHECK_EQ(12, r.Call(1, 0));
2327 CHECK_EQ(13, r.Call(0, 1));
2328 CHECK_EQ(14, r.Call(0, 0));
2329}
2330
Ben Murdochc5610432016-08-08 18:44:38 +01002331WASM_EXEC_TEST(SimpleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002332 TestSignatures sigs;
2333 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002334
Ben Murdoch097c5b22016-05-18 11:27:45 +01002335 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2336 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2337 t1.CompileAndAdd(/*sig_index*/ 1);
2338
2339 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002340 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002341 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002342
2343 // Signature table.
2344 module.AddSignature(sigs.f_ff());
2345 module.AddSignature(sigs.i_ii());
2346 module.AddSignature(sigs.d_dd());
2347
2348 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002349 int table[] = {0, 1};
2350 module.AddIndirectFunctionTable(table, 2);
2351 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002352
2353 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002354 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002355 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002356
2357 CHECK_EQ(88, r.Call(0));
2358 CHECK_EQ(44, r.Call(1));
2359 CHECK_TRAP(r.Call(2));
2360}
2361
Ben Murdochc5610432016-08-08 18:44:38 +01002362WASM_EXEC_TEST(MultipleCallIndirect) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002363 TestSignatures sigs;
2364 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002365
Ben Murdoch097c5b22016-05-18 11:27:45 +01002366 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2367 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2368 t1.CompileAndAdd(/*sig_index*/ 1);
2369
2370 WasmFunctionCompiler t2(sigs.i_ii(), &module);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002371 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002372 t2.CompileAndAdd(/*sig_index*/ 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002373
2374 // Signature table.
2375 module.AddSignature(sigs.f_ff());
2376 module.AddSignature(sigs.i_ii());
2377 module.AddSignature(sigs.d_dd());
2378
2379 // Function table.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002380 int table[] = {0, 1};
2381 module.AddIndirectFunctionTable(table, 2);
2382 module.PopulateIndirectFunctionTable();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002383
2384 // Builder the caller function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002385 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32(),
2386 MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002387 BUILD(r, WASM_I32_ADD(
2388 WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2389 WASM_GET_LOCAL(2)),
2390 WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
2391 WASM_GET_LOCAL(0))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002392
2393 CHECK_EQ(5, r.Call(0, 1, 2));
2394 CHECK_EQ(19, r.Call(0, 1, 9));
2395 CHECK_EQ(1, r.Call(1, 0, 2));
2396 CHECK_EQ(1, r.Call(1, 0, 9));
2397
2398 CHECK_TRAP(r.Call(0, 2, 1));
2399 CHECK_TRAP(r.Call(1, 2, 0));
2400 CHECK_TRAP(r.Call(2, 0, 1));
2401 CHECK_TRAP(r.Call(2, 1, 0));
2402}
2403
Ben Murdochc5610432016-08-08 18:44:38 +01002404WASM_EXEC_TEST(CallIndirect_NoTable) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002405 TestSignatures sigs;
2406 TestingModule module;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002407
Ben Murdoch097c5b22016-05-18 11:27:45 +01002408 // One function.
2409 WasmFunctionCompiler t1(sigs.i_ii(), &module);
2410 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2411 t1.CompileAndAdd(/*sig_index*/ 1);
2412
2413 // Signature table.
2414 module.AddSignature(sigs.f_ff());
2415 module.AddSignature(sigs.i_ii());
2416
2417 // Builder the caller function.
2418 WasmRunner<int32_t> r(&module, MachineType::Int32());
Ben Murdochc5610432016-08-08 18:44:38 +01002419 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
Ben Murdoch097c5b22016-05-18 11:27:45 +01002420
2421 CHECK_TRAP(r.Call(0));
2422 CHECK_TRAP(r.Call(1));
2423 CHECK_TRAP(r.Call(2));
2424}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002425
Ben Murdochc5610432016-08-08 18:44:38 +01002426WASM_EXEC_TEST(F32Floor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002427 WasmRunner<float> r(MachineType::Float32());
2428 BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0)));
2429
Ben Murdochda12d292016-06-02 14:46:10 +01002430 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(floorf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002431}
2432
Ben Murdochc5610432016-08-08 18:44:38 +01002433WASM_EXEC_TEST(F32Ceil) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002434 WasmRunner<float> r(MachineType::Float32());
2435 BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0)));
2436
Ben Murdochda12d292016-06-02 14:46:10 +01002437 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(ceilf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002438}
2439
Ben Murdochc5610432016-08-08 18:44:38 +01002440WASM_EXEC_TEST(F32Trunc) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002441 WasmRunner<float> r(MachineType::Float32());
2442 BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0)));
2443
Ben Murdochda12d292016-06-02 14:46:10 +01002444 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(truncf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002445}
2446
Ben Murdochc5610432016-08-08 18:44:38 +01002447WASM_EXEC_TEST(F32NearestInt) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002448 WasmRunner<float> r(MachineType::Float32());
2449 BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0)));
2450
Ben Murdochda12d292016-06-02 14:46:10 +01002451 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyintf(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002452}
2453
Ben Murdochc5610432016-08-08 18:44:38 +01002454WASM_EXEC_TEST(F64Floor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002455 WasmRunner<double> r(MachineType::Float64());
2456 BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0)));
2457
Ben Murdochda12d292016-06-02 14:46:10 +01002458 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(floor(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002459}
2460
Ben Murdochc5610432016-08-08 18:44:38 +01002461WASM_EXEC_TEST(F64Ceil) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002462 WasmRunner<double> r(MachineType::Float64());
2463 BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0)));
2464
Ben Murdochda12d292016-06-02 14:46:10 +01002465 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(ceil(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002466}
2467
Ben Murdochc5610432016-08-08 18:44:38 +01002468WASM_EXEC_TEST(F64Trunc) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002469 WasmRunner<double> r(MachineType::Float64());
2470 BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
2471
Ben Murdochda12d292016-06-02 14:46:10 +01002472 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(trunc(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002473}
2474
Ben Murdochc5610432016-08-08 18:44:38 +01002475WASM_EXEC_TEST(F64NearestInt) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002476 WasmRunner<double> r(MachineType::Float64());
2477 BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
2478
Ben Murdochda12d292016-06-02 14:46:10 +01002479 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), r.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002480}
2481
Ben Murdochc5610432016-08-08 18:44:38 +01002482WASM_EXEC_TEST(F32Min) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002483 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2484 BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2485
2486 FOR_FLOAT32_INPUTS(i) {
2487 FOR_FLOAT32_INPUTS(j) {
2488 float expected;
2489 if (*i < *j) {
2490 expected = *i;
2491 } else if (*j < *i) {
2492 expected = *j;
2493 } else if (*i != *i) {
2494 // If *i or *j is NaN, then the result is NaN.
2495 expected = *i;
2496 } else {
2497 expected = *j;
2498 }
2499
Ben Murdochda12d292016-06-02 14:46:10 +01002500 CHECK_FLOAT_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002501 }
2502 }
2503}
2504
Ben Murdochc5610432016-08-08 18:44:38 +01002505WASM_EXEC_TEST(F64Min) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002506 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2507 BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2508
2509 FOR_FLOAT64_INPUTS(i) {
2510 FOR_FLOAT64_INPUTS(j) {
2511 double expected;
2512 if (*i < *j) {
2513 expected = *i;
2514 } else if (*j < *i) {
2515 expected = *j;
2516 } else if (*i != *i) {
2517 // If *i or *j is NaN, then the result is NaN.
2518 expected = *i;
2519 } else {
2520 expected = *j;
2521 }
2522
Ben Murdochda12d292016-06-02 14:46:10 +01002523 CHECK_DOUBLE_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002524 }
2525 }
2526}
2527
Ben Murdochc5610432016-08-08 18:44:38 +01002528WASM_EXEC_TEST(F32Max) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002529 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2530 BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2531
2532 FOR_FLOAT32_INPUTS(i) {
2533 FOR_FLOAT32_INPUTS(j) {
2534 float expected;
2535 if (*i > *j) {
2536 expected = *i;
2537 } else if (*j > *i) {
2538 expected = *j;
2539 } else if (*i != *i) {
2540 // If *i or *j is NaN, then the result is NaN.
2541 expected = *i;
2542 } else {
2543 expected = *j;
2544 }
2545
Ben Murdochda12d292016-06-02 14:46:10 +01002546 CHECK_FLOAT_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002547 }
2548 }
2549}
2550
Ben Murdochc5610432016-08-08 18:44:38 +01002551WASM_EXEC_TEST(F64Max) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002552 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2553 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2554
2555 FOR_FLOAT64_INPUTS(i) {
2556 FOR_FLOAT64_INPUTS(j) {
2557 double expected;
2558 if (*i > *j) {
2559 expected = *i;
2560 } else if (*j > *i) {
2561 expected = *j;
2562 } else if (*i != *i) {
2563 // If *i or *j is NaN, then the result is NaN.
2564 expected = *i;
2565 } else {
2566 expected = *j;
2567 }
2568
Ben Murdochda12d292016-06-02 14:46:10 +01002569 CHECK_DOUBLE_EQ(expected, r.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002570 }
2571 }
2572}
2573
Ben Murdochc5610432016-08-08 18:44:38 +01002574// TODO(ahaas): Fix on mips and reenable.
2575#if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
Ben Murdoch097c5b22016-05-18 11:27:45 +01002576
Ben Murdochc5610432016-08-08 18:44:38 +01002577WASM_EXEC_TEST(F32Min_Snan) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002578 // Test that the instruction does not return a signalling NaN.
2579 {
2580 WasmRunner<float> r;
2581 BUILD(r,
2582 WASM_F32_MIN(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
2583 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
2584 }
2585 {
2586 WasmRunner<float> r;
2587 BUILD(r,
2588 WASM_F32_MIN(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
2589 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
2590 }
2591}
2592
Ben Murdochc5610432016-08-08 18:44:38 +01002593WASM_EXEC_TEST(F32Max_Snan) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002594 // Test that the instruction does not return a signalling NaN.
2595 {
2596 WasmRunner<float> r;
2597 BUILD(r,
2598 WASM_F32_MAX(WASM_F32(bit_cast<float>(0xff80f1e2)), WASM_F32(57.67)));
2599 CHECK_EQ(0xffc0f1e2, bit_cast<uint32_t>(r.Call()));
2600 }
2601 {
2602 WasmRunner<float> r;
2603 BUILD(r,
2604 WASM_F32_MAX(WASM_F32(45.73), WASM_F32(bit_cast<float>(0x7f80f1e2))));
2605 CHECK_EQ(0x7fc0f1e2, bit_cast<uint32_t>(r.Call()));
2606 }
2607}
2608
Ben Murdochc5610432016-08-08 18:44:38 +01002609WASM_EXEC_TEST(F64Min_Snan) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002610 // Test that the instruction does not return a signalling NaN.
2611 {
2612 WasmRunner<double> r;
2613 BUILD(r, WASM_F64_MIN(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
2614 WASM_F64(57.67)));
2615 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2616 }
2617 {
2618 WasmRunner<double> r;
2619 BUILD(r, WASM_F64_MIN(WASM_F64(45.73),
2620 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
2621 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2622 }
2623}
2624
Ben Murdochc5610432016-08-08 18:44:38 +01002625WASM_EXEC_TEST(F64Max_Snan) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002626 // Test that the instruction does not return a signalling NaN.
2627 {
2628 WasmRunner<double> r;
2629 BUILD(r, WASM_F64_MAX(WASM_F64(bit_cast<double>(0xfff000000000f1e2)),
2630 WASM_F64(57.67)));
2631 CHECK_EQ(0xfff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2632 }
2633 {
2634 WasmRunner<double> r;
2635 BUILD(r, WASM_F64_MAX(WASM_F64(45.73),
2636 WASM_F64(bit_cast<double>(0x7ff000000000f1e2))));
2637 CHECK_EQ(0x7ff800000000f1e2, bit_cast<uint64_t>(r.Call()));
2638 }
2639}
2640
2641#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002642
Ben Murdochc5610432016-08-08 18:44:38 +01002643WASM_EXEC_TEST(I32SConvertF32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002644 WasmRunner<int32_t> r(MachineType::Float32());
2645 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0)));
2646
2647 FOR_FLOAT32_INPUTS(i) {
2648 if (*i < static_cast<float>(INT32_MAX) &&
2649 *i >= static_cast<float>(INT32_MIN)) {
2650 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i));
2651 } else {
2652 CHECK_TRAP32(r.Call(*i));
2653 }
2654 }
2655}
2656
Ben Murdochc5610432016-08-08 18:44:38 +01002657WASM_EXEC_TEST(I32SConvertF64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002658 WasmRunner<int32_t> r(MachineType::Float64());
2659 BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0)));
2660
2661 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002662 if (*i < (static_cast<double>(INT32_MAX) + 1.0) &&
2663 *i > (static_cast<double>(INT32_MIN) - 1.0)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002664 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
2665 } else {
2666 CHECK_TRAP32(r.Call(*i));
2667 }
2668 }
2669}
2670
Ben Murdochc5610432016-08-08 18:44:38 +01002671WASM_EXEC_TEST(I32UConvertF32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002672 WasmRunner<uint32_t> r(MachineType::Float32());
2673 BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0)));
2674
2675 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002676 if (*i < (static_cast<float>(UINT32_MAX) + 1.0) && *i > -1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002677 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
2678 } else {
2679 CHECK_TRAP32(r.Call(*i));
2680 }
2681 }
2682}
2683
Ben Murdochc5610432016-08-08 18:44:38 +01002684WASM_EXEC_TEST(I32UConvertF64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002685 WasmRunner<uint32_t> r(MachineType::Float64());
2686 BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0)));
2687
2688 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002689 if (*i < (static_cast<float>(UINT32_MAX) + 1.0) && *i > -1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002690 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i));
2691 } else {
2692 CHECK_TRAP32(r.Call(*i));
2693 }
2694 }
2695}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002696
Ben Murdochc5610432016-08-08 18:44:38 +01002697WASM_EXEC_TEST(F64CopySign) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002698 WasmRunner<double> r(MachineType::Float64(), MachineType::Float64());
2699 BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2700
2701 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002702 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(copysign(*i, *j), r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002703 }
2704}
2705
Ben Murdochc5610432016-08-08 18:44:38 +01002706WASM_EXEC_TEST(F32CopySign) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002707 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32());
2708 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
2709
2710 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01002711 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(copysignf(*i, *j), r.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002712 }
2713}
2714
Ben Murdoch097c5b22016-05-18 11:27:45 +01002715void CompileCallIndirectMany(LocalType param) {
2716 // Make sure we don't run out of registers when compiling indirect calls
2717 // with many many parameters.
2718 TestSignatures sigs;
2719 for (byte num_params = 0; num_params < 40; num_params++) {
Ben Murdochda12d292016-06-02 14:46:10 +01002720 v8::base::AccountingAllocator allocator;
2721 Zone zone(&allocator);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002722 HandleScope scope(CcTest::InitIsolateOnce());
2723 TestingModule module;
2724 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
2725
2726 module.AddSignature(sig);
2727 module.AddSignature(sig);
2728 module.AddIndirectFunctionTable(nullptr, 0);
2729
2730 WasmFunctionCompiler t(sig, &module);
2731
2732 std::vector<byte> code;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002733 ADD_CODE(code, kExprI8Const, 0);
2734 for (byte p = 0; p < num_params; p++) {
2735 ADD_CODE(code, kExprGetLocal, p);
2736 }
Ben Murdochc5610432016-08-08 18:44:38 +01002737 ADD_CODE(code, kExprCallIndirect, static_cast<byte>(num_params), 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002738
2739 t.Build(&code[0], &code[0] + code.size());
2740 t.Compile();
2741 }
2742}
2743
Ben Murdoch097c5b22016-05-18 11:27:45 +01002744TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); }
2745
Ben Murdoch097c5b22016-05-18 11:27:45 +01002746#if WASM_64
2747TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); }
2748#endif
2749
Ben Murdoch097c5b22016-05-18 11:27:45 +01002750TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); }
2751
Ben Murdoch097c5b22016-05-18 11:27:45 +01002752TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); }
Ben Murdochda12d292016-06-02 14:46:10 +01002753
Ben Murdochc5610432016-08-08 18:44:38 +01002754WASM_EXEC_TEST(Int32RemS_dead) {
Ben Murdochda12d292016-06-02 14:46:10 +01002755 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32());
2756 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_ZERO);
2757 const int32_t kMin = std::numeric_limits<int32_t>::min();
2758 CHECK_EQ(0, r.Call(133, 100));
2759 CHECK_EQ(0, r.Call(kMin, -1));
2760 CHECK_EQ(0, r.Call(0, 1));
2761 CHECK_TRAP(r.Call(100, 0));
2762 CHECK_TRAP(r.Call(-1001, 0));
2763 CHECK_TRAP(r.Call(kMin, 0));
2764}