Commit 2e0faaf9 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm simd] Implement I64x2Add I64x2Sub on x64

Bug: v8:8460
Change-Id: I49c745f4dc2a97249621598ad0044c546638a9d5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1678402
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Auto-Submit: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62495}
parent c84e19ea
......@@ -21,6 +21,7 @@
V(paddb, 66, 0F, FC) \
V(paddw, 66, 0F, FD) \
V(paddd, 66, 0F, FE) \
V(paddq, 66, 0F, D4) \
V(paddsb, 66, 0F, EC) \
V(paddsw, 66, 0F, ED) \
V(paddusb, 66, 0F, DC) \
......@@ -46,6 +47,7 @@
V(psubb, 66, 0F, F8) \
V(psubw, 66, 0F, F9) \
V(psubd, 66, 0F, FA) \
V(psubq, 66, 0F, FB) \
V(psubsb, 66, 0F, E8) \
V(psubsw, 66, 0F, E9) \
V(psubusb, 66, 0F, D8) \
......
......@@ -1857,6 +1857,10 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord64(node), VisitI64x2ExtractLane(node);
case IrOpcode::kI64x2ReplaceLane:
return MarkAsSimd128(node), VisitI64x2ReplaceLane(node);
case IrOpcode::kI64x2Add:
return MarkAsSimd128(node), VisitI64x2Add(node);
case IrOpcode::kI64x2Sub:
return MarkAsSimd128(node), VisitI64x2Sub(node);
case IrOpcode::kI32x4Splat:
return MarkAsSimd128(node), VisitI32x4Splat(node);
case IrOpcode::kI32x4ExtractLane:
......@@ -2505,6 +2509,8 @@ void InstructionSelector::VisitF64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Add(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Sub(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64
void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
......
......@@ -2434,6 +2434,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
case kX64I64x2Add: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
__ paddq(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
}
case kX64I64x2Sub: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
__ psubq(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
}
case kX64I32x4Splat: {
XMMRegister dst = i.OutputSimd128Register();
if (instr->InputAt(0)->IsRegister()) {
......
......@@ -179,6 +179,8 @@ namespace compiler {
V(X64F32x4Lt) \
V(X64F32x4Le) \
V(X64I64x2Splat) \
V(X64I64x2Add) \
V(X64I64x2Sub) \
V(X64I32x4Splat) \
V(X64I64x2ExtractLane) \
V(X64I64x2ReplaceLane) \
......
......@@ -145,6 +145,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64F32x4Lt:
case kX64F32x4Le:
case kX64I64x2Splat:
case kX64I64x2Add:
case kX64I64x2Sub:
case kX64I32x4Splat:
case kX64I64x2ExtractLane:
case kX64I64x2ReplaceLane:
......
......@@ -2563,6 +2563,8 @@ VISIT_ATOMIC_BINOP(Xor)
V(F32x4Ne) \
V(F32x4Lt) \
V(F32x4Le) \
V(I64x2Add) \
V(I64x2Sub) \
V(I32x4Add) \
V(I32x4AddHoriz) \
V(I32x4Sub) \
......
......@@ -264,6 +264,8 @@ MachineType AtomicOpType(Operator const* op) {
V(F32x4Lt, Operator::kNoProperties, 2, 0, 1) \
V(F32x4Le, Operator::kNoProperties, 2, 0, 1) \
V(I64x2Splat, Operator::kNoProperties, 1, 0, 1) \
V(I64x2Add, Operator::kCommutative, 2, 0, 1) \
V(I64x2Sub, Operator::kNoProperties, 2, 0, 1) \
V(I32x4Splat, Operator::kNoProperties, 1, 0, 1) \
V(I32x4SConvertF32x4, Operator::kNoProperties, 1, 0, 1) \
V(I32x4SConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \
......
......@@ -493,6 +493,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* I64x2Splat();
const Operator* I64x2ExtractLane(int32_t);
const Operator* I64x2ReplaceLane(int32_t);
const Operator* I64x2Add();
const Operator* I64x2Sub();
const Operator* I32x4Splat();
const Operator* I32x4ExtractLane(int32_t);
......
......@@ -756,6 +756,8 @@
V(I64x2Splat) \
V(I64x2ExtractLane) \
V(I64x2ReplaceLane) \
V(I64x2Add) \
V(I64x2Sub) \
V(I32x4Splat) \
V(I32x4ExtractLane) \
V(I32x4ReplaceLane) \
......
......@@ -4059,6 +4059,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
inputs[0]);
case wasm::kExprI64x2Splat:
return graph()->NewNode(mcgraph()->machine()->I64x2Splat(), inputs[0]);
case wasm::kExprI64x2Add:
return graph()->NewNode(mcgraph()->machine()->I64x2Add(), inputs[0],
inputs[1]);
case wasm::kExprI64x2Sub:
return graph()->NewNode(mcgraph()->machine()->I64x2Sub(), inputs[0],
inputs[1]);
case wasm::kExprI32x4Splat:
return graph()->NewNode(mcgraph()->machine()->I32x4Splat(), inputs[0]);
case wasm::kExprI32x4SConvertF32x4:
......
......@@ -1873,6 +1873,8 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
mnemonic = "psrlw";
} else if (opcode == 0xD2) {
mnemonic = "psrld";
} else if (opcode == 0xD4) {
mnemonic = "paddq";
} else if (opcode == 0xD5) {
mnemonic = "pmullw";
} else if (opcode == 0xD7) {
......@@ -1923,6 +1925,8 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
mnemonic = "psubw";
} else if (opcode == 0xFA) {
mnemonic = "psubd";
} else if (opcode == 0xFB) {
mnemonic = "psubq";
} else if (opcode == 0xFC) {
mnemonic = "paddb";
} else if (opcode == 0xFD) {
......
......@@ -2177,6 +2177,8 @@ class ThreadImpl {
BINOP_CASE(F32x4Mul, f32x4, float4, 4, a * b)
BINOP_CASE(F32x4Min, f32x4, float4, 4, a < b ? a : b)
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(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))
......
......@@ -222,7 +222,9 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_SIMD_OP(Eq, "eq")
CASE_SIMD_OP(Ne, "ne")
CASE_SIMD_OP(Add, "add")
CASE_I64x2_OP(Add, "add")
CASE_SIMD_OP(Sub, "sub")
CASE_I64x2_OP(Sub, "sub")
CASE_SIMD_OP(Mul, "mul")
CASE_F64x2_OP(Splat, "splat")
CASE_F32x4_OP(Abs, "abs")
......
......@@ -354,6 +354,8 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, bool hasBigIntFeature);
V(I32x4MinU, 0xfd81, s_ss) \
V(I32x4MaxS, 0xfd82, s_ss) \
V(I32x4MaxU, 0xfd83, s_ss) \
V(I64x2Add, 0xfd8a, s_ss) \
V(I64x2Sub, 0xfd8d, s_ss) \
V(F32x4Abs, 0xfd95, s_s) \
V(F32x4Neg, 0xfd96, s_s) \
V(F32x4RecipApprox, 0xfd98, s_s) \
......
......@@ -22,6 +22,7 @@ namespace {
using FloatUnOp = float (*)(float);
using FloatBinOp = float (*)(float, float);
using FloatCompareOp = int (*)(float, float);
using Int64BinOp = int64_t (*)(int64_t, int64_t);
using Int32UnOp = int32_t (*)(int32_t);
using Int32BinOp = int32_t (*)(int32_t, int32_t);
using Int32CompareOp = int (*)(int32_t, int32_t);
......@@ -758,6 +759,42 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ReplaceLane) {
CHECK_EQ(i, ReadLittleEndianValue<int64_t>(&g[i]));
}
}
void RunI64x2BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64BinOp expected_op) {
WasmRunner<int32_t, int64_t, int64_t> r(execution_tier, lower_simd);
// Global to hold output.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
// Build fn to splat test values, perform binop, and write the result.
byte value1 = 0, value2 = 1;
byte temp1 = r.AllocateLocal(kWasmS128);
byte temp2 = r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(temp1, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(value1))),
WASM_SET_LOCAL(temp2, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(value2))),
WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(opcode, WASM_GET_LOCAL(temp1),
WASM_GET_LOCAL(temp2))),
WASM_ONE);
FOR_INT64_INPUTS(x) {
FOR_INT64_INPUTS(y) {
r.Call(x, y);
int64_t expected = expected_op(x, y);
for (int i = 0; i < 2; i++) {
CHECK_EQ(expected, ReadLittleEndianValue<int64_t>(&g[i]));
}
}
}
}
WASM_SIMD_TEST_NO_LOWERING(I64x2Add) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Add,
base::AddWithWraparound);
}
WASM_SIMD_TEST_NO_LOWERING(I64x2Sub) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Sub,
base::SubWithWraparound);
}
#endif // V8_TARGET_ARCH_X64
WASM_SIMD_TEST(I32x4Splat) {
......
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