Commit ceee7cfe authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][x64] Prototype i64x2.bitmask

Implement on interpreter and x64.

Bug: v8:10997
Change-Id: I3537ce54e1b56cc3b04d91cb07c430c35b88c3aa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2459109
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70459}
parent d813f56c
......@@ -1994,6 +1994,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsSimd128(node), VisitI64x2UConvertI32x4Low(node);
case IrOpcode::kI64x2UConvertI32x4High:
return MarkAsSimd128(node), VisitI64x2UConvertI32x4High(node);
case IrOpcode::kI64x2BitMask:
return MarkAsWord32(node), VisitI64x2BitMask(node);
case IrOpcode::kI64x2Shl:
return MarkAsSimd128(node), VisitI64x2Shl(node);
case IrOpcode::kI64x2ShrS:
......@@ -2697,9 +2699,12 @@ void InstructionSelector::VisitI64x2UConvertI32x4High(Node* node) {
}
#endif // !V8_TARGET_ARCH_ARM64
// TODO(v8:10975): Prototyping load lane and store lane.
#if !V8_TARGET_ARCH_X64
// TODO(v8:10975): Prototyping load lane and store lane.
void InstructionSelector::VisitLoadLane(Node* node) { UNIMPLEMENTED(); }
// TODO(v8:10997) Prototype i64x2.bitmask.
void InstructionSelector::VisitI64x2BitMask(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64
void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
......
......@@ -2728,6 +2728,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Psubq(dst, src);
break;
}
case kX64I64x2BitMask: {
__ Movmskpd(i.OutputRegister(), i.InputSimd128Register(0));
break;
}
case kX64I64x2Shl: {
// Take shift value modulo 2^6.
ASSEMBLE_SIMD_SHIFT(Psllq, 6);
......
......@@ -205,6 +205,7 @@ namespace compiler {
V(X64I64x2ExtractLane) \
V(X64I64x2ReplaceLane) \
V(X64I64x2Neg) \
V(X64I64x2BitMask) \
V(X64I64x2Shl) \
V(X64I64x2ShrS) \
V(X64I64x2Add) \
......
......@@ -177,6 +177,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I64x2ExtractLane:
case kX64I64x2ReplaceLane:
case kX64I64x2Neg:
case kX64I64x2BitMask:
case kX64I64x2Shl:
case kX64I64x2ShrS:
case kX64I64x2Add:
......
......@@ -2867,6 +2867,7 @@ VISIT_ATOMIC_BINOP(Xor)
V(F32x4RecipApprox) \
V(F32x4RecipSqrtApprox) \
V(I64x2Neg) \
V(I64x2BitMask) \
V(I32x4SConvertI16x8Low) \
V(I32x4SConvertI16x8High) \
V(I32x4Neg) \
......
......@@ -398,6 +398,7 @@ ShiftKind ShiftKindOf(Operator const* op) {
V(I64x2SConvertI32x4High, Operator::kNoProperties, 1, 0, 1) \
V(I64x2UConvertI32x4Low, Operator::kNoProperties, 1, 0, 1) \
V(I64x2UConvertI32x4High, Operator::kNoProperties, 1, 0, 1) \
V(I64x2BitMask, Operator::kNoProperties, 1, 0, 1) \
V(I64x2Shl, Operator::kNoProperties, 2, 0, 1) \
V(I64x2ShrS, Operator::kNoProperties, 2, 0, 1) \
V(I64x2Add, Operator::kCommutative, 2, 0, 1) \
......
......@@ -652,6 +652,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* I64x2SConvertI32x4High();
const Operator* I64x2UConvertI32x4Low();
const Operator* I64x2UConvertI32x4High();
const Operator* I64x2BitMask();
const Operator* I64x2Shl();
const Operator* I64x2ShrS();
const Operator* I64x2Add();
......
......@@ -823,6 +823,7 @@
V(I64x2SConvertI32x4High) \
V(I64x2UConvertI32x4Low) \
V(I64x2UConvertI32x4High) \
V(I64x2BitMask) \
V(I64x2Shl) \
V(I64x2ShrS) \
V(I64x2Add) \
......
......@@ -4597,6 +4597,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI64x2UConvertI32x4High:
return graph()->NewNode(mcgraph()->machine()->I64x2UConvertI32x4High(),
inputs[0]);
case wasm::kExprI64x2BitMask:
return graph()->NewNode(mcgraph()->machine()->I64x2BitMask(), inputs[0]);
case wasm::kExprI64x2Shl:
return graph()->NewNode(mcgraph()->machine()->I64x2Shl(), inputs[0],
inputs[1]);
......
......@@ -325,6 +325,7 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_I8x16_OP(BitMask, "bitmask")
CASE_I16x8_OP(BitMask, "bitmask")
CASE_I32x4_OP(BitMask, "bitmask")
CASE_I64x2_OP(BitMask, "bitmask")
CASE_F32x4_OP(Pmin, "pmin")
CASE_F32x4_OP(Pmax, "pmax")
......
......@@ -475,6 +475,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
V(I16x8Q15MulRSatS, 0xfd9c, s_ss) \
V(I64x2Eq, 0xfdc0, s_ss) \
V(F32x4Qfma, 0xfdb4, s_sss) \
V(I64x2BitMask, 0xfdc4, i_s) \
V(F32x4Qfms, 0xfdd4, s_sss) \
V(F64x2Qfma, 0xfdfe, s_sss) \
V(F64x2Qfms, 0xfdff, s_sss) \
......
......@@ -1581,6 +1581,27 @@ WASM_SIMD_TEST(I32x4BitMask) {
}
}
// TODO(v8:10997) Prototyping i64x2.bitmask.
#if V8_TARGET_ARCH_X64
WASM_SIMD_TEST_NO_LOWERING(I64x2BitMask) {
FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
byte value1 = r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(value1, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(0))),
WASM_SET_LOCAL(value1, WASM_SIMD_I64x2_REPLACE_LANE(
0, WASM_GET_LOCAL(value1), WASM_I64V_1(0))),
WASM_SIMD_UNOP(kExprI64x2BitMask, WASM_GET_LOCAL(value1)));
for (int64_t x : compiler::ValueHelper::GetVector<int64_t>()) {
int32_t actual = r.Call(x);
// Lane 0 is always 0 (positive).
int32_t expected = std::signbit(static_cast<double>(x)) ? 0x2 : 0x0;
CHECK_EQ(actual, expected);
}
}
#endif // V8_TARGET_ARCH_X64
WASM_SIMD_TEST(I8x16Splat) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
// Set up a global to hold output vector.
......
......@@ -2293,6 +2293,7 @@ class WasmInterpreterInternals {
BITMASK_CASE(I8x16BitMask, i8x16, int16, 16)
BITMASK_CASE(I16x8BitMask, i16x8, int8, 8)
BITMASK_CASE(I32x4BitMask, i32x4, int4, 4)
BITMASK_CASE(I64x2BitMask, i64x2, int2, 2)
#undef BITMASK_CASE
#define CMPOP_CASE(op, name, stype, out_stype, count, expr) \
......
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