Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/assembler-inl.h"
6 : #include "test/cctest/cctest.h"
7 : #include "test/cctest/compiler/value-helper.h"
8 : #include "test/cctest/wasm/wasm-run-utils.h"
9 : #include "test/common/wasm/wasm-macro-gen.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace wasm {
14 : namespace test_run_wasm_simd {
15 :
16 : namespace {
17 :
18 : typedef float (*FloatUnOp)(float);
19 : typedef float (*FloatBinOp)(float, float);
20 : typedef int (*FloatCompareOp)(float, float);
21 : typedef int32_t (*Int32UnOp)(int32_t);
22 : typedef int32_t (*Int32BinOp)(int32_t, int32_t);
23 : typedef int (*Int32CompareOp)(int32_t, int32_t);
24 : typedef int32_t (*Int32ShiftOp)(int32_t, int);
25 : typedef int16_t (*Int16UnOp)(int16_t);
26 : typedef int16_t (*Int16BinOp)(int16_t, int16_t);
27 : typedef int (*Int16CompareOp)(int16_t, int16_t);
28 : typedef int16_t (*Int16ShiftOp)(int16_t, int);
29 : typedef int8_t (*Int8UnOp)(int8_t);
30 : typedef int8_t (*Int8BinOp)(int8_t, int8_t);
31 : typedef int (*Int8CompareOp)(int8_t, int8_t);
32 : typedef int8_t (*Int8ShiftOp)(int8_t, int);
33 :
34 : #define WASM_SIMD_TEST(name) \
35 : void RunWasm_##name##_Impl(WasmExecutionMode execution_mode); \
36 : TEST(RunWasm_##name##_compiled) { \
37 : EXPERIMENTAL_FLAG_SCOPE(simd); \
38 : RunWasm_##name##_Impl(kExecuteCompiled); \
39 : } \
40 : TEST(RunWasm_##name##_simd_lowered) { \
41 : EXPERIMENTAL_FLAG_SCOPE(simd); \
42 : RunWasm_##name##_Impl(kExecuteSimdLowered); \
43 : } \
44 : void RunWasm_##name##_Impl(WasmExecutionMode execution_mode)
45 :
46 : #define WASM_SIMD_COMPILED_TEST(name) \
47 : void RunWasm_##name##_Impl(WasmExecutionMode execution_mode); \
48 : TEST(RunWasm_##name##_compiled) { \
49 : EXPERIMENTAL_FLAG_SCOPE(simd); \
50 : RunWasm_##name##_Impl(kExecuteCompiled); \
51 : } \
52 : void RunWasm_##name##_Impl(WasmExecutionMode execution_mode)
53 :
54 : // Generic expected value functions.
55 : template <typename T>
56 912 : T Negate(T a) {
57 912 : return -a;
58 : }
59 :
60 : template <typename T>
61 42312 : T Add(T a, T b) {
62 42312 : return a + b;
63 : }
64 :
65 : template <typename T>
66 42312 : T Sub(T a, T b) {
67 42312 : return a - b;
68 : }
69 :
70 : template <typename T>
71 41340 : T Mul(T a, T b) {
72 41340 : return a * b;
73 : }
74 :
75 : template <typename T>
76 : T Div(T a, T b) {
77 : return a / b;
78 : }
79 :
80 : template <typename T>
81 42312 : T Minimum(T a, T b) {
82 42312 : return a <= b ? a : b;
83 : }
84 :
85 : template <typename T>
86 42312 : T Maximum(T a, T b) {
87 42312 : return a >= b ? a : b;
88 : }
89 :
90 : template <typename T>
91 42312 : T UnsignedMinimum(T a, T b) {
92 : using UnsignedT = typename std::make_unsigned<T>::type;
93 42312 : return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? a : b;
94 : }
95 :
96 : template <typename T>
97 42312 : T UnsignedMaximum(T a, T b) {
98 : using UnsignedT = typename std::make_unsigned<T>::type;
99 42312 : return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? a : b;
100 : }
101 :
102 : template <typename T>
103 42312 : int Equal(T a, T b) {
104 42312 : return a == b ? -1 : 0;
105 : }
106 :
107 : template <typename T>
108 42312 : int NotEqual(T a, T b) {
109 42312 : return a != b ? -1 : 0;
110 : }
111 :
112 : template <typename T>
113 42312 : int Less(T a, T b) {
114 42312 : return a < b ? -1 : 0;
115 : }
116 :
117 : template <typename T>
118 42312 : int LessEqual(T a, T b) {
119 42312 : return a <= b ? -1 : 0;
120 : }
121 :
122 : template <typename T>
123 42312 : int Greater(T a, T b) {
124 42312 : return a > b ? -1 : 0;
125 : }
126 :
127 : template <typename T>
128 42312 : int GreaterEqual(T a, T b) {
129 42312 : return a >= b ? -1 : 0;
130 : }
131 :
132 : template <typename T>
133 42312 : int UnsignedLess(T a, T b) {
134 : using UnsignedT = typename std::make_unsigned<T>::type;
135 42312 : return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? -1 : 0;
136 : }
137 :
138 : template <typename T>
139 42312 : int UnsignedLessEqual(T a, T b) {
140 : using UnsignedT = typename std::make_unsigned<T>::type;
141 42312 : return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? -1 : 0;
142 : }
143 :
144 : template <typename T>
145 42312 : int UnsignedGreater(T a, T b) {
146 : using UnsignedT = typename std::make_unsigned<T>::type;
147 42312 : return static_cast<UnsignedT>(a) > static_cast<UnsignedT>(b) ? -1 : 0;
148 : }
149 :
150 : template <typename T>
151 42312 : int UnsignedGreaterEqual(T a, T b) {
152 : using UnsignedT = typename std::make_unsigned<T>::type;
153 42312 : return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? -1 : 0;
154 : }
155 :
156 : template <typename T>
157 804 : T LogicalShiftLeft(T a, int shift) {
158 804 : return a << shift;
159 : }
160 :
161 : template <typename T>
162 804 : T LogicalShiftRight(T a, int shift) {
163 : using UnsignedT = typename std::make_unsigned<T>::type;
164 804 : return static_cast<UnsignedT>(a) >> shift;
165 : }
166 :
167 : template <typename T>
168 : T Clamp(int64_t value) {
169 : static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
170 7776 : int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min());
171 7776 : int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max());
172 7776 : int64_t clamped = std::max(min, std::min(max, value));
173 7776 : return static_cast<T>(clamped);
174 : }
175 :
176 : template <typename T>
177 : int64_t Widen(T value) {
178 : static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
179 3888 : return static_cast<int64_t>(value);
180 : }
181 :
182 : template <typename T>
183 : int64_t UnsignedWiden(T value) {
184 : static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
185 : using UnsignedT = typename std::make_unsigned<T>::type;
186 3888 : return static_cast<int64_t>(static_cast<UnsignedT>(value));
187 : }
188 :
189 : template <typename T>
190 : T Narrow(int64_t value) {
191 : return Clamp<T>(value);
192 : }
193 :
194 : template <typename T>
195 : T UnsignedNarrow(int64_t value) {
196 : static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
197 : using UnsignedT = typename std::make_unsigned<T>::type;
198 : return static_cast<T>(Clamp<UnsignedT>(value & 0xffffffffu));
199 : }
200 :
201 : template <typename T>
202 1944 : T AddSaturate(T a, T b) {
203 3888 : return Clamp<T>(Widen(a) + Widen(b));
204 : }
205 :
206 : template <typename T>
207 1944 : T SubSaturate(T a, T b) {
208 3888 : return Clamp<T>(Widen(a) - Widen(b));
209 : }
210 :
211 : template <typename T>
212 1944 : T UnsignedAddSaturate(T a, T b) {
213 : using UnsignedT = typename std::make_unsigned<T>::type;
214 3888 : return Clamp<UnsignedT>(UnsignedWiden(a) + UnsignedWiden(b));
215 : }
216 :
217 : template <typename T>
218 1944 : T UnsignedSubSaturate(T a, T b) {
219 : using UnsignedT = typename std::make_unsigned<T>::type;
220 3888 : return Clamp<UnsignedT>(UnsignedWiden(a) - UnsignedWiden(b));
221 : }
222 :
223 : template <typename T>
224 40368 : T And(T a, T b) {
225 40368 : return a & b;
226 : }
227 :
228 : template <typename T>
229 40368 : T Or(T a, T b) {
230 40368 : return a | b;
231 : }
232 :
233 : template <typename T>
234 40368 : T Xor(T a, T b) {
235 40368 : return a ^ b;
236 : }
237 :
238 : template <typename T>
239 696 : T Not(T a) {
240 696 : return ~a;
241 : }
242 :
243 : template <typename T>
244 : T LogicalNot(T a) {
245 : return a == 0 ? -1 : 0;
246 : }
247 :
248 : template <typename T>
249 : T Sqrt(T a) {
250 : return std::sqrt(a);
251 : }
252 :
253 : template <typename T>
254 : T Recip(T a) {
255 : return 1.0f / a;
256 : }
257 :
258 : template <typename T>
259 : T RecipSqrt(T a) {
260 : return 1.0f / std::sqrt(a);
261 : }
262 :
263 : } // namespace
264 :
265 : #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
266 : WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
267 : WASM_SIMD_##TYPE##_EXTRACT_LANE( \
268 : lane_index, WASM_GET_LOCAL(value))), \
269 : WASM_RETURN1(WASM_ZERO))
270 :
271 : #define WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3) \
272 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
273 : , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
274 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
275 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3)
276 :
277 : #define WASM_SIMD_CHECK_SPLAT4(TYPE, value, LANE_TYPE, lv) \
278 : WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv, lv, lv, lv)
279 :
280 : #define WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, lv5, \
281 : lv6, lv7) \
282 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
283 : , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
284 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
285 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
286 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
287 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
288 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
289 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7)
290 :
291 : #define WASM_SIMD_CHECK_SPLAT8(TYPE, value, LANE_TYPE, lv) \
292 : WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv)
293 :
294 : #define WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, \
295 : lv5, lv6, lv7, lv8, lv9, lv10, lv11, lv12, lv13, \
296 : lv14, lv15) \
297 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
298 : , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
299 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
300 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
301 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
302 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
303 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
304 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7), \
305 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv8, 8), \
306 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv9, 9), \
307 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv10, 10), \
308 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv11, 11), \
309 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv12, 12), \
310 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv13, 13), \
311 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv14, 14), \
312 : WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv15, 15)
313 :
314 : #define WASM_SIMD_CHECK_SPLAT16(TYPE, value, LANE_TYPE, lv) \
315 : WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv, \
316 : lv, lv, lv, lv, lv, lv, lv, lv)
317 :
318 : #define WASM_SIMD_CHECK_F32_LANE(value, lane_value, lane_index) \
319 : WASM_IF(WASM_F32_NE(WASM_GET_LOCAL(lane_value), \
320 : WASM_SIMD_F32x4_EXTRACT_LANE(lane_index, \
321 : WASM_GET_LOCAL(value))), \
322 : WASM_RETURN1(WASM_ZERO))
323 :
324 : #define WASM_SIMD_CHECK_F32x4(value, lv0, lv1, lv2, lv3) \
325 : WASM_SIMD_CHECK_F32_LANE(value, lv0, 0) \
326 : , WASM_SIMD_CHECK_F32_LANE(value, lv1, 1), \
327 : WASM_SIMD_CHECK_F32_LANE(value, lv2, 2), \
328 : WASM_SIMD_CHECK_F32_LANE(value, lv3, 3)
329 :
330 : #define WASM_SIMD_CHECK_SPLAT_F32x4(value, lv) \
331 : WASM_SIMD_CHECK_F32x4(value, lv, lv, lv, lv)
332 :
333 : #define WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, lane_index) \
334 : WASM_IF(WASM_F32_GT(WASM_GET_LOCAL(low), \
335 : WASM_SIMD_F32x4_EXTRACT_LANE(lane_index, \
336 : WASM_GET_LOCAL(value))), \
337 : WASM_RETURN1(WASM_ZERO)) \
338 : , WASM_IF(WASM_F32_LT(WASM_GET_LOCAL(high), \
339 : WASM_SIMD_F32x4_EXTRACT_LANE(lane_index, \
340 : WASM_GET_LOCAL(value))), \
341 : WASM_RETURN1(WASM_ZERO))
342 :
343 : #define WASM_SIMD_CHECK_SPLAT_F32x4_ESTIMATE(value, low, high) \
344 : WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 0) \
345 : , WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 1), \
346 : WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 2), \
347 : WASM_SIMD_CHECK_F32_LANE_ESTIMATE(value, low, high, 3)
348 :
349 : #define TO_BYTE(val) static_cast<byte>(val)
350 : #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op)
351 : #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat)
352 : #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op)
353 : #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op)
354 : #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift)
355 : #define WASM_SIMD_CONCAT_OP(op, bytes, x, y) \
356 : x, y, WASM_SIMD_OP(op), TO_BYTE(bytes)
357 : #define WASM_SIMD_SELECT(format, x, y, z) x, y, z, WASM_SIMD_OP(kExprS128Select)
358 : #define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat)
359 : #define WASM_SIMD_F32x4_EXTRACT_LANE(lane, x) \
360 : x, WASM_SIMD_OP(kExprF32x4ExtractLane), TO_BYTE(lane)
361 : #define WASM_SIMD_F32x4_REPLACE_LANE(lane, x, y) \
362 : x, y, WASM_SIMD_OP(kExprF32x4ReplaceLane), TO_BYTE(lane)
363 :
364 : #define WASM_SIMD_I32x4_SPLAT(x) x, WASM_SIMD_OP(kExprI32x4Splat)
365 : #define WASM_SIMD_I32x4_EXTRACT_LANE(lane, x) \
366 : x, WASM_SIMD_OP(kExprI32x4ExtractLane), TO_BYTE(lane)
367 : #define WASM_SIMD_I32x4_REPLACE_LANE(lane, x, y) \
368 : x, y, WASM_SIMD_OP(kExprI32x4ReplaceLane), TO_BYTE(lane)
369 :
370 : #define WASM_SIMD_I16x8_SPLAT(x) x, WASM_SIMD_OP(kExprI16x8Splat)
371 : #define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \
372 : x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane)
373 : #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \
374 : x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane)
375 :
376 : #define WASM_SIMD_I8x16_SPLAT(x) x, WASM_SIMD_OP(kExprI8x16Splat)
377 : #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \
378 : x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane)
379 : #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \
380 : x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane)
381 :
382 : #define WASM_SIMD_S8x16_SHUFFLE_OP(opcode, m, x, y) \
383 : x, y, WASM_SIMD_OP(opcode), TO_BYTE(m[0]), TO_BYTE(m[1]), TO_BYTE(m[2]), \
384 : TO_BYTE(m[3]), TO_BYTE(m[4]), TO_BYTE(m[5]), TO_BYTE(m[6]), \
385 : TO_BYTE(m[7]), TO_BYTE(m[8]), TO_BYTE(m[9]), TO_BYTE(m[10]), \
386 : TO_BYTE(m[11]), TO_BYTE(m[12]), TO_BYTE(m[13]), TO_BYTE(m[14]), \
387 : TO_BYTE(m[15])
388 :
389 : #define WASM_SIMD_LOAD_MEM(index) \
390 : index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, ZERO_OFFSET
391 : #define WASM_SIMD_STORE_MEM(index, val) \
392 : index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, ZERO_OFFSET
393 :
394 : // Skip FP tests involving extremely large or extremely small values, which
395 : // may fail due to non-IEEE-754 SIMD arithmetic on some platforms.
396 0 : bool SkipFPValue(float x) {
397 : float abs_x = std::fabs(x);
398 : const float kSmallFloatThreshold = 1.0e-32f;
399 : const float kLargeFloatThreshold = 1.0e32f;
400 0 : return abs_x != 0.0f && // 0 or -0 are fine.
401 0 : (abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold);
402 : }
403 :
404 : // Skip tests where the expected value is a NaN, since our wasm test code
405 : // doesn't handle NaNs. Also skip extreme values.
406 0 : bool SkipFPExpectedValue(float x) { return std::isnan(x) || SkipFPValue(x); }
407 :
408 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
409 : V8_TARGET_ARCH_MIPS64
410 : WASM_SIMD_TEST(F32x4Splat) {
411 : WasmRunner<int32_t, float> r(execution_mode);
412 : byte lane_val = 0;
413 : byte simd = r.AllocateLocal(kWasmS128);
414 : BUILD(r,
415 : WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
416 : WASM_SIMD_CHECK_SPLAT_F32x4(simd, lane_val), WASM_RETURN1(WASM_ONE));
417 :
418 : FOR_FLOAT32_INPUTS(i) {
419 : if (SkipFPExpectedValue(*i)) continue;
420 : CHECK_EQ(1, r.Call(*i));
421 : }
422 : }
423 :
424 : WASM_SIMD_TEST(F32x4ReplaceLane) {
425 : WasmRunner<int32_t, float, float> r(execution_mode);
426 : byte old_val = 0;
427 : byte new_val = 1;
428 : byte simd = r.AllocateLocal(kWasmS128);
429 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(old_val))),
430 : WASM_SET_LOCAL(simd,
431 : WASM_SIMD_F32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
432 : WASM_GET_LOCAL(new_val))),
433 : WASM_SIMD_CHECK_F32x4(simd, new_val, old_val, old_val, old_val),
434 : WASM_SET_LOCAL(simd,
435 : WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
436 : WASM_GET_LOCAL(new_val))),
437 : WASM_SIMD_CHECK_F32x4(simd, new_val, new_val, old_val, old_val),
438 : WASM_SET_LOCAL(simd,
439 : WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
440 : WASM_GET_LOCAL(new_val))),
441 : WASM_SIMD_CHECK_F32x4(simd, new_val, new_val, new_val, old_val),
442 : WASM_SET_LOCAL(simd,
443 : WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
444 : WASM_GET_LOCAL(new_val))),
445 : WASM_SIMD_CHECK_SPLAT_F32x4(simd, new_val), WASM_RETURN1(WASM_ONE));
446 :
447 : CHECK_EQ(1, r.Call(3.14159f, -1.5f));
448 : }
449 :
450 : // Tests both signed and unsigned conversion.
451 : WASM_SIMD_TEST(F32x4ConvertI32x4) {
452 : WasmRunner<int32_t, int32_t, float, float> r(execution_mode);
453 : byte a = 0;
454 : byte expected_signed = 1;
455 : byte expected_unsigned = 2;
456 : byte simd0 = r.AllocateLocal(kWasmS128);
457 : byte simd1 = r.AllocateLocal(kWasmS128);
458 : byte simd2 = r.AllocateLocal(kWasmS128);
459 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
460 : WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprF32x4SConvertI32x4,
461 : WASM_GET_LOCAL(simd0))),
462 : WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected_signed),
463 : WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprF32x4UConvertI32x4,
464 : WASM_GET_LOCAL(simd0))),
465 : WASM_SIMD_CHECK_SPLAT_F32x4(simd2, expected_unsigned),
466 : WASM_RETURN1(WASM_ONE));
467 :
468 : FOR_INT32_INPUTS(i) {
469 : CHECK_EQ(1, r.Call(*i, static_cast<float>(*i),
470 : static_cast<float>(static_cast<uint32_t>(*i))));
471 : }
472 : }
473 :
474 : void RunF32x4UnOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
475 : FloatUnOp expected_op, float error = 0.0f) {
476 : WasmRunner<int32_t, float, float, float> r(execution_mode);
477 : byte a = 0;
478 : byte low = 1;
479 : byte high = 2;
480 : byte simd = r.AllocateLocal(kWasmS128);
481 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
482 : WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))),
483 : WASM_SIMD_CHECK_SPLAT_F32x4_ESTIMATE(simd, low, high),
484 : WASM_RETURN1(WASM_ONE));
485 :
486 : FOR_FLOAT32_INPUTS(i) {
487 : if (SkipFPValue(*i)) continue;
488 : float expected = expected_op(*i);
489 : if (SkipFPExpectedValue(expected)) continue;
490 : float abs_error = std::abs(expected) * error;
491 : CHECK_EQ(1, r.Call(*i, expected - abs_error, expected + abs_error));
492 : }
493 : }
494 :
495 : WASM_SIMD_TEST(F32x4Abs) {
496 : RunF32x4UnOpTest(execution_mode, kExprF32x4Abs, std::abs);
497 : }
498 : WASM_SIMD_TEST(F32x4Neg) {
499 : RunF32x4UnOpTest(execution_mode, kExprF32x4Neg, Negate);
500 : }
501 :
502 : static const float kApproxError = 0.01f;
503 :
504 : WASM_SIMD_COMPILED_TEST(F32x4RecipApprox) {
505 : RunF32x4UnOpTest(execution_mode, kExprF32x4RecipApprox, Recip, kApproxError);
506 : }
507 :
508 : WASM_SIMD_COMPILED_TEST(F32x4RecipSqrtApprox) {
509 : RunF32x4UnOpTest(execution_mode, kExprF32x4RecipSqrtApprox, RecipSqrt,
510 : kApproxError);
511 : }
512 :
513 : void RunF32x4BinOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
514 : FloatBinOp expected_op) {
515 : WasmRunner<int32_t, float, float, float> r(execution_mode);
516 : byte a = 0;
517 : byte b = 1;
518 : byte expected = 2;
519 : byte simd0 = r.AllocateLocal(kWasmS128);
520 : byte simd1 = r.AllocateLocal(kWasmS128);
521 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
522 : WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))),
523 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
524 : WASM_GET_LOCAL(simd1))),
525 : WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected), WASM_RETURN1(WASM_ONE));
526 :
527 : FOR_FLOAT32_INPUTS(i) {
528 : if (SkipFPValue(*i)) continue;
529 : FOR_FLOAT32_INPUTS(j) {
530 : if (SkipFPValue(*j)) continue;
531 : float expected = expected_op(*i, *j);
532 : if (SkipFPExpectedValue(expected)) continue;
533 : CHECK_EQ(1, r.Call(*i, *j, expected));
534 : }
535 : }
536 : }
537 :
538 : WASM_SIMD_TEST(F32x4Add) {
539 : RunF32x4BinOpTest(execution_mode, kExprF32x4Add, Add);
540 : }
541 : WASM_SIMD_TEST(F32x4Sub) {
542 : RunF32x4BinOpTest(execution_mode, kExprF32x4Sub, Sub);
543 : }
544 : WASM_SIMD_TEST(F32x4Mul) {
545 : RunF32x4BinOpTest(execution_mode, kExprF32x4Mul, Mul);
546 : }
547 : WASM_SIMD_TEST(F32x4_Min) {
548 : RunF32x4BinOpTest(execution_mode, kExprF32x4Min, JSMin);
549 : }
550 : WASM_SIMD_TEST(F32x4_Max) {
551 : RunF32x4BinOpTest(execution_mode, kExprF32x4Max, JSMax);
552 : }
553 :
554 : void RunF32x4CompareOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
555 : FloatCompareOp expected_op) {
556 : WasmRunner<int32_t, float, float, int32_t> r(execution_mode);
557 : byte a = 0;
558 : byte b = 1;
559 : byte expected = 2;
560 : byte simd0 = r.AllocateLocal(kWasmS128);
561 : byte simd1 = r.AllocateLocal(kWasmS128);
562 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
563 : WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))),
564 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
565 : WASM_GET_LOCAL(simd1))),
566 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
567 :
568 : FOR_FLOAT32_INPUTS(i) {
569 : if (SkipFPValue(*i)) continue;
570 : FOR_FLOAT32_INPUTS(j) {
571 : if (SkipFPValue(*j)) continue;
572 : float diff = *i - *j;
573 : if (SkipFPExpectedValue(diff)) continue;
574 : CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j)));
575 : }
576 : }
577 : }
578 :
579 : WASM_SIMD_TEST(F32x4Eq) {
580 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Eq, Equal);
581 : }
582 :
583 : WASM_SIMD_TEST(F32x4Ne) {
584 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Ne, NotEqual);
585 : }
586 :
587 : WASM_SIMD_TEST(F32x4Gt) {
588 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Gt, Greater);
589 : }
590 :
591 : WASM_SIMD_TEST(F32x4Ge) {
592 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Ge, GreaterEqual);
593 : }
594 :
595 : WASM_SIMD_TEST(F32x4Lt) {
596 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Lt, Less);
597 : }
598 :
599 : WASM_SIMD_TEST(F32x4Le) {
600 : RunF32x4CompareOpTest(execution_mode, kExprF32x4Le, LessEqual);
601 : }
602 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
603 : // V8_TARGET_ARCH_MIPS64
604 :
605 23766 : WASM_SIMD_TEST(I32x4Splat) {
606 : // Store SIMD value in a local variable, use extract lane to check lane values
607 : // This test is not a test for ExtractLane as Splat does not create
608 : // interesting SIMD values.
609 : //
610 : // SetLocal(1, I32x4Splat(Local(0)));
611 : // For each lane index
612 : // if(Local(0) != I32x4ExtractLane(Local(1), index)
613 : // return 0
614 : //
615 : // return 1
616 12 : WasmRunner<int32_t, int32_t> r(execution_mode);
617 : byte lane_val = 0;
618 : byte simd = r.AllocateLocal(kWasmS128);
619 12 : BUILD(r,
620 : WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
621 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, lane_val), WASM_ONE);
622 :
623 12 : FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
624 12 : }
625 :
626 23766 : WASM_SIMD_TEST(I32x4ReplaceLane) {
627 12 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
628 : byte old_val = 0;
629 : byte new_val = 1;
630 : byte simd = r.AllocateLocal(kWasmS128);
631 12 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(old_val))),
632 : WASM_SET_LOCAL(simd,
633 : WASM_SIMD_I32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
634 : WASM_GET_LOCAL(new_val))),
635 : WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, old_val, old_val, old_val),
636 : WASM_SET_LOCAL(simd,
637 : WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
638 : WASM_GET_LOCAL(new_val))),
639 : WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, old_val, old_val),
640 : WASM_SET_LOCAL(simd,
641 : WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
642 : WASM_GET_LOCAL(new_val))),
643 : WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, new_val, old_val),
644 : WASM_SET_LOCAL(simd,
645 : WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
646 : WASM_GET_LOCAL(new_val))),
647 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, new_val), WASM_ONE);
648 :
649 12 : CHECK_EQ(1, r.Call(1, 2));
650 12 : }
651 :
652 23766 : WASM_SIMD_TEST(I16x8Splat) {
653 12 : WasmRunner<int32_t, int32_t> r(execution_mode);
654 : byte lane_val = 0;
655 : byte simd = r.AllocateLocal(kWasmS128);
656 12 : BUILD(r,
657 : WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(lane_val))),
658 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, lane_val), WASM_ONE);
659 :
660 12 : FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
661 12 : }
662 :
663 23766 : WASM_SIMD_TEST(I16x8ReplaceLane) {
664 12 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
665 : byte old_val = 0;
666 : byte new_val = 1;
667 : byte simd = r.AllocateLocal(kWasmS128);
668 12 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(old_val))),
669 : WASM_SET_LOCAL(simd,
670 : WASM_SIMD_I16x8_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
671 : WASM_GET_LOCAL(new_val))),
672 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, old_val, old_val, old_val,
673 : old_val, old_val, old_val, old_val),
674 : WASM_SET_LOCAL(simd,
675 : WASM_SIMD_I16x8_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
676 : WASM_GET_LOCAL(new_val))),
677 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, old_val, old_val,
678 : old_val, old_val, old_val, old_val),
679 : WASM_SET_LOCAL(simd,
680 : WASM_SIMD_I16x8_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
681 : WASM_GET_LOCAL(new_val))),
682 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, new_val, old_val,
683 : old_val, old_val, old_val, old_val),
684 : WASM_SET_LOCAL(simd,
685 : WASM_SIMD_I16x8_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
686 : WASM_GET_LOCAL(new_val))),
687 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, new_val, new_val,
688 : old_val, old_val, old_val, old_val),
689 : WASM_SET_LOCAL(simd,
690 : WASM_SIMD_I16x8_REPLACE_LANE(4, WASM_GET_LOCAL(simd),
691 : WASM_GET_LOCAL(new_val))),
692 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, new_val, new_val,
693 : new_val, old_val, old_val, old_val),
694 : WASM_SET_LOCAL(simd,
695 : WASM_SIMD_I16x8_REPLACE_LANE(5, WASM_GET_LOCAL(simd),
696 : WASM_GET_LOCAL(new_val))),
697 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, new_val, new_val,
698 : new_val, new_val, old_val, old_val),
699 : WASM_SET_LOCAL(simd,
700 : WASM_SIMD_I16x8_REPLACE_LANE(6, WASM_GET_LOCAL(simd),
701 : WASM_GET_LOCAL(new_val))),
702 : WASM_SIMD_CHECK8(I16x8, simd, I32, new_val, new_val, new_val, new_val,
703 : new_val, new_val, new_val, old_val),
704 : WASM_SET_LOCAL(simd,
705 : WASM_SIMD_I16x8_REPLACE_LANE(7, WASM_GET_LOCAL(simd),
706 : WASM_GET_LOCAL(new_val))),
707 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, new_val), WASM_ONE);
708 :
709 12 : CHECK_EQ(1, r.Call(1, 2));
710 12 : }
711 :
712 23766 : WASM_SIMD_TEST(I8x16Splat) {
713 12 : WasmRunner<int32_t, int32_t> r(execution_mode);
714 : byte lane_val = 0;
715 : byte simd = r.AllocateLocal(kWasmS128);
716 12 : BUILD(r,
717 : WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(lane_val))),
718 : WASM_SIMD_CHECK_SPLAT8(I8x16, simd, I32, lane_val), WASM_ONE);
719 :
720 12 : FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
721 12 : }
722 :
723 23766 : WASM_SIMD_TEST(I8x16ReplaceLane) {
724 12 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
725 : byte old_val = 0;
726 : byte new_val = 1;
727 : byte simd = r.AllocateLocal(kWasmS128);
728 12 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(old_val))),
729 : WASM_SET_LOCAL(simd,
730 : WASM_SIMD_I8x16_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
731 : WASM_GET_LOCAL(new_val))),
732 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, old_val, old_val, old_val,
733 : old_val, old_val, old_val, old_val, old_val, old_val,
734 : old_val, old_val, old_val, old_val, old_val, old_val),
735 : WASM_SET_LOCAL(simd,
736 : WASM_SIMD_I8x16_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
737 : WASM_GET_LOCAL(new_val))),
738 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, old_val, old_val,
739 : old_val, old_val, old_val, old_val, old_val, old_val,
740 : old_val, old_val, old_val, old_val, old_val, old_val),
741 : WASM_SET_LOCAL(simd,
742 : WASM_SIMD_I8x16_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
743 : WASM_GET_LOCAL(new_val))),
744 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, old_val,
745 : old_val, old_val, old_val, old_val, old_val, old_val,
746 : old_val, old_val, old_val, old_val, old_val, old_val),
747 : WASM_SET_LOCAL(simd,
748 : WASM_SIMD_I8x16_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
749 : WASM_GET_LOCAL(new_val))),
750 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
751 : old_val, old_val, old_val, old_val, old_val, old_val,
752 : old_val, old_val, old_val, old_val, old_val, old_val),
753 : WASM_SET_LOCAL(simd,
754 : WASM_SIMD_I8x16_REPLACE_LANE(4, WASM_GET_LOCAL(simd),
755 : WASM_GET_LOCAL(new_val))),
756 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
757 : new_val, old_val, old_val, old_val, old_val, old_val,
758 : old_val, old_val, old_val, old_val, old_val, old_val),
759 : WASM_SET_LOCAL(simd,
760 : WASM_SIMD_I8x16_REPLACE_LANE(5, WASM_GET_LOCAL(simd),
761 : WASM_GET_LOCAL(new_val))),
762 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
763 : new_val, new_val, old_val, old_val, old_val, old_val,
764 : old_val, old_val, old_val, old_val, old_val, old_val),
765 : WASM_SET_LOCAL(simd,
766 : WASM_SIMD_I8x16_REPLACE_LANE(6, WASM_GET_LOCAL(simd),
767 : WASM_GET_LOCAL(new_val))),
768 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
769 : new_val, new_val, new_val, old_val, old_val, old_val,
770 : old_val, old_val, old_val, old_val, old_val, old_val),
771 : WASM_SET_LOCAL(simd,
772 : WASM_SIMD_I8x16_REPLACE_LANE(7, WASM_GET_LOCAL(simd),
773 : WASM_GET_LOCAL(new_val))),
774 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
775 : new_val, new_val, new_val, new_val, old_val, old_val,
776 : old_val, old_val, old_val, old_val, old_val, old_val),
777 : WASM_SET_LOCAL(simd,
778 : WASM_SIMD_I8x16_REPLACE_LANE(8, WASM_GET_LOCAL(simd),
779 : WASM_GET_LOCAL(new_val))),
780 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
781 : new_val, new_val, new_val, new_val, new_val, old_val,
782 : old_val, old_val, old_val, old_val, old_val, old_val),
783 : WASM_SET_LOCAL(simd,
784 : WASM_SIMD_I8x16_REPLACE_LANE(9, WASM_GET_LOCAL(simd),
785 : WASM_GET_LOCAL(new_val))),
786 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
787 : new_val, new_val, new_val, new_val, new_val, new_val,
788 : old_val, old_val, old_val, old_val, old_val, old_val),
789 : WASM_SET_LOCAL(simd,
790 : WASM_SIMD_I8x16_REPLACE_LANE(10, WASM_GET_LOCAL(simd),
791 : WASM_GET_LOCAL(new_val))),
792 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
793 : new_val, new_val, new_val, new_val, new_val, new_val,
794 : new_val, old_val, old_val, old_val, old_val, old_val),
795 : WASM_SET_LOCAL(simd,
796 : WASM_SIMD_I8x16_REPLACE_LANE(11, WASM_GET_LOCAL(simd),
797 : WASM_GET_LOCAL(new_val))),
798 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
799 : new_val, new_val, new_val, new_val, new_val, new_val,
800 : new_val, new_val, old_val, old_val, old_val, old_val),
801 : WASM_SET_LOCAL(simd,
802 : WASM_SIMD_I8x16_REPLACE_LANE(12, WASM_GET_LOCAL(simd),
803 : WASM_GET_LOCAL(new_val))),
804 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
805 : new_val, new_val, new_val, new_val, new_val, new_val,
806 : new_val, new_val, new_val, old_val, old_val, old_val),
807 : WASM_SET_LOCAL(simd,
808 : WASM_SIMD_I8x16_REPLACE_LANE(13, WASM_GET_LOCAL(simd),
809 : WASM_GET_LOCAL(new_val))),
810 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
811 : new_val, new_val, new_val, new_val, new_val, new_val,
812 : new_val, new_val, new_val, new_val, old_val, old_val),
813 : WASM_SET_LOCAL(simd,
814 : WASM_SIMD_I8x16_REPLACE_LANE(14, WASM_GET_LOCAL(simd),
815 : WASM_GET_LOCAL(new_val))),
816 : WASM_SIMD_CHECK16(I8x16, simd, I32, new_val, new_val, new_val, new_val,
817 : new_val, new_val, new_val, new_val, new_val, new_val,
818 : new_val, new_val, new_val, new_val, new_val, old_val),
819 : WASM_SET_LOCAL(simd,
820 : WASM_SIMD_I8x16_REPLACE_LANE(15, WASM_GET_LOCAL(simd),
821 : WASM_GET_LOCAL(new_val))),
822 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, new_val), WASM_ONE);
823 :
824 12 : CHECK_EQ(1, r.Call(1, 2));
825 12 : }
826 :
827 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
828 : V8_TARGET_ARCH_MIPS64
829 : // Determines if conversion from float to int will be valid.
830 : bool CanRoundToZeroAndConvert(double val, bool unsigned_integer) {
831 : const double max_uint = static_cast<double>(0xffffffffu);
832 : const double max_int = static_cast<double>(kMaxInt);
833 : const double min_int = static_cast<double>(kMinInt);
834 :
835 : // Check for NaN.
836 : if (val != val) {
837 : return false;
838 : }
839 :
840 : // Round to zero and check for overflow. This code works because 32 bit
841 : // integers can be exactly represented by ieee-754 64bit floating-point
842 : // values.
843 : return unsigned_integer ? (val < (max_uint + 1.0)) && (val > -1)
844 : : (val < (max_int + 1.0)) && (val > (min_int - 1.0));
845 : }
846 :
847 : int ConvertInvalidValue(double val, bool unsigned_integer) {
848 : if (val != val) {
849 : return 0;
850 : } else {
851 : if (unsigned_integer) {
852 : return (val < 0) ? 0 : 0xffffffffu;
853 : } else {
854 : return (val < 0) ? kMinInt : kMaxInt;
855 : }
856 : }
857 : }
858 :
859 : int32_t ConvertToInt(double val, bool unsigned_integer) {
860 : int32_t result =
861 : unsigned_integer ? static_cast<uint32_t>(val) : static_cast<int32_t>(val);
862 :
863 : if (!CanRoundToZeroAndConvert(val, unsigned_integer)) {
864 : result = ConvertInvalidValue(val, unsigned_integer);
865 : }
866 : return result;
867 : }
868 :
869 : // Tests both signed and unsigned conversion.
870 : WASM_SIMD_TEST(I32x4ConvertF32x4) {
871 : WasmRunner<int32_t, float, int32_t, int32_t> r(execution_mode);
872 : byte a = 0;
873 : byte expected_signed = 1;
874 : byte expected_unsigned = 2;
875 : byte simd0 = r.AllocateLocal(kWasmS128);
876 : byte simd1 = r.AllocateLocal(kWasmS128);
877 : byte simd2 = r.AllocateLocal(kWasmS128);
878 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
879 : WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertF32x4,
880 : WASM_GET_LOCAL(simd0))),
881 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed),
882 : WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertF32x4,
883 : WASM_GET_LOCAL(simd0))),
884 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE);
885 :
886 : FOR_FLOAT32_INPUTS(i) {
887 : if (SkipFPValue(*i)) continue;
888 : int32_t signed_value = ConvertToInt(*i, false);
889 : int32_t unsigned_value = ConvertToInt(*i, true);
890 : CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value));
891 : }
892 : }
893 :
894 : // Tests both signed and unsigned conversion from I16x8 (unpacking).
895 : WASM_SIMD_COMPILED_TEST(I32x4ConvertI16x8) {
896 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
897 : byte a = 0;
898 : byte unpacked_signed = 1;
899 : byte unpacked_unsigned = 2;
900 : byte simd0 = r.AllocateLocal(kWasmS128);
901 : byte simd1 = r.AllocateLocal(kWasmS128);
902 : byte simd2 = r.AllocateLocal(kWasmS128);
903 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
904 : WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertI16x8Low,
905 : WASM_GET_LOCAL(simd0))),
906 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, unpacked_signed),
907 : WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertI16x8High,
908 : WASM_GET_LOCAL(simd0))),
909 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, unpacked_unsigned), WASM_ONE);
910 :
911 : FOR_INT16_INPUTS(i) {
912 : int32_t unpacked_signed = static_cast<int32_t>(Widen<int16_t>(*i));
913 : int32_t unpacked_unsigned =
914 : static_cast<int32_t>(UnsignedWiden<int16_t>(*i));
915 : CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned));
916 : }
917 : }
918 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
919 : // V8_TARGET_ARCH_MIPS64
920 :
921 24 : void RunI32x4UnOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
922 : Int32UnOp expected_op) {
923 24 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
924 : byte a = 0;
925 : byte expected = 1;
926 : byte simd = r.AllocateLocal(kWasmS128);
927 24 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
928 : WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))),
929 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE);
930 :
931 24 : FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
932 24 : }
933 :
934 23742 : WASM_SIMD_TEST(I32x4Neg) {
935 12 : RunI32x4UnOpTest(execution_mode, kExprI32x4Neg, Negate);
936 0 : }
937 :
938 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64
939 23754 : WASM_SIMD_TEST(S128Not) { RunI32x4UnOpTest(execution_mode, kExprS128Not, Not); }
940 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64
941 :
942 120 : void RunI32x4BinOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
943 : Int32BinOp expected_op) {
944 120 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
945 : byte a = 0;
946 : byte b = 1;
947 : byte expected = 2;
948 : byte simd0 = r.AllocateLocal(kWasmS128);
949 : byte simd1 = r.AllocateLocal(kWasmS128);
950 120 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
951 : WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))),
952 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
953 : WASM_GET_LOCAL(simd1))),
954 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
955 :
956 7080 : FOR_INT32_INPUTS(i) {
957 403680 : FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
958 : }
959 120 : }
960 :
961 23742 : WASM_SIMD_TEST(I32x4Add) {
962 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4Add, Add);
963 0 : }
964 :
965 23742 : WASM_SIMD_TEST(I32x4Sub) {
966 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4Sub, Sub);
967 0 : }
968 :
969 23742 : WASM_SIMD_TEST(I32x4Mul) {
970 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4Mul, Mul);
971 0 : }
972 :
973 23742 : WASM_SIMD_TEST(I32x4MinS) {
974 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4MinS, Minimum);
975 0 : }
976 :
977 23742 : WASM_SIMD_TEST(I32x4MaxS) {
978 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4MaxS, Maximum);
979 0 : }
980 :
981 23742 : WASM_SIMD_TEST(I32x4MinU) {
982 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4MinU, UnsignedMinimum);
983 0 : }
984 :
985 23742 : WASM_SIMD_TEST(I32x4MaxU) {
986 12 : RunI32x4BinOpTest(execution_mode, kExprI32x4MaxU, UnsignedMaximum);
987 0 : }
988 :
989 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
990 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
991 23742 : WASM_SIMD_TEST(S128And) {
992 12 : RunI32x4BinOpTest(execution_mode, kExprS128And, And);
993 0 : }
994 :
995 23754 : WASM_SIMD_TEST(S128Or) { RunI32x4BinOpTest(execution_mode, kExprS128Or, Or); }
996 :
997 23742 : WASM_SIMD_TEST(S128Xor) {
998 12 : RunI32x4BinOpTest(execution_mode, kExprS128Xor, Xor);
999 0 : }
1000 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
1001 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1002 :
1003 120 : void RunI32x4CompareOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1004 : Int32CompareOp expected_op) {
1005 120 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1006 : byte a = 0;
1007 : byte b = 1;
1008 : byte expected = 2;
1009 : byte simd0 = r.AllocateLocal(kWasmS128);
1010 : byte simd1 = r.AllocateLocal(kWasmS128);
1011 120 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
1012 : WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))),
1013 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
1014 : WASM_GET_LOCAL(simd1))),
1015 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
1016 :
1017 7080 : FOR_INT32_INPUTS(i) {
1018 403680 : FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
1019 : }
1020 120 : }
1021 :
1022 23742 : WASM_SIMD_TEST(I32x4Eq) {
1023 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4Eq, Equal);
1024 0 : }
1025 :
1026 23742 : WASM_SIMD_TEST(I32x4Ne) {
1027 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4Ne, NotEqual);
1028 0 : }
1029 :
1030 23742 : WASM_SIMD_TEST(I32x4LtS) {
1031 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4LtS, Less);
1032 0 : }
1033 :
1034 23742 : WASM_SIMD_TEST(I32x4LeS) {
1035 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4LeS, LessEqual);
1036 0 : }
1037 :
1038 23742 : WASM_SIMD_TEST(I32x4GtS) {
1039 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4GtS, Greater);
1040 0 : }
1041 :
1042 23742 : WASM_SIMD_TEST(I32x4GeS) {
1043 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4GeS, GreaterEqual);
1044 0 : }
1045 :
1046 23742 : WASM_SIMD_TEST(I32x4LtU) {
1047 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4LtU, UnsignedLess);
1048 0 : }
1049 :
1050 23742 : WASM_SIMD_TEST(I32x4LeU) {
1051 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4LeU, UnsignedLessEqual);
1052 0 : }
1053 :
1054 23742 : WASM_SIMD_TEST(I32x4GtU) {
1055 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4GtU, UnsignedGreater);
1056 0 : }
1057 :
1058 23742 : WASM_SIMD_TEST(I32x4GeU) {
1059 12 : RunI32x4CompareOpTest(execution_mode, kExprI32x4GeU, UnsignedGreaterEqual);
1060 0 : }
1061 :
1062 36 : void RunI32x4ShiftOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1063 : Int32ShiftOp expected_op, int shift) {
1064 36 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
1065 : byte a = 0;
1066 : byte expected = 1;
1067 : byte simd = r.AllocateLocal(kWasmS128);
1068 36 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
1069 : WASM_SET_LOCAL(
1070 : simd, WASM_SIMD_SHIFT_OP(simd_op, shift, WASM_GET_LOCAL(simd))),
1071 : WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE);
1072 :
1073 36 : FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
1074 36 : }
1075 :
1076 23742 : WASM_SIMD_TEST(I32x4Shl) {
1077 12 : RunI32x4ShiftOpTest(execution_mode, kExprI32x4Shl, LogicalShiftLeft, 1);
1078 0 : }
1079 :
1080 23742 : WASM_SIMD_TEST(I32x4ShrS) {
1081 12 : RunI32x4ShiftOpTest(execution_mode, kExprI32x4ShrS, ArithmeticShiftRight, 1);
1082 0 : }
1083 :
1084 23742 : WASM_SIMD_TEST(I32x4ShrU) {
1085 12 : RunI32x4ShiftOpTest(execution_mode, kExprI32x4ShrU, LogicalShiftRight, 1);
1086 0 : }
1087 :
1088 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1089 : V8_TARGET_ARCH_MIPS64
1090 : // Tests both signed and unsigned conversion from I8x16 (unpacking).
1091 : WASM_SIMD_COMPILED_TEST(I16x8ConvertI8x16) {
1092 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1093 : byte a = 0;
1094 : byte unpacked_signed = 1;
1095 : byte unpacked_unsigned = 2;
1096 : byte simd0 = r.AllocateLocal(kWasmS128);
1097 : byte simd1 = r.AllocateLocal(kWasmS128);
1098 : byte simd2 = r.AllocateLocal(kWasmS128);
1099 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))),
1100 : WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI16x8SConvertI8x16Low,
1101 : WASM_GET_LOCAL(simd0))),
1102 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, unpacked_signed),
1103 : WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI16x8UConvertI8x16High,
1104 : WASM_GET_LOCAL(simd0))),
1105 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, unpacked_unsigned), WASM_ONE);
1106 :
1107 : FOR_INT8_INPUTS(i) {
1108 : int32_t unpacked_signed = static_cast<int32_t>(Widen<int8_t>(*i));
1109 : int32_t unpacked_unsigned = static_cast<int32_t>(UnsignedWiden<int8_t>(*i));
1110 : CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned));
1111 : }
1112 : }
1113 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1114 : // V8_TARGET_ARCH_MIPS64
1115 :
1116 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1117 : V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_X64
1118 12 : void RunI16x8UnOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1119 : Int16UnOp expected_op) {
1120 12 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
1121 : byte a = 0;
1122 : byte expected = 1;
1123 : byte simd = r.AllocateLocal(kWasmS128);
1124 12 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
1125 : WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))),
1126 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE);
1127 :
1128 12 : FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
1129 12 : }
1130 :
1131 23742 : WASM_SIMD_TEST(I16x8Neg) {
1132 12 : RunI16x8UnOpTest(execution_mode, kExprI16x8Neg, Negate);
1133 0 : }
1134 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1135 : // V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_X64
1136 :
1137 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1138 : V8_TARGET_ARCH_MIPS64
1139 : // Tests both signed and unsigned conversion from I32x4 (packing).
1140 : WASM_SIMD_COMPILED_TEST(I16x8ConvertI32x4) {
1141 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1142 : byte a = 0;
1143 : byte packed_signed = 1;
1144 : byte packed_unsigned = 2;
1145 : byte simd0 = r.AllocateLocal(kWasmS128);
1146 : byte simd1 = r.AllocateLocal(kWasmS128);
1147 : byte simd2 = r.AllocateLocal(kWasmS128);
1148 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
1149 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI16x8SConvertI32x4,
1150 : WASM_GET_LOCAL(simd0),
1151 : WASM_GET_LOCAL(simd0))),
1152 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, packed_signed),
1153 : WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI16x8UConvertI32x4,
1154 : WASM_GET_LOCAL(simd0),
1155 : WASM_GET_LOCAL(simd0))),
1156 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, packed_unsigned), WASM_ONE);
1157 :
1158 : FOR_INT32_INPUTS(i) {
1159 : int32_t packed_signed = Narrow<int16_t>(*i);
1160 : int32_t packed_unsigned = UnsignedNarrow<int16_t>(*i);
1161 : // Sign-extend here, since ExtractLane sign extends.
1162 : if (packed_unsigned & 0x8000) packed_unsigned |= 0xffff0000;
1163 : CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned));
1164 : }
1165 : }
1166 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1167 : // V8_TARGET_ARCH_MIPS64
1168 :
1169 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
1170 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1171 132 : void RunI16x8BinOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1172 : Int16BinOp expected_op) {
1173 132 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1174 : byte a = 0;
1175 : byte b = 1;
1176 : byte expected = 2;
1177 : byte simd0 = r.AllocateLocal(kWasmS128);
1178 : byte simd1 = r.AllocateLocal(kWasmS128);
1179 132 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
1180 : WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))),
1181 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
1182 : WASM_GET_LOCAL(simd1))),
1183 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), WASM_ONE);
1184 :
1185 1320 : FOR_INT16_INPUTS(i) {
1186 10692 : FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
1187 : }
1188 132 : }
1189 :
1190 23742 : WASM_SIMD_TEST(I16x8Add) {
1191 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8Add, Add);
1192 0 : }
1193 :
1194 23742 : WASM_SIMD_TEST(I16x8AddSaturateS) {
1195 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8AddSaturateS, AddSaturate);
1196 0 : }
1197 :
1198 23742 : WASM_SIMD_TEST(I16x8Sub) {
1199 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8Sub, Sub);
1200 0 : }
1201 :
1202 23742 : WASM_SIMD_TEST(I16x8SubSaturateS) {
1203 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8SubSaturateS, SubSaturate);
1204 0 : }
1205 :
1206 23742 : WASM_SIMD_TEST(I16x8Mul) {
1207 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8Mul, Mul);
1208 0 : }
1209 :
1210 23742 : WASM_SIMD_TEST(I16x8MinS) {
1211 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8MinS, Minimum);
1212 0 : }
1213 :
1214 23742 : WASM_SIMD_TEST(I16x8MaxS) {
1215 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8MaxS, Maximum);
1216 0 : }
1217 :
1218 23742 : WASM_SIMD_TEST(I16x8AddSaturateU) {
1219 : RunI16x8BinOpTest(execution_mode, kExprI16x8AddSaturateU,
1220 12 : UnsignedAddSaturate);
1221 0 : }
1222 :
1223 23742 : WASM_SIMD_TEST(I16x8SubSaturateU) {
1224 : RunI16x8BinOpTest(execution_mode, kExprI16x8SubSaturateU,
1225 12 : UnsignedSubSaturate);
1226 0 : }
1227 :
1228 23742 : WASM_SIMD_TEST(I16x8MinU) {
1229 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8MinU, UnsignedMinimum);
1230 0 : }
1231 :
1232 23742 : WASM_SIMD_TEST(I16x8MaxU) {
1233 12 : RunI16x8BinOpTest(execution_mode, kExprI16x8MaxU, UnsignedMaximum);
1234 0 : }
1235 :
1236 120 : void RunI16x8CompareOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1237 : Int16CompareOp expected_op) {
1238 120 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1239 : byte a = 0;
1240 : byte b = 1;
1241 : byte expected = 2;
1242 : byte simd0 = r.AllocateLocal(kWasmS128);
1243 : byte simd1 = r.AllocateLocal(kWasmS128);
1244 120 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
1245 : WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))),
1246 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
1247 : WASM_GET_LOCAL(simd1))),
1248 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), WASM_ONE);
1249 :
1250 1200 : FOR_INT16_INPUTS(i) {
1251 9720 : FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
1252 : }
1253 120 : }
1254 :
1255 23742 : WASM_SIMD_TEST(I16x8Eq) {
1256 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8Eq, Equal);
1257 0 : }
1258 :
1259 23742 : WASM_SIMD_TEST(I16x8Ne) {
1260 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8Ne, NotEqual);
1261 0 : }
1262 :
1263 23742 : WASM_SIMD_TEST(I16x8LtS) {
1264 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8LtS, Less);
1265 0 : }
1266 :
1267 23742 : WASM_SIMD_TEST(I16x8LeS) {
1268 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8LeS, LessEqual);
1269 0 : }
1270 :
1271 23742 : WASM_SIMD_TEST(I16x8GtS) {
1272 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8GtS, Greater);
1273 0 : }
1274 :
1275 23742 : WASM_SIMD_TEST(I16x8GeS) {
1276 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8GeS, GreaterEqual);
1277 0 : }
1278 :
1279 23742 : WASM_SIMD_TEST(I16x8GtU) {
1280 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8GtU, UnsignedGreater);
1281 0 : }
1282 :
1283 23742 : WASM_SIMD_TEST(I16x8GeU) {
1284 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8GeU, UnsignedGreaterEqual);
1285 0 : }
1286 :
1287 23742 : WASM_SIMD_TEST(I16x8LtU) {
1288 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8LtU, UnsignedLess);
1289 0 : }
1290 :
1291 23742 : WASM_SIMD_TEST(I16x8LeU) {
1292 12 : RunI16x8CompareOpTest(execution_mode, kExprI16x8LeU, UnsignedLessEqual);
1293 0 : }
1294 :
1295 36 : void RunI16x8ShiftOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1296 : Int16ShiftOp expected_op, int shift) {
1297 36 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
1298 : byte a = 0;
1299 : byte expected = 1;
1300 : byte simd = r.AllocateLocal(kWasmS128);
1301 36 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
1302 : WASM_SET_LOCAL(
1303 : simd, WASM_SIMD_SHIFT_OP(simd_op, shift, WASM_GET_LOCAL(simd))),
1304 : WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE);
1305 :
1306 36 : FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
1307 36 : }
1308 :
1309 23742 : WASM_SIMD_TEST(I16x8Shl) {
1310 12 : RunI16x8ShiftOpTest(execution_mode, kExprI16x8Shl, LogicalShiftLeft, 1);
1311 0 : }
1312 :
1313 23742 : WASM_SIMD_TEST(I16x8ShrS) {
1314 12 : RunI16x8ShiftOpTest(execution_mode, kExprI16x8ShrS, ArithmeticShiftRight, 1);
1315 0 : }
1316 :
1317 23742 : WASM_SIMD_TEST(I16x8ShrU) {
1318 12 : RunI16x8ShiftOpTest(execution_mode, kExprI16x8ShrU, LogicalShiftRight, 1);
1319 0 : }
1320 :
1321 12 : void RunI8x16UnOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1322 : Int8UnOp expected_op) {
1323 12 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
1324 : byte a = 0;
1325 : byte expected = 1;
1326 : byte simd = r.AllocateLocal(kWasmS128);
1327 12 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))),
1328 : WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))),
1329 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE);
1330 :
1331 12 : FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
1332 12 : }
1333 :
1334 23742 : WASM_SIMD_TEST(I8x16Neg) {
1335 12 : RunI8x16UnOpTest(execution_mode, kExprI8x16Neg, Negate);
1336 0 : }
1337 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
1338 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1339 :
1340 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1341 : V8_TARGET_ARCH_MIPS64
1342 : // Tests both signed and unsigned conversion from I16x8 (packing).
1343 : WASM_SIMD_COMPILED_TEST(I8x16ConvertI16x8) {
1344 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1345 : byte a = 0;
1346 : byte packed_signed = 1;
1347 : byte packed_unsigned = 2;
1348 : byte simd0 = r.AllocateLocal(kWasmS128);
1349 : byte simd1 = r.AllocateLocal(kWasmS128);
1350 : byte simd2 = r.AllocateLocal(kWasmS128);
1351 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))),
1352 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI8x16SConvertI16x8,
1353 : WASM_GET_LOCAL(simd0),
1354 : WASM_GET_LOCAL(simd0))),
1355 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, packed_signed),
1356 : WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI8x16UConvertI16x8,
1357 : WASM_GET_LOCAL(simd0),
1358 : WASM_GET_LOCAL(simd0))),
1359 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd2, I32, packed_unsigned), WASM_ONE);
1360 :
1361 : FOR_INT16_INPUTS(i) {
1362 : int32_t packed_signed = Narrow<int8_t>(*i);
1363 : int32_t packed_unsigned = UnsignedNarrow<int8_t>(*i);
1364 : // Sign-extend here, since ExtractLane sign extends.
1365 : if (packed_unsigned & 0x80) packed_unsigned |= 0xffffff00;
1366 : CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned));
1367 : }
1368 : }
1369 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1370 : // V8_TARGET_ARCH_MIPS64
1371 :
1372 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
1373 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1374 120 : void RunI8x16BinOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1375 : Int8BinOp expected_op) {
1376 120 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1377 : byte a = 0;
1378 : byte b = 1;
1379 : byte expected = 2;
1380 : byte simd0 = r.AllocateLocal(kWasmS128);
1381 : byte simd1 = r.AllocateLocal(kWasmS128);
1382 120 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))),
1383 : WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))),
1384 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
1385 : WASM_GET_LOCAL(simd1))),
1386 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), WASM_ONE);
1387 :
1388 1200 : FOR_INT8_INPUTS(i) {
1389 9720 : FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
1390 : }
1391 120 : }
1392 :
1393 23742 : WASM_SIMD_TEST(I8x16Add) {
1394 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16Add, Add);
1395 0 : }
1396 :
1397 23742 : WASM_SIMD_TEST(I8x16AddSaturateS) {
1398 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16AddSaturateS, AddSaturate);
1399 0 : }
1400 :
1401 23742 : WASM_SIMD_TEST(I8x16Sub) {
1402 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16Sub, Sub);
1403 0 : }
1404 :
1405 23742 : WASM_SIMD_TEST(I8x16SubSaturateS) {
1406 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16SubSaturateS, SubSaturate);
1407 0 : }
1408 :
1409 23742 : WASM_SIMD_TEST(I8x16MinS) {
1410 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16MinS, Minimum);
1411 0 : }
1412 :
1413 23742 : WASM_SIMD_TEST(I8x16MaxS) {
1414 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16MaxS, Maximum);
1415 0 : }
1416 :
1417 23742 : WASM_SIMD_TEST(I8x16AddSaturateU) {
1418 : RunI8x16BinOpTest(execution_mode, kExprI8x16AddSaturateU,
1419 12 : UnsignedAddSaturate);
1420 0 : }
1421 :
1422 23742 : WASM_SIMD_TEST(I8x16SubSaturateU) {
1423 : RunI8x16BinOpTest(execution_mode, kExprI8x16SubSaturateU,
1424 12 : UnsignedSubSaturate);
1425 0 : }
1426 :
1427 23742 : WASM_SIMD_TEST(I8x16MinU) {
1428 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16MinU, UnsignedMinimum);
1429 0 : }
1430 :
1431 23742 : WASM_SIMD_TEST(I8x16MaxU) {
1432 12 : RunI8x16BinOpTest(execution_mode, kExprI8x16MaxU, UnsignedMaximum);
1433 0 : }
1434 :
1435 120 : void RunI8x16CompareOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1436 : Int8CompareOp expected_op) {
1437 120 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
1438 : byte a = 0;
1439 : byte b = 1;
1440 : byte expected = 2;
1441 : byte simd0 = r.AllocateLocal(kWasmS128);
1442 : byte simd1 = r.AllocateLocal(kWasmS128);
1443 120 : BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))),
1444 : WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))),
1445 : WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
1446 : WASM_GET_LOCAL(simd1))),
1447 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), WASM_ONE);
1448 :
1449 1200 : FOR_INT8_INPUTS(i) {
1450 9720 : FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
1451 : }
1452 120 : }
1453 :
1454 23742 : WASM_SIMD_TEST(I8x16Eq) {
1455 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16Eq, Equal);
1456 0 : }
1457 :
1458 23742 : WASM_SIMD_TEST(I8x16Ne) {
1459 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16Ne, NotEqual);
1460 0 : }
1461 :
1462 23742 : WASM_SIMD_TEST(I8x16GtS) {
1463 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16GtS, Greater);
1464 0 : }
1465 :
1466 23742 : WASM_SIMD_TEST(I8x16GeS) {
1467 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16GeS, GreaterEqual);
1468 0 : }
1469 :
1470 23742 : WASM_SIMD_TEST(I8x16LtS) {
1471 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16LtS, Less);
1472 0 : }
1473 :
1474 23742 : WASM_SIMD_TEST(I8x16LeS) {
1475 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16LeS, LessEqual);
1476 0 : }
1477 :
1478 23742 : WASM_SIMD_TEST(I8x16GtU) {
1479 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16GtU, UnsignedGreater);
1480 0 : }
1481 :
1482 23742 : WASM_SIMD_TEST(I8x16GeU) {
1483 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16GeU, UnsignedGreaterEqual);
1484 0 : }
1485 :
1486 23742 : WASM_SIMD_TEST(I8x16LtU) {
1487 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16LtU, UnsignedLess);
1488 0 : }
1489 :
1490 23742 : WASM_SIMD_TEST(I8x16LeU) {
1491 12 : RunI8x16CompareOpTest(execution_mode, kExprI8x16LeU, UnsignedLessEqual);
1492 0 : }
1493 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
1494 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1495 :
1496 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1497 : V8_TARGET_ARCH_MIPS64
1498 : WASM_SIMD_TEST(I8x16Mul) {
1499 : RunI8x16BinOpTest(execution_mode, kExprI8x16Mul, Mul);
1500 : }
1501 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1502 : // V8_TARGET_ARCH_MIPS64
1503 :
1504 0 : void RunI8x16ShiftOpTest(WasmExecutionMode execution_mode, WasmOpcode simd_op,
1505 : Int8ShiftOp expected_op, int shift) {
1506 0 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
1507 : byte a = 0;
1508 : byte expected = 1;
1509 : byte simd = r.AllocateLocal(kWasmS128);
1510 0 : BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))),
1511 : WASM_SET_LOCAL(
1512 : simd, WASM_SIMD_SHIFT_OP(simd_op, shift, WASM_GET_LOCAL(simd))),
1513 : WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE);
1514 :
1515 0 : FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
1516 0 : }
1517 :
1518 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1519 : V8_TARGET_ARCH_MIPS64
1520 : WASM_SIMD_TEST(I8x16Shl) {
1521 : RunI8x16ShiftOpTest(execution_mode, kExprI8x16Shl, LogicalShiftLeft, 1);
1522 : }
1523 :
1524 : WASM_SIMD_TEST(I8x16ShrS) {
1525 : RunI8x16ShiftOpTest(execution_mode, kExprI8x16ShrS, ArithmeticShiftRight, 1);
1526 : }
1527 :
1528 : WASM_SIMD_TEST(I8x16ShrU) {
1529 : RunI8x16ShiftOpTest(execution_mode, kExprI8x16ShrU, LogicalShiftRight, 1);
1530 : }
1531 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
1532 : // V8_TARGET_ARCH_MIPS64
1533 :
1534 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
1535 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1536 : // Test Select by making a mask where the 0th and 3rd lanes are true and the
1537 : // rest false, and comparing for non-equality with zero to convert to a boolean
1538 : // vector.
1539 : #define WASM_SIMD_SELECT_TEST(format) \
1540 : WASM_SIMD_COMPILED_TEST(S##format##Select) { \
1541 : WasmRunner<int32_t, int32_t, int32_t> r(execution_mode); \
1542 : byte val1 = 0; \
1543 : byte val2 = 1; \
1544 : byte src1 = r.AllocateLocal(kWasmS128); \
1545 : byte src2 = r.AllocateLocal(kWasmS128); \
1546 : byte zero = r.AllocateLocal(kWasmS128); \
1547 : byte mask = r.AllocateLocal(kWasmS128); \
1548 : BUILD(r, \
1549 : WASM_SET_LOCAL(src1, \
1550 : WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(val1))), \
1551 : WASM_SET_LOCAL(src2, \
1552 : WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(val2))), \
1553 : WASM_SET_LOCAL(zero, WASM_SIMD_I##format##_SPLAT(WASM_ZERO)), \
1554 : WASM_SET_LOCAL(mask, WASM_SIMD_I##format##_REPLACE_LANE( \
1555 : 1, WASM_GET_LOCAL(zero), WASM_I32V(-1))), \
1556 : WASM_SET_LOCAL(mask, WASM_SIMD_I##format##_REPLACE_LANE( \
1557 : 2, WASM_GET_LOCAL(mask), WASM_I32V(-1))), \
1558 : WASM_SET_LOCAL( \
1559 : mask, \
1560 : WASM_SIMD_SELECT( \
1561 : format, \
1562 : WASM_SIMD_BINOP(kExprI##format##Ne, WASM_GET_LOCAL(mask), \
1563 : WASM_GET_LOCAL(zero)), \
1564 : WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2))), \
1565 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
1566 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 1), \
1567 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \
1568 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \
1569 : \
1570 : CHECK_EQ(1, r.Call(0x12, 0x34)); \
1571 : }
1572 :
1573 23754 : WASM_SIMD_SELECT_TEST(32x4)
1574 23754 : WASM_SIMD_SELECT_TEST(16x8)
1575 23754 : WASM_SIMD_SELECT_TEST(8x16)
1576 :
1577 : // Test Select by making a mask where the 0th and 3rd lanes are non-zero and the
1578 : // rest 0. The mask is not the result of a comparison op.
1579 : #define WASM_SIMD_NON_CANONICAL_SELECT_TEST(format) \
1580 : WASM_SIMD_COMPILED_TEST(S##format##NonCanonicalSelect) { \
1581 : WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode); \
1582 : byte val1 = 0; \
1583 : byte val2 = 1; \
1584 : byte combined = 2; \
1585 : byte src1 = r.AllocateLocal(kWasmS128); \
1586 : byte src2 = r.AllocateLocal(kWasmS128); \
1587 : byte zero = r.AllocateLocal(kWasmS128); \
1588 : byte mask = r.AllocateLocal(kWasmS128); \
1589 : BUILD(r, \
1590 : WASM_SET_LOCAL(src1, \
1591 : WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(val1))), \
1592 : WASM_SET_LOCAL(src2, \
1593 : WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(val2))), \
1594 : WASM_SET_LOCAL(zero, WASM_SIMD_I##format##_SPLAT(WASM_ZERO)), \
1595 : WASM_SET_LOCAL(mask, WASM_SIMD_I##format##_REPLACE_LANE( \
1596 : 1, WASM_GET_LOCAL(zero), WASM_I32V(0xF))), \
1597 : WASM_SET_LOCAL(mask, WASM_SIMD_I##format##_REPLACE_LANE( \
1598 : 2, WASM_GET_LOCAL(mask), WASM_I32V(0xF))), \
1599 : WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(mask), \
1600 : WASM_GET_LOCAL(src1), \
1601 : WASM_GET_LOCAL(src2))), \
1602 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
1603 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 1), \
1604 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 2), \
1605 : WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \
1606 : \
1607 : CHECK_EQ(1, r.Call(0x12, 0x34, 0x32)); \
1608 : }
1609 :
1610 23754 : WASM_SIMD_NON_CANONICAL_SELECT_TEST(32x4)
1611 23754 : WASM_SIMD_NON_CANONICAL_SELECT_TEST(16x8)
1612 23754 : WASM_SIMD_NON_CANONICAL_SELECT_TEST(8x16)
1613 :
1614 : // Test binary ops with two lane test patterns, all lanes distinct.
1615 : template <typename T>
1616 12 : void RunBinaryLaneOpTest(
1617 : WasmExecutionMode execution_mode, WasmOpcode simd_op,
1618 : const std::array<T, kSimd128Size / sizeof(T)>& expected) {
1619 12 : WasmRunner<int32_t> r(execution_mode);
1620 : // Set up two test patterns as globals, e.g. [0, 1, 2, 3] and [4, 5, 6, 7].
1621 12 : T* src0 = r.builder().AddGlobal<T>(kWasmS128);
1622 12 : T* src1 = r.builder().AddGlobal<T>(kWasmS128);
1623 : static const int kElems = kSimd128Size / sizeof(T);
1624 84 : for (int i = 0; i < kElems; i++) {
1625 72 : src0[i] = i;
1626 72 : src1[i] = kElems + i;
1627 : }
1628 12 : if (simd_op == kExprS8x16Shuffle) {
1629 0 : BUILD(r,
1630 : WASM_SET_GLOBAL(0, WASM_SIMD_S8x16_SHUFFLE_OP(simd_op, expected,
1631 : WASM_GET_GLOBAL(0),
1632 : WASM_GET_GLOBAL(1))),
1633 : WASM_ONE);
1634 : } else {
1635 12 : BUILD(r,
1636 : WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(simd_op, WASM_GET_GLOBAL(0),
1637 : WASM_GET_GLOBAL(1))),
1638 : WASM_ONE);
1639 : }
1640 :
1641 12 : CHECK_EQ(1, r.Call());
1642 72 : for (size_t i = 0; i < expected.size(); i++) {
1643 72 : CHECK_EQ(src0[i], expected[i]);
1644 : }
1645 12 : }
1646 :
1647 23742 : WASM_SIMD_COMPILED_TEST(I32x4AddHoriz) {
1648 : RunBinaryLaneOpTest<int32_t>(execution_mode, kExprI32x4AddHoriz,
1649 6 : {{1, 5, 9, 13}});
1650 6 : }
1651 :
1652 23742 : WASM_SIMD_COMPILED_TEST(I16x8AddHoriz) {
1653 : RunBinaryLaneOpTest<int16_t>(execution_mode, kExprI16x8AddHoriz,
1654 6 : {{1, 5, 9, 13, 17, 21, 25, 29}});
1655 6 : }
1656 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
1657 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
1658 :
1659 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
1660 : V8_TARGET_ARCH_MIPS64
1661 : WASM_SIMD_COMPILED_TEST(F32x4AddHoriz) {
1662 : RunBinaryLaneOpTest<float>(execution_mode, kExprF32x4AddHoriz,
1663 : {{1.0f, 5.0f, 9.0f, 13.0f}});
1664 : }
1665 :
1666 : // Test some regular shuffles that may have special handling on some targets.
1667 : // Test a normal and unary versions (where second operand isn't used).
1668 : WASM_SIMD_COMPILED_TEST(S32x4Dup) {
1669 : RunBinaryLaneOpTest<int8_t>(
1670 : execution_mode, kExprS8x16Shuffle,
1671 : {{16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19}});
1672 : RunBinaryLaneOpTest<int8_t>(
1673 : execution_mode, kExprS8x16Shuffle,
1674 : {{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7}});
1675 : }
1676 :
1677 : WASM_SIMD_COMPILED_TEST(S32x4ZipLeft) {
1678 : RunBinaryLaneOpTest<int8_t>(
1679 : execution_mode, kExprS8x16Shuffle,
1680 : {{0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23}});
1681 : RunBinaryLaneOpTest<int8_t>(
1682 : execution_mode, kExprS8x16Shuffle,
1683 : {{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7}});
1684 : }
1685 :
1686 : WASM_SIMD_COMPILED_TEST(S32x4ZipRight) {
1687 : RunBinaryLaneOpTest<int8_t>(
1688 : execution_mode, kExprS8x16Shuffle,
1689 : {{8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31}});
1690 : RunBinaryLaneOpTest<int8_t>(
1691 : execution_mode, kExprS8x16Shuffle,
1692 : {{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15}});
1693 : }
1694 :
1695 : WASM_SIMD_COMPILED_TEST(S32x4UnzipLeft) {
1696 : RunBinaryLaneOpTest<int8_t>(
1697 : execution_mode, kExprS8x16Shuffle,
1698 : {{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}});
1699 : RunBinaryLaneOpTest<int8_t>(
1700 : execution_mode, kExprS8x16Shuffle,
1701 : {{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11}});
1702 : }
1703 :
1704 : WASM_SIMD_COMPILED_TEST(S32x4UnzipRight) {
1705 : RunBinaryLaneOpTest<int8_t>(
1706 : execution_mode, kExprS8x16Shuffle,
1707 : {{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}});
1708 : RunBinaryLaneOpTest<int8_t>(
1709 : execution_mode, kExprS8x16Shuffle,
1710 : {{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15}});
1711 : }
1712 :
1713 : WASM_SIMD_COMPILED_TEST(S32x4TransposeLeft) {
1714 : RunBinaryLaneOpTest<int8_t>(
1715 : execution_mode, kExprS8x16Shuffle,
1716 : {{0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 24, 25, 26, 27}});
1717 : RunBinaryLaneOpTest<int8_t>(
1718 : execution_mode, kExprS8x16Shuffle,
1719 : {{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11}});
1720 : }
1721 :
1722 : WASM_SIMD_COMPILED_TEST(S32x4TransposeRight) {
1723 : RunBinaryLaneOpTest<int8_t>(
1724 : execution_mode, kExprS8x16Shuffle,
1725 : {{4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31}});
1726 : RunBinaryLaneOpTest<int8_t>(
1727 : execution_mode, kExprS8x16Shuffle,
1728 : {{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15}});
1729 : }
1730 :
1731 : // Reverses are only unary.
1732 : WASM_SIMD_COMPILED_TEST(S32x2Reverse) {
1733 : RunBinaryLaneOpTest<int8_t>(
1734 : execution_mode, kExprS8x16Shuffle,
1735 : {{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}});
1736 : }
1737 :
1738 : // Test irregular shuffle.
1739 : WASM_SIMD_COMPILED_TEST(S32x4Irregular) {
1740 : RunBinaryLaneOpTest<int8_t>(
1741 : execution_mode, kExprS8x16Shuffle,
1742 : {{0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19, 20, 21, 22, 23}});
1743 : RunBinaryLaneOpTest<int8_t>(
1744 : execution_mode, kExprS8x16Shuffle,
1745 : {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7}});
1746 : }
1747 :
1748 : WASM_SIMD_COMPILED_TEST(S16x8Dup) {
1749 : RunBinaryLaneOpTest<int8_t>(
1750 : execution_mode, kExprS8x16Shuffle,
1751 : {{18, 19, 18, 19, 18, 19, 18, 19, 18, 19, 18, 19, 18, 19, 18, 19}});
1752 : RunBinaryLaneOpTest<int8_t>(
1753 : execution_mode, kExprS8x16Shuffle,
1754 : {{6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7}});
1755 : }
1756 :
1757 : WASM_SIMD_COMPILED_TEST(S16x8ZipLeft) {
1758 : RunBinaryLaneOpTest<int8_t>(
1759 : execution_mode, kExprS8x16Shuffle,
1760 : {{0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23}});
1761 : RunBinaryLaneOpTest<int8_t>(
1762 : execution_mode, kExprS8x16Shuffle,
1763 : {{0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7}});
1764 : }
1765 :
1766 : WASM_SIMD_COMPILED_TEST(S16x8ZipRight) {
1767 : RunBinaryLaneOpTest<int8_t>(
1768 : execution_mode, kExprS8x16Shuffle,
1769 : {{8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31}});
1770 : RunBinaryLaneOpTest<int8_t>(
1771 : execution_mode, kExprS8x16Shuffle,
1772 : {{8, 9, 8, 9, 10, 11, 10, 11, 12, 13, 12, 13, 14, 15, 14, 15}});
1773 : }
1774 :
1775 : WASM_SIMD_COMPILED_TEST(S16x8UnzipLeft) {
1776 : RunBinaryLaneOpTest<int8_t>(
1777 : execution_mode, kExprS8x16Shuffle,
1778 : {{0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}});
1779 : RunBinaryLaneOpTest<int8_t>(
1780 : execution_mode, kExprS8x16Shuffle,
1781 : {{0, 1, 4, 5, 8, 9, 12, 13, 0, 1, 4, 5, 8, 9, 12, 13}});
1782 : }
1783 :
1784 : WASM_SIMD_COMPILED_TEST(S16x8UnzipRight) {
1785 : RunBinaryLaneOpTest<int8_t>(
1786 : execution_mode, kExprS8x16Shuffle,
1787 : {{2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}});
1788 : RunBinaryLaneOpTest<int8_t>(
1789 : execution_mode, kExprS8x16Shuffle,
1790 : {{2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15}});
1791 : }
1792 :
1793 : WASM_SIMD_COMPILED_TEST(S16x8TransposeLeft) {
1794 : RunBinaryLaneOpTest<int8_t>(
1795 : execution_mode, kExprS8x16Shuffle,
1796 : {{0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29}});
1797 : RunBinaryLaneOpTest<int8_t>(
1798 : execution_mode, kExprS8x16Shuffle,
1799 : {{0, 1, 0, 1, 4, 5, 4, 5, 8, 9, 8, 9, 12, 13, 12, 13}});
1800 : }
1801 :
1802 : WASM_SIMD_COMPILED_TEST(S16x8TransposeRight) {
1803 : RunBinaryLaneOpTest<int8_t>(
1804 : execution_mode, kExprS8x16Shuffle,
1805 : {{2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31}});
1806 : RunBinaryLaneOpTest<int8_t>(
1807 : execution_mode, kExprS8x16Shuffle,
1808 : {{2, 3, 2, 3, 6, 7, 6, 7, 10, 11, 10, 11, 14, 15, 14, 15}});
1809 : }
1810 :
1811 : WASM_SIMD_COMPILED_TEST(S16x4Reverse) {
1812 : RunBinaryLaneOpTest<int8_t>(
1813 : execution_mode, kExprS8x16Shuffle,
1814 : {{6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9}});
1815 : }
1816 :
1817 : WASM_SIMD_COMPILED_TEST(S16x2Reverse) {
1818 : RunBinaryLaneOpTest<int8_t>(
1819 : execution_mode, kExprS8x16Shuffle,
1820 : {{2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13}});
1821 : }
1822 :
1823 : WASM_SIMD_COMPILED_TEST(S16x8Irregular) {
1824 : RunBinaryLaneOpTest<int8_t>(
1825 : execution_mode, kExprS8x16Shuffle,
1826 : {{0, 1, 16, 17, 16, 17, 0, 1, 4, 5, 20, 21, 6, 7, 22, 23}});
1827 : RunBinaryLaneOpTest<int8_t>(
1828 : execution_mode, kExprS8x16Shuffle,
1829 : {{0, 1, 0, 1, 0, 1, 0, 1, 4, 5, 4, 5, 6, 7, 6, 7}});
1830 : }
1831 :
1832 : WASM_SIMD_COMPILED_TEST(S8x16Dup) {
1833 : RunBinaryLaneOpTest<int8_t>(
1834 : execution_mode, kExprS8x16Shuffle,
1835 : {{19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19}});
1836 : RunBinaryLaneOpTest<int8_t>(
1837 : execution_mode, kExprS8x16Shuffle,
1838 : {{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}});
1839 : }
1840 :
1841 : WASM_SIMD_COMPILED_TEST(S8x16ZipLeft) {
1842 : RunBinaryLaneOpTest<int8_t>(
1843 : execution_mode, kExprS8x16Shuffle,
1844 : {{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}});
1845 : RunBinaryLaneOpTest<int8_t>(
1846 : execution_mode, kExprS8x16Shuffle,
1847 : {{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}});
1848 : }
1849 :
1850 : WASM_SIMD_COMPILED_TEST(S8x16ZipRight) {
1851 : RunBinaryLaneOpTest<int8_t>(
1852 : execution_mode, kExprS8x16Shuffle,
1853 : {{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31}});
1854 : RunBinaryLaneOpTest<int8_t>(
1855 : execution_mode, kExprS8x16Shuffle,
1856 : {{8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}});
1857 : }
1858 :
1859 : WASM_SIMD_COMPILED_TEST(S8x16UnzipLeft) {
1860 : RunBinaryLaneOpTest<int8_t>(
1861 : execution_mode, kExprS8x16Shuffle,
1862 : {{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}});
1863 : RunBinaryLaneOpTest<int8_t>(
1864 : execution_mode, kExprS8x16Shuffle,
1865 : {{0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14}});
1866 : }
1867 :
1868 : WASM_SIMD_COMPILED_TEST(S8x16UnzipRight) {
1869 : RunBinaryLaneOpTest<int8_t>(
1870 : execution_mode, kExprS8x16Shuffle,
1871 : {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}});
1872 : RunBinaryLaneOpTest<int8_t>(
1873 : execution_mode, kExprS8x16Shuffle,
1874 : {{1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, 7, 9, 11, 13, 15}});
1875 : }
1876 :
1877 : WASM_SIMD_COMPILED_TEST(S8x16TransposeLeft) {
1878 : RunBinaryLaneOpTest<int8_t>(
1879 : execution_mode, kExprS8x16Shuffle,
1880 : {{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30}});
1881 : RunBinaryLaneOpTest<int8_t>(
1882 : execution_mode, kExprS8x16Shuffle,
1883 : {{0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}});
1884 : }
1885 :
1886 : WASM_SIMD_COMPILED_TEST(S8x16TransposeRight) {
1887 : RunBinaryLaneOpTest<int8_t>(
1888 : execution_mode, kExprS8x16Shuffle,
1889 : {{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31}});
1890 : RunBinaryLaneOpTest<int8_t>(
1891 : execution_mode, kExprS8x16Shuffle,
1892 : {{1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}});
1893 : }
1894 :
1895 : WASM_SIMD_COMPILED_TEST(S8x8Reverse) {
1896 : RunBinaryLaneOpTest<int8_t>(
1897 : execution_mode, kExprS8x16Shuffle,
1898 : {{7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8}});
1899 : }
1900 :
1901 : WASM_SIMD_COMPILED_TEST(S8x4Reverse) {
1902 : RunBinaryLaneOpTest<int8_t>(
1903 : execution_mode, kExprS8x16Shuffle,
1904 : {{3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12}});
1905 : }
1906 :
1907 : WASM_SIMD_COMPILED_TEST(S8x2Reverse) {
1908 : RunBinaryLaneOpTest<int8_t>(
1909 : execution_mode, kExprS8x16Shuffle,
1910 : {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}});
1911 : }
1912 :
1913 : WASM_SIMD_COMPILED_TEST(S8x16Irregular) {
1914 : RunBinaryLaneOpTest<int8_t>(
1915 : execution_mode, kExprS8x16Shuffle,
1916 : {{0, 16, 0, 16, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}});
1917 : RunBinaryLaneOpTest<int8_t>(
1918 : execution_mode, kExprS8x16Shuffle,
1919 : {{0, 0, 0, 0, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}});
1920 : }
1921 :
1922 : // Test shuffles that concatenate the two vectors.
1923 :
1924 : WASM_SIMD_COMPILED_TEST(S8x16Concat) {
1925 : static const int kLanes = 16;
1926 : std::array<uint8_t, kLanes> expected;
1927 : for (int bias = 1; bias < kLanes; bias++) {
1928 : int i = 0;
1929 : // last kLanes - bias bytes of first vector.
1930 : for (int j = bias; j < kLanes; j++) {
1931 : expected[i++] = j;
1932 : }
1933 : // first bias lanes of second vector
1934 : for (int j = 0; j < bias; j++) {
1935 : expected[i++] = j + kLanes;
1936 : }
1937 : RunBinaryLaneOpTest(execution_mode, kExprS8x16Shuffle, expected);
1938 : }
1939 : }
1940 :
1941 : // Boolean unary operations are 'AllTrue' and 'AnyTrue', which return an integer
1942 : // result. Use relational ops on numeric vectors to create the boolean vector
1943 : // test inputs. Test inputs with all true, all false, one true, and one false.
1944 : #define WASM_SIMD_BOOL_REDUCTION_TEST(format, lanes) \
1945 : WASM_SIMD_COMPILED_TEST(ReductionTest##lanes) { \
1946 : WasmRunner<int32_t> r(execution_mode); \
1947 : byte zero = r.AllocateLocal(kWasmS128); \
1948 : byte one_one = r.AllocateLocal(kWasmS128); \
1949 : byte reduced = r.AllocateLocal(kWasmI32); \
1950 : BUILD(r, WASM_SET_LOCAL(zero, WASM_SIMD_I##format##_SPLAT(WASM_ZERO)), \
1951 : WASM_SET_LOCAL( \
1952 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AnyTrue, \
1953 : WASM_SIMD_BINOP(kExprI##format##Eq, \
1954 : WASM_GET_LOCAL(zero), \
1955 : WASM_GET_LOCAL(zero)))), \
1956 : WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1957 : WASM_RETURN1(WASM_ZERO)), \
1958 : WASM_SET_LOCAL( \
1959 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AnyTrue, \
1960 : WASM_SIMD_BINOP(kExprI##format##Ne, \
1961 : WASM_GET_LOCAL(zero), \
1962 : WASM_GET_LOCAL(zero)))), \
1963 : WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1964 : WASM_RETURN1(WASM_ZERO)), \
1965 : WASM_SET_LOCAL( \
1966 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, \
1967 : WASM_SIMD_BINOP(kExprI##format##Eq, \
1968 : WASM_GET_LOCAL(zero), \
1969 : WASM_GET_LOCAL(zero)))), \
1970 : WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1971 : WASM_RETURN1(WASM_ZERO)), \
1972 : WASM_SET_LOCAL( \
1973 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, \
1974 : WASM_SIMD_BINOP(kExprI##format##Ne, \
1975 : WASM_GET_LOCAL(zero), \
1976 : WASM_GET_LOCAL(zero)))), \
1977 : WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1978 : WASM_RETURN1(WASM_ZERO)), \
1979 : WASM_SET_LOCAL(one_one, \
1980 : WASM_SIMD_I##format##_REPLACE_LANE( \
1981 : lanes - 1, WASM_GET_LOCAL(zero), WASM_ONE)), \
1982 : WASM_SET_LOCAL( \
1983 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AnyTrue, \
1984 : WASM_SIMD_BINOP(kExprI##format##Eq, \
1985 : WASM_GET_LOCAL(one_one), \
1986 : WASM_GET_LOCAL(zero)))), \
1987 : WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1988 : WASM_RETURN1(WASM_ZERO)), \
1989 : WASM_SET_LOCAL( \
1990 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AnyTrue, \
1991 : WASM_SIMD_BINOP(kExprI##format##Ne, \
1992 : WASM_GET_LOCAL(one_one), \
1993 : WASM_GET_LOCAL(zero)))), \
1994 : WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(reduced), WASM_ZERO), \
1995 : WASM_RETURN1(WASM_ZERO)), \
1996 : WASM_SET_LOCAL( \
1997 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, \
1998 : WASM_SIMD_BINOP(kExprI##format##Eq, \
1999 : WASM_GET_LOCAL(one_one), \
2000 : WASM_GET_LOCAL(zero)))), \
2001 : WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(reduced), WASM_ZERO), \
2002 : WASM_RETURN1(WASM_ZERO)), \
2003 : WASM_SET_LOCAL( \
2004 : reduced, WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, \
2005 : WASM_SIMD_BINOP(kExprI##format##Ne, \
2006 : WASM_GET_LOCAL(one_one), \
2007 : WASM_GET_LOCAL(zero)))), \
2008 : WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(reduced), WASM_ZERO), \
2009 : WASM_RETURN1(WASM_ZERO)), \
2010 : WASM_ONE); \
2011 : CHECK_EQ(1, r.Call()); \
2012 : }
2013 :
2014 : WASM_SIMD_BOOL_REDUCTION_TEST(32x4, 4)
2015 : WASM_SIMD_BOOL_REDUCTION_TEST(16x8, 8)
2016 : WASM_SIMD_BOOL_REDUCTION_TEST(8x16, 16)
2017 :
2018 : WASM_SIMD_TEST(SimdI32x4ExtractWithF32x4) {
2019 : WasmRunner<int32_t> r(execution_mode);
2020 : BUILD(r, WASM_IF_ELSE_I(
2021 : WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
2022 : 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))),
2023 : WASM_I32_REINTERPRET_F32(WASM_F32(30.5))),
2024 : WASM_I32V(1), WASM_I32V(0)));
2025 : CHECK_EQ(1, r.Call());
2026 : }
2027 :
2028 : WASM_SIMD_TEST(SimdF32x4ExtractWithI32x4) {
2029 : WasmRunner<int32_t> r(execution_mode);
2030 : BUILD(r,
2031 : WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
2032 : 0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(15))),
2033 : WASM_F32_REINTERPRET_I32(WASM_I32V(15))),
2034 : WASM_I32V(1), WASM_I32V(0)));
2035 : CHECK_EQ(1, r.Call());
2036 : }
2037 :
2038 : WASM_SIMD_TEST(SimdF32x4AddWithI32x4) {
2039 : // Choose two floating point values whose sum is normal and exactly
2040 : // representable as a float.
2041 : const int kOne = 0x3f800000;
2042 : const int kTwo = 0x40000000;
2043 : WasmRunner<int32_t> r(execution_mode);
2044 : BUILD(r,
2045 : WASM_IF_ELSE_I(
2046 : WASM_F32_EQ(
2047 : WASM_SIMD_F32x4_EXTRACT_LANE(
2048 : 0, WASM_SIMD_BINOP(kExprF32x4Add,
2049 : WASM_SIMD_I32x4_SPLAT(WASM_I32V(kOne)),
2050 : WASM_SIMD_I32x4_SPLAT(WASM_I32V(kTwo)))),
2051 : WASM_F32_ADD(WASM_F32_REINTERPRET_I32(WASM_I32V(kOne)),
2052 : WASM_F32_REINTERPRET_I32(WASM_I32V(kTwo)))),
2053 : WASM_I32V(1), WASM_I32V(0)));
2054 : CHECK_EQ(1, r.Call());
2055 : }
2056 :
2057 : WASM_SIMD_TEST(SimdI32x4AddWithF32x4) {
2058 : WasmRunner<int32_t> r(execution_mode);
2059 : BUILD(r,
2060 : WASM_IF_ELSE_I(
2061 : WASM_I32_EQ(
2062 : WASM_SIMD_I32x4_EXTRACT_LANE(
2063 : 0, WASM_SIMD_BINOP(kExprI32x4Add,
2064 : WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25)),
2065 : WASM_SIMD_F32x4_SPLAT(WASM_F32(31.5)))),
2066 : WASM_I32_ADD(WASM_I32_REINTERPRET_F32(WASM_F32(21.25)),
2067 : WASM_I32_REINTERPRET_F32(WASM_F32(31.5)))),
2068 : WASM_I32V(1), WASM_I32V(0)));
2069 : CHECK_EQ(1, r.Call());
2070 : }
2071 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
2072 : // V8_TARGET_ARCH_MIPS64
2073 :
2074 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
2075 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2076 23766 : WASM_SIMD_TEST(SimdI32x4Local) {
2077 12 : WasmRunner<int32_t> r(execution_mode);
2078 : r.AllocateLocal(kWasmS128);
2079 12 : BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
2080 :
2081 : WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(0)));
2082 12 : CHECK_EQ(31, r.Call());
2083 12 : }
2084 :
2085 23766 : WASM_SIMD_TEST(SimdI32x4SplatFromExtract) {
2086 12 : WasmRunner<int32_t> r(execution_mode);
2087 : r.AllocateLocal(kWasmI32);
2088 : r.AllocateLocal(kWasmS128);
2089 12 : BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_EXTRACT_LANE(
2090 : 0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(76)))),
2091 : WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0))),
2092 : WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)));
2093 12 : CHECK_EQ(76, r.Call());
2094 12 : }
2095 :
2096 23766 : WASM_SIMD_TEST(SimdI32x4For) {
2097 12 : WasmRunner<int32_t> r(execution_mode);
2098 : r.AllocateLocal(kWasmI32);
2099 : r.AllocateLocal(kWasmS128);
2100 12 : BUILD(r,
2101 :
2102 : WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
2103 : WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(1),
2104 : WASM_I32V(53))),
2105 : WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(1),
2106 : WASM_I32V(23))),
2107 : WASM_SET_LOCAL(0, WASM_I32V(0)),
2108 : WASM_LOOP(
2109 : WASM_SET_LOCAL(
2110 : 1, WASM_SIMD_BINOP(kExprI32x4Add, WASM_GET_LOCAL(1),
2111 : WASM_SIMD_I32x4_SPLAT(WASM_I32V(1)))),
2112 : WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(5)), WASM_BR(1))),
2113 : WASM_SET_LOCAL(0, WASM_I32V(1)),
2114 : WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
2115 : WASM_I32V(36)),
2116 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2117 : WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)),
2118 : WASM_I32V(58)),
2119 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2120 : WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(1)),
2121 : WASM_I32V(28)),
2122 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2123 : WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
2124 : WASM_I32V(36)),
2125 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2126 : WASM_GET_LOCAL(0));
2127 12 : CHECK_EQ(1, r.Call());
2128 12 : }
2129 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
2130 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2131 :
2132 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
2133 : V8_TARGET_ARCH_MIPS64
2134 : WASM_SIMD_TEST(SimdF32x4For) {
2135 : WasmRunner<int32_t> r(execution_mode);
2136 : r.AllocateLocal(kWasmI32);
2137 : r.AllocateLocal(kWasmS128);
2138 : BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25))),
2139 : WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
2140 : WASM_F32(19.5))),
2141 : WASM_SET_LOCAL(0, WASM_I32V(0)),
2142 : WASM_LOOP(
2143 : WASM_SET_LOCAL(
2144 : 1, WASM_SIMD_BINOP(kExprF32x4Add, WASM_GET_LOCAL(1),
2145 : WASM_SIMD_F32x4_SPLAT(WASM_F32(2.0)))),
2146 : WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(3)), WASM_BR(1))),
2147 : WASM_SET_LOCAL(0, WASM_I32V(1)),
2148 : WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
2149 : WASM_F32(27.25)),
2150 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2151 : WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
2152 : WASM_F32(25.5)),
2153 : WASM_SET_LOCAL(0, WASM_I32V(0))),
2154 : WASM_GET_LOCAL(0));
2155 : CHECK_EQ(1, r.Call());
2156 : }
2157 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
2158 : // V8_TARGET_ARCH_MIPS64
2159 :
2160 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
2161 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2162 :
2163 : template <typename T, int numLanes = 4>
2164 : void SetVectorByLanes(T* v, const std::array<T, numLanes>& arr) {
2165 48 : for (int lane = 0; lane < numLanes; lane++) {
2166 48 : const T& value = arr[lane];
2167 : #if defined(V8_TARGET_BIG_ENDIAN)
2168 : v[numLanes - 1 - lane] = value;
2169 : #else
2170 48 : v[lane] = value;
2171 : #endif
2172 : }
2173 : }
2174 :
2175 : template <typename T>
2176 : const T& GetScalar(T* v, int lane) {
2177 : constexpr int kElems = kSimd128Size / sizeof(T);
2178 : #if defined(V8_TARGET_BIG_ENDIAN)
2179 : const int index = kElems - 1 - lane;
2180 : #else
2181 : const int index = lane;
2182 : #endif
2183 : USE(kElems);
2184 : DCHECK(index >= 0 && index < kElems);
2185 : return v[index];
2186 : }
2187 :
2188 23766 : WASM_SIMD_TEST(SimdI32x4GetGlobal) {
2189 12 : WasmRunner<int32_t, int32_t> r(execution_mode);
2190 : // Pad the globals with a few unused slots to get a non-zero offset.
2191 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2192 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2193 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2194 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2195 12 : int32_t* global = r.builder().AddGlobal<int32_t>(kWasmS128);
2196 24 : SetVectorByLanes(global, {{0, 1, 2, 3}});
2197 : r.AllocateLocal(kWasmI32);
2198 12 : BUILD(
2199 : r, WASM_SET_LOCAL(1, WASM_I32V(1)),
2200 : WASM_IF(WASM_I32_NE(WASM_I32V(0),
2201 : WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(4))),
2202 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2203 : WASM_IF(WASM_I32_NE(WASM_I32V(1),
2204 : WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(4))),
2205 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2206 : WASM_IF(WASM_I32_NE(WASM_I32V(2),
2207 : WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(4))),
2208 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2209 : WASM_IF(WASM_I32_NE(WASM_I32V(3),
2210 : WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(4))),
2211 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2212 : WASM_GET_LOCAL(1));
2213 12 : CHECK_EQ(1, r.Call(0));
2214 12 : }
2215 :
2216 23766 : WASM_SIMD_TEST(SimdI32x4SetGlobal) {
2217 12 : WasmRunner<int32_t, int32_t> r(execution_mode);
2218 : // Pad the globals with a few unused slots to get a non-zero offset.
2219 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2220 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2221 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2222 : r.builder().AddGlobal<int32_t>(kWasmI32); // purposefully unused
2223 12 : int32_t* global = r.builder().AddGlobal<int32_t>(kWasmS128);
2224 12 : BUILD(r, WASM_SET_GLOBAL(4, WASM_SIMD_I32x4_SPLAT(WASM_I32V(23))),
2225 : WASM_SET_GLOBAL(4, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(4),
2226 : WASM_I32V(34))),
2227 : WASM_SET_GLOBAL(4, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(4),
2228 : WASM_I32V(45))),
2229 : WASM_SET_GLOBAL(4, WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(4),
2230 : WASM_I32V(56))),
2231 : WASM_I32V(1));
2232 12 : CHECK_EQ(1, r.Call(0));
2233 12 : CHECK_EQ(GetScalar(global, 0), 23);
2234 12 : CHECK_EQ(GetScalar(global, 1), 34);
2235 12 : CHECK_EQ(GetScalar(global, 2), 45);
2236 12 : CHECK_EQ(GetScalar(global, 3), 56);
2237 12 : }
2238 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
2239 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2240 :
2241 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
2242 : V8_TARGET_ARCH_MIPS64
2243 : WASM_SIMD_TEST(SimdF32x4GetGlobal) {
2244 : WasmRunner<int32_t, int32_t> r(execution_mode);
2245 : float* global = r.builder().AddGlobal<float>(kWasmS128);
2246 : SetVectorByLanes<float>(global, {{0.0, 1.5, 2.25, 3.5}});
2247 : r.AllocateLocal(kWasmI32);
2248 : BUILD(
2249 : r, WASM_SET_LOCAL(1, WASM_I32V(1)),
2250 : WASM_IF(WASM_F32_NE(WASM_F32(0.0),
2251 : WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
2252 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2253 : WASM_IF(WASM_F32_NE(WASM_F32(1.5),
2254 : WASM_SIMD_F32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
2255 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2256 : WASM_IF(WASM_F32_NE(WASM_F32(2.25),
2257 : WASM_SIMD_F32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
2258 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2259 : WASM_IF(WASM_F32_NE(WASM_F32(3.5),
2260 : WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
2261 : WASM_SET_LOCAL(1, WASM_I32V(0))),
2262 : WASM_GET_LOCAL(1));
2263 : CHECK_EQ(1, r.Call(0));
2264 : }
2265 :
2266 : WASM_SIMD_TEST(SimdF32x4SetGlobal) {
2267 : WasmRunner<int32_t, int32_t> r(execution_mode);
2268 : float* global = r.builder().AddGlobal<float>(kWasmS128);
2269 : BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_SPLAT(WASM_F32(13.5))),
2270 : WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
2271 : WASM_F32(45.5))),
2272 : WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
2273 : WASM_F32(32.25))),
2274 : WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
2275 : WASM_F32(65.0))),
2276 : WASM_I32V(1));
2277 : CHECK_EQ(1, r.Call(0));
2278 : CHECK_EQ(GetScalar(global, 0), 13.5f);
2279 : CHECK_EQ(GetScalar(global, 1), 45.5f);
2280 : CHECK_EQ(GetScalar(global, 2), 32.25f);
2281 : CHECK_EQ(GetScalar(global, 3), 65.0f);
2282 : }
2283 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||
2284 : // V8_TARGET_ARCH_MIPS64
2285 :
2286 : #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 || \
2287 : V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2288 23742 : WASM_SIMD_COMPILED_TEST(SimdLoadStoreLoad) {
2289 6 : WasmRunner<int32_t> r(execution_mode);
2290 : int32_t* memory = r.builder().AddMemoryElems<int32_t>(8);
2291 : // Load memory, store it, then reload it and extract the first lane. Use a
2292 : // non-zero offset into the memory of 1 lane (4 bytes) to test indexing.
2293 6 : BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(4), WASM_SIMD_LOAD_MEM(WASM_I32V(4))),
2294 : WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(4))));
2295 :
2296 354 : FOR_INT32_INPUTS(i) {
2297 348 : int32_t expected = *i;
2298 : r.builder().WriteMemory(&memory[1], expected);
2299 348 : CHECK_EQ(expected, r.Call());
2300 : }
2301 6 : }
2302 : #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 ||
2303 : // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
2304 :
2305 : #undef WASM_SIMD_TEST
2306 : #undef WASM_SIMD_COMPILED_TEST
2307 : #undef WASM_SIMD_CHECK_LANE
2308 : #undef WASM_SIMD_CHECK4
2309 : #undef WASM_SIMD_CHECK_SPLAT4
2310 : #undef WASM_SIMD_CHECK8
2311 : #undef WASM_SIMD_CHECK_SPLAT8
2312 : #undef WASM_SIMD_CHECK16
2313 : #undef WASM_SIMD_CHECK_SPLAT16
2314 : #undef WASM_SIMD_CHECK_F32_LANE
2315 : #undef WASM_SIMD_CHECK_F32x4
2316 : #undef WASM_SIMD_CHECK_SPLAT_F32x4
2317 : #undef WASM_SIMD_CHECK_F32_LANE_ESTIMATE
2318 : #undef WASM_SIMD_CHECK_SPLAT_F32x4_ESTIMATE
2319 : #undef TO_BYTE
2320 : #undef WASM_SIMD_OP
2321 : #undef WASM_SIMD_SPLAT
2322 : #undef WASM_SIMD_UNOP
2323 : #undef WASM_SIMD_BINOP
2324 : #undef WASM_SIMD_SHIFT_OP
2325 : #undef WASM_SIMD_CONCAT_OP
2326 : #undef WASM_SIMD_SELECT
2327 : #undef WASM_SIMD_F32x4_SPLAT
2328 : #undef WASM_SIMD_F32x4_EXTRACT_LANE
2329 : #undef WASM_SIMD_F32x4_REPLACE_LANE
2330 : #undef WASM_SIMD_I32x4_SPLAT
2331 : #undef WASM_SIMD_I32x4_EXTRACT_LANE
2332 : #undef WASM_SIMD_I32x4_REPLACE_LANE
2333 : #undef WASM_SIMD_I16x8_SPLAT
2334 : #undef WASM_SIMD_I16x8_EXTRACT_LANE
2335 : #undef WASM_SIMD_I16x8_REPLACE_LANE
2336 : #undef WASM_SIMD_I8x16_SPLAT
2337 : #undef WASM_SIMD_I8x16_EXTRACT_LANE
2338 : #undef WASM_SIMD_I8x16_REPLACE_LANE
2339 : #undef WASM_SIMD_S8x16_SHUFFLE_OP
2340 : #undef WASM_SIMD_LOAD_MEM
2341 : #undef WASM_SIMD_STORE_MEM
2342 : #undef WASM_SIMD_SELECT_TEST
2343 : #undef WASM_SIMD_NON_CANONICAL_SELECT_TEST
2344 : #undef WASM_SIMD_BOOL_REDUCTION_TEST
2345 :
2346 : } // namespace test_run_wasm_simd
2347 : } // namespace wasm
2348 : } // namespace internal
2349 71154 : } // namespace v8
|