OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/wasm/wasm-macro-gen.h" | 6 #include "src/wasm/wasm-macro-gen.h" |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 #include "test/cctest/wasm/wasm-run-utils.h" | 9 #include "test/cctest/wasm/wasm-run-utils.h" |
10 | 10 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 return a << shift; | 162 return a << shift; |
163 } | 163 } |
164 | 164 |
165 template <typename T> | 165 template <typename T> |
166 T LogicalShiftRight(T a, int shift) { | 166 T LogicalShiftRight(T a, int shift) { |
167 using UnsignedT = typename std::make_unsigned<T>::type; | 167 using UnsignedT = typename std::make_unsigned<T>::type; |
168 return static_cast<UnsignedT>(a) >> shift; | 168 return static_cast<UnsignedT>(a) >> shift; |
169 } | 169 } |
170 | 170 |
171 template <typename T> | 171 template <typename T> |
| 172 T Clamp(int64_t value) { |
| 173 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 174 int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); |
| 175 int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); |
| 176 int64_t clamped = std::max(min, std::min(max, value)); |
| 177 return static_cast<T>(clamped); |
| 178 } |
| 179 |
| 180 template <typename T> |
172 int64_t Widen(T value) { | 181 int64_t Widen(T value) { |
173 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); | 182 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
174 return static_cast<int64_t>(value); | 183 return static_cast<int64_t>(value); |
175 } | 184 } |
176 | 185 |
177 template <typename T> | 186 template <typename T> |
178 int64_t UnsignedWiden(T value) { | 187 int64_t UnsignedWiden(T value) { |
179 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); | 188 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
180 using UnsignedT = typename std::make_unsigned<T>::type; | 189 using UnsignedT = typename std::make_unsigned<T>::type; |
181 return static_cast<int64_t>(static_cast<UnsignedT>(value)); | 190 return static_cast<int64_t>(static_cast<UnsignedT>(value)); |
182 } | 191 } |
183 | 192 |
184 template <typename T> | 193 template <typename T> |
185 T Clamp(int64_t value) { | 194 T Narrow(int64_t value) { |
186 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); | 195 return Clamp<T>(value); |
187 int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); | |
188 int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); | |
189 int64_t clamped = std::max(min, std::min(max, value)); | |
190 return static_cast<T>(clamped); | |
191 } | 196 } |
192 | 197 |
193 template <typename T> | 198 template <typename T> |
| 199 T UnsignedNarrow(int64_t value) { |
| 200 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 201 using UnsignedT = typename std::make_unsigned<T>::type; |
| 202 return static_cast<T>(Clamp<UnsignedT>(value & 0xffffffffu)); |
| 203 } |
| 204 |
| 205 template <typename T> |
194 T AddSaturate(T a, T b) { | 206 T AddSaturate(T a, T b) { |
195 return Clamp<T>(Widen(a) + Widen(b)); | 207 return Clamp<T>(Widen(a) + Widen(b)); |
196 } | 208 } |
197 | 209 |
198 template <typename T> | 210 template <typename T> |
199 T SubSaturate(T a, T b) { | 211 T SubSaturate(T a, T b) { |
200 return Clamp<T>(Widen(a) - Widen(b)); | 212 return Clamp<T>(Widen(a) - Widen(b)); |
201 } | 213 } |
202 | 214 |
203 template <typename T> | 215 template <typename T> |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane) | 392 x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane) |
381 #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \ | 393 #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \ |
382 x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane) | 394 x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane) |
383 | 395 |
384 #define WASM_SIMD_I8x16_SPLAT(x) x, WASM_SIMD_OP(kExprI8x16Splat) | 396 #define WASM_SIMD_I8x16_SPLAT(x) x, WASM_SIMD_OP(kExprI8x16Splat) |
385 #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ | 397 #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ |
386 x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) | 398 x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) |
387 #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ | 399 #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ |
388 x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) | 400 x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) |
389 | 401 |
390 #define WASM_SIMD_F32x4_FROM_I32x4(x) x, WASM_SIMD_OP(kExprF32x4SConvertI32x4) | |
391 #define WASM_SIMD_F32x4_FROM_U32x4(x) x, WASM_SIMD_OP(kExprF32x4UConvertI32x4) | |
392 #define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4) | |
393 #define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4) | |
394 | |
395 // Skip FP tests involving extremely large or extremely small values, which | 402 // Skip FP tests involving extremely large or extremely small values, which |
396 // may fail due to non-IEEE-754 SIMD arithmetic on some platforms. | 403 // may fail due to non-IEEE-754 SIMD arithmetic on some platforms. |
397 bool SkipFPValue(float x) { | 404 bool SkipFPValue(float x) { |
398 float abs_x = std::fabs(x); | 405 float abs_x = std::fabs(x); |
399 const float kSmallFloatThreshold = 1.0e-32f; | 406 const float kSmallFloatThreshold = 1.0e-32f; |
400 const float kLargeFloatThreshold = 1.0e32f; | 407 const float kLargeFloatThreshold = 1.0e32f; |
401 return abs_x != 0.0f && // 0 or -0 are fine. | 408 return abs_x != 0.0f && // 0 or -0 are fine. |
402 (abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold); | 409 (abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold); |
403 } | 410 } |
404 | 411 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // Tests both signed and unsigned conversion. | 461 // Tests both signed and unsigned conversion. |
455 WASM_EXEC_COMPILED_TEST(F32x4ConvertI32x4) { | 462 WASM_EXEC_COMPILED_TEST(F32x4ConvertI32x4) { |
456 FLAG_wasm_simd_prototype = true; | 463 FLAG_wasm_simd_prototype = true; |
457 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled); | 464 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled); |
458 byte a = 0; | 465 byte a = 0; |
459 byte expected_signed = 1; | 466 byte expected_signed = 1; |
460 byte expected_unsigned = 2; | 467 byte expected_unsigned = 2; |
461 byte simd0 = r.AllocateLocal(kWasmS128); | 468 byte simd0 = r.AllocateLocal(kWasmS128); |
462 byte simd1 = r.AllocateLocal(kWasmS128); | 469 byte simd1 = r.AllocateLocal(kWasmS128); |
463 byte simd2 = r.AllocateLocal(kWasmS128); | 470 byte simd2 = r.AllocateLocal(kWasmS128); |
464 BUILD( | 471 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
465 r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 472 WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprF32x4SConvertI32x4, |
466 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_FROM_I32x4(WASM_GET_LOCAL(simd0))), | 473 WASM_GET_LOCAL(simd0))), |
467 WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected_signed), | 474 WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected_signed), |
468 WASM_SET_LOCAL(simd2, WASM_SIMD_F32x4_FROM_U32x4(WASM_GET_LOCAL(simd0))), | 475 WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprF32x4UConvertI32x4, |
469 WASM_SIMD_CHECK_SPLAT_F32x4(simd2, expected_unsigned), | 476 WASM_GET_LOCAL(simd0))), |
470 WASM_RETURN1(WASM_ONE)); | 477 WASM_SIMD_CHECK_SPLAT_F32x4(simd2, expected_unsigned), |
| 478 WASM_RETURN1(WASM_ONE)); |
471 | 479 |
472 FOR_INT32_INPUTS(i) { | 480 FOR_INT32_INPUTS(i) { |
473 CHECK_EQ(1, r.Call(*i, static_cast<float>(*i), | 481 CHECK_EQ(1, r.Call(*i, static_cast<float>(*i), |
474 static_cast<float>(static_cast<uint32_t>(*i)))); | 482 static_cast<float>(static_cast<uint32_t>(*i)))); |
475 } | 483 } |
476 } | 484 } |
477 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET || V8_TARGET_ARCH_MIPS || | 485 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET || V8_TARGET_ARCH_MIPS || |
478 // V8_TARGET_ARCH_MIPS64 | 486 // V8_TARGET_ARCH_MIPS64 |
479 | 487 |
480 #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 488 #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 int32_t result = | 897 int32_t result = |
890 unsigned_integer ? static_cast<uint32_t>(val) : static_cast<int32_t>(val); | 898 unsigned_integer ? static_cast<uint32_t>(val) : static_cast<int32_t>(val); |
891 | 899 |
892 if (!CanRoundToZeroAndConvert(val, unsigned_integer)) { | 900 if (!CanRoundToZeroAndConvert(val, unsigned_integer)) { |
893 result = ConvertInvalidValue(val, unsigned_integer); | 901 result = ConvertInvalidValue(val, unsigned_integer); |
894 } | 902 } |
895 return result; | 903 return result; |
896 } | 904 } |
897 | 905 |
898 // Tests both signed and unsigned conversion. | 906 // Tests both signed and unsigned conversion. |
899 WASM_EXEC_COMPILED_TEST(I32x4Convert32x4) { | 907 WASM_EXEC_COMPILED_TEST(I32x4ConvertF32x4) { |
900 FLAG_wasm_simd_prototype = true; | 908 FLAG_wasm_simd_prototype = true; |
901 WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled); | 909 WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled); |
902 byte a = 0; | 910 byte a = 0; |
903 byte expected_signed = 1; | 911 byte expected_signed = 1; |
904 byte expected_unsigned = 2; | 912 byte expected_unsigned = 2; |
905 byte simd0 = r.AllocateLocal(kWasmS128); | 913 byte simd0 = r.AllocateLocal(kWasmS128); |
906 byte simd1 = r.AllocateLocal(kWasmS128); | 914 byte simd1 = r.AllocateLocal(kWasmS128); |
907 byte simd2 = r.AllocateLocal(kWasmS128); | 915 byte simd2 = r.AllocateLocal(kWasmS128); |
908 BUILD( | 916 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
909 r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 917 WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertF32x4, |
910 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), | 918 WASM_GET_LOCAL(simd0))), |
911 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), | 919 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), |
912 WASM_SET_LOCAL(simd2, WASM_SIMD_U32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), | 920 WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertF32x4, |
913 WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE); | 921 WASM_GET_LOCAL(simd0))), |
| 922 WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE); |
914 | 923 |
915 FOR_FLOAT32_INPUTS(i) { | 924 FOR_FLOAT32_INPUTS(i) { |
916 if (SkipFPValue(*i)) continue; | 925 if (SkipFPValue(*i)) continue; |
917 int32_t signed_value = ConvertToInt(*i, false); | 926 int32_t signed_value = ConvertToInt(*i, false); |
918 int32_t unsigned_value = ConvertToInt(*i, true); | 927 int32_t unsigned_value = ConvertToInt(*i, true); |
919 CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value)); | 928 CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value)); |
920 } | 929 } |
921 } | 930 } |
922 | 931 |
| 932 #if V8_TARGET_ARCH_ARM |
| 933 // Tests both signed and unsigned conversion from I16x8 (unpacking). |
| 934 WASM_EXEC_COMPILED_TEST(I32x4ConvertI16x8) { |
| 935 FLAG_wasm_simd_prototype = true; |
| 936 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 937 byte a = 0; |
| 938 byte unpacked_signed = 1; |
| 939 byte unpacked_unsigned = 2; |
| 940 byte simd0 = r.AllocateLocal(kWasmS128); |
| 941 byte simd1 = r.AllocateLocal(kWasmS128); |
| 942 byte simd2 = r.AllocateLocal(kWasmS128); |
| 943 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
| 944 WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertI16x8Low, |
| 945 WASM_GET_LOCAL(simd0))), |
| 946 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, unpacked_signed), |
| 947 WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertI16x8High, |
| 948 WASM_GET_LOCAL(simd0))), |
| 949 WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, unpacked_unsigned), WASM_ONE); |
| 950 |
| 951 FOR_INT16_INPUTS(i) { |
| 952 int32_t unpacked_signed = Widen<int16_t>(*i); |
| 953 int32_t unpacked_unsigned = UnsignedWiden<int16_t>(*i); |
| 954 CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned)); |
| 955 } |
| 956 } |
| 957 #endif // V8_TARGET_ARCH_ARM |
| 958 |
923 void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { | 959 void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { |
924 FLAG_wasm_simd_prototype = true; | 960 FLAG_wasm_simd_prototype = true; |
925 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 961 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
926 byte a = 0; | 962 byte a = 0; |
927 byte expected = 1; | 963 byte expected = 1; |
928 byte simd = r.AllocateLocal(kWasmS128); | 964 byte simd = r.AllocateLocal(kWasmS128); |
929 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 965 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
930 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), | 966 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
931 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); | 967 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), WASM_ONE); |
932 | 968 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 WASM_EXEC_COMPILED_TEST(I32x4ShrS) { | 1111 WASM_EXEC_COMPILED_TEST(I32x4ShrS) { |
1076 RunI32x4ShiftOpTest(kExprI32x4ShrS, ArithmeticShiftRight, 1); | 1112 RunI32x4ShiftOpTest(kExprI32x4ShrS, ArithmeticShiftRight, 1); |
1077 } | 1113 } |
1078 | 1114 |
1079 WASM_EXEC_COMPILED_TEST(I32x4ShrU) { | 1115 WASM_EXEC_COMPILED_TEST(I32x4ShrU) { |
1080 RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1); | 1116 RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1); |
1081 } | 1117 } |
1082 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET | 1118 #endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET |
1083 | 1119 |
1084 #if V8_TARGET_ARCH_ARM | 1120 #if V8_TARGET_ARCH_ARM |
| 1121 // Tests both signed and unsigned conversion from I8x16 (unpacking). |
| 1122 WASM_EXEC_COMPILED_TEST(I16x8ConvertI8x16) { |
| 1123 FLAG_wasm_simd_prototype = true; |
| 1124 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1125 byte a = 0; |
| 1126 byte unpacked_signed = 1; |
| 1127 byte unpacked_unsigned = 2; |
| 1128 byte simd0 = r.AllocateLocal(kWasmS128); |
| 1129 byte simd1 = r.AllocateLocal(kWasmS128); |
| 1130 byte simd2 = r.AllocateLocal(kWasmS128); |
| 1131 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
| 1132 WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI16x8SConvertI8x16Low, |
| 1133 WASM_GET_LOCAL(simd0))), |
| 1134 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, unpacked_signed), |
| 1135 WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI16x8UConvertI8x16High, |
| 1136 WASM_GET_LOCAL(simd0))), |
| 1137 WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, unpacked_unsigned), WASM_ONE); |
| 1138 |
| 1139 FOR_INT8_INPUTS(i) { |
| 1140 int32_t unpacked_signed = Widen<int8_t>(*i); |
| 1141 int32_t unpacked_unsigned = UnsignedWiden<int8_t>(*i); |
| 1142 CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned)); |
| 1143 } |
| 1144 } |
| 1145 |
1085 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { | 1146 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { |
1086 FLAG_wasm_simd_prototype = true; | 1147 FLAG_wasm_simd_prototype = true; |
1087 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 1148 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
1088 byte a = 0; | 1149 byte a = 0; |
1089 byte expected = 1; | 1150 byte expected = 1; |
1090 byte simd = r.AllocateLocal(kWasmS128); | 1151 byte simd = r.AllocateLocal(kWasmS128); |
1091 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), | 1152 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
1092 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), | 1153 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
1093 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE); | 1154 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), WASM_ONE); |
1094 | 1155 |
1095 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } | 1156 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } |
1096 } | 1157 } |
1097 | 1158 |
1098 WASM_EXEC_COMPILED_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); } | 1159 WASM_EXEC_COMPILED_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); } |
1099 | 1160 |
| 1161 // Tests both signed and unsigned conversion from I32x4 (packing). |
| 1162 WASM_EXEC_COMPILED_TEST(I16x8ConvertI32x4) { |
| 1163 FLAG_wasm_simd_prototype = true; |
| 1164 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1165 byte a = 0; |
| 1166 byte packed_signed = 1; |
| 1167 byte packed_unsigned = 2; |
| 1168 byte simd0 = r.AllocateLocal(kWasmS128); |
| 1169 byte simd1 = r.AllocateLocal(kWasmS128); |
| 1170 byte simd2 = r.AllocateLocal(kWasmS128); |
| 1171 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 1172 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI16x8SConvertI32x4, |
| 1173 WASM_GET_LOCAL(simd0), |
| 1174 WASM_GET_LOCAL(simd0))), |
| 1175 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, packed_signed), |
| 1176 WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI16x8UConvertI32x4, |
| 1177 WASM_GET_LOCAL(simd0), |
| 1178 WASM_GET_LOCAL(simd0))), |
| 1179 WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, packed_unsigned), WASM_ONE); |
| 1180 |
| 1181 FOR_INT32_INPUTS(i) { |
| 1182 int32_t packed_signed = Narrow<int16_t>(*i); |
| 1183 int32_t packed_unsigned = UnsignedNarrow<int16_t>(*i); |
| 1184 // Sign-extend here, since ExtractLane sign extends. |
| 1185 if (packed_unsigned & 0x8000) packed_unsigned |= 0xffff0000; |
| 1186 CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned)); |
| 1187 } |
| 1188 } |
| 1189 |
1100 void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) { | 1190 void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) { |
1101 FLAG_wasm_simd_prototype = true; | 1191 FLAG_wasm_simd_prototype = true; |
1102 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 1192 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
1103 byte a = 0; | 1193 byte a = 0; |
1104 byte b = 1; | 1194 byte b = 1; |
1105 byte expected = 2; | 1195 byte expected = 2; |
1106 byte simd0 = r.AllocateLocal(kWasmS128); | 1196 byte simd0 = r.AllocateLocal(kWasmS128); |
1107 byte simd1 = r.AllocateLocal(kWasmS128); | 1197 byte simd1 = r.AllocateLocal(kWasmS128); |
1108 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), | 1198 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
1109 WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))), | 1199 WASM_SET_LOCAL(simd1, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(b))), |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 byte simd = r.AllocateLocal(kWasmS128); | 1338 byte simd = r.AllocateLocal(kWasmS128); |
1249 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), | 1339 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
1250 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), | 1340 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
1251 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE); | 1341 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), WASM_ONE); |
1252 | 1342 |
1253 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } | 1343 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); } |
1254 } | 1344 } |
1255 | 1345 |
1256 WASM_EXEC_COMPILED_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); } | 1346 WASM_EXEC_COMPILED_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); } |
1257 | 1347 |
| 1348 // Tests both signed and unsigned conversion from I16x8 (packing). |
| 1349 WASM_EXEC_COMPILED_TEST(I8x16ConvertI16x8) { |
| 1350 FLAG_wasm_simd_prototype = true; |
| 1351 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1352 byte a = 0; |
| 1353 byte packed_signed = 1; |
| 1354 byte packed_unsigned = 2; |
| 1355 byte simd0 = r.AllocateLocal(kWasmS128); |
| 1356 byte simd1 = r.AllocateLocal(kWasmS128); |
| 1357 byte simd2 = r.AllocateLocal(kWasmS128); |
| 1358 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
| 1359 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI8x16SConvertI16x8, |
| 1360 WASM_GET_LOCAL(simd0), |
| 1361 WASM_GET_LOCAL(simd0))), |
| 1362 WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, packed_signed), |
| 1363 WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI8x16UConvertI16x8, |
| 1364 WASM_GET_LOCAL(simd0), |
| 1365 WASM_GET_LOCAL(simd0))), |
| 1366 WASM_SIMD_CHECK_SPLAT16(I8x16, simd2, I32, packed_unsigned), WASM_ONE); |
| 1367 |
| 1368 FOR_INT16_INPUTS(i) { |
| 1369 int32_t packed_signed = Narrow<int8_t>(*i); |
| 1370 int32_t packed_unsigned = UnsignedNarrow<int8_t>(*i); |
| 1371 // Sign-extend here, since ExtractLane sign extends. |
| 1372 if (packed_unsigned & 0x80) packed_unsigned |= 0xffffff00; |
| 1373 CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned)); |
| 1374 } |
| 1375 } |
| 1376 |
1258 void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) { | 1377 void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) { |
1259 FLAG_wasm_simd_prototype = true; | 1378 FLAG_wasm_simd_prototype = true; |
1260 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 1379 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
1261 byte a = 0; | 1380 byte a = 0; |
1262 byte b = 1; | 1381 byte b = 1; |
1263 byte expected = 2; | 1382 byte expected = 2; |
1264 byte simd0 = r.AllocateLocal(kWasmS128); | 1383 byte simd0 = r.AllocateLocal(kWasmS128); |
1265 byte simd1 = r.AllocateLocal(kWasmS128); | 1384 byte simd1 = r.AllocateLocal(kWasmS128); |
1266 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), | 1385 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
1267 WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))), | 1386 WASM_SET_LOCAL(simd1, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(b))), |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 WASM_SIMD_I32x4_EXTRACT_LANE( | 1979 WASM_SIMD_I32x4_EXTRACT_LANE( |
1861 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); | 1980 0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO))); |
1862 | 1981 |
1863 FOR_INT32_INPUTS(i) { | 1982 FOR_INT32_INPUTS(i) { |
1864 int32_t expected = *i; | 1983 int32_t expected = *i; |
1865 r.module().WriteMemory(&memory[0], expected); | 1984 r.module().WriteMemory(&memory[0], expected); |
1866 CHECK_EQ(expected, r.Call()); | 1985 CHECK_EQ(expected, r.Call()); |
1867 } | 1986 } |
1868 } | 1987 } |
1869 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 1988 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
OLD | NEW |