Commit 40d7e1a6 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm simd] Implement I64x2Mul

Bug: v8:8460
Change-Id: Ie7df93babd3b3345166890d57e341b5f8ddac01b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1687776
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62727}
parent 81b289a0
......@@ -1875,6 +1875,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsSimd128(node), VisitI64x2Add(node);
case IrOpcode::kI64x2Sub:
return MarkAsSimd128(node), VisitI64x2Sub(node);
case IrOpcode::kI64x2Mul:
return MarkAsSimd128(node), VisitI64x2Mul(node);
case IrOpcode::kI64x2Eq:
return MarkAsSimd128(node), VisitI64x2Eq(node);
case IrOpcode::kI64x2Ne:
......@@ -2552,6 +2554,7 @@ void InstructionSelector::VisitI64x2Shl(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ShrS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Add(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Sub(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Mul(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Eq(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Ne(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2GtS(Node* node) { UNIMPLEMENTED(); }
......
......@@ -2512,6 +2512,32 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ psubq(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
}
case kX64I64x2Mul: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
CpuFeatureScope sse_scope(tasm(), SSE4_1);
XMMRegister left = i.InputSimd128Register(0);
XMMRegister right = i.InputSimd128Register(1);
XMMRegister tmp1 = i.ToSimd128Register(instr->TempAt(0));
XMMRegister tmp2 = i.ToSimd128Register(instr->TempAt(1));
__ movaps(tmp1, left);
__ movaps(tmp2, right);
// Multiply high dword of each qword of left with right.
__ psrlq(tmp1, 32);
__ pmuludq(tmp1, right);
// Multiply high dword of each qword of right with left.
__ psrlq(tmp2, 32);
__ pmuludq(tmp2, left);
__ paddq(tmp2, tmp1);
__ psllq(tmp2, 32);
__ pmuludq(left, right);
__ paddq(left, tmp2); // left == dst
break;
}
case kX64I64x2Eq: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
CpuFeatureScope sse_scope(tasm(), SSE4_1);
......
......@@ -190,6 +190,7 @@ namespace compiler {
V(X64I64x2ShrS) \
V(X64I64x2Add) \
V(X64I64x2Sub) \
V(X64I64x2Mul) \
V(X64I64x2Eq) \
V(X64I64x2Ne) \
V(X64I64x2GtS) \
......
......@@ -156,6 +156,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I64x2ShrS:
case kX64I64x2Add:
case kX64I64x2Sub:
case kX64I64x2Mul:
case kX64I64x2Eq:
case kX64I64x2Ne:
case kX64I64x2GtS:
......
......@@ -2829,6 +2829,15 @@ void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
g.UseRegister(node->InputAt(0)));
}
void InstructionSelector::VisitI64x2Mul(Node* node) {
X64OperandGenerator g(this);
InstructionOperand temps[] = {g.TempSimd128Register(),
g.TempSimd128Register()};
Emit(kX64I64x2Mul, g.DefineSameAsFirst(node),
g.UseUniqueRegister(node->InputAt(0)),
g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
}
void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
X64OperandGenerator g(this);
Emit(kX64I32x4SConvertF32x4, g.DefineSameAsFirst(node),
......
......@@ -269,6 +269,7 @@ MachineType AtomicOpType(Operator const* op) {
V(I64x2Neg, Operator::kNoProperties, 1, 0, 1) \
V(I64x2Add, Operator::kCommutative, 2, 0, 1) \
V(I64x2Sub, Operator::kNoProperties, 2, 0, 1) \
V(I64x2Mul, Operator::kCommutative, 2, 0, 1) \
V(I64x2Eq, Operator::kCommutative, 2, 0, 1) \
V(I64x2Ne, Operator::kCommutative, 2, 0, 1) \
V(I64x2GtS, Operator::kNoProperties, 2, 0, 1) \
......
......@@ -503,6 +503,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* I64x2ShrS(int32_t);
const Operator* I64x2Add();
const Operator* I64x2Sub();
const Operator* I64x2Mul();
const Operator* I64x2Eq();
const Operator* I64x2Ne();
const Operator* I64x2GtS();
......
......@@ -774,6 +774,7 @@
V(I64x2ShrS) \
V(I64x2Add) \
V(I64x2Sub) \
V(I64x2Mul) \
V(I64x2Eq) \
V(I64x2Ne) \
V(I64x2GtS) \
......
......@@ -4064,6 +4064,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI64x2Sub:
return graph()->NewNode(mcgraph()->machine()->I64x2Sub(), inputs[0],
inputs[1]);
case wasm::kExprI64x2Mul:
return graph()->NewNode(mcgraph()->machine()->I64x2Mul(), inputs[0],
inputs[1]);
case wasm::kExprI64x2Eq:
return graph()->NewNode(mcgraph()->machine()->I64x2Eq(), inputs[0],
inputs[1]);
......
......@@ -2235,6 +2235,7 @@ class ThreadImpl {
BINOP_CASE(F32x4Max, f32x4, float4, 4, a > b ? a : b)
BINOP_CASE(I64x2Add, i64x2, int2, 2, base::AddWithWraparound(a, b))
BINOP_CASE(I64x2Sub, i64x2, int2, 2, base::SubWithWraparound(a, b))
BINOP_CASE(I64x2Mul, i64x2, int2, 2, base::MulWithWraparound(a, b))
BINOP_CASE(I32x4Add, i32x4, int4, 4, base::AddWithWraparound(a, b))
BINOP_CASE(I32x4Sub, i32x4, int4, 4, base::SubWithWraparound(a, b))
BINOP_CASE(I32x4Mul, i32x4, int4, 4, base::MulWithWraparound(a, b))
......
......@@ -232,6 +232,7 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_SIMD_OP(Sub, "sub")
CASE_I64x2_OP(Sub, "sub")
CASE_SIMD_OP(Mul, "mul")
CASE_I64x2_OP(Mul, "mul")
CASE_F64x2_OP(Splat, "splat")
CASE_F32x4_OP(Abs, "abs")
CASE_F32x4_OP(AddHoriz, "add_horizontal")
......
......@@ -371,6 +371,7 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, bool hasBigIntFeature);
V(S1x2AllTrue, 0xfd86, i_s) \
V(I64x2Add, 0xfd8a, s_ss) \
V(I64x2Sub, 0xfd8d, s_ss) \
V(I64x2Mul, 0xfd8c, s_ss) \
V(F32x4Abs, 0xfd95, s_s) \
V(F32x4Neg, 0xfd96, s_s) \
V(F32x4RecipApprox, 0xfd98, s_s) \
......
......@@ -925,6 +925,11 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2Sub) {
base::SubWithWraparound);
}
WASM_SIMD_TEST_NO_LOWERING(I64x2Mul) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Mul,
base::MulWithWraparound);
}
WASM_SIMD_TEST_NO_LOWERING(I64x2Eq) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Eq, Equal);
}
......
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