Commit 7f570150 authored by aseemgarg's avatar aseemgarg Committed by Commit bot

[wasm]implement simd lowering for F32x4 and I32x4 binops

BUG=v8:4124
R=bradnelson@chromium.org,bbudge@chromium.org,gdeepti@chromium.org

Review-Url: https://codereview.chromium.org/2713613005
Cr-Commit-Position: refs/heads/master@{#43465}
parent ef2a9e2d
......@@ -72,16 +72,26 @@ void SimdScalarLowering::LowerGraph() {
}
#define FOREACH_INT32X4_OPCODE(V) \
V(Int32x4Add) \
V(Int32x4ExtractLane) \
V(Int32x4Splat) \
V(Int32x4ReplaceLane)
V(Int32x4ExtractLane) \
V(Int32x4ReplaceLane) \
V(Int32x4Add) \
V(Int32x4Sub) \
V(Int32x4Mul) \
V(Simd128And) \
V(Simd128Or) \
V(Simd128Xor)
#define FOREACH_FLOAT32X4_OPCODE(V) \
V(Float32x4Add) \
V(Float32x4ExtractLane) \
V(Float32x4Splat) \
V(Float32x4ReplaceLane)
V(Float32x4ExtractLane) \
V(Float32x4ReplaceLane) \
V(Float32x4Add) \
V(Float32x4Sub) \
V(Float32x4Mul) \
V(Float32x4Div) \
V(Float32x4Min) \
V(Float32x4Max)
void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
switch (node->opcode()) {
......@@ -377,14 +387,30 @@ void SimdScalarLowering::LowerNode(Node* node) {
}
break;
}
case IrOpcode::kInt32x4Add: {
LowerBinaryOp(node, rep_type, machine()->Int32Add());
break;
}
case IrOpcode::kFloat32x4Add: {
LowerBinaryOp(node, rep_type, machine()->Float32Add());
break;
}
#define I32X4_BINOP_CASE(opcode, instruction) \
case IrOpcode::opcode: { \
LowerBinaryOp(node, rep_type, machine()->instruction()); \
break; \
}
I32X4_BINOP_CASE(kInt32x4Add, Int32Add)
I32X4_BINOP_CASE(kInt32x4Sub, Int32Sub)
I32X4_BINOP_CASE(kInt32x4Mul, Int32Mul)
I32X4_BINOP_CASE(kSimd128And, Word32And)
I32X4_BINOP_CASE(kSimd128Or, Word32Or)
I32X4_BINOP_CASE(kSimd128Xor, Word32Xor)
#undef I32X4_BINOP_CASE
#define F32X4_BINOP_CASE(name) \
case IrOpcode::kFloat32x4##name: { \
LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
break; \
}
F32X4_BINOP_CASE(Add)
F32X4_BINOP_CASE(Sub)
F32X4_BINOP_CASE(Mul)
F32X4_BINOP_CASE(Div)
F32X4_BINOP_CASE(Min)
F32X4_BINOP_CASE(Max)
#undef F32X4_BINOP_CASE
case IrOpcode::kInt32x4Splat:
case IrOpcode::kFloat32x4Splat: {
Node* rep_node[kMaxLanes];
......
......@@ -3380,6 +3380,18 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode,
case wasm::kExprF32x4Sub:
return graph()->NewNode(jsgraph()->machine()->Float32x4Sub(), inputs[0],
inputs[1]);
case wasm::kExprF32x4Mul:
return graph()->NewNode(jsgraph()->machine()->Float32x4Mul(), inputs[0],
inputs[1]);
case wasm::kExprF32x4Div:
return graph()->NewNode(jsgraph()->machine()->Float32x4Div(), inputs[0],
inputs[1]);
case wasm::kExprF32x4Min:
return graph()->NewNode(jsgraph()->machine()->Float32x4Min(), inputs[0],
inputs[1]);
case wasm::kExprF32x4Max:
return graph()->NewNode(jsgraph()->machine()->Float32x4Max(), inputs[0],
inputs[1]);
case wasm::kExprF32x4Eq:
return graph()->NewNode(jsgraph()->machine()->Float32x4Equal(), inputs[0],
inputs[1]);
......
......@@ -619,36 +619,6 @@ class LocalDeclEncoder {
#define WASM_GROW_MEMORY(x) x, kExprGrowMemory, 0
#define WASM_MEMORY_SIZE kExprMemorySize, 0
//------------------------------------------------------------------------------
// Simd Operations.
//------------------------------------------------------------------------------
// TODO(bbudge) Migrate these into tests.
#define WASM_SIMD_F32x4_SPLAT(x) \
x, kSimdPrefix, static_cast<byte>(kExprF32x4Splat)
#define WASM_SIMD_F32x4_EXTRACT_LANE(lane, x) \
x, kSimdPrefix, static_cast<byte>(kExprF32x4ExtractLane), \
static_cast<byte>(lane)
#define WASM_SIMD_F32x4_REPLACE_LANE(lane, x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprF32x4ReplaceLane), \
static_cast<byte>(lane)
#define WASM_SIMD_F32x4_ADD(x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprF32x4Add)
#define WASM_SIMD_F32x4_SUB(x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprF32x4Sub)
#define WASM_SIMD_I32x4_SPLAT(x) \
x, kSimdPrefix, static_cast<byte>(kExprI32x4Splat)
#define WASM_SIMD_I32x4_EXTRACT_LANE(lane, x) \
x, kSimdPrefix, static_cast<byte>(kExprI32x4ExtractLane), \
static_cast<byte>(lane)
#define WASM_SIMD_I32x4_REPLACE_LANE(lane, x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprI32x4ReplaceLane), \
static_cast<byte>(lane)
#define WASM_SIMD_I32x4_ADD(x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprI32x4Add)
#define WASM_SIMD_I32x4_SUB(x, y) \
x, y, kSimdPrefix, static_cast<byte>(kExprI32x4Sub)
#define SIG_ENTRY_v_v kWasmFunctionTypeForm, 0, 0
#define SIZEOF_SIG_ENTRY_v_v 3
......
......@@ -193,6 +193,7 @@ v8_executable("cctest") {
"wasm/test-run-wasm-js.cc",
"wasm/test-run-wasm-module.cc",
"wasm/test-run-wasm-relocation.cc",
"wasm/test-run-wasm-simd.cc",
"wasm/test-run-wasm.cc",
"wasm/test-wasm-breakpoints.cc",
"wasm/test-wasm-interpreter-entry.cc",
......@@ -211,7 +212,6 @@ v8_executable("cctest") {
"test-macro-assembler-arm.cc",
"test-run-wasm-relocation-arm.cc",
"test-simulator-arm.cc",
"wasm/test-run-wasm-simd.cc",
]
} else if (v8_current_cpu == "arm64") {
sources += [ ### gcmole(arch:arm64) ###
......@@ -226,7 +226,6 @@ v8_executable("cctest") {
"test-run-wasm-relocation-arm64.cc",
"test-utils-arm64.cc",
"test-utils-arm64.h",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "x86") {
sources += [ ### gcmole(arch:ia32) ###
......@@ -238,7 +237,6 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-ia32.cc",
"test-run-wasm-relocation-ia32.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips") {
sources += [ ### gcmole(arch:mips) ###
......@@ -248,7 +246,6 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips.cc",
"test-macro-assembler-mips.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mipsel") {
sources += [ ### gcmole(arch:mipsel) ###
......@@ -258,7 +255,6 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips.cc",
"test-macro-assembler-mips.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips64") {
sources += [ ### gcmole(arch:mips64) ###
......@@ -268,7 +264,6 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips64.cc",
"test-macro-assembler-mips64.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips64el") {
sources += [ ### gcmole(arch:mips64el) ###
......@@ -278,7 +273,6 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips64.cc",
"test-macro-assembler-mips64.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "x64") {
sources += [ ### gcmole(arch:x64) ###
......@@ -290,7 +284,6 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-x64.cc",
"test-run-wasm-relocation-x64.cc",
"wasm/test-run-wasm-simd.cc",
]
} else if (v8_current_cpu == "x87") {
sources += [ ### gcmole(arch:x87) ###
......@@ -302,7 +295,6 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-x87.cc",
"test-run-wasm-relocation-x87.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
sources += [ ### gcmole(arch:ppc) ###
......@@ -310,7 +302,6 @@ v8_executable("cctest") {
"test-code-stubs.cc",
"test-code-stubs.h",
"test-disasm-ppc.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [ ### gcmole(arch:s390) ###
......@@ -318,7 +309,6 @@ v8_executable("cctest") {
"test-code-stubs.cc",
"test-code-stubs.h",
"test-disasm-s390.cc",
"wasm/test-run-wasm-simd-lowering.cc",
]
}
......
......@@ -215,6 +215,7 @@
'wasm/test-run-wasm-js.cc',
'wasm/test-run-wasm-module.cc',
'wasm/test-run-wasm-relocation.cc',
'wasm/test-run-wasm-simd.cc',
'wasm/test-wasm-breakpoints.cc',
'wasm/test-wasm-interpreter-entry.cc',
'wasm/test-wasm-stack.cc',
......@@ -230,7 +231,6 @@
'test-macro-assembler-ia32.cc',
'test-log-stack-tracer.cc',
'test-run-wasm-relocation-ia32.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_x64': [ ### gcmole(arch:x64) ###
'test-assembler-x64.cc',
......@@ -241,7 +241,6 @@
'test-macro-assembler-x64.cc',
'test-log-stack-tracer.cc',
'test-run-wasm-relocation-x64.cc',
'wasm/test-run-wasm-simd.cc',
],
'cctest_sources_arm': [ ### gcmole(arch:arm) ###
'test-assembler-arm.cc',
......@@ -252,7 +251,6 @@
'test-macro-assembler-arm.cc',
'test-run-wasm-relocation-arm.cc',
'test-simulator-arm.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_arm64': [ ### gcmole(arch:arm64) ###
'test-utils-arm64.cc',
......@@ -266,21 +264,18 @@
'test-javascript-arm64.cc',
'test-js-arm64-variables.cc',
'test-run-wasm-relocation-arm64.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_s390': [ ### gcmole(arch:s390) ###
'test-assembler-s390.cc',
'test-code-stubs.cc',
'test-code-stubs.h',
'test-disasm-s390.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_ppc': [ ### gcmole(arch:ppc) ###
'test-assembler-ppc.cc',
'test-code-stubs.cc',
'test-code-stubs.h',
'test-disasm-ppc.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips': [ ### gcmole(arch:mips) ###
'test-assembler-mips.cc',
......@@ -289,7 +284,6 @@
'test-code-stubs-mips.cc',
'test-disasm-mips.cc',
'test-macro-assembler-mips.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mipsel': [ ### gcmole(arch:mipsel) ###
'test-assembler-mips.cc',
......@@ -298,7 +292,6 @@
'test-code-stubs-mips.cc',
'test-disasm-mips.cc',
'test-macro-assembler-mips.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips64': [ ### gcmole(arch:mips64) ###
'test-assembler-mips64.cc',
......@@ -307,7 +300,6 @@
'test-code-stubs-mips64.cc',
'test-disasm-mips64.cc',
'test-macro-assembler-mips64.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips64el': [ ### gcmole(arch:mips64el) ###
'test-assembler-mips64.cc',
......@@ -316,7 +308,6 @@
'test-code-stubs-mips64.cc',
'test-disasm-mips64.cc',
'test-macro-assembler-mips64.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_x87': [ ### gcmole(arch:x87) ###
'test-assembler-x87.cc',
......@@ -327,7 +318,6 @@
'test-macro-assembler-x87.cc',
'test-log-stack-tracer.cc',
'test-run-wasm-relocation-x87.cc',
'wasm/test-run-wasm-simd-lowering.cc'
],
},
'includes': ['../../gypfiles/toolchain.gypi', '../../gypfiles/features.gypi'],
......
// Copyright 2016 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/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-module.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/value-helper.h"
#include "test/cctest/wasm/wasm-run-utils.h"
#include "test/common/wasm/test-signatures.h"
using namespace v8::base;
using namespace v8::internal;
using namespace v8::internal::compiler;
using namespace v8::internal::wasm;
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Splat) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(5))));
FOR_INT32_INPUTS(i) { CHECK_EQ(5, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Add) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r, WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_ADD(WASM_SIMD_I32x4_SPLAT(WASM_I32V(5)),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(6)))));
FOR_INT32_INPUTS(i) { CHECK_EQ(11, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Splat) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_F32x4_SPLAT(WASM_F32(9.5))),
WASM_F32(9.5)),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Extract_With_F32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r, WASM_IF_ELSE_I(
WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))),
WASM_I32_REINTERPRET_F32(WASM_F32(30.5))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Extract_With_I32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(15))),
WASM_F32_REINTERPRET_I32(WASM_I32V(15))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Add_With_I32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(
WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_F32x4_ADD(
WASM_SIMD_I32x4_SPLAT(WASM_I32V(32)),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(19)))),
WASM_F32_ADD(WASM_F32_REINTERPRET_I32(WASM_I32V(32)),
WASM_F32_REINTERPRET_I32(WASM_I32V(19)))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Add_With_F32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(
WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_ADD(
WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25)),
WASM_SIMD_F32x4_SPLAT(WASM_F32(31.5)))),
WASM_I32_ADD(WASM_I32_REINTERPRET_F32(WASM_F32(21.25)),
WASM_I32_REINTERPRET_F32(WASM_F32(31.5)))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Local) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(31, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Replace_Lane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
WASM_SET_LOCAL(0, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(0),
WASM_I32V(53))),
WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(53, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Replace_Lane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmF32);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(23.5))),
WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
WASM_F32(65.25))),
WASM_SET_LOCAL(0, WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1))),
WASM_IF(WASM_F32_EQ(WASM_GET_LOCAL(0), WASM_F32(65.25)),
WASM_RETURN1(WASM_I32V(1))),
WASM_I32V(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Splat_From_Extract) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(76)))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0))),
WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)));
FOR_INT32_INPUTS(i) { CHECK_EQ(76, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Get_Global) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
*(global) = 0;
*(global + 1) = 1;
*(global + 2) = 2;
*(global + 3) = 3;
r.AllocateLocal(kWasmI32);
BUILD(
r, WASM_SET_LOCAL(1, WASM_I32V(1)),
WASM_IF(WASM_I32_NE(WASM_I32V(0),
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(1),
WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(2),
WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(3),
WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_Set_Global) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(23))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
WASM_I32V(34))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
WASM_I32V(45))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
WASM_I32V(56))),
WASM_I32V(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
CHECK_EQ(*global, 23);
CHECK_EQ(*(global + 1), 34);
CHECK_EQ(*(global + 2), 45);
CHECK_EQ(*(global + 3), 56);
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Get_Global) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
float* global = r.module().AddGlobal<float>(kWasmS128);
*(global) = 0.0;
*(global + 1) = 1.5;
*(global + 2) = 2.25;
*(global + 3) = 3.5;
r.AllocateLocal(kWasmI32);
BUILD(
r, WASM_SET_LOCAL(1, WASM_I32V(1)),
WASM_IF(WASM_F32_NE(WASM_F32(0.0),
WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(1.5),
WASM_SIMD_F32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(2.25),
WASM_SIMD_F32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(3.5),
WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Set_Global) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
float* global = r.module().AddGlobal<float>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_SPLAT(WASM_F32(13.5))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
WASM_F32(45.5))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
WASM_F32(32.25))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
WASM_F32(65.0))),
WASM_I32V(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
CHECK_EQ(*global, 13.5);
CHECK_EQ(*(global + 1), 45.5);
CHECK_EQ(*(global + 2), 32.25);
CHECK_EQ(*(global + 3), 65.0);
}
WASM_EXEC_COMPILED_TEST(Simd_I32x4_For) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r,
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(1),
WASM_I32V(53))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(1),
WASM_I32V(23))),
WASM_SET_LOCAL(0, WASM_I32V(0)),
WASM_LOOP(
WASM_SET_LOCAL(
1, WASM_SIMD_I32x4_ADD(WASM_GET_LOCAL(1),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(1)))),
WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(5)), WASM_BR(1))),
WASM_SET_LOCAL(0, WASM_I32V(1)),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
WASM_I32V(36)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)),
WASM_I32V(58)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(1)),
WASM_I32V(28)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
WASM_I32V(36)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_For) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25))),
WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
WASM_F32(19.5))),
WASM_SET_LOCAL(0, WASM_I32V(0)),
WASM_LOOP(
WASM_SET_LOCAL(
1, WASM_SIMD_F32x4_ADD(WASM_GET_LOCAL(1),
WASM_SIMD_F32x4_SPLAT(WASM_F32(2.0)))),
WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(3)), WASM_BR(1))),
WASM_SET_LOCAL(0, WASM_I32V(1)),
WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
WASM_F32(27.25)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
WASM_F32(25.5)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
......@@ -56,6 +56,11 @@ 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;
......@@ -209,6 +214,12 @@ T Not(T a) {
} // namespace
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64
#define SIMD_LOWERING_TARGET 1
#else
#define SIMD_LOWERING_TARGET 0
#endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64
// TODO(gdeepti): These are tests using sample values to verify functional
// correctness of opcodes, add more tests for a range of values and macroize
// tests.
......@@ -299,11 +310,24 @@ T Not(T a) {
WASM_SIMD_I##format##_SPLAT(WASM_ZERO), \
WASM_SIMD_OP(kExprS##format##Select)
#define WASM_SIMD_F32x4_SPLAT(x) x, WASM_SIMD_OP(kExprF32x4Splat)
#define WASM_SIMD_F32x4_EXTRACT_LANE(lane, x) \
x, WASM_SIMD_OP(kExprF32x4ExtractLane), TO_BYTE(lane)
#define WASM_SIMD_F32x4_REPLACE_LANE(lane, x, y) \
x, y, WASM_SIMD_OP(kExprF32x4ReplaceLane), TO_BYTE(lane)
#define WASM_SIMD_I32x4_SPLAT(x) x, WASM_SIMD_OP(kExprI32x4Splat)
#define WASM_SIMD_I32x4_EXTRACT_LANE(lane, x) \
x, WASM_SIMD_OP(kExprI32x4ExtractLane), TO_BYTE(lane)
#define WASM_SIMD_I32x4_REPLACE_LANE(lane, x, y) \
x, y, WASM_SIMD_OP(kExprI32x4ReplaceLane), TO_BYTE(lane)
#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)
......@@ -315,8 +339,8 @@ T Not(T a) {
#define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4)
#define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4)
#if V8_TARGET_ARCH_ARM
WASM_EXEC_TEST(F32x4Splat) {
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(F32x4Splat) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, float> r(kExecuteCompiled);
......@@ -329,7 +353,7 @@ WASM_EXEC_TEST(F32x4Splat) {
FOR_FLOAT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
}
WASM_EXEC_TEST(F32x4ReplaceLane) {
WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, float, float> r(kExecuteCompiled);
byte old_val = 0;
......@@ -353,11 +377,13 @@ WASM_EXEC_TEST(F32x4ReplaceLane) {
WASM_GET_LOCAL(new_val))),
WASM_SIMD_CHECK_SPLAT4(F32x4, simd, F32, new_val), WASM_ONE);
CHECK_EQ(1, r.Call(3.14159, -1.5));
CHECK_EQ(1, r.Call(3.14159f, -1.5f));
}
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM
// Tests both signed and unsigned conversion.
WASM_EXEC_TEST(F32x4FromInt32x4) {
WASM_EXEC_COMPILED_TEST(F32x4FromInt32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled);
byte a = 0;
......@@ -395,10 +421,13 @@ void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) {
}
}
WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); }
WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
WASM_EXEC_COMPILED_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); }
#endif // V8_TARGET_ARCH_ARM
void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) {
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op,
bool skip_zero_inputs = false) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, float, float, float> r(kExecuteCompiled);
byte a = 0;
......@@ -416,19 +445,36 @@ void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) {
if (std::isnan(*i)) continue;
FOR_FLOAT32_INPUTS(j) {
if (std::isnan(*j)) continue;
if (skip_zero_inputs && std::fpclassify(*i) == FP_ZERO &&
std::fpclassify(*j) == FP_ZERO)
continue;
float expected = expected_op(*i, *j);
// SIMD on some platforms may handle denormalized numbers differently.
// TODO(bbudge) On platforms that flush denorms to zero, test with
// expected == 0.
if (std::fpclassify(expected) == FP_SUBNORMAL) continue;
if (std::isnan(expected)) continue;
CHECK_EQ(1, r.Call(*i, *j, expected));
}
}
}
WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); }
WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); }
WASM_EXEC_COMPILED_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); }
WASM_EXEC_COMPILED_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); }
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(F32x4Mul) { RunF32x4BinOpTest(kExprF32x4Mul, Mul); }
WASM_EXEC_COMPILED_TEST(F32x4Div) { RunF32x4BinOpTest(kExprF32x4Div, Div); }
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Min) {
RunF32x4BinOpTest(kExprF32x4Min, Minimum, true);
}
WASM_EXEC_COMPILED_TEST(Simd_F32x4_Max) {
RunF32x4BinOpTest(kExprF32x4Max, Maximum, true);
}
#endif // SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM
void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled);
......@@ -457,11 +503,16 @@ void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) {
}
}
WASM_EXEC_TEST(F32x4Equal) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); }
WASM_EXEC_TEST(F32x4NotEqual) { RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); }
WASM_EXEC_COMPILED_TEST(F32x4Equal) {
RunF32x4CompareOpTest(kExprF32x4Eq, Equal);
}
WASM_EXEC_COMPILED_TEST(F32x4NotEqual) {
RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual);
}
#endif // V8_TARGET_ARCH_ARM
WASM_EXEC_TEST(I32x4Splat) {
WASM_EXEC_COMPILED_TEST(I32x4Splat) {
FLAG_wasm_simd_prototype = true;
// Store SIMD value in a local variable, use extract lane to check lane values
......@@ -484,7 +535,7 @@ WASM_EXEC_TEST(I32x4Splat) {
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
}
WASM_EXEC_TEST(I32x4ReplaceLane) {
WASM_EXEC_COMPILED_TEST(I32x4ReplaceLane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
byte old_val = 0;
......@@ -513,7 +564,7 @@ WASM_EXEC_TEST(I32x4ReplaceLane) {
#if V8_TARGET_ARCH_ARM
WASM_EXEC_TEST(I16x8Splat) {
WASM_EXEC_COMPILED_TEST(I16x8Splat) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
......@@ -526,7 +577,7 @@ WASM_EXEC_TEST(I16x8Splat) {
FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
}
WASM_EXEC_TEST(I16x8ReplaceLane) {
WASM_EXEC_COMPILED_TEST(I16x8ReplaceLane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
byte old_val = 0;
......@@ -576,7 +627,7 @@ WASM_EXEC_TEST(I16x8ReplaceLane) {
CHECK_EQ(1, r.Call(1, 2));
}
WASM_EXEC_TEST(I8x16Splat) {
WASM_EXEC_COMPILED_TEST(I8x16Splat) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
......@@ -589,7 +640,7 @@ WASM_EXEC_TEST(I8x16Splat) {
FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
}
WASM_EXEC_TEST(I8x16ReplaceLane) {
WASM_EXEC_COMPILED_TEST(I8x16ReplaceLane) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
byte old_val = 0;
......@@ -735,7 +786,7 @@ int32_t ConvertToInt(double val, bool unsigned_integer) {
}
// Tests both signed and unsigned conversion.
WASM_EXEC_TEST(I32x4FromFloat32x4) {
WASM_EXEC_COMPILED_TEST(I32x4FromFloat32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled);
byte a = 0;
......@@ -771,9 +822,9 @@ void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) {
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
}
WASM_EXEC_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); }
WASM_EXEC_COMPILED_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); }
WASM_EXEC_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); }
WASM_EXEC_COMPILED_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); }
#endif // V8_TARGET_ARCH_ARM
void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
......@@ -795,30 +846,38 @@ void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
}
}
WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); }
WASM_EXEC_COMPILED_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); }
WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); }
WASM_EXEC_COMPILED_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); }
#if V8_TARGET_ARCH_ARM
WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); }
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); }
WASM_EXEC_COMPILED_TEST(S128And) { RunI32x4BinOpTest(kExprS128And, And); }
WASM_EXEC_TEST(I32x4Min) { RunI32x4BinOpTest(kExprI32x4MinS, Minimum); }
WASM_EXEC_COMPILED_TEST(S128Or) { RunI32x4BinOpTest(kExprS128Or, Or); }
WASM_EXEC_TEST(I32x4Max) { RunI32x4BinOpTest(kExprI32x4MaxS, Maximum); }
WASM_EXEC_COMPILED_TEST(S128Xor) { RunI32x4BinOpTest(kExprS128Xor, Xor); }
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_TEST(Ui32x4Min) {
#if V8_TARGET_ARCH_ARM
WASM_EXEC_COMPILED_TEST(I32x4Min) {
RunI32x4BinOpTest(kExprI32x4MinS, Minimum);
}
WASM_EXEC_COMPILED_TEST(I32x4Max) {
RunI32x4BinOpTest(kExprI32x4MaxS, Maximum);
}
WASM_EXEC_COMPILED_TEST(Ui32x4Min) {
RunI32x4BinOpTest(kExprI32x4MinU, UnsignedMinimum);
}
WASM_EXEC_TEST(Ui32x4Max) {
WASM_EXEC_COMPILED_TEST(Ui32x4Max) {
RunI32x4BinOpTest(kExprI32x4MaxU, UnsignedMaximum);
}
WASM_EXEC_TEST(S128And) { RunI32x4BinOpTest(kExprS128And, And); }
WASM_EXEC_TEST(S128Or) { RunI32x4BinOpTest(kExprS128Or, Or); }
WASM_EXEC_TEST(S128Xor) { RunI32x4BinOpTest(kExprS128Xor, Xor); }
void RunI32x4CompareOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
FLAG_wasm_simd_prototype = true;
......@@ -841,35 +900,43 @@ void RunI32x4CompareOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
}
}
WASM_EXEC_TEST(I32x4Equal) { RunI32x4CompareOpTest(kExprI32x4Eq, Equal); }
WASM_EXEC_COMPILED_TEST(I32x4Equal) {
RunI32x4CompareOpTest(kExprI32x4Eq, Equal);
}
WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4CompareOpTest(kExprI32x4Ne, NotEqual); }
WASM_EXEC_COMPILED_TEST(I32x4NotEqual) {
RunI32x4CompareOpTest(kExprI32x4Ne, NotEqual);
}
WASM_EXEC_TEST(I32x4Greater) { RunI32x4CompareOpTest(kExprI32x4GtS, Greater); }
WASM_EXEC_COMPILED_TEST(I32x4Greater) {
RunI32x4CompareOpTest(kExprI32x4GtS, Greater);
}
WASM_EXEC_TEST(I32x4GreaterEqual) {
WASM_EXEC_COMPILED_TEST(I32x4GreaterEqual) {
RunI32x4CompareOpTest(kExprI32x4GeS, GreaterEqual);
}
WASM_EXEC_TEST(I32x4Less) { RunI32x4CompareOpTest(kExprI32x4LtS, Less); }
WASM_EXEC_COMPILED_TEST(I32x4Less) {
RunI32x4CompareOpTest(kExprI32x4LtS, Less);
}
WASM_EXEC_TEST(I32x4LessEqual) {
WASM_EXEC_COMPILED_TEST(I32x4LessEqual) {
RunI32x4CompareOpTest(kExprI32x4LeS, LessEqual);
}
WASM_EXEC_TEST(Ui32x4Greater) {
WASM_EXEC_COMPILED_TEST(Ui32x4Greater) {
RunI32x4CompareOpTest(kExprI32x4GtU, UnsignedGreater);
}
WASM_EXEC_TEST(Ui32x4GreaterEqual) {
WASM_EXEC_COMPILED_TEST(Ui32x4GreaterEqual) {
RunI32x4CompareOpTest(kExprI32x4GeU, UnsignedGreaterEqual);
}
WASM_EXEC_TEST(Ui32x4Less) {
WASM_EXEC_COMPILED_TEST(Ui32x4Less) {
RunI32x4CompareOpTest(kExprI32x4LtU, UnsignedLess);
}
WASM_EXEC_TEST(Ui32x4LessEqual) {
WASM_EXEC_COMPILED_TEST(Ui32x4LessEqual) {
RunI32x4CompareOpTest(kExprI32x4LeU, UnsignedLessEqual);
}
......@@ -888,15 +955,15 @@ void RunI32x4ShiftOpTest(WasmOpcode simd_op, Int32ShiftOp expected_op,
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
}
WASM_EXEC_TEST(I32x4Shl) {
WASM_EXEC_COMPILED_TEST(I32x4Shl) {
RunI32x4ShiftOpTest(kExprI32x4Shl, LogicalShiftLeft, 1);
}
WASM_EXEC_TEST(I32x4ShrS) {
WASM_EXEC_COMPILED_TEST(I32x4ShrS) {
RunI32x4ShiftOpTest(kExprI32x4ShrS, ArithmeticShiftRight, 1);
}
WASM_EXEC_TEST(I32x4ShrU) {
WASM_EXEC_COMPILED_TEST(I32x4ShrU) {
RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1);
}
......@@ -913,7 +980,7 @@ void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) {
FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
}
WASM_EXEC_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); }
WASM_EXEC_COMPILED_TEST(I16x8Neg) { RunI16x8UnOpTest(kExprI16x8Neg, Negate); }
void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) {
FLAG_wasm_simd_prototype = true;
......@@ -934,37 +1001,41 @@ void RunI16x8BinOpTest(WasmOpcode simd_op, Int16BinOp expected_op) {
}
}
WASM_EXEC_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); }
WASM_EXEC_COMPILED_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); }
WASM_EXEC_TEST(I16x8AddSaturate) {
WASM_EXEC_COMPILED_TEST(I16x8AddSaturate) {
RunI16x8BinOpTest(kExprI16x8AddSaturateS, AddSaturate);
}
WASM_EXEC_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); }
WASM_EXEC_COMPILED_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); }
WASM_EXEC_TEST(I16x8SubSaturate) {
WASM_EXEC_COMPILED_TEST(I16x8SubSaturate) {
RunI16x8BinOpTest(kExprI16x8SubSaturateS, SubSaturate);
}
WASM_EXEC_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); }
WASM_EXEC_COMPILED_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); }
WASM_EXEC_TEST(I16x8Min) { RunI16x8BinOpTest(kExprI16x8MinS, Minimum); }
WASM_EXEC_COMPILED_TEST(I16x8Min) {
RunI16x8BinOpTest(kExprI16x8MinS, Minimum);
}
WASM_EXEC_TEST(I16x8Max) { RunI16x8BinOpTest(kExprI16x8MaxS, Maximum); }
WASM_EXEC_COMPILED_TEST(I16x8Max) {
RunI16x8BinOpTest(kExprI16x8MaxS, Maximum);
}
WASM_EXEC_TEST(Ui16x8AddSaturate) {
WASM_EXEC_COMPILED_TEST(Ui16x8AddSaturate) {
RunI16x8BinOpTest(kExprI16x8AddSaturateU, UnsignedAddSaturate);
}
WASM_EXEC_TEST(Ui16x8SubSaturate) {
WASM_EXEC_COMPILED_TEST(Ui16x8SubSaturate) {
RunI16x8BinOpTest(kExprI16x8SubSaturateU, UnsignedSubSaturate);
}
WASM_EXEC_TEST(Ui16x8Min) {
WASM_EXEC_COMPILED_TEST(Ui16x8Min) {
RunI16x8BinOpTest(kExprI16x8MinU, UnsignedMinimum);
}
WASM_EXEC_TEST(Ui16x8Max) {
WASM_EXEC_COMPILED_TEST(Ui16x8Max) {
RunI16x8BinOpTest(kExprI16x8MaxU, UnsignedMaximum);
}
......@@ -989,35 +1060,43 @@ void RunI16x8CompareOpTest(WasmOpcode simd_op, Int16BinOp expected_op) {
}
}
WASM_EXEC_TEST(I16x8Equal) { RunI16x8CompareOpTest(kExprI16x8Eq, Equal); }
WASM_EXEC_COMPILED_TEST(I16x8Equal) {
RunI16x8CompareOpTest(kExprI16x8Eq, Equal);
}
WASM_EXEC_TEST(I16x8NotEqual) { RunI16x8CompareOpTest(kExprI16x8Ne, NotEqual); }
WASM_EXEC_COMPILED_TEST(I16x8NotEqual) {
RunI16x8CompareOpTest(kExprI16x8Ne, NotEqual);
}
WASM_EXEC_TEST(I16x8Greater) { RunI16x8CompareOpTest(kExprI16x8GtS, Greater); }
WASM_EXEC_COMPILED_TEST(I16x8Greater) {
RunI16x8CompareOpTest(kExprI16x8GtS, Greater);
}
WASM_EXEC_TEST(I16x8GreaterEqual) {
WASM_EXEC_COMPILED_TEST(I16x8GreaterEqual) {
RunI16x8CompareOpTest(kExprI16x8GeS, GreaterEqual);
}
WASM_EXEC_TEST(I16x8Less) { RunI16x8CompareOpTest(kExprI16x8LtS, Less); }
WASM_EXEC_COMPILED_TEST(I16x8Less) {
RunI16x8CompareOpTest(kExprI16x8LtS, Less);
}
WASM_EXEC_TEST(I16x8LessEqual) {
WASM_EXEC_COMPILED_TEST(I16x8LessEqual) {
RunI16x8CompareOpTest(kExprI16x8LeS, LessEqual);
}
WASM_EXEC_TEST(Ui16x8Greater) {
WASM_EXEC_COMPILED_TEST(Ui16x8Greater) {
RunI16x8CompareOpTest(kExprI16x8GtU, UnsignedGreater);
}
WASM_EXEC_TEST(Ui16x8GreaterEqual) {
WASM_EXEC_COMPILED_TEST(Ui16x8GreaterEqual) {
RunI16x8CompareOpTest(kExprI16x8GeU, UnsignedGreaterEqual);
}
WASM_EXEC_TEST(Ui16x8Less) {
WASM_EXEC_COMPILED_TEST(Ui16x8Less) {
RunI16x8CompareOpTest(kExprI16x8LtU, UnsignedLess);
}
WASM_EXEC_TEST(Ui16x8LessEqual) {
WASM_EXEC_COMPILED_TEST(Ui16x8LessEqual) {
RunI16x8CompareOpTest(kExprI16x8LeU, UnsignedLessEqual);
}
......@@ -1036,15 +1115,15 @@ void RunI16x8ShiftOpTest(WasmOpcode simd_op, Int16ShiftOp expected_op,
FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
}
WASM_EXEC_TEST(I16x8Shl) {
WASM_EXEC_COMPILED_TEST(I16x8Shl) {
RunI16x8ShiftOpTest(kExprI16x8Shl, LogicalShiftLeft, 1);
}
WASM_EXEC_TEST(I16x8ShrS) {
WASM_EXEC_COMPILED_TEST(I16x8ShrS) {
RunI16x8ShiftOpTest(kExprI16x8ShrS, ArithmeticShiftRight, 1);
}
WASM_EXEC_TEST(I16x8ShrU) {
WASM_EXEC_COMPILED_TEST(I16x8ShrU) {
RunI16x8ShiftOpTest(kExprI16x8ShrU, LogicalShiftRight, 1);
}
......@@ -1061,7 +1140,7 @@ void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) {
FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i))); }
}
WASM_EXEC_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); }
WASM_EXEC_COMPILED_TEST(I8x16Neg) { RunI8x16UnOpTest(kExprI8x16Neg, Negate); }
void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) {
FLAG_wasm_simd_prototype = true;
......@@ -1082,37 +1161,41 @@ void RunI8x16BinOpTest(WasmOpcode simd_op, Int8BinOp expected_op) {
}
}
WASM_EXEC_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); }
WASM_EXEC_COMPILED_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); }
WASM_EXEC_TEST(I8x16AddSaturate) {
WASM_EXEC_COMPILED_TEST(I8x16AddSaturate) {
RunI8x16BinOpTest(kExprI8x16AddSaturateS, AddSaturate);
}
WASM_EXEC_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); }
WASM_EXEC_COMPILED_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); }
WASM_EXEC_TEST(I8x16SubSaturate) {
WASM_EXEC_COMPILED_TEST(I8x16SubSaturate) {
RunI8x16BinOpTest(kExprI8x16SubSaturateS, SubSaturate);
}
WASM_EXEC_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); }
WASM_EXEC_COMPILED_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); }
WASM_EXEC_TEST(I8x16Min) { RunI8x16BinOpTest(kExprI8x16MinS, Minimum); }
WASM_EXEC_COMPILED_TEST(I8x16Min) {
RunI8x16BinOpTest(kExprI8x16MinS, Minimum);
}
WASM_EXEC_TEST(I8x16Max) { RunI8x16BinOpTest(kExprI8x16MaxS, Maximum); }
WASM_EXEC_COMPILED_TEST(I8x16Max) {
RunI8x16BinOpTest(kExprI8x16MaxS, Maximum);
}
WASM_EXEC_TEST(Ui8x16AddSaturate) {
WASM_EXEC_COMPILED_TEST(Ui8x16AddSaturate) {
RunI8x16BinOpTest(kExprI8x16AddSaturateU, UnsignedAddSaturate);
}
WASM_EXEC_TEST(Ui8x16SubSaturate) {
WASM_EXEC_COMPILED_TEST(Ui8x16SubSaturate) {
RunI8x16BinOpTest(kExprI8x16SubSaturateU, UnsignedSubSaturate);
}
WASM_EXEC_TEST(Ui8x16Min) {
WASM_EXEC_COMPILED_TEST(Ui8x16Min) {
RunI8x16BinOpTest(kExprI8x16MinU, UnsignedMinimum);
}
WASM_EXEC_TEST(Ui8x16Max) {
WASM_EXEC_COMPILED_TEST(Ui8x16Max) {
RunI8x16BinOpTest(kExprI8x16MaxU, UnsignedMaximum);
}
......@@ -1137,35 +1220,43 @@ void RunI8x16CompareOpTest(WasmOpcode simd_op, Int8BinOp expected_op) {
}
}
WASM_EXEC_TEST(I8x16Equal) { RunI8x16CompareOpTest(kExprI8x16Eq, Equal); }
WASM_EXEC_COMPILED_TEST(I8x16Equal) {
RunI8x16CompareOpTest(kExprI8x16Eq, Equal);
}
WASM_EXEC_TEST(I8x16NotEqual) { RunI8x16CompareOpTest(kExprI8x16Ne, NotEqual); }
WASM_EXEC_COMPILED_TEST(I8x16NotEqual) {
RunI8x16CompareOpTest(kExprI8x16Ne, NotEqual);
}
WASM_EXEC_TEST(I8x16Greater) { RunI8x16CompareOpTest(kExprI8x16GtS, Greater); }
WASM_EXEC_COMPILED_TEST(I8x16Greater) {
RunI8x16CompareOpTest(kExprI8x16GtS, Greater);
}
WASM_EXEC_TEST(I8x16GreaterEqual) {
WASM_EXEC_COMPILED_TEST(I8x16GreaterEqual) {
RunI8x16CompareOpTest(kExprI8x16GeS, GreaterEqual);
}
WASM_EXEC_TEST(I8x16Less) { RunI8x16CompareOpTest(kExprI8x16LtS, Less); }
WASM_EXEC_COMPILED_TEST(I8x16Less) {
RunI8x16CompareOpTest(kExprI8x16LtS, Less);
}
WASM_EXEC_TEST(I8x16LessEqual) {
WASM_EXEC_COMPILED_TEST(I8x16LessEqual) {
RunI8x16CompareOpTest(kExprI8x16LeS, LessEqual);
}
WASM_EXEC_TEST(Ui8x16Greater) {
WASM_EXEC_COMPILED_TEST(Ui8x16Greater) {
RunI8x16CompareOpTest(kExprI8x16GtU, UnsignedGreater);
}
WASM_EXEC_TEST(Ui8x16GreaterEqual) {
WASM_EXEC_COMPILED_TEST(Ui8x16GreaterEqual) {
RunI8x16CompareOpTest(kExprI8x16GeU, UnsignedGreaterEqual);
}
WASM_EXEC_TEST(Ui8x16Less) {
WASM_EXEC_COMPILED_TEST(Ui8x16Less) {
RunI8x16CompareOpTest(kExprI8x16LtU, UnsignedLess);
}
WASM_EXEC_TEST(Ui8x16LessEqual) {
WASM_EXEC_COMPILED_TEST(Ui8x16LessEqual) {
RunI8x16CompareOpTest(kExprI8x16LeU, UnsignedLessEqual);
}
......@@ -1184,22 +1275,22 @@ void RunI8x16ShiftOpTest(WasmOpcode simd_op, Int8ShiftOp expected_op,
FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); }
}
WASM_EXEC_TEST(I8x16Shl) {
WASM_EXEC_COMPILED_TEST(I8x16Shl) {
RunI8x16ShiftOpTest(kExprI8x16Shl, LogicalShiftLeft, 1);
}
WASM_EXEC_TEST(I8x16ShrS) {
WASM_EXEC_COMPILED_TEST(I8x16ShrS) {
RunI8x16ShiftOpTest(kExprI8x16ShrS, ArithmeticShiftRight, 1);
}
WASM_EXEC_TEST(I8x16ShrU) {
WASM_EXEC_COMPILED_TEST(I8x16ShrU) {
RunI8x16ShiftOpTest(kExprI8x16ShrU, LogicalShiftRight, 1);
}
// Test Select by making a mask where the first two lanes are true and the rest
// false, and comparing for non-equality with zero to materialize a bool vector.
#define WASM_SIMD_SELECT_TEST(format) \
WASM_EXEC_TEST(S##format##Select) { \
WASM_EXEC_COMPILED_TEST(S##format##Select) { \
FLAG_wasm_simd_prototype = true; \
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); \
byte val1 = 0; \
......@@ -1235,3 +1326,235 @@ WASM_SIMD_SELECT_TEST(32x4)
WASM_SIMD_SELECT_TEST(16x8)
WASM_SIMD_SELECT_TEST(8x16)
#endif // V8_TARGET_ARCH_ARM
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdI32x4ExtractWithF32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r, WASM_IF_ELSE_I(
WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))),
WASM_I32_REINTERPRET_F32(WASM_F32(30.5))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdF32x4ExtractWithI32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(15))),
WASM_F32_REINTERPRET_I32(WASM_I32V(15))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdF32x4AddWithI32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(
WASM_F32_EQ(
WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_BINOP(kExprF32x4Add,
WASM_SIMD_I32x4_SPLAT(WASM_I32V(32)),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(19)))),
WASM_F32_ADD(WASM_F32_REINTERPRET_I32(WASM_I32V(32)),
WASM_F32_REINTERPRET_I32(WASM_I32V(19)))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdI32x4AddWithF32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_IF_ELSE_I(
WASM_I32_EQ(
WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_BINOP(kExprI32x4Add,
WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25)),
WASM_SIMD_F32x4_SPLAT(WASM_F32(31.5)))),
WASM_I32_ADD(WASM_I32_REINTERPRET_F32(WASM_F32(21.25)),
WASM_I32_REINTERPRET_F32(WASM_F32(31.5)))),
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdI32x4Local) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(31, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdI32x4SplatFromExtract) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(76)))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0))),
WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)));
FOR_INT32_INPUTS(i) { CHECK_EQ(76, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdI32x4For) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r,
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(1),
WASM_I32V(53))),
WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(1),
WASM_I32V(23))),
WASM_SET_LOCAL(0, WASM_I32V(0)),
WASM_LOOP(
WASM_SET_LOCAL(
1, WASM_SIMD_BINOP(kExprI32x4Add, WASM_GET_LOCAL(1),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(1)))),
WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(5)), WASM_BR(1))),
WASM_SET_LOCAL(0, WASM_I32V(1)),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
WASM_I32V(36)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)),
WASM_I32V(58)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(1)),
WASM_I32V(28)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
WASM_I32V(36)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
WASM_EXEC_COMPILED_TEST(SimdF32x4For) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
r.AllocateLocal(kWasmI32);
r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25))),
WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
WASM_F32(19.5))),
WASM_SET_LOCAL(0, WASM_I32V(0)),
WASM_LOOP(
WASM_SET_LOCAL(
1, WASM_SIMD_BINOP(kExprF32x4Add, WASM_GET_LOCAL(1),
WASM_SIMD_F32x4_SPLAT(WASM_F32(2.0)))),
WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(3)), WASM_BR(1))),
WASM_SET_LOCAL(0, WASM_I32V(1)),
WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
WASM_F32(27.25)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
WASM_F32(25.5)),
WASM_SET_LOCAL(0, WASM_I32V(0))),
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdI32x4GetGlobal) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
*(global) = 0;
*(global + 1) = 1;
*(global + 2) = 2;
*(global + 3) = 3;
r.AllocateLocal(kWasmI32);
BUILD(
r, WASM_SET_LOCAL(1, WASM_I32V(1)),
WASM_IF(WASM_I32_NE(WASM_I32V(0),
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(1),
WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(2),
WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_I32_NE(WASM_I32V(3),
WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
}
WASM_EXEC_COMPILED_TEST(SimdI32x4SetGlobal) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(23))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
WASM_I32V(34))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
WASM_I32V(45))),
WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
WASM_I32V(56))),
WASM_I32V(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
CHECK_EQ(*global, 23);
CHECK_EQ(*(global + 1), 34);
CHECK_EQ(*(global + 2), 45);
CHECK_EQ(*(global + 3), 56);
}
WASM_EXEC_COMPILED_TEST(SimdF32x4GetGlobal) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
float* global = r.module().AddGlobal<float>(kWasmS128);
*(global) = 0.0;
*(global + 1) = 1.5;
*(global + 2) = 2.25;
*(global + 3) = 3.5;
r.AllocateLocal(kWasmI32);
BUILD(
r, WASM_SET_LOCAL(1, WASM_I32V(1)),
WASM_IF(WASM_F32_NE(WASM_F32(0.0),
WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(1.5),
WASM_SIMD_F32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(2.25),
WASM_SIMD_F32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_IF(WASM_F32_NE(WASM_F32(3.5),
WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
WASM_SET_LOCAL(1, WASM_I32V(0))),
WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
}
WASM_EXEC_COMPILED_TEST(SimdF32x4SetGlobal) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
float* global = r.module().AddGlobal<float>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_SPLAT(WASM_F32(13.5))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
WASM_F32(45.5))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
WASM_F32(32.25))),
WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
WASM_F32(65.0))),
WASM_I32V(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
CHECK_EQ(*global, 13.5);
CHECK_EQ(*(global + 1), 45.5);
CHECK_EQ(*(global + 2), 32.25);
CHECK_EQ(*(global + 3), 65.0);
}
#endif // SIMD_LOWERING_TARGET
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment