Index: test/cctest/wasm/test-run-wasm-simd.cc |
diff --git a/test/cctest/wasm/test-run-wasm-simd.cc b/test/cctest/wasm/test-run-wasm-simd.cc |
index 4bff07b7accc8460d1499bfe1c1c38d6df78bc23..e251d150c72649bcd868cccf95f1749f85a0d619 100644 |
--- a/test/cctest/wasm/test-run-wasm-simd.cc |
+++ b/test/cctest/wasm/test-run-wasm-simd.cc |
@@ -169,6 +169,15 @@ T LogicalShiftRight(T a, int shift) { |
} |
template <typename T> |
+T Clamp(int64_t value) { |
+ static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
+ int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); |
+ int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); |
+ int64_t clamped = std::max(min, std::min(max, value)); |
+ return static_cast<T>(clamped); |
+} |
+ |
+template <typename T> |
int64_t Widen(T value) { |
static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
return static_cast<int64_t>(value); |
@@ -182,12 +191,15 @@ int64_t UnsignedWiden(T value) { |
} |
template <typename T> |
-T Clamp(int64_t value) { |
+T Narrow(int64_t value) { |
+ return Clamp<T>(value); |
+} |
+ |
+template <typename T> |
+T UnsignedNarrow(int64_t value) { |
static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
- int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); |
- int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); |
- int64_t clamped = std::max(min, std::min(max, value)); |
- return static_cast<T>(clamped); |
+ using UnsignedT = typename std::make_unsigned<T>::type; |
+ return static_cast<T>(Clamp<UnsignedT>(value & 0xffffffffu)); |
} |
template <typename T> |
@@ -387,11 +399,6 @@ T RecipSqrtRefine(T a, T b) { |
#define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ |
x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) |
-#define WASM_SIMD_F32x4_FROM_I32x4(x) x, WASM_SIMD_OP(kExprF32x4SConvertI32x4) |
-#define WASM_SIMD_F32x4_FROM_U32x4(x) x, WASM_SIMD_OP(kExprF32x4UConvertI32x4) |
-#define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4) |
-#define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4) |
- |
// Skip FP tests involving extremely large or extremely small values, which |
// may fail due to non-IEEE-754 SIMD arithmetic on some platforms. |
bool SkipFPValue(float x) { |
@@ -461,13 +468,14 @@ WASM_EXEC_COMPILED_TEST(F32x4ConvertI32x4) { |
byte simd0 = r.AllocateLocal(kWasmS128); |
byte simd1 = r.AllocateLocal(kWasmS128); |
byte simd2 = r.AllocateLocal(kWasmS128); |
- BUILD( |
- r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
- WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_FROM_I32x4(WASM_GET_LOCAL(simd0))), |
- WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected_signed), |
- WASM_SET_LOCAL(simd2, WASM_SIMD_F32x4_FROM_U32x4(WASM_GET_LOCAL(simd0))), |
- WASM_SIMD_CHECK_SPLAT_F32x4(simd2, expected_unsigned), |
- WASM_RETURN1(WASM_ONE)); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprF32x4SConvertI32x4, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprF32x4UConvertI32x4, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT_F32x4(simd2, expected_unsigned), |
+ WASM_RETURN1(WASM_ONE)); |
FOR_INT32_INPUTS(i) { |
CHECK_EQ(1, r.Call(*i, static_cast<float>(*i), |
@@ -896,7 +904,7 @@ int32_t ConvertToInt(double val, bool unsigned_integer) { |
} |
// Tests both signed and unsigned conversion. |
-WASM_EXEC_COMPILED_TEST(I32x4Convert32x4) { |
+WASM_EXEC_COMPILED_TEST(I32x4ConvertF32x4) { |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled); |
byte a = 0; |
@@ -905,12 +913,13 @@ WASM_EXEC_COMPILED_TEST(I32x4Convert32x4) { |
byte simd0 = r.AllocateLocal(kWasmS128); |
byte simd1 = r.AllocateLocal(kWasmS128); |
byte simd2 = r.AllocateLocal(kWasmS128); |
- BUILD( |
- r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
- WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), |
- WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), |
- WASM_SET_LOCAL(simd2, WASM_SIMD_U32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), |
- WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertF32x4, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertF32x4, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE); |
FOR_FLOAT32_INPUTS(i) { |
if (SkipFPValue(*i)) continue; |
@@ -920,6 +929,33 @@ WASM_EXEC_COMPILED_TEST(I32x4Convert32x4) { |
} |
} |
+#if V8_TARGET_ARCH_ARM |
+// Tests both signed and unsigned conversion from I16x8 (unpacking). |
+WASM_EXEC_COMPILED_TEST(I32x4ConvertI16x8) { |
+ FLAG_wasm_simd_prototype = true; |
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
+ byte a = 0; |
+ byte unpacked_signed = 1; |
+ byte unpacked_unsigned = 2; |
+ byte simd0 = r.AllocateLocal(kWasmS128); |
+ byte simd1 = r.AllocateLocal(kWasmS128); |
+ byte simd2 = r.AllocateLocal(kWasmS128); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI32x4SConvertI16x8Low, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, unpacked_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI32x4UConvertI16x8High, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, unpacked_unsigned), WASM_ONE); |
+ |
+ FOR_INT16_INPUTS(i) { |
+ int32_t unpacked_signed = Widen<int16_t>(*i); |
+ int32_t unpacked_unsigned = UnsignedWiden<int16_t>(*i); |
+ CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned)); |
+ } |
+} |
+#endif // V8_TARGET_ARCH_ARM |
+ |
void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
@@ -1082,6 +1118,31 @@ WASM_EXEC_COMPILED_TEST(I32x4ShrU) { |
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET |
#if V8_TARGET_ARCH_ARM |
+// Tests both signed and unsigned conversion from I8x16 (unpacking). |
+WASM_EXEC_COMPILED_TEST(I16x8ConvertI8x16) { |
+ FLAG_wasm_simd_prototype = true; |
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
+ byte a = 0; |
+ byte unpacked_signed = 1; |
+ byte unpacked_unsigned = 2; |
+ byte simd0 = r.AllocateLocal(kWasmS128); |
+ byte simd1 = r.AllocateLocal(kWasmS128); |
+ byte simd2 = r.AllocateLocal(kWasmS128); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_UNOP(kExprI16x8SConvertI8x16Low, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, unpacked_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_UNOP(kExprI16x8UConvertI8x16High, |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, unpacked_unsigned), WASM_ONE); |
+ |
+ FOR_INT8_INPUTS(i) { |
+ int32_t unpacked_signed = Widen<int8_t>(*i); |
+ int32_t unpacked_unsigned = UnsignedWiden<int8_t>(*i); |
+ CHECK_EQ(1, r.Call(*i, unpacked_signed, unpacked_unsigned)); |
+ } |
+} |
+ |
void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
@@ -1097,6 +1158,35 @@ void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { |
WASM_EXEC_COMPILED_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); } |
+// Tests both signed and unsigned conversion from I32x4 (packing). |
+WASM_EXEC_COMPILED_TEST(I16x8ConvertI32x4) { |
+ FLAG_wasm_simd_prototype = true; |
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
+ byte a = 0; |
+ byte packed_signed = 1; |
+ byte packed_unsigned = 2; |
+ byte simd0 = r.AllocateLocal(kWasmS128); |
+ byte simd1 = r.AllocateLocal(kWasmS128); |
+ byte simd2 = r.AllocateLocal(kWasmS128); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI16x8SConvertI32x4, |
+ WASM_GET_LOCAL(simd0), |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, packed_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI16x8UConvertI32x4, |
+ WASM_GET_LOCAL(simd0), |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT8(I16x8, simd2, I32, packed_unsigned), WASM_ONE); |
+ |
+ FOR_INT32_INPUTS(i) { |
+ int32_t packed_signed = Narrow<int16_t>(*i); |
+ int32_t packed_unsigned = UnsignedNarrow<int16_t>(*i); |
+ // Sign-extend here, since ExtractLane sign extends. |
+ if (packed_unsigned & 0x8000) packed_unsigned |= 0xffff0000; |
+ CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned)); |
+ } |
+} |
+ |
void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) { |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
@@ -1255,6 +1345,35 @@ void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) { |
WASM_EXEC_COMPILED_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); } |
+// Tests both signed and unsigned conversion from I16x8 (packing). |
+WASM_EXEC_COMPILED_TEST(I8x16ConvertI16x8) { |
+ FLAG_wasm_simd_prototype = true; |
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
+ byte a = 0; |
+ byte packed_signed = 1; |
+ byte packed_unsigned = 2; |
+ byte simd0 = r.AllocateLocal(kWasmS128); |
+ byte simd1 = r.AllocateLocal(kWasmS128); |
+ byte simd2 = r.AllocateLocal(kWasmS128); |
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
+ WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(kExprI8x16SConvertI16x8, |
+ WASM_GET_LOCAL(simd0), |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, packed_signed), |
+ WASM_SET_LOCAL(simd2, WASM_SIMD_BINOP(kExprI8x16UConvertI16x8, |
+ WASM_GET_LOCAL(simd0), |
+ WASM_GET_LOCAL(simd0))), |
+ WASM_SIMD_CHECK_SPLAT16(I8x16, simd2, I32, packed_unsigned), WASM_ONE); |
+ |
+ FOR_INT16_INPUTS(i) { |
+ int32_t packed_signed = Narrow<int8_t>(*i); |
+ int32_t packed_unsigned = UnsignedNarrow<int8_t>(*i); |
+ // Sign-extend here, since ExtractLane sign extends. |
+ if (packed_unsigned & 0x80) packed_unsigned |= 0xffffff00; |
+ CHECK_EQ(1, r.Call(*i, packed_signed, packed_unsigned)); |
+ } |
+} |
+ |
void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) { |
FLAG_wasm_simd_prototype = true; |
WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |