LCOV - code coverage report
Current view: top level - test/cctest/wasm - test-run-wasm-simd.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 361 440 82.0 %
Date: 2017-10-20 Functions: 277 351 78.9 %

          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

Generated by: LCOV version 1.10