Commit 82144cf3 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Implement i64x2 shifts for ia32

Bug: v8:9728
Change-Id: If45c7f9fcadef1c18d4889e407920861892cff1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1866684Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64695}
parent 0d787761
......@@ -334,7 +334,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
AVX_PACKED_OP3(Minpd, minpd)
AVX_PACKED_OP3(Maxpd, maxpd)
AVX_PACKED_OP3(Cmpunordpd, cmpunordpd)
AVX_PACKED_OP3(Psllq, psllq)
AVX_PACKED_OP3(Psrlq, psrlq)
#undef AVX_PACKED_OP3
AVX_PACKED_OP3_WITH_TYPE(Psllq, psllq, XMMRegister, uint8_t)
#undef AVX_PACKED_OP3_WITH_TYPE
// Non-SSE2 instructions.
......
......@@ -2011,6 +2011,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Psubq(dst, src);
break;
}
case kIA32I64x2Shl: {
XMMRegister tmp = i.TempSimd128Register(0);
Register shift = i.InputRegister(1);
// Take shift value modulo 64.
__ and_(shift, Immediate(63));
__ Movd(tmp, shift);
__ Psllq(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp);
break;
}
case kIA32I64x2ShrS: {
XMMRegister dst = i.OutputSimd128Register();
XMMRegister src = i.InputSimd128Register(0);
XMMRegister tmp = i.TempSimd128Register(0);
XMMRegister tmp2 = i.TempSimd128Register(1);
Operand shift = i.InputOperand(1);
// Take shift value modulo 64.
__ and_(shift, Immediate(63));
__ Movd(tmp, shift);
// Set up a mask [0x80000000,0,0x80000000,0].
__ Pcmpeqb(tmp2, tmp2);
__ Psllq(tmp2, tmp2, 63);
__ Psrlq(tmp2, tmp2, tmp);
__ Psrlq(dst, src, tmp);
__ Pxor(dst, tmp2);
__ Psubq(dst, tmp2);
break;
}
case kIA32I64x2ShrU: {
XMMRegister tmp = i.TempSimd128Register(0);
Register shift = i.InputRegister(1);
// Take shift value modulo 64.
__ and_(shift, Immediate(63));
__ Movd(tmp, shift);
__ Psrlq(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp);
break;
}
case kSSEF32x4Splat: {
DCHECK_EQ(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
XMMRegister dst = i.OutputSimd128Register();
......
......@@ -136,6 +136,9 @@ namespace compiler {
V(IA32I64x2SplatI32Pair) \
V(IA32I64x2ReplaceLaneI32Pair) \
V(IA32I64x2Neg) \
V(IA32I64x2Shl) \
V(IA32I64x2ShrS) \
V(IA32I64x2ShrU) \
V(SSEF32x4Splat) \
V(AVXF32x4Splat) \
V(SSEF32x4ExtractLane) \
......
......@@ -117,6 +117,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kIA32I64x2SplatI32Pair:
case kIA32I64x2ReplaceLaneI32Pair:
case kIA32I64x2Neg:
case kIA32I64x2Shl:
case kIA32I64x2ShrS:
case kIA32I64x2ShrU:
case kSSEF32x4Splat:
case kAVXF32x4Splat:
case kSSEF32x4ExtractLane:
......
......@@ -2067,6 +2067,10 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) {
V(I16x8ShrS) \
V(I16x8ShrU)
#define SIMD_SHIFT_OPCODES_UNIFED_SSE_AVX(V) \
V(I64x2Shl) \
V(I64x2ShrU)
#define SIMD_I8X16_RIGHT_SHIFT_OPCODES(V) \
V(I8x16ShrS) \
V(I8x16ShrU)
......@@ -2131,6 +2135,21 @@ void InstructionSelector::VisitI64x2Neg(Node* node) {
Emit(kIA32I64x2Neg, g.DefineAsRegister(node), operand0);
}
void InstructionSelector::VisitI64x2ShrS(Node* node) {
IA32OperandGenerator g(this);
InstructionOperand temps[] = {g.TempSimd128Register(),
g.TempSimd128Register()};
if (IsSupported(AVX)) {
Emit(kIA32I64x2ShrS, g.DefineAsRegister(node),
g.UseUniqueRegister(node->InputAt(0)), g.Use(node->InputAt(1)),
arraysize(temps), temps);
} else {
Emit(kIA32I64x2ShrS, g.DefineSameAsFirst(node),
g.UseUniqueRegister(node->InputAt(0)), g.Use(node->InputAt(1)),
arraysize(temps), temps);
}
}
void InstructionSelector::VisitF32x4Splat(Node* node) {
VisitRRSimd(this, node, kAVXF32x4Splat, kSSEF32x4Splat);
}
......@@ -2252,6 +2271,14 @@ SIMD_SHIFT_OPCODES(VISIT_SIMD_SHIFT)
#undef VISIT_SIMD_SHIFT
#undef SIMD_SHIFT_OPCODES
#define VISIT_SIMD_SHIFT_UNIFIED_SSE_AVX(Opcode) \
void InstructionSelector::Visit##Opcode(Node* node) { \
VisitRROSimdShift(this, node, kIA32##Opcode, kIA32##Opcode); \
}
SIMD_SHIFT_OPCODES_UNIFED_SSE_AVX(VISIT_SIMD_SHIFT_UNIFIED_SSE_AVX)
#undef VISIT_SIMD_SHIFT_UNIFIED_SSE_AVX
#undef SIMD_SHIFT_OPCODES_UNIFED_SSE_AVX
#define VISIT_SIMD_I8x16_RIGHT_SHIFT(Opcode) \
void InstructionSelector::Visit##Opcode(Node* node) { \
VisitRROI8x16SimdRightShift(this, node, kIA32##Opcode); \
......
......@@ -2677,18 +2677,18 @@ void InstructionSelector::VisitF64x2Le(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Min(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Max(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Neg(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Shl(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ShrS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ShrU(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_IA32
void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
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::VisitI64x2ShrU(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2GtS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2GeS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2GtU(Node* node) { UNIMPLEMENTED(); }
......
......@@ -968,7 +968,6 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2Neg) {
base::NegateWithWraparound);
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
void RunI64x2ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64ShiftOp expected_op) {
// Intentionally shift by 64, should be no-op.
......@@ -1010,6 +1009,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ShrU) {
LogicalShiftRight);
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
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);
......
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