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