OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/wasm/wasm-macro-gen.h" | 5 #include "src/wasm/wasm-macro-gen.h" |
6 | 6 |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 #include "test/cctest/wasm/wasm-run-utils.h" | 9 #include "test/cctest/wasm/wasm-run-utils.h" |
10 | 10 |
11 using namespace v8::base; | 11 using namespace v8::base; |
12 using namespace v8::internal; | 12 using namespace v8::internal; |
13 using namespace v8::internal::compiler; | 13 using namespace v8::internal::compiler; |
14 using namespace v8::internal::wasm; | 14 using namespace v8::internal::wasm; |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 typedef float (*FloatUnOp)(float); | 18 typedef float (*FloatUnOp)(float); |
19 typedef float (*FloatBinOp)(float, float); | 19 typedef float (*FloatBinOp)(float, float); |
20 typedef int32_t (*FloatCompareOp)(float, float); | 20 typedef int32_t (*FloatCompareOp)(float, float); |
21 typedef int32_t (*Int32UnOp)(int32_t); | 21 typedef int32_t (*Int32UnOp)(int32_t); |
22 typedef int32_t (*Int32BinOp)(int32_t, int32_t); | 22 typedef int32_t (*Int32BinOp)(int32_t, int32_t); |
| 23 typedef int32_t (*Int32ShiftOp)(int32_t, int); |
23 typedef int16_t (*Int16UnOp)(int16_t); | 24 typedef int16_t (*Int16UnOp)(int16_t); |
24 typedef int16_t (*Int16BinOp)(int16_t, int16_t); | 25 typedef int16_t (*Int16BinOp)(int16_t, int16_t); |
| 26 typedef int16_t (*Int16ShiftOp)(int16_t, int); |
25 typedef int8_t (*Int8UnOp)(int8_t); | 27 typedef int8_t (*Int8UnOp)(int8_t); |
26 typedef int8_t (*Int8BinOp)(int8_t, int8_t); | 28 typedef int8_t (*Int8BinOp)(int8_t, int8_t); |
| 29 typedef int8_t (*Int8ShiftOp)(int8_t, int); |
27 | 30 |
28 #if V8_TARGET_ARCH_ARM | 31 #if V8_TARGET_ARCH_ARM |
29 // Floating point specific value functions. | 32 // Floating point specific value functions. |
30 int32_t Equal(float a, float b) { return a == b ? -1 : 0; } | 33 int32_t Equal(float a, float b) { return a == b ? -1 : 0; } |
31 | 34 |
32 int32_t NotEqual(float a, float b) { return a != b ? -1 : 0; } | 35 int32_t NotEqual(float a, float b) { return a != b ? -1 : 0; } |
33 #endif // V8_TARGET_ARCH_ARM | 36 #endif // V8_TARGET_ARCH_ARM |
34 | 37 |
35 // Generic expected value functions. | 38 // Generic expected value functions. |
36 template <typename T> | 39 template <typename T> |
(...skipping 10 matching lines...) Expand all Loading... |
47 T Sub(T a, T b) { | 50 T Sub(T a, T b) { |
48 return a - b; | 51 return a - b; |
49 } | 52 } |
50 | 53 |
51 template <typename T> | 54 template <typename T> |
52 T Mul(T a, T b) { | 55 T Mul(T a, T b) { |
53 return a * b; | 56 return a * b; |
54 } | 57 } |
55 | 58 |
56 template <typename T> | 59 template <typename T> |
| 60 T Minimum(T a, T b) { |
| 61 return a <= b ? a : b; |
| 62 } |
| 63 |
| 64 template <typename T> |
| 65 T Maximum(T a, T b) { |
| 66 return a >= b ? a : b; |
| 67 } |
| 68 |
| 69 template <typename T> |
| 70 T UnsignedMinimum(T a, T b) { |
| 71 using UnsignedT = typename std::make_unsigned<T>::type; |
| 72 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? a : b; |
| 73 } |
| 74 |
| 75 template <typename T> |
| 76 T UnsignedMaximum(T a, T b) { |
| 77 using UnsignedT = typename std::make_unsigned<T>::type; |
| 78 return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? a : b; |
| 79 } |
| 80 |
| 81 template <typename T> |
57 T Equal(T a, T b) { | 82 T Equal(T a, T b) { |
58 return a == b ? -1 : 0; | 83 return a == b ? -1 : 0; |
59 } | 84 } |
60 | 85 |
61 template <typename T> | 86 template <typename T> |
62 T NotEqual(T a, T b) { | 87 T NotEqual(T a, T b) { |
63 return a != b ? -1 : 0; | 88 return a != b ? -1 : 0; |
64 } | 89 } |
65 | 90 |
66 template <typename T> | 91 template <typename T> |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 using UnsignedT = typename std::make_unsigned<T>::type; | 125 using UnsignedT = typename std::make_unsigned<T>::type; |
101 return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? -1 : 0; | 126 return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? -1 : 0; |
102 } | 127 } |
103 | 128 |
104 template <typename T> | 129 template <typename T> |
105 T UnsignedLessEqual(T a, T b) { | 130 T UnsignedLessEqual(T a, T b) { |
106 using UnsignedT = typename std::make_unsigned<T>::type; | 131 using UnsignedT = typename std::make_unsigned<T>::type; |
107 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? -1 : 0; | 132 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? -1 : 0; |
108 } | 133 } |
109 | 134 |
| 135 template <typename T> |
| 136 T LogicalShiftLeft(T a, int shift) { |
| 137 return a << shift; |
| 138 } |
| 139 |
| 140 template <typename T> |
| 141 T LogicalShiftRight(T a, int shift) { |
| 142 using UnsignedT = typename std::make_unsigned<T>::type; |
| 143 return static_cast<UnsignedT>(a) >> shift; |
| 144 } |
| 145 |
| 146 template <typename T> |
| 147 int64_t Widen(T value) { |
| 148 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 149 return static_cast<int64_t>(value); |
| 150 } |
| 151 |
| 152 template <typename T> |
| 153 int64_t UnsignedWiden(T value) { |
| 154 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 155 using UnsignedT = typename std::make_unsigned<T>::type; |
| 156 return static_cast<int64_t>(static_cast<UnsignedT>(value)); |
| 157 } |
| 158 |
| 159 template <typename T> |
| 160 T Clamp(int64_t value) { |
| 161 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 162 int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); |
| 163 int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); |
| 164 int64_t clamped = std::max(min, std::min(max, value)); |
| 165 return static_cast<T>(clamped); |
| 166 } |
| 167 |
| 168 template <typename T> |
| 169 T AddSaturate(T a, T b) { |
| 170 return Clamp<T>(Widen(a) + Widen(b)); |
| 171 } |
| 172 |
| 173 template <typename T> |
| 174 T SubSaturate(T a, T b) { |
| 175 return Clamp<T>(Widen(a) - Widen(b)); |
| 176 } |
| 177 |
| 178 template <typename T> |
| 179 T UnsignedAddSaturate(T a, T b) { |
| 180 using UnsignedT = typename std::make_unsigned<T>::type; |
| 181 return Clamp<UnsignedT>(UnsignedWiden(a) + UnsignedWiden(b)); |
| 182 } |
| 183 |
| 184 template <typename T> |
| 185 T UnsignedSubSaturate(T a, T b) { |
| 186 using UnsignedT = typename std::make_unsigned<T>::type; |
| 187 return Clamp<UnsignedT>(UnsignedWiden(a) - UnsignedWiden(b)); |
| 188 } |
| 189 |
110 } // namespace | 190 } // namespace |
111 | 191 |
112 // TODO(gdeepti): These are tests using sample values to verify functional | 192 // TODO(gdeepti): These are tests using sample values to verify functional |
113 // correctness of opcodes, add more tests for a range of values and macroize | 193 // correctness of opcodes, add more tests for a range of values and macroize |
114 // tests. | 194 // tests. |
115 | 195 |
116 // TODO(bbudge) Figure out how to compare floats in Wasm code that can handle | 196 // TODO(bbudge) Figure out how to compare floats in Wasm code that can handle |
117 // NaNs. For now, our tests avoid using NaNs. | 197 // NaNs. For now, our tests avoid using NaNs. |
118 #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ | 198 #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ |
119 WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ | 199 WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 | 257 |
178 #define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \ | 258 #define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \ |
179 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \ | 259 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \ |
180 , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \ | 260 , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \ |
181 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \ | 261 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \ |
182 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3) | 262 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3) |
183 | 263 |
184 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ | 264 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ |
185 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) | 265 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) |
186 | 266 |
| 267 #define WASM_SIMD_UNOP(opcode, x) x, kSimdPrefix, static_cast<byte>(opcode) |
| 268 #define WASM_SIMD_BINOP(opcode, x, y) \ |
| 269 x, y, kSimdPrefix, static_cast<byte>(opcode) |
| 270 #define WASM_SIMD_SHIFT_OP(opcode, x, shift) \ |
| 271 x, kSimdPrefix, static_cast<byte>(opcode), static_cast<byte>(shift) |
| 272 |
187 #if V8_TARGET_ARCH_ARM | 273 #if V8_TARGET_ARCH_ARM |
188 WASM_EXEC_TEST(F32x4Splat) { | 274 WASM_EXEC_TEST(F32x4Splat) { |
189 FLAG_wasm_simd_prototype = true; | 275 FLAG_wasm_simd_prototype = true; |
190 | 276 |
191 WasmRunner<int32_t, float> r(kExecuteCompiled); | 277 WasmRunner<int32_t, float> r(kExecuteCompiled); |
192 byte lane_val = 0; | 278 byte lane_val = 0; |
193 byte simd = r.AllocateLocal(kWasmS128); | 279 byte simd = r.AllocateLocal(kWasmS128); |
194 BUILD(r, | 280 BUILD(r, |
195 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))), | 281 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))), |
196 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), WASM_ONE); | 282 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), WASM_ONE); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 CHECK_EQ(1, r.Call(0x1234, 0x5678)); | 362 CHECK_EQ(1, r.Call(0x1234, 0x5678)); |
277 } | 363 } |
278 | 364 |
279 void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) { | 365 void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) { |
280 FLAG_wasm_simd_prototype = true; | 366 FLAG_wasm_simd_prototype = true; |
281 WasmRunner<int32_t, float, float> r(kExecuteCompiled); | 367 WasmRunner<int32_t, float, float> r(kExecuteCompiled); |
282 byte a = 0; | 368 byte a = 0; |
283 byte expected = 1; | 369 byte expected = 1; |
284 byte simd = r.AllocateLocal(kWasmS128); | 370 byte simd = r.AllocateLocal(kWasmS128); |
285 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 371 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
286 WASM_SET_LOCAL(simd, | 372 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
287 WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | |
288 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, expected), WASM_ONE); | 373 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, expected), WASM_ONE); |
289 | 374 |
290 FOR_FLOAT32_INPUTS(i) { | 375 FOR_FLOAT32_INPUTS(i) { |
291 if (std::isnan(*i)) continue; | 376 if (std::isnan(*i)) continue; |
292 CHECK_EQ(1, r.Call(*i, expected_op(*i))); | 377 CHECK_EQ(1, r.Call(*i, expected_op(*i))); |
293 } | 378 } |
294 } | 379 } |
295 | 380 |
296 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } | 381 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } |
297 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } | 382 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } |
298 | 383 |
299 void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) { | 384 void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) { |
300 FLAG_wasm_simd_prototype = true; | 385 FLAG_wasm_simd_prototype = true; |
301 WasmRunner<int32_t, float, float, float> r(kExecuteCompiled); | 386 WasmRunner<int32_t, float, float, float> r(kExecuteCompiled); |
302 byte a = 0; | 387 byte a = 0; |
303 byte b = 1; | 388 byte b = 1; |
304 byte expected = 2; | 389 byte expected = 2; |
305 byte simd0 = r.AllocateLocal(kWasmS128); | 390 byte simd0 = r.AllocateLocal(kWasmS128); |
306 byte simd1 = r.AllocateLocal(kWasmS128); | 391 byte simd1 = r.AllocateLocal(kWasmS128); |
307 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 392 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
308 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), | 393 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), |
309 WASM_SET_LOCAL(simd1, | 394 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
310 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), | 395 WASM_GET_LOCAL(simd1))), |
311 WASM_GET_LOCAL(simd1))), | |
312 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), WASM_ONE); | 396 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), WASM_ONE); |
313 | 397 |
314 FOR_FLOAT32_INPUTS(i) { | 398 FOR_FLOAT32_INPUTS(i) { |
315 if (std::isnan(*i)) continue; | 399 if (std::isnan(*i)) continue; |
316 FOR_FLOAT32_INPUTS(j) { | 400 FOR_FLOAT32_INPUTS(j) { |
317 if (std::isnan(*j)) continue; | 401 if (std::isnan(*j)) continue; |
318 float expected = expected_op(*i, *j); | 402 float expected = expected_op(*i, *j); |
319 // SIMD on some platforms may handle denormalized numbers differently. | 403 // SIMD on some platforms may handle denormalized numbers differently. |
320 // TODO(bbudge) On platforms that flush denorms to zero, test with | 404 // TODO(bbudge) On platforms that flush denorms to zero, test with |
321 // expected == 0. | 405 // expected == 0. |
322 if (std::fpclassify(expected) == FP_SUBNORMAL) continue; | 406 if (std::fpclassify(expected) == FP_SUBNORMAL) continue; |
323 CHECK_EQ(1, r.Call(*i, *j, expected)); | 407 CHECK_EQ(1, r.Call(*i, *j, expected)); |
324 } | 408 } |
325 } | 409 } |
326 } | 410 } |
327 | 411 |
328 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } | 412 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } |
329 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } | 413 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } |
330 | 414 |
331 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) { | 415 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) { |
332 FLAG_wasm_simd_prototype = true; | 416 FLAG_wasm_simd_prototype = true; |
333 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled); | 417 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled); |
334 byte a = 0; | 418 byte a = 0; |
335 byte b = 1; | 419 byte b = 1; |
336 byte expected = 2; | 420 byte expected = 2; |
337 byte simd0 = r.AllocateLocal(kWasmS128); | 421 byte simd0 = r.AllocateLocal(kWasmS128); |
338 byte simd1 = r.AllocateLocal(kWasmS128); | 422 byte simd1 = r.AllocateLocal(kWasmS128); |
339 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 423 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
340 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), | 424 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), |
341 WASM_SET_LOCAL(simd1, | 425 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
342 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), | 426 WASM_GET_LOCAL(simd1))), |
343 WASM_GET_LOCAL(simd1))), | |
344 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); | 427 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); |
345 | 428 |
346 FOR_FLOAT32_INPUTS(i) { | 429 FOR_FLOAT32_INPUTS(i) { |
347 if (std::isnan(*i)) continue; | 430 if (std::isnan(*i)) continue; |
348 FOR_FLOAT32_INPUTS(j) { | 431 FOR_FLOAT32_INPUTS(j) { |
349 if (std::isnan(*j)) continue; | 432 if (std::isnan(*j)) continue; |
350 // SIMD on some platforms may handle denormalized numbers differently. | 433 // SIMD on some platforms may handle denormalized numbers differently. |
351 // Check for number pairs that are very close together. | 434 // Check for number pairs that are very close together. |
352 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue; | 435 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue; |
353 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); | 436 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 } | 739 } |
657 } | 740 } |
658 | 741 |
659 void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { | 742 void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { |
660 FLAG_wasm_simd_prototype = true; | 743 FLAG_wasm_simd_prototype = true; |
661 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 744 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
662 byte a = 0; | 745 byte a = 0; |
663 byte expected = 1; | 746 byte expected = 1; |
664 byte simd = r.AllocateLocal(kWasmS128); | 747 byte simd = r.AllocateLocal(kWasmS128); |
665 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 748 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
666 WASM_SET_LOCAL(simd, | 749 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
667 WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | |
668 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); | 750 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); |
669 | 751 |
670 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } | 752 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } |
671 } | 753 } |
672 | 754 |
673 WASM_EXEC_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); } | 755 WASM_EXEC_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); } |
674 #endif // V8_TARGET_ARCH_ARM | 756 #endif // V8_TARGET_ARCH_ARM |
675 | 757 |
676 void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) { | 758 void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) { |
677 FLAG_wasm_simd_prototype = true; | 759 FLAG_wasm_simd_prototype = true; |
678 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 760 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
679 byte a = 0; | 761 byte a = 0; |
680 byte b = 1; | 762 byte b = 1; |
681 byte expected = 2; | 763 byte expected = 2; |
682 byte simd0 = r.AllocateLocal(kWasmS128); | 764 byte simd0 = r.AllocateLocal(kWasmS128); |
683 byte simd1 = r.AllocateLocal(kWasmS128); | 765 byte simd1 = r.AllocateLocal(kWasmS128); |
684 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 766 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
685 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))), | 767 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))), |
686 WASM_SET_LOCAL(simd1, | 768 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
687 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), | 769 WASM_GET_LOCAL(simd1))), |
688 WASM_GET_LOCAL(simd1))), | |
689 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); | 770 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); |
690 | 771 |
691 FOR_INT32_INPUTS(i) { | 772 FOR_INT32_INPUTS(i) { |
692 FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 773 FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
693 } | 774 } |
694 } | 775 } |
695 | 776 |
696 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } | 777 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } |
697 | 778 |
698 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } | 779 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } |
699 | 780 |
700 #if V8_TARGET_ARCH_ARM | 781 #if V8_TARGET_ARCH_ARM |
701 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); } | 782 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); } |
702 | 783 |
| 784 WASM_EXEC_TEST(I32x4Min) { RunI32x4BinOpTest(kExprI32x4MinS, Minimum); } |
| 785 |
| 786 WASM_EXEC_TEST(I32x4Max) { RunI32x4BinOpTest(kExprI32x4MaxS, Maximum); } |
| 787 |
703 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } | 788 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } |
704 | 789 |
705 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } | 790 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } |
706 | 791 |
707 WASM_EXEC_TEST(I32x4Greater) { RunI32x4BinOpTest(kExprI32x4GtS, Greater); } | 792 WASM_EXEC_TEST(I32x4Greater) { RunI32x4BinOpTest(kExprI32x4GtS, Greater); } |
708 | 793 |
709 WASM_EXEC_TEST(I32x4GreaterEqual) { | 794 WASM_EXEC_TEST(I32x4GreaterEqual) { |
710 RunI32x4BinOpTest(kExprI32x4GeS, GreaterEqual); | 795 RunI32x4BinOpTest(kExprI32x4GeS, GreaterEqual); |
711 } | 796 } |
712 | 797 |
713 WASM_EXEC_TEST(I32x4Less) { RunI32x4BinOpTest(kExprI32x4LtS, Less); } | 798 WASM_EXEC_TEST(I32x4Less) { RunI32x4BinOpTest(kExprI32x4LtS, Less); } |
714 | 799 |
715 WASM_EXEC_TEST(I32x4LessEqual) { RunI32x4BinOpTest(kExprI32x4LeS, LessEqual); } | 800 WASM_EXEC_TEST(I32x4LessEqual) { RunI32x4BinOpTest(kExprI32x4LeS, LessEqual); } |
716 | 801 |
| 802 WASM_EXEC_TEST(Ui32x4Min) { |
| 803 RunI32x4BinOpTest(kExprI32x4MinU, UnsignedMinimum); |
| 804 } |
| 805 |
| 806 WASM_EXEC_TEST(Ui32x4Max) { |
| 807 RunI32x4BinOpTest(kExprI32x4MaxU, UnsignedMaximum); |
| 808 } |
| 809 |
717 WASM_EXEC_TEST(Ui32x4Greater) { | 810 WASM_EXEC_TEST(Ui32x4Greater) { |
718 RunI32x4BinOpTest(kExprI32x4GtU, UnsignedGreater); | 811 RunI32x4BinOpTest(kExprI32x4GtU, UnsignedGreater); |
719 } | 812 } |
720 | 813 |
721 WASM_EXEC_TEST(Ui32x4GreaterEqual) { | 814 WASM_EXEC_TEST(Ui32x4GreaterEqual) { |
722 RunI32x4BinOpTest(kExprI32x4GeU, UnsignedGreaterEqual); | 815 RunI32x4BinOpTest(kExprI32x4GeU, UnsignedGreaterEqual); |
723 } | 816 } |
724 | 817 |
725 WASM_EXEC_TEST(Ui32x4Less) { RunI32x4BinOpTest(kExprI32x4LtU, UnsignedLess); } | 818 WASM_EXEC_TEST(Ui32x4Less) { RunI32x4BinOpTest(kExprI32x4LtU, UnsignedLess); } |
726 | 819 |
727 WASM_EXEC_TEST(Ui32x4LessEqual) { | 820 WASM_EXEC_TEST(Ui32x4LessEqual) { |
728 RunI32x4BinOpTest(kExprI32x4LeU, UnsignedLessEqual); | 821 RunI32x4BinOpTest(kExprI32x4LeU, UnsignedLessEqual); |
729 } | 822 } |
730 | 823 |
| 824 void RunI32x4ShiftOpTest(WasmOpcode simd_op, Int32ShiftOp expected_op, |
| 825 int shift) { |
| 826 FLAG_wasm_simd_prototype = true; |
| 827 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 828 byte a = 0; |
| 829 byte expected = 1; |
| 830 byte simd = r.AllocateLocal(kWasmS128); |
| 831 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 832 WASM_SET_LOCAL( |
| 833 simd, WASM_SIMD_SHIFT_OP(simd_op, WASM_GET_LOCAL(simd), shift)), |
| 834 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); |
| 835 |
| 836 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 837 } |
| 838 |
| 839 WASM_EXEC_TEST(I32x4Shl) { |
| 840 RunI32x4ShiftOpTest(kExprI32x4Shl, LogicalShiftLeft, 1); |
| 841 } |
| 842 |
| 843 WASM_EXEC_TEST(I32x4ShrS) { |
| 844 RunI32x4ShiftOpTest(kExprI32x4ShrS, ArithmeticShiftRight, 1); |
| 845 } |
| 846 |
| 847 WASM_EXEC_TEST(I32x4ShrU) { |
| 848 RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1); |
| 849 } |
| 850 |
731 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { | 851 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { |
732 FLAG_wasm_simd_prototype = true; | 852 FLAG_wasm_simd_prototype = true; |
733 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 853 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
734 byte a = 0; | 854 byte a = 0; |
735 byte expected = 1; | 855 byte expected = 1; |
736 byte simd = r.AllocateLocal(kWasmS128); | 856 byte simd = r.AllocateLocal(kWasmS128); |
737 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), | 857 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
738 WASM_SET_LOCAL(simd, | 858 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
739 WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | |
740 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE); | 859 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE); |
741 | 860 |
742 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } | 861 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } |
743 } | 862 } |
744 | 863 |
745 WASM_EXEC_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); } | 864 WASM_EXEC_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); } |
746 | 865 |
747 void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) { | 866 void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) { |
748 FLAG_wasm_simd_prototype = true; | 867 FLAG_wasm_simd_prototype = true; |
749 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 868 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
750 byte a = 0; | 869 byte a = 0; |
751 byte b = 1; | 870 byte b = 1; |
752 byte expected = 2; | 871 byte expected = 2; |
753 byte simd0 = r.AllocateLocal(kWasmS128); | 872 byte simd0 = r.AllocateLocal(kWasmS128); |
754 byte simd1 = r.AllocateLocal(kWasmS128); | 873 byte simd1 = r.AllocateLocal(kWasmS128); |
755 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), | 874 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
756 WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))), | 875 WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))), |
757 WASM_SET_LOCAL(simd1, | 876 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
758 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), | 877 WASM_GET_LOCAL(simd1))), |
759 WASM_GET_LOCAL(simd1))), | |
760 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), WASM_ONE); | 878 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), WASM_ONE); |
761 | 879 |
762 FOR_INT16_INPUTS(i) { | 880 FOR_INT16_INPUTS(i) { |
763 FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 881 FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
764 } | 882 } |
765 } | 883 } |
766 | 884 |
767 WASM_EXEC_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); } | 885 WASM_EXEC_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); } |
768 | 886 |
| 887 WASM_EXEC_TEST(I16x8AddSaturate) { |
| 888 RunI16x8BinOpTest(kExprI16x8AddSaturateS, AddSaturate); |
| 889 } |
| 890 |
769 WASM_EXEC_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); } | 891 WASM_EXEC_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); } |
770 | 892 |
| 893 WASM_EXEC_TEST(I16x8SubSaturate) { |
| 894 RunI16x8BinOpTest(kExprI16x8SubSaturateS, SubSaturate); |
| 895 } |
| 896 |
771 WASM_EXEC_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); } | 897 WASM_EXEC_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); } |
772 | 898 |
| 899 WASM_EXEC_TEST(I16x8Min) { RunI16x8BinOpTest(kExprI16x8MinS, Minimum); } |
| 900 |
| 901 WASM_EXEC_TEST(I16x8Max) { RunI16x8BinOpTest(kExprI16x8MaxS, Maximum); } |
| 902 |
773 WASM_EXEC_TEST(I16x8Equal) { RunI16x8BinOpTest(kExprI16x8Eq, Equal); } | 903 WASM_EXEC_TEST(I16x8Equal) { RunI16x8BinOpTest(kExprI16x8Eq, Equal); } |
774 | 904 |
775 WASM_EXEC_TEST(I16x8NotEqual) { RunI16x8BinOpTest(kExprI16x8Ne, NotEqual); } | 905 WASM_EXEC_TEST(I16x8NotEqual) { RunI16x8BinOpTest(kExprI16x8Ne, NotEqual); } |
776 | 906 |
777 WASM_EXEC_TEST(I16x8Greater) { RunI16x8BinOpTest(kExprI16x8GtS, Greater); } | 907 WASM_EXEC_TEST(I16x8Greater) { RunI16x8BinOpTest(kExprI16x8GtS, Greater); } |
778 | 908 |
779 WASM_EXEC_TEST(I16x8GreaterEqual) { | 909 WASM_EXEC_TEST(I16x8GreaterEqual) { |
780 RunI16x8BinOpTest(kExprI16x8GeS, GreaterEqual); | 910 RunI16x8BinOpTest(kExprI16x8GeS, GreaterEqual); |
781 } | 911 } |
782 | 912 |
783 WASM_EXEC_TEST(I16x8Less) { RunI16x8BinOpTest(kExprI16x8LtS, Less); } | 913 WASM_EXEC_TEST(I16x8Less) { RunI16x8BinOpTest(kExprI16x8LtS, Less); } |
784 | 914 |
785 WASM_EXEC_TEST(I16x8LessEqual) { RunI16x8BinOpTest(kExprI16x8LeS, LessEqual); } | 915 WASM_EXEC_TEST(I16x8LessEqual) { RunI16x8BinOpTest(kExprI16x8LeS, LessEqual); } |
786 | 916 |
| 917 WASM_EXEC_TEST(Ui16x8AddSaturate) { |
| 918 RunI16x8BinOpTest(kExprI16x8AddSaturateU, UnsignedAddSaturate); |
| 919 } |
| 920 |
| 921 WASM_EXEC_TEST(Ui16x8SubSaturate) { |
| 922 RunI16x8BinOpTest(kExprI16x8SubSaturateU, UnsignedSubSaturate); |
| 923 } |
| 924 |
| 925 WASM_EXEC_TEST(Ui16x8Min) { |
| 926 RunI16x8BinOpTest(kExprI16x8MinU, UnsignedMinimum); |
| 927 } |
| 928 |
| 929 WASM_EXEC_TEST(Ui16x8Max) { |
| 930 RunI16x8BinOpTest(kExprI16x8MaxU, UnsignedMaximum); |
| 931 } |
| 932 |
787 WASM_EXEC_TEST(Ui16x8Greater) { | 933 WASM_EXEC_TEST(Ui16x8Greater) { |
788 RunI16x8BinOpTest(kExprI16x8GtU, UnsignedGreater); | 934 RunI16x8BinOpTest(kExprI16x8GtU, UnsignedGreater); |
789 } | 935 } |
790 | 936 |
791 WASM_EXEC_TEST(Ui16x8GreaterEqual) { | 937 WASM_EXEC_TEST(Ui16x8GreaterEqual) { |
792 RunI16x8BinOpTest(kExprI16x8GeU, UnsignedGreaterEqual); | 938 RunI16x8BinOpTest(kExprI16x8GeU, UnsignedGreaterEqual); |
793 } | 939 } |
794 | 940 |
795 WASM_EXEC_TEST(Ui16x8Less) { RunI16x8BinOpTest(kExprI16x8LtU, UnsignedLess); } | 941 WASM_EXEC_TEST(Ui16x8Less) { RunI16x8BinOpTest(kExprI16x8LtU, UnsignedLess); } |
796 | 942 |
797 WASM_EXEC_TEST(Ui16x8LessEqual) { | 943 WASM_EXEC_TEST(Ui16x8LessEqual) { |
798 RunI16x8BinOpTest(kExprI16x8LeU, UnsignedLessEqual); | 944 RunI16x8BinOpTest(kExprI16x8LeU, UnsignedLessEqual); |
799 } | 945 } |
800 | 946 |
| 947 void RunI16x8ShiftOpTest(WasmOpcode simd_op, Int16ShiftOp expected_op, |
| 948 int shift) { |
| 949 FLAG_wasm_simd_prototype = true; |
| 950 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 951 byte a = 0; |
| 952 byte expected = 1; |
| 953 byte simd = r.AllocateLocal(kWasmS128); |
| 954 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
| 955 WASM_SET_LOCAL( |
| 956 simd, WASM_SIMD_SHIFT_OP(simd_op, WASM_GET_LOCAL(simd), shift)), |
| 957 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE); |
| 958 |
| 959 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 960 } |
| 961 |
| 962 WASM_EXEC_TEST(I16x8Shl) { |
| 963 RunI16x8ShiftOpTest(kExprI16x8Shl, LogicalShiftLeft, 1); |
| 964 } |
| 965 |
| 966 WASM_EXEC_TEST(I16x8ShrS) { |
| 967 RunI16x8ShiftOpTest(kExprI16x8ShrS, ArithmeticShiftRight, 1); |
| 968 } |
| 969 |
| 970 WASM_EXEC_TEST(I16x8ShrU) { |
| 971 RunI16x8ShiftOpTest(kExprI16x8ShrU, LogicalShiftRight, 1); |
| 972 } |
| 973 |
801 void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) { | 974 void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) { |
802 FLAG_wasm_simd_prototype = true; | 975 FLAG_wasm_simd_prototype = true; |
803 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 976 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
804 byte a = 0; | 977 byte a = 0; |
805 byte expected = 1; | 978 byte expected = 1; |
806 byte simd = r.AllocateLocal(kWasmS128); | 979 byte simd = r.AllocateLocal(kWasmS128); |
807 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), | 980 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
808 WASM_SET_LOCAL(simd, | 981 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
809 WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | |
810 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE); | 982 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE); |
811 | 983 |
812 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } | 984 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } |
813 } | 985 } |
814 | 986 |
815 WASM_EXEC_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); } | 987 WASM_EXEC_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); } |
816 | 988 |
817 void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) { | 989 void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) { |
818 FLAG_wasm_simd_prototype = true; | 990 FLAG_wasm_simd_prototype = true; |
819 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 991 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
820 byte a = 0; | 992 byte a = 0; |
821 byte b = 1; | 993 byte b = 1; |
822 byte expected = 2; | 994 byte expected = 2; |
823 byte simd0 = r.AllocateLocal(kWasmS128); | 995 byte simd0 = r.AllocateLocal(kWasmS128); |
824 byte simd1 = r.AllocateLocal(kWasmS128); | 996 byte simd1 = r.AllocateLocal(kWasmS128); |
825 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), | 997 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
826 WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))), | 998 WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))), |
827 WASM_SET_LOCAL(simd1, | 999 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
828 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), | 1000 WASM_GET_LOCAL(simd1))), |
829 WASM_GET_LOCAL(simd1))), | |
830 WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), WASM_ONE); | 1001 WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), WASM_ONE); |
831 | 1002 |
832 FOR_INT8_INPUTS(i) { | 1003 FOR_INT8_INPUTS(i) { |
833 FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 1004 FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
834 } | 1005 } |
835 } | 1006 } |
836 | 1007 |
837 WASM_EXEC_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); } | 1008 WASM_EXEC_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); } |
838 | 1009 |
| 1010 WASM_EXEC_TEST(I8x16AddSaturate) { |
| 1011 RunI8x16BinOpTest(kExprI8x16AddSaturateS, AddSaturate); |
| 1012 } |
| 1013 |
839 WASM_EXEC_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); } | 1014 WASM_EXEC_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); } |
840 | 1015 |
| 1016 WASM_EXEC_TEST(I8x16SubSaturate) { |
| 1017 RunI8x16BinOpTest(kExprI8x16SubSaturateS, SubSaturate); |
| 1018 } |
| 1019 |
841 WASM_EXEC_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); } | 1020 WASM_EXEC_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); } |
842 | 1021 |
| 1022 WASM_EXEC_TEST(I8x16Min) { RunI8x16BinOpTest(kExprI8x16MinS, Minimum); } |
| 1023 |
| 1024 WASM_EXEC_TEST(I8x16Max) { RunI8x16BinOpTest(kExprI8x16MaxS, Maximum); } |
| 1025 |
843 WASM_EXEC_TEST(I8x16Equal) { RunI8x16BinOpTest(kExprI8x16Eq, Equal); } | 1026 WASM_EXEC_TEST(I8x16Equal) { RunI8x16BinOpTest(kExprI8x16Eq, Equal); } |
844 | 1027 |
845 WASM_EXEC_TEST(I8x16NotEqual) { RunI8x16BinOpTest(kExprI8x16Ne, NotEqual); } | 1028 WASM_EXEC_TEST(I8x16NotEqual) { RunI8x16BinOpTest(kExprI8x16Ne, NotEqual); } |
846 | 1029 |
847 WASM_EXEC_TEST(I8x16Greater) { RunI8x16BinOpTest(kExprI8x16GtS, Greater); } | 1030 WASM_EXEC_TEST(I8x16Greater) { RunI8x16BinOpTest(kExprI8x16GtS, Greater); } |
848 | 1031 |
849 WASM_EXEC_TEST(I8x16GreaterEqual) { | 1032 WASM_EXEC_TEST(I8x16GreaterEqual) { |
850 RunI8x16BinOpTest(kExprI8x16GeS, GreaterEqual); | 1033 RunI8x16BinOpTest(kExprI8x16GeS, GreaterEqual); |
851 } | 1034 } |
852 | 1035 |
853 WASM_EXEC_TEST(I8x16Less) { RunI8x16BinOpTest(kExprI8x16LtS, Less); } | 1036 WASM_EXEC_TEST(I8x16Less) { RunI8x16BinOpTest(kExprI8x16LtS, Less); } |
854 | 1037 |
855 WASM_EXEC_TEST(I8x16LessEqual) { RunI8x16BinOpTest(kExprI8x16LeS, LessEqual); } | 1038 WASM_EXEC_TEST(I8x16LessEqual) { RunI8x16BinOpTest(kExprI8x16LeS, LessEqual); } |
856 | 1039 |
| 1040 WASM_EXEC_TEST(Ui8x16AddSaturate) { |
| 1041 RunI8x16BinOpTest(kExprI8x16AddSaturateU, UnsignedAddSaturate); |
| 1042 } |
| 1043 |
| 1044 WASM_EXEC_TEST(Ui8x16SubSaturate) { |
| 1045 RunI8x16BinOpTest(kExprI8x16SubSaturateU, UnsignedSubSaturate); |
| 1046 } |
| 1047 |
| 1048 WASM_EXEC_TEST(Ui8x16Min) { |
| 1049 RunI8x16BinOpTest(kExprI8x16MinU, UnsignedMinimum); |
| 1050 } |
| 1051 |
| 1052 WASM_EXEC_TEST(Ui8x16Max) { |
| 1053 RunI8x16BinOpTest(kExprI8x16MaxU, UnsignedMaximum); |
| 1054 } |
| 1055 |
857 WASM_EXEC_TEST(Ui8x16Greater) { | 1056 WASM_EXEC_TEST(Ui8x16Greater) { |
858 RunI8x16BinOpTest(kExprI8x16GtU, UnsignedGreater); | 1057 RunI8x16BinOpTest(kExprI8x16GtU, UnsignedGreater); |
859 } | 1058 } |
860 | 1059 |
861 WASM_EXEC_TEST(Ui8x16GreaterEqual) { | 1060 WASM_EXEC_TEST(Ui8x16GreaterEqual) { |
862 RunI8x16BinOpTest(kExprI8x16GeU, UnsignedGreaterEqual); | 1061 RunI8x16BinOpTest(kExprI8x16GeU, UnsignedGreaterEqual); |
863 } | 1062 } |
864 | 1063 |
865 WASM_EXEC_TEST(Ui8x16Less) { RunI8x16BinOpTest(kExprI8x16LtU, UnsignedLess); } | 1064 WASM_EXEC_TEST(Ui8x16Less) { RunI8x16BinOpTest(kExprI8x16LtU, UnsignedLess); } |
866 | 1065 |
867 WASM_EXEC_TEST(Ui8x16LessEqual) { | 1066 WASM_EXEC_TEST(Ui8x16LessEqual) { |
868 RunI8x16BinOpTest(kExprI8x16LeU, UnsignedLessEqual); | 1067 RunI8x16BinOpTest(kExprI8x16LeU, UnsignedLessEqual); |
869 } | 1068 } |
| 1069 |
| 1070 void RunI8x16ShiftOpTest(WasmOpcode simd_op, Int8ShiftOp expected_op, |
| 1071 int shift) { |
| 1072 FLAG_wasm_simd_prototype = true; |
| 1073 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1074 byte a = 0; |
| 1075 byte expected = 1; |
| 1076 byte simd = r.AllocateLocal(kWasmS128); |
| 1077 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
| 1078 WASM_SET_LOCAL( |
| 1079 simd, WASM_SIMD_SHIFT_OP(simd_op, WASM_GET_LOCAL(simd), shift)), |
| 1080 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE); |
| 1081 |
| 1082 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 1083 } |
| 1084 |
| 1085 WASM_EXEC_TEST(I8x16Shl) { |
| 1086 RunI8x16ShiftOpTest(kExprI8x16Shl, LogicalShiftLeft, 1); |
| 1087 } |
| 1088 |
| 1089 WASM_EXEC_TEST(I8x16ShrS) { |
| 1090 RunI8x16ShiftOpTest(kExprI8x16ShrS, ArithmeticShiftRight, 1); |
| 1091 } |
| 1092 |
| 1093 WASM_EXEC_TEST(I8x16ShrU) { |
| 1094 RunI8x16ShiftOpTest(kExprI8x16ShrU, LogicalShiftRight, 1); |
| 1095 } |
870 #endif // V8_TARGET_ARCH_ARM | 1096 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |