Commit 2468dacd authored by dusan.simicic's avatar dusan.simicic Committed by Commit bot

MIPS[64]: Support for some SIMD operations (3)

Add support for I32x4Mul, I32x4MaxS, I32x4MinS, I32x4Eq,
I32x4Ne, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4MaxU,
I32x4MinU, S32x4Select operations for mips32 and mips64
architectures

BUG=

Review-Url: https://codereview.chromium.org/2780713003
Cr-Commit-Position: refs/heads/master@{#44559}
parent 2aaacddd
......@@ -2140,7 +2140,8 @@ void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 &&
// !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && \
!V8_TARGET_ARCH_MIPS64
void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4ShrS(Node* node) { UNIMPLEMENTED(); }
......@@ -2160,7 +2161,8 @@ void InstructionSelector::VisitI32x4MinU(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4MaxU(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4ShrU(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
// !V8_TARGET_ARCH_MIPS64
#if !V8_TARGET_ARCH_ARM
void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
......@@ -2362,9 +2364,11 @@ void InstructionSelector::VisitS1x16Zero(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
// !V8_TARGET_ARCH_MIPS64
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS && \
!V8_TARGET_ARCH_MIPS64
void InstructionSelector::VisitS32x4Select(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS &&
// !V8_TARGET_ARCH_MIPS64
#if !V8_TARGET_ARCH_ARM
void InstructionSelector::VisitS16x8Select(Node* node) { UNIMPLEMENTED(); }
......
......@@ -1699,6 +1699,74 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ffint_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsI32x4Mul: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ mulv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MaxS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ max_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MinS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ min_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Eq: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ ceq_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Ne: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ ceq_w(dst, i.InputSimd128Register(0), i.InputSimd128Register(1));
__ nor_v(dst, dst, dst);
break;
}
case kMipsI32x4Shl: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ slli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4ShrS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ srai_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4ShrU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ srli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4MaxU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ max_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MinU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ min_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsS32x4Select: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
DCHECK(i.OutputSimd128Register().is(i.InputSimd128Register(0)));
__ bsel_v(i.OutputSimd128Register(), i.InputSimd128Register(2),
i.InputSimd128Register(1));
break;
}
}
return kSuccess;
} // NOLINT(readability/fn_size)
......
......@@ -143,7 +143,18 @@ namespace compiler {
V(MipsF32x4ExtractLane) \
V(MipsF32x4ReplaceLane) \
V(MipsF32x4SConvertI32x4) \
V(MipsF32x4UConvertI32x4)
V(MipsF32x4UConvertI32x4) \
V(MipsI32x4Mul) \
V(MipsI32x4MaxS) \
V(MipsI32x4MinS) \
V(MipsI32x4Eq) \
V(MipsI32x4Ne) \
V(MipsI32x4Shl) \
V(MipsI32x4ShrS) \
V(MipsI32x4ShrU) \
V(MipsI32x4MaxU) \
V(MipsI32x4MinU) \
V(MipsS32x4Select)
// Addressing modes represent the "shape" of inputs to an instruction.
// Many instructions support multiple addressing modes. Addressing modes
......
......@@ -128,6 +128,12 @@ static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
g.UseRegister(node->InputAt(1)));
}
void VisitRRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
MipsOperandGenerator g(selector);
selector->Emit(
opcode, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(2)));
}
static void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
......@@ -1985,6 +1991,50 @@ void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
VisitRR(this, kMipsF32x4UConvertI32x4, node);
}
void InstructionSelector::VisitI32x4Mul(Node* node) {
VisitRRR(this, kMipsI32x4Mul, node);
}
void InstructionSelector::VisitI32x4MaxS(Node* node) {
VisitRRR(this, kMipsI32x4MaxS, node);
}
void InstructionSelector::VisitI32x4MinS(Node* node) {
VisitRRR(this, kMipsI32x4MinS, node);
}
void InstructionSelector::VisitI32x4Eq(Node* node) {
VisitRRR(this, kMipsI32x4Eq, node);
}
void InstructionSelector::VisitI32x4Ne(Node* node) {
VisitRRR(this, kMipsI32x4Ne, node);
}
void InstructionSelector::VisitI32x4Shl(Node* node) {
VisitRRI(this, kMipsI32x4Shl, node);
}
void InstructionSelector::VisitI32x4ShrS(Node* node) {
VisitRRI(this, kMipsI32x4ShrS, node);
}
void InstructionSelector::VisitI32x4ShrU(Node* node) {
VisitRRI(this, kMipsI32x4ShrU, node);
}
void InstructionSelector::VisitI32x4MaxU(Node* node) {
VisitRRR(this, kMipsI32x4MaxU, node);
}
void InstructionSelector::VisitI32x4MinU(Node* node) {
VisitRRR(this, kMipsI32x4MinU, node);
}
void InstructionSelector::VisitS32x4Select(Node* node) {
VisitRRRR(this, kMipsS32x4Select, node);
}
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
......
......@@ -2029,6 +2029,74 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ffint_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMips64I32x4Mul: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ mulv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4MaxS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ max_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4MinS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ min_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4Eq: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ ceq_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4Ne: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ ceq_w(dst, i.InputSimd128Register(0), i.InputSimd128Register(1));
__ nor_v(dst, dst, dst);
break;
}
case kMips64I32x4Shl: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ slli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMips64I32x4ShrS: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ srai_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMips64I32x4ShrU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ srli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMips64I32x4MaxU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ max_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4MinU: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ min_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64S32x4Select: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
DCHECK(i.OutputSimd128Register().is(i.InputSimd128Register(0)));
__ bsel_v(i.OutputSimd128Register(), i.InputSimd128Register(2),
i.InputSimd128Register(1));
break;
}
}
return kSuccess;
} // NOLINT(readability/fn_size)
......
......@@ -177,7 +177,18 @@ namespace compiler {
V(Mips64F32x4ExtractLane) \
V(Mips64F32x4ReplaceLane) \
V(Mips64F32x4SConvertI32x4) \
V(Mips64F32x4UConvertI32x4)
V(Mips64F32x4UConvertI32x4) \
V(Mips64I32x4Mul) \
V(Mips64I32x4MaxS) \
V(Mips64I32x4MinS) \
V(Mips64I32x4Eq) \
V(Mips64I32x4Ne) \
V(Mips64I32x4Shl) \
V(Mips64I32x4ShrS) \
V(Mips64I32x4ShrU) \
V(Mips64I32x4MaxU) \
V(Mips64I32x4MinU) \
V(Mips64S32x4Select)
// Addressing modes represent the "shape" of inputs to an instruction.
// Many instructions support multiple addressing modes. Addressing modes
......
......@@ -166,6 +166,12 @@ static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
g.UseRegister(node->InputAt(1)));
}
void VisitRRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
Mips64OperandGenerator g(selector);
selector->Emit(
opcode, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(2)));
}
static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
......@@ -2736,6 +2742,50 @@ void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
VisitRR(this, kMips64F32x4UConvertI32x4, node);
}
void InstructionSelector::VisitI32x4Mul(Node* node) {
VisitRRR(this, kMips64I32x4Mul, node);
}
void InstructionSelector::VisitI32x4MaxS(Node* node) {
VisitRRR(this, kMips64I32x4MaxS, node);
}
void InstructionSelector::VisitI32x4MinS(Node* node) {
VisitRRR(this, kMips64I32x4MinS, node);
}
void InstructionSelector::VisitI32x4Eq(Node* node) {
VisitRRR(this, kMips64I32x4Eq, node);
}
void InstructionSelector::VisitI32x4Ne(Node* node) {
VisitRRR(this, kMips64I32x4Ne, node);
}
void InstructionSelector::VisitI32x4Shl(Node* node) {
VisitRRI(this, kMips64I32x4Shl, node);
}
void InstructionSelector::VisitI32x4ShrS(Node* node) {
VisitRRI(this, kMips64I32x4ShrS, node);
}
void InstructionSelector::VisitI32x4ShrU(Node* node) {
VisitRRI(this, kMips64I32x4ShrU, node);
}
void InstructionSelector::VisitI32x4MaxU(Node* node) {
VisitRRR(this, kMips64I32x4MaxU, node);
}
void InstructionSelector::VisitI32x4MinU(Node* node) {
VisitRRR(this, kMips64I32x4MinU, node);
}
void InstructionSelector::VisitS32x4Select(Node* node) {
VisitRRRR(this, kMips64S32x4Select, node);
}
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
......
......@@ -997,9 +997,11 @@ WASM_EXEC_COMPILED_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); }
WASM_EXEC_COMPILED_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); }
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET || \
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
WASM_EXEC_COMPILED_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); }
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET ||
// V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(S128And) { RunI32x4BinOpTest(kExprS128And, And); }
......@@ -1009,7 +1011,8 @@ WASM_EXEC_COMPILED_TEST(S128Or) { RunI32x4BinOpTest(kExprS128Or, Or); }
WASM_EXEC_COMPILED_TEST(S128Xor) { RunI32x4BinOpTest(kExprS128Xor, Xor); }
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET || \
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
WASM_EXEC_COMPILED_TEST(I32x4Min) {
RunI32x4BinOpTest(kExprI32x4MinS, Minimum);
}
......@@ -1052,7 +1055,8 @@ WASM_EXEC_COMPILED_TEST(I32x4Eq) { RunI32x4CompareOpTest(kExprI32x4Eq, Equal); }
WASM_EXEC_COMPILED_TEST(I32x4Ne) {
RunI32x4CompareOpTest(kExprI32x4Ne, NotEqual);
}
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET ||
// V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(I32x4LtS) {
......@@ -1088,7 +1092,8 @@ WASM_EXEC_COMPILED_TEST(I32x4GeU) {
}
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET || \
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
void RunI32x4ShiftOpTest(WasmOpcode simd_op, Int32ShiftOp expected_op,
int shift) {
FLAG_wasm_simd_prototype = true;
......@@ -1115,7 +1120,8 @@ WASM_EXEC_COMPILED_TEST(I32x4ShrS) {
WASM_EXEC_COMPILED_TEST(I32x4ShrU) {
RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1);
}
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || SIMD_LOWERING_TARGET ||
// V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
#if V8_TARGET_ARCH_ARM
// Tests both signed and unsigned conversion from I8x16 (unpacking).
......@@ -1518,7 +1524,8 @@ WASM_EXEC_COMPILED_TEST(I8x16ShrU) {
}
#endif // V8_TARGET_ARCH_ARM
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64
#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_MIPS || \
V8_TARGET_ARCH_MIPS64
// 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) \
......@@ -1555,7 +1562,8 @@ WASM_EXEC_COMPILED_TEST(I8x16ShrU) {
}
WASM_SIMD_SELECT_TEST(32x4)
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64
#endif // V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_MIPS ||
// V8_TARGET_ARCH_MIPS64
#if V8_TARGET_ARCH_ARM
WASM_SIMD_SELECT_TEST(16x8)
......
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