Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: test/cctest/wasm/test-run-wasm-simd.cc

Issue 2713613005: [wasm]implement simd lowering for F32x4 and I32x4 binops (Closed)
Patch Set: use namespace Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/assembler-inl.h" 5 #include "test/cctest/wasm/test-wasm-simd-common.h"
6 #include "src/wasm/wasm-macro-gen.h"
7 #include "test/cctest/cctest.h"
8 #include "test/cctest/compiler/value-helper.h"
9 #include "test/cctest/wasm/wasm-run-utils.h"
10 6
11 using namespace v8::base; 7 using namespace v8::base;
12 using namespace v8::internal; 8 using namespace v8::internal;
13 using namespace v8::internal::compiler; 9 using namespace v8::internal::compiler;
14 using namespace v8::internal::wasm; 10 using namespace v8::internal::wasm;
15 11
16 namespace { 12 namespace test_wasm_simd_common {
17
18 typedef float (*FloatUnOp)(float);
19 typedef float (*FloatBinOp)(float, float);
20 typedef int32_t (*FloatCompareOp)(float, float);
21 typedef int32_t (*Int32UnOp)(int32_t);
22 typedef int32_t (*Int32BinOp)(int32_t, int32_t);
23 typedef int32_t (*Int32ShiftOp)(int32_t, int);
24 typedef int16_t (*Int16UnOp)(int16_t);
25 typedef int16_t (*Int16BinOp)(int16_t, int16_t);
26 typedef int16_t (*Int16ShiftOp)(int16_t, int);
27 typedef int8_t (*Int8UnOp)(int8_t);
28 typedef int8_t (*Int8BinOp)(int8_t, int8_t);
29 typedef int8_t (*Int8ShiftOp)(int8_t, int);
30 13
31 #if V8_TARGET_ARCH_ARM 14 #if V8_TARGET_ARCH_ARM
15 namespace {
32 // Floating point specific value functions, only used by ARM so far. 16 // Floating point specific value functions, only used by ARM so far.
33 int32_t Equal(float a, float b) { return a == b ? 1 : 0; } 17 int32_t Equal(float a, float b) { return a == b ? 1 : 0; }
34 18
35 int32_t NotEqual(float a, float b) { return a != b ? 1 : 0; } 19 int32_t NotEqual(float a, float b) { return a != b ? 1 : 0; }
36 #endif // V8_TARGET_ARCH_ARM
37
38 // Generic expected value functions.
39 template <typename T>
40 T Negate(T a) {
41 return -a;
42 } 20 }
43 21
44 template <typename T> 22 WASM_EXEC_TEST(F32x4Splat) { RunF32x4SplatTest(); }
45 T Add(T a, T b) {
46 return a + b;
47 }
48 23
49 template <typename T> 24 WASM_EXEC_TEST(F32x4ReplaceLane) { RunF32x4ReplaceLaneTest(); }
50 T Sub(T a, T b) {
51 return a - b;
52 }
53
54 template <typename T>
55 T Mul(T a, T b) {
56 return a * b;
57 }
58
59 template <typename T>
60 T Minimum(T a, T b) {
61 return a <= b ? a : b;
62 }
63
64 template <typename T>
65 T Maximum(T a, T b) {
66 return a >= b ? a : b;
67 }
68
69 template <typename T>
70 T UnsignedMinimum(T a, T b) {
71 using UnsignedT = typename std::make_unsigned<T>::type;
72 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? a : b;
73 }
74
75 template <typename T>
76 T UnsignedMaximum(T a, T b) {
77 using UnsignedT = typename std::make_unsigned<T>::type;
78 return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? a : b;
79 }
80
81 template <typename T>
82 T Equal(T a, T b) {
83 return a == b ? 1 : 0;
84 }
85
86 template <typename T>
87 T NotEqual(T a, T b) {
88 return a != b ? 1 : 0;
89 }
90
91 template <typename T>
92 T Greater(T a, T b) {
93 return a > b ? 1 : 0;
94 }
95
96 template <typename T>
97 T GreaterEqual(T a, T b) {
98 return a >= b ? 1 : 0;
99 }
100
101 template <typename T>
102 T Less(T a, T b) {
103 return a < b ? 1 : 0;
104 }
105
106 template <typename T>
107 T LessEqual(T a, T b) {
108 return a <= b ? 1 : 0;
109 }
110
111 template <typename T>
112 T UnsignedGreater(T a, T b) {
113 using UnsignedT = typename std::make_unsigned<T>::type;
114 return static_cast<UnsignedT>(a) > static_cast<UnsignedT>(b) ? 1 : 0;
115 }
116
117 template <typename T>
118 T UnsignedGreaterEqual(T a, T b) {
119 using UnsignedT = typename std::make_unsigned<T>::type;
120 return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? 1 : 0;
121 }
122
123 template <typename T>
124 T UnsignedLess(T a, T b) {
125 using UnsignedT = typename std::make_unsigned<T>::type;
126 return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? 1 : 0;
127 }
128
129 template <typename T>
130 T UnsignedLessEqual(T a, T b) {
131 using UnsignedT = typename std::make_unsigned<T>::type;
132 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? 1 : 0;
133 }
134
135 template <typename T>
136 T LogicalShiftLeft(T a, int shift) {
137 return a << shift;
138 }
139
140 template <typename T>
141 T LogicalShiftRight(T a, int shift) {
142 using UnsignedT = typename std::make_unsigned<T>::type;
143 return static_cast<UnsignedT>(a) >> shift;
144 }
145
146 template <typename T>
147 int64_t Widen(T value) {
148 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
149 return static_cast<int64_t>(value);
150 }
151
152 template <typename T>
153 int64_t UnsignedWiden(T value) {
154 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
155 using UnsignedT = typename std::make_unsigned<T>::type;
156 return static_cast<int64_t>(static_cast<UnsignedT>(value));
157 }
158
159 template <typename T>
160 T Clamp(int64_t value) {
161 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
162 int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min());
163 int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max());
164 int64_t clamped = std::max(min, std::min(max, value));
165 return static_cast<T>(clamped);
166 }
167
168 template <typename T>
169 T AddSaturate(T a, T b) {
170 return Clamp<T>(Widen(a) + Widen(b));
171 }
172
173 template <typename T>
174 T SubSaturate(T a, T b) {
175 return Clamp<T>(Widen(a) - Widen(b));
176 }
177
178 template <typename T>
179 T UnsignedAddSaturate(T a, T b) {
180 using UnsignedT = typename std::make_unsigned<T>::type;
181 return Clamp<UnsignedT>(UnsignedWiden(a) + UnsignedWiden(b));
182 }
183
184 template <typename T>
185 T UnsignedSubSaturate(T a, T b) {
186 using UnsignedT = typename std::make_unsigned<T>::type;
187 return Clamp<UnsignedT>(UnsignedWiden(a) - UnsignedWiden(b));
188 }
189
190 template <typename T>
191 T And(T a, T b) {
192 return a & b;
193 }
194
195 template <typename T>
196 T Or(T a, T b) {
197 return a | b;
198 }
199
200 template <typename T>
201 T Xor(T a, T b) {
202 return a ^ b;
203 }
204
205 template <typename T>
206 T Not(T a) {
207 return ~a;
208 }
209
210 } // namespace
211
212 // TODO(gdeepti): These are tests using sample values to verify functional
213 // correctness of opcodes, add more tests for a range of values and macroize
214 // tests.
215
216 // TODO(bbudge) Figure out how to compare floats in Wasm code that can handle
217 // NaNs. For now, our tests avoid using NaNs.
218 #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
219 WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
220 WASM_SIMD_##TYPE##_EXTRACT_LANE( \
221 lane_index, WASM_GET_LOCAL(value))), \
222 WASM_RETURN1(WASM_ZERO))
223
224 #define WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3) \
225 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
226 , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
227 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
228 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3)
229
230 #define WASM_SIMD_CHECK_SPLAT4(TYPE, value, LANE_TYPE, lv) \
231 WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv, lv, lv, lv)
232
233 #define WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, lv5, \
234 lv6, lv7) \
235 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
236 , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
237 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
238 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
239 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
240 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
241 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
242 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7)
243
244 #define WASM_SIMD_CHECK_SPLAT8(TYPE, value, LANE_TYPE, lv) \
245 WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv)
246
247 #define WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, \
248 lv5, lv6, lv7, lv8, lv9, lv10, lv11, lv12, lv13, \
249 lv14, lv15) \
250 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
251 , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
252 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
253 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
254 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
255 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
256 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
257 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7), \
258 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv8, 8), \
259 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv9, 9), \
260 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv10, 10), \
261 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv11, 11), \
262 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv12, 12), \
263 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv13, 13), \
264 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv14, 14), \
265 WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv15, 15)
266
267 #define WASM_SIMD_CHECK_SPLAT16(TYPE, value, LANE_TYPE, lv) \
268 WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv, \
269 lv, lv, lv, lv, lv, lv, lv, lv)
270
271 #define WASM_SIMD_CHECK_F32_LANE(TYPE, value, lane_value, lane_index) \
272 WASM_IF( \
273 WASM_I32_NE(WASM_I32_REINTERPRET_F32(WASM_GET_LOCAL(lane_value)), \
274 WASM_I32_REINTERPRET_F32(WASM_SIMD_##TYPE##_EXTRACT_LANE( \
275 lane_index, WASM_GET_LOCAL(value)))), \
276 WASM_RETURN1(WASM_ZERO))
277
278 #define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \
279 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \
280 , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \
281 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \
282 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3)
283
284 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \
285 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv)
286
287 #define TO_BYTE(val) static_cast<byte>(val)
288 #define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op)
289 #define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat)
290 #define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op)
291 #define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op)
292 #define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift)
293 #define WASM_SIMD_SELECT(format, x, y, z) \
294 x, y, z, WASM_SIMD_OP(kExprS##format##Select)
295 // Since boolean vectors can't be checked directly, materialize them into
296 // integer vectors using a Select operation.
297 #define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \
298 x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \
299 WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \
300 WASM_SIMD_OP(kExprS##format##Select)
301
302 #define WASM_SIMD_I16x8_SPLAT(x) x, WASM_SIMD_OP(kExprI16x8Splat)
303 #define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \
304 x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane)
305 #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \
306 x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane)
307 #define WASM_SIMD_I8x16_SPLAT(x) x, WASM_SIMD_OP(kExprI8x16Splat)
308 #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \
309 x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane)
310 #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \
311 x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane)
312
313 #define WASM_SIMD_F32x4_FROM_I32x4(x) x, WASM_SIMD_OP(kExprF32x4SConvertI32x4)
314 #define WASM_SIMD_F32x4_FROM_U32x4(x) x, WASM_SIMD_OP(kExprF32x4UConvertI32x4)
315 #define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4)
316 #define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4)
317
318 #if V8_TARGET_ARCH_ARM
319 WASM_EXEC_TEST(F32x4Splat) {
320 FLAG_wasm_simd_prototype = true;
321
322 WasmRunner<int32_t, float> r(kExecuteCompiled);
323 byte lane_val = 0;
324 byte simd = r.AllocateLocal(kWasmS128);
325 BUILD(r,
326 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
327 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), WASM_ONE);
328
329 FOR_FLOAT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
330 }
331
332 WASM_EXEC_TEST(F32x4ReplaceLane) {
333 FLAG_wasm_simd_prototype = true;
334 WasmRunner<int32_t, float, float> r(kExecuteCompiled);
335 byte old_val = 0;
336 byte new_val = 1;
337 byte simd = r.AllocateLocal(kWasmS128);
338 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(old_val))),
339 WASM_SET_LOCAL(simd,
340 WASM_SIMD_F32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
341 WASM_GET_LOCAL(new_val))),
342 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, old_val, old_val, old_val),
343 WASM_SET_LOCAL(simd,
344 WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
345 WASM_GET_LOCAL(new_val))),
346 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, old_val, old_val),
347 WASM_SET_LOCAL(simd,
348 WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
349 WASM_GET_LOCAL(new_val))),
350 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, new_val, old_val),
351 WASM_SET_LOCAL(simd,
352 WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
353 WASM_GET_LOCAL(new_val))),
354 WASM_SIMD_CHECK_SPLAT4(F32x4, simd, F32, new_val), WASM_ONE);
355
356 CHECK_EQ(1, r.Call(3.14159, -1.5));
357 }
358 25
359 // Tests both signed and unsigned conversion. 26 // Tests both signed and unsigned conversion.
360 WASM_EXEC_TEST(F32x4FromInt32x4) { 27 WASM_EXEC_TEST(F32x4FromInt32x4) {
361 FLAG_wasm_simd_prototype = true; 28 FLAG_wasm_simd_prototype = true;
362 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled); 29 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled);
363 byte a = 0; 30 byte a = 0;
364 byte expected_signed = 1; 31 byte expected_signed = 1;
365 byte expected_unsigned = 2; 32 byte expected_unsigned = 2;
366 byte simd0 = r.AllocateLocal(kWasmS128); 33 byte simd0 = r.AllocateLocal(kWasmS128);
367 byte simd1 = r.AllocateLocal(kWasmS128); 34 byte simd1 = r.AllocateLocal(kWasmS128);
(...skipping 23 matching lines...) Expand all
391 58
392 FOR_FLOAT32_INPUTS(i) { 59 FOR_FLOAT32_INPUTS(i) {
393 if (std::isnan(*i)) continue; 60 if (std::isnan(*i)) continue;
394 CHECK_EQ(1, r.Call(*i, expected_op(*i))); 61 CHECK_EQ(1, r.Call(*i, expected_op(*i)));
395 } 62 }
396 } 63 }
397 64
398 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } 65 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
399 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } 66 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); }
400 67
401 void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) {
402 FLAG_wasm_simd_prototype = true;
403 WasmRunner<int32_t, float, float, float> r(kExecuteCompiled);
404 byte a = 0;
405 byte b = 1;
406 byte expected = 2;
407 byte simd0 = r.AllocateLocal(kWasmS128);
408 byte simd1 = r.AllocateLocal(kWasmS128);
409 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
410 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))),
411 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
412 WASM_GET_LOCAL(simd1))),
413 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), WASM_ONE);
414
415 FOR_FLOAT32_INPUTS(i) {
416 if (std::isnan(*i)) continue;
417 FOR_FLOAT32_INPUTS(j) {
418 if (std::isnan(*j)) continue;
419 float expected = expected_op(*i, *j);
420 // SIMD on some platforms may handle denormalized numbers differently.
421 // TODO(bbudge) On platforms that flush denorms to zero, test with
422 // expected == 0.
423 if (std::fpclassify(expected) == FP_SUBNORMAL) continue;
424 CHECK_EQ(1, r.Call(*i, *j, expected));
425 }
426 }
427 }
428
429 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } 68 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); }
430 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } 69 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); }
431 70
432 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) { 71 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) {
433 FLAG_wasm_simd_prototype = true; 72 FLAG_wasm_simd_prototype = true;
434 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled); 73 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled);
435 byte a = 0; 74 byte a = 0;
436 byte b = 1; 75 byte b = 1;
437 byte expected = 2; 76 byte expected = 2;
438 byte simd0 = r.AllocateLocal(kWasmS128); 77 byte simd0 = r.AllocateLocal(kWasmS128);
(...skipping 15 matching lines...) Expand all
454 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue; 93 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue;
455 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); 94 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j)));
456 } 95 }
457 } 96 }
458 } 97 }
459 98
460 WASM_EXEC_TEST(F32x4Equal) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); } 99 WASM_EXEC_TEST(F32x4Equal) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); }
461 WASM_EXEC_TEST(F32x4NotEqual) { RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); } 100 WASM_EXEC_TEST(F32x4NotEqual) { RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); }
462 #endif // V8_TARGET_ARCH_ARM 101 #endif // V8_TARGET_ARCH_ARM
463 102
464 WASM_EXEC_TEST(I32x4Splat) { 103 WASM_EXEC_TEST(I32x4Splat) { RunI32x4SplatTest(); }
465 FLAG_wasm_simd_prototype = true;
466 104
467 // Store SIMD value in a local variable, use extract lane to check lane values 105 WASM_EXEC_TEST(I32x4ReplaceLane) { RunI32x4ReplaceLaneTest(); }
468 // This test is not a test for ExtractLane as Splat does not create
469 // interesting SIMD values.
470 //
471 // SetLocal(1, I32x4Splat(Local(0)));
472 // For each lane index
473 // if(Local(0) != I32x4ExtractLane(Local(1), index)
474 // return 0
475 //
476 // return 1
477 WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
478 byte lane_val = 0;
479 byte simd = r.AllocateLocal(kWasmS128);
480 BUILD(r,
481 WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
482 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, lane_val), WASM_ONE);
483
484 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
485 }
486
487 WASM_EXEC_TEST(I32x4ReplaceLane) {
488 FLAG_wasm_simd_prototype = true;
489 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
490 byte old_val = 0;
491 byte new_val = 1;
492 byte simd = r.AllocateLocal(kWasmS128);
493 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(old_val))),
494 WASM_SET_LOCAL(simd,
495 WASM_SIMD_I32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
496 WASM_GET_LOCAL(new_val))),
497 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, old_val, old_val, old_val),
498 WASM_SET_LOCAL(simd,
499 WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
500 WASM_GET_LOCAL(new_val))),
501 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, old_val, old_val),
502 WASM_SET_LOCAL(simd,
503 WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
504 WASM_GET_LOCAL(new_val))),
505 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, new_val, old_val),
506 WASM_SET_LOCAL(simd,
507 WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
508 WASM_GET_LOCAL(new_val))),
509 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, new_val), WASM_ONE);
510
511 CHECK_EQ(1, r.Call(1, 2));
512 }
513 106
514 #if V8_TARGET_ARCH_ARM 107 #if V8_TARGET_ARCH_ARM
515 108
516 WASM_EXEC_TEST(I16x8Splat) { 109 WASM_EXEC_TEST(I16x8Splat) {
517 FLAG_wasm_simd_prototype = true; 110 FLAG_wasm_simd_prototype = true;
518 111
519 WasmRunner<int32_t, int32_t> r(kExecuteCompiled); 112 WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
520 byte lane_val = 0; 113 byte lane_val = 0;
521 byte simd = r.AllocateLocal(kWasmS128); 114 byte simd = r.AllocateLocal(kWasmS128);
522 BUILD(r, 115 BUILD(r,
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); 362 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE);
770 363
771 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } 364 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
772 } 365 }
773 366
774 WASM_EXEC_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); } 367 WASM_EXEC_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); }
775 368
776 WASM_EXEC_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); } 369 WASM_EXEC_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); }
777 #endif // V8_TARGET_ARCH_ARM 370 #endif // V8_TARGET_ARCH_ARM
778 371
779 void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
780 FLAG_wasm_simd_prototype = true;
781 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled);
782 byte a = 0;
783 byte b = 1;
784 byte expected = 2;
785 byte simd0 = r.AllocateLocal(kWasmS128);
786 byte simd1 = r.AllocateLocal(kWasmS128);
787 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
788 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))),
789 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0),
790 WASM_GET_LOCAL(simd1))),
791 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
792
793 FOR_INT32_INPUTS(i) {
794 FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
795 }
796 }
797
798 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } 372 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); }
799 373
800 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } 374 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); }
801 375
802 #if V8_TARGET_ARCH_ARM 376 #if V8_TARGET_ARCH_ARM
803 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); } 377 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); }
804 378
805 WASM_EXEC_TEST(I32x4Min) { RunI32x4BinOpTest(kExprI32x4MinS, Minimum); } 379 WASM_EXEC_TEST(I32x4Min) { RunI32x4BinOpTest(kExprI32x4MinS, Minimum); }
806 380
807 WASM_EXEC_TEST(I32x4Max) { RunI32x4BinOpTest(kExprI32x4MaxS, Maximum); } 381 WASM_EXEC_TEST(I32x4Max) { RunI32x4BinOpTest(kExprI32x4MaxS, Maximum); }
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \ 802 WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \
1229 WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \ 803 WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \
1230 \ 804 \
1231 CHECK_EQ(1, r.Call(0x12, 0x34)); \ 805 CHECK_EQ(1, r.Call(0x12, 0x34)); \
1232 } 806 }
1233 807
1234 WASM_SIMD_SELECT_TEST(32x4) 808 WASM_SIMD_SELECT_TEST(32x4)
1235 WASM_SIMD_SELECT_TEST(16x8) 809 WASM_SIMD_SELECT_TEST(16x8)
1236 WASM_SIMD_SELECT_TEST(8x16) 810 WASM_SIMD_SELECT_TEST(8x16)
1237 #endif // V8_TARGET_ARCH_ARM 811 #endif // V8_TARGET_ARCH_ARM
812 } // namespace test_wasm_simd_common
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698