Commit 12faf0f8 authored by dusan.simicic's avatar dusan.simicic Committed by Commit bot

MIPS[64]: Support for some SIMD operations

Adds support for I32x4Splat, I32x4ExtractLane, I32x4ReplaceLane,
I32x4Add, I32x4Sub, S128Zero operations for mips32 and mips64
architectures.

BUG=

Note: Depends on patch: https://codereview.chromium.org/2740123004/
Review-Url: https://codereview.chromium.org/2753903004
Cr-Commit-Position: refs/heads/master@{#44326}
parent 3258b269
...@@ -2096,7 +2096,8 @@ void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); } ...@@ -2096,7 +2096,8 @@ void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
#endif // V8_TARGET_ARCH_ARM #endif // V8_TARGET_ARCH_ARM
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 && \
!V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
void InstructionSelector::VisitI32x4Splat(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI32x4Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4ExtractLane(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
...@@ -2106,7 +2107,8 @@ void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); } ...@@ -2106,7 +2107,8 @@ void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4Add(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI32x4Add(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI32x4Sub(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 #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
void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI32x4Shl(Node* node) { UNIMPLEMENTED(); }
...@@ -2270,7 +2272,8 @@ void InstructionSelector::VisitS128Xor(Node* node) { UNIMPLEMENTED(); } ...@@ -2270,7 +2272,8 @@ void InstructionSelector::VisitS128Xor(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_ARM #endif // !V8_TARGET_ARCH_ARM
#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::VisitS128Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS1x4Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS1x4Zero(Node* node) { UNIMPLEMENTED(); }
...@@ -2278,7 +2281,10 @@ void InstructionSelector::VisitS1x4Zero(Node* node) { UNIMPLEMENTED(); } ...@@ -2278,7 +2281,10 @@ void InstructionSelector::VisitS1x4Zero(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS1x8Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS1x8Zero(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS1x16Zero(Node* node) { UNIMPLEMENTED(); } 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
void InstructionSelector::VisitS32x4Select(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS32x4Select(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM #endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM
......
...@@ -1602,6 +1602,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1602,6 +1602,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kAtomicCompareExchangeWord32: case kAtomicCompareExchangeWord32:
UNREACHABLE(); UNREACHABLE();
break; break;
case kMipsS128Zero: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ xor_v(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
break;
}
case kMipsI32x4Splat: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ fill_w(i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kMipsI32x4ExtractLane: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ copy_s_w(i.OutputRegister(), i.InputSimd128Register(0),
i.InputInt8(1));
break;
}
case kMipsI32x4ReplaceLane: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
__ move_v(dst, src);
}
__ insert_w(dst, i.InputInt8(1), i.InputRegister(2));
break;
}
case kMipsI32x4Add: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ addv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Sub: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ subv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
} }
return kSuccess; return kSuccess;
} // NOLINT(readability/fn_size) } // NOLINT(readability/fn_size)
......
...@@ -132,7 +132,13 @@ namespace compiler { ...@@ -132,7 +132,13 @@ namespace compiler {
V(MipsByteSwap32) \ V(MipsByteSwap32) \
V(MipsStackClaim) \ V(MipsStackClaim) \
V(MipsSeb) \ V(MipsSeb) \
V(MipsSeh) V(MipsSeh) \
V(MipsS128Zero) \
V(MipsI32x4Splat) \
V(MipsI32x4ExtractLane) \
V(MipsI32x4ReplaceLane) \
V(MipsI32x4Add) \
V(MipsI32x4Sub)
// Addressing modes represent the "shape" of inputs to an instruction. // Addressing modes represent the "shape" of inputs to an instruction.
// Many instructions support multiple addressing modes. Addressing modes // Many instructions support multiple addressing modes. Addressing modes
......
...@@ -136,6 +136,22 @@ static void VisitRR(InstructionSelector* selector, ArchOpcode opcode, ...@@ -136,6 +136,22 @@ static void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
g.UseRegister(node->InputAt(0))); g.UseRegister(node->InputAt(0)));
} }
static void VisitRRI(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
MipsOperandGenerator g(selector);
int32_t imm = OpParameter<int32_t>(node);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)), g.UseImmediate(imm));
}
static void VisitRRIR(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
MipsOperandGenerator g(selector);
int32_t imm = OpParameter<int32_t>(node);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)), g.UseImmediate(imm),
g.UseRegister(node->InputAt(1)));
}
static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
Node* node) { Node* node) {
...@@ -1899,6 +1915,46 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { ...@@ -1899,6 +1915,46 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE(); UNREACHABLE();
} }
void InstructionSelector::VisitI32x4Splat(Node* node) {
VisitRR(this, kMipsI32x4Splat, node);
}
void InstructionSelector::VisitI32x4ExtractLane(Node* node) {
VisitRRI(this, kMipsI32x4ExtractLane, node);
}
void InstructionSelector::VisitI32x4ReplaceLane(Node* node) {
VisitRRIR(this, kMipsI32x4ReplaceLane, node);
}
void InstructionSelector::VisitI32x4Add(Node* node) {
VisitRRR(this, kMipsI32x4Add, node);
}
void InstructionSelector::VisitI32x4Sub(Node* node) {
VisitRRR(this, kMipsI32x4Sub, node);
}
void InstructionSelector::VisitS128Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x4Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x8Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x16Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -1932,6 +1932,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1932,6 +1932,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Assert(eq, static_cast<BailoutReason>(i.InputOperand(2).immediate()), __ Assert(eq, static_cast<BailoutReason>(i.InputOperand(2).immediate()),
i.InputRegister(0), Operand(i.InputRegister(1))); i.InputRegister(0), Operand(i.InputRegister(1)));
break; break;
case kMips64S128Zero: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ xor_v(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
break;
}
case kMips64I32x4Splat: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ fill_w(i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kMips64I32x4ExtractLane: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ copy_s_w(i.OutputRegister(), i.InputSimd128Register(0),
i.InputInt8(1));
break;
}
case kMips64I32x4ReplaceLane: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
__ move_v(dst, src);
}
__ insert_w(dst, i.InputInt8(1), i.InputRegister(2));
break;
}
case kMips64I32x4Add: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ addv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMips64I32x4Sub: {
CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
__ subv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
} }
return kSuccess; return kSuccess;
} // NOLINT(readability/fn_size) } // NOLINT(readability/fn_size)
......
...@@ -166,7 +166,13 @@ namespace compiler { ...@@ -166,7 +166,13 @@ namespace compiler {
V(Mips64StackClaim) \ V(Mips64StackClaim) \
V(Mips64Seb) \ V(Mips64Seb) \
V(Mips64Seh) \ V(Mips64Seh) \
V(Mips64AssertEqual) V(Mips64AssertEqual) \
V(Mips64S128Zero) \
V(Mips64I32x4Splat) \
V(Mips64I32x4ExtractLane) \
V(Mips64I32x4ReplaceLane) \
V(Mips64I32x4Add) \
V(Mips64I32x4Sub)
// Addressing modes represent the "shape" of inputs to an instruction. // Addressing modes represent the "shape" of inputs to an instruction.
// Many instructions support multiple addressing modes. Addressing modes // Many instructions support multiple addressing modes. Addressing modes
......
...@@ -141,6 +141,22 @@ static void VisitRR(InstructionSelector* selector, ArchOpcode opcode, ...@@ -141,6 +141,22 @@ static void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
g.UseRegister(node->InputAt(0))); g.UseRegister(node->InputAt(0)));
} }
static void VisitRRI(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
Mips64OperandGenerator g(selector);
int32_t imm = OpParameter<int32_t>(node);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)), g.UseImmediate(imm));
}
static void VisitRRIR(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
Mips64OperandGenerator g(selector);
int32_t imm = OpParameter<int32_t>(node);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)), g.UseImmediate(imm),
g.UseRegister(node->InputAt(1)));
}
static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
Node* node) { Node* node) {
...@@ -2650,6 +2666,46 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { ...@@ -2650,6 +2666,46 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE(); UNREACHABLE();
} }
void InstructionSelector::VisitI32x4Splat(Node* node) {
VisitRR(this, kMips64I32x4Splat, node);
}
void InstructionSelector::VisitI32x4ExtractLane(Node* node) {
VisitRRI(this, kMips64I32x4ExtractLane, node);
}
void InstructionSelector::VisitI32x4ReplaceLane(Node* node) {
VisitRRIR(this, kMips64I32x4ReplaceLane, node);
}
void InstructionSelector::VisitI32x4Add(Node* node) {
VisitRRR(this, kMips64I32x4Add, node);
}
void InstructionSelector::VisitI32x4Sub(Node* node) {
VisitRRR(this, kMips64I32x4Sub, node);
}
void InstructionSelector::VisitS128Zero(Node* node) {
Mips64OperandGenerator g(this);
Emit(kMips64S128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x4Zero(Node* node) {
Mips64OperandGenerator g(this);
Emit(kMips64S128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x8Zero(Node* node) {
Mips64OperandGenerator g(this);
Emit(kMips64S128Zero, g.DefineSameAsFirst(node));
}
void InstructionSelector::VisitS1x16Zero(Node* node) {
Mips64OperandGenerator g(this);
Emit(kMips64S128Zero, g.DefineSameAsFirst(node));
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -49,7 +49,7 @@ namespace internal { ...@@ -49,7 +49,7 @@ namespace internal {
bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); } bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); }
bool CpuFeatures::SupportsWasmSimd128() { return false; } bool CpuFeatures::SupportsWasmSimd128() { return IsSupported(MIPS_SIMD); }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Operand and MemOperand. // Operand and MemOperand.
......
...@@ -49,7 +49,7 @@ namespace internal { ...@@ -49,7 +49,7 @@ namespace internal {
bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); } bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); }
bool CpuFeatures::SupportsWasmSimd128() { return false; } bool CpuFeatures::SupportsWasmSimd128() { return IsSupported(MIPS_SIMD); }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Operand and MemOperand. // Operand and MemOperand.
......
...@@ -31,11 +31,12 @@ typedef int8_t (*Int8BinOp)(int8_t, int8_t); ...@@ -31,11 +31,12 @@ typedef int8_t (*Int8BinOp)(int8_t, int8_t);
typedef int (*Int8CompareOp)(int8_t, int8_t); typedef int (*Int8CompareOp)(int8_t, int8_t);
typedef int8_t (*Int8ShiftOp)(int8_t, int); typedef int8_t (*Int8ShiftOp)(int8_t, int);
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && \
!V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64
#define SIMD_LOWERING_TARGET 1 #define SIMD_LOWERING_TARGET 1
#else #else
#define SIMD_LOWERING_TARGET 0 #define SIMD_LOWERING_TARGET 0
#endif // !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 #endif
// Generic expected value functions. // Generic expected value functions.
template <typename T> template <typename T>
......
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