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

Unified Diff: test/cctest/wasm/test-wasm-simd-common.h

Issue 2713613005: [wasm]implement simd lowering for F32x4 and I32x4 binops (Closed)
Patch Set: use namespace Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/cctest/wasm/test-wasm-simd-common.h
diff --git a/test/cctest/wasm/test-wasm-simd-common.h b/test/cctest/wasm/test-wasm-simd-common.h
new file mode 100644
index 0000000000000000000000000000000000000000..053990d23f4cc36111ae969559dd324f03b0e7fc
--- /dev/null
+++ b/test/cctest/wasm/test-wasm-simd-common.h
@@ -0,0 +1,310 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/assembler-inl.h"
+#include "src/wasm/wasm-macro-gen.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/value-helper.h"
+#include "test/cctest/wasm/wasm-run-utils.h"
+
+namespace test_wasm_simd_common {
+
+typedef float (*FloatUnOp)(float);
+typedef float (*FloatBinOp)(float, float);
+typedef int32_t (*FloatCompareOp)(float, float);
+typedef int32_t (*Int32UnOp)(int32_t);
+typedef int32_t (*Int32BinOp)(int32_t, int32_t);
+typedef int32_t (*Int32ShiftOp)(int32_t, int);
+typedef int16_t (*Int16UnOp)(int16_t);
+typedef int16_t (*Int16BinOp)(int16_t, int16_t);
+typedef int16_t (*Int16ShiftOp)(int16_t, int);
+typedef int8_t (*Int8UnOp)(int8_t);
+typedef int8_t (*Int8BinOp)(int8_t, int8_t);
+typedef int8_t (*Int8ShiftOp)(int8_t, int);
+
+// Generic expected value functions.
+template <typename T>
+T Negate(T a) {
+ return -a;
+}
+
+template <typename T>
+T Add(T a, T b) {
+ return a + b;
+}
+
+template <typename T>
+T Sub(T a, T b) {
+ return a - b;
+}
+
+template <typename T>
+T Mul(T a, T b) {
+ return a * b;
+}
+
+template <typename T>
+T Div(T a, T b) {
+ return a / b;
+}
+
+template <typename T>
+T Minimum(T a, T b) {
+ return a <= b ? a : b;
+}
+
+template <typename T>
+T Maximum(T a, T b) {
+ return a >= b ? a : b;
+}
+
+template <typename T>
+T UnsignedMinimum(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? a : b;
+}
+
+template <typename T>
+T UnsignedMaximum(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? a : b;
+}
+
+template <typename T>
+T Equal(T a, T b) {
+ return a == b ? 1 : 0;
+}
+
+template <typename T>
+T NotEqual(T a, T b) {
+ return a != b ? 1 : 0;
+}
+
+template <typename T>
+T Greater(T a, T b) {
+ return a > b ? 1 : 0;
+}
+
+template <typename T>
+T GreaterEqual(T a, T b) {
+ return a >= b ? 1 : 0;
+}
+
+template <typename T>
+T Less(T a, T b) {
+ return a < b ? 1 : 0;
+}
+
+template <typename T>
+T LessEqual(T a, T b) {
+ return a <= b ? 1 : 0;
+}
+
+template <typename T>
+T UnsignedGreater(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) > static_cast<UnsignedT>(b) ? 1 : 0;
+}
+
+template <typename T>
+T UnsignedGreaterEqual(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? 1 : 0;
+}
+
+template <typename T>
+T UnsignedLess(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? 1 : 0;
+}
+
+template <typename T>
+T UnsignedLessEqual(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? 1 : 0;
+}
+
+template <typename T>
+T LogicalShiftLeft(T a, int shift) {
+ return a << shift;
+}
+
+template <typename T>
+T LogicalShiftRight(T a, int shift) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedT>(a) >> shift;
+}
+
+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);
+}
+
+template <typename T>
+int64_t UnsignedWiden(T value) {
+ static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller");
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<int64_t>(static_cast<UnsignedT>(value));
+}
+
+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>
+T AddSaturate(T a, T b) {
+ return Clamp<T>(Widen(a) + Widen(b));
+}
+
+template <typename T>
+T SubSaturate(T a, T b) {
+ return Clamp<T>(Widen(a) - Widen(b));
+}
+
+template <typename T>
+T UnsignedAddSaturate(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return Clamp<UnsignedT>(UnsignedWiden(a) + UnsignedWiden(b));
+}
+
+template <typename T>
+T UnsignedSubSaturate(T a, T b) {
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return Clamp<UnsignedT>(UnsignedWiden(a) - UnsignedWiden(b));
+}
+
+template <typename T>
+T And(T a, T b) {
+ return a & b;
+}
+
+template <typename T>
+T Or(T a, T b) {
+ return a | b;
+}
+
+template <typename T>
+T Xor(T a, T b) {
+ return a ^ b;
+}
+
+template <typename T>
+T Not(T a) {
+ return ~a;
+}
+
+#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
+ WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
+ WASM_SIMD_##TYPE##_EXTRACT_LANE( \
+ lane_index, WASM_GET_LOCAL(value))), \
+ WASM_RETURN1(WASM_ZERO))
+
+#define WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3) \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
+ , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3)
+
+#define WASM_SIMD_CHECK_SPLAT4(TYPE, value, LANE_TYPE, lv) \
+ WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv, lv, lv, lv)
+
+#define WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, lv5, \
+ lv6, lv7) \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
+ , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7)
+
+#define WASM_SIMD_CHECK_SPLAT8(TYPE, value, LANE_TYPE, lv) \
+ WASM_SIMD_CHECK8(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv)
+
+#define WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3, lv4, \
+ lv5, lv6, lv7, lv8, lv9, lv10, lv11, lv12, lv13, \
+ lv14, lv15) \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
+ , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv4, 4), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv5, 5), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv6, 6), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv7, 7), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv8, 8), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv9, 9), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv10, 10), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv11, 11), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv12, 12), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv13, 13), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv14, 14), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv15, 15)
+
+#define WASM_SIMD_CHECK_SPLAT16(TYPE, value, LANE_TYPE, lv) \
+ WASM_SIMD_CHECK16(TYPE, value, LANE_TYPE, lv, lv, lv, lv, lv, lv, lv, lv, \
+ lv, lv, lv, lv, lv, lv, lv, lv)
+
+#define WASM_SIMD_CHECK_F32_LANE(TYPE, value, lane_value, lane_index) \
+ WASM_IF( \
+ WASM_I32_NE(WASM_I32_REINTERPRET_F32(WASM_GET_LOCAL(lane_value)), \
+ WASM_I32_REINTERPRET_F32(WASM_SIMD_##TYPE##_EXTRACT_LANE( \
+ lane_index, WASM_GET_LOCAL(value)))), \
+ WASM_RETURN1(WASM_ZERO))
+
+#define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \
+ , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3)
+
+#define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \
+ WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv)
+
+#define TO_BYTE(val) static_cast<byte>(val)
+#define WASM_SIMD_OP(op) kSimdPrefix, TO_BYTE(op)
+#define WASM_SIMD_SPLAT(Type, x) x, WASM_SIMD_OP(kExpr##Type##Splat)
+#define WASM_SIMD_UNOP(op, x) x, WASM_SIMD_OP(op)
+#define WASM_SIMD_BINOP(op, x, y) x, y, WASM_SIMD_OP(op)
+#define WASM_SIMD_SHIFT_OP(op, shift, x) x, WASM_SIMD_OP(op), TO_BYTE(shift)
+#define WASM_SIMD_SELECT(format, x, y, z) \
+ x, y, z, WASM_SIMD_OP(kExprS##format##Select)
+// Since boolean vectors can't be checked directly, materialize them into
+// integer vectors using a Select operation.
+#define WASM_SIMD_MATERIALIZE_BOOLS(format, x) \
+ x, WASM_SIMD_I##format##_SPLAT(WASM_ONE), \
+ WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \
+ WASM_SIMD_OP(kExprS##format##Select)
+
bbudge 2017/02/24 20:53:36 Could you also move the SIMD macros from wasm-macr
aseemgarg 2017/02/25 03:25:16 Done.
+#define WASM_SIMD_I16x8_SPLAT(x) x, WASM_SIMD_OP(kExprI16x8Splat)
+#define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \
+ x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane)
+#define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \
+ x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane)
+#define WASM_SIMD_I8x16_SPLAT(x) x, WASM_SIMD_OP(kExprI8x16Splat)
+#define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \
+ x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane)
+#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)
+
+void RunF32x4SplatTest();
+void RunF32x4ReplaceLaneTest();
+void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op,
+ bool skip_zero_inputs = false);
+void RunI32x4SplatTest();
+void RunI32x4ReplaceLaneTest();
+void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op);
+} // namespace test_wasm_simd_common

Powered by Google App Engine
This is Rietveld 408576698