| Index: src/compiler/arm/instruction-selector-arm.cc
|
| diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
|
| index d69a82c608e48296fd6bb5a608f69b92e12212a5..9850e40cf340f3586ec37c3ea551e6176e216207 100644
|
| --- a/src/compiler/arm/instruction-selector-arm.cc
|
| +++ b/src/compiler/arm/instruction-selector-arm.cc
|
| @@ -91,6 +91,27 @@ void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
|
| g.UseRegister(node->InputAt(1)));
|
| }
|
|
|
| +void VisitRRRShuffle(InstructionSelector* selector, ArchOpcode opcode,
|
| + Node* node) {
|
| + ArmOperandGenerator g(selector);
|
| + // Swap inputs to save an instruction in the CodeGenerator for High ops.
|
| + if (opcode == kArmS32x4ZipRight || opcode == kArmS32x4UnzipRight ||
|
| + opcode == kArmS32x4TransposeRight || opcode == kArmS16x8ZipRight ||
|
| + opcode == kArmS16x8UnzipRight || opcode == kArmS16x8TransposeRight ||
|
| + opcode == kArmS8x16ZipRight || opcode == kArmS8x16UnzipRight ||
|
| + opcode == kArmS8x16TransposeRight) {
|
| + Node* in0 = node->InputAt(0);
|
| + Node* in1 = node->InputAt(1);
|
| + node->ReplaceInput(0, in1);
|
| + node->ReplaceInput(1, in0);
|
| + }
|
| + // Use DefineSameAsFirst for binary ops that clobber their inputs, e.g. the
|
| + // NEON vzip, vuzp, and vtrn instructions.
|
| + selector->Emit(opcode, g.DefineSameAsFirst(node),
|
| + g.UseRegister(node->InputAt(0)),
|
| + g.UseRegister(node->InputAt(1)));
|
| +}
|
| +
|
| void VisitRRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
|
| ArmOperandGenerator g(selector);
|
| // Use DefineSameAsFirst for ternary ops that clobber their first input,
|
| @@ -2393,6 +2414,12 @@ VISIT_ATOMIC_BINOP(Xor)
|
| V(I16x8UConvertI8x16High, kArmI16x8UConvertI8x16High) \
|
| V(I8x16Neg, kArmI8x16Neg) \
|
| V(S128Not, kArmS128Not) \
|
| + V(S32x2Reverse, kArmS32x2Reverse) \
|
| + V(S16x4Reverse, kArmS16x4Reverse) \
|
| + V(S16x2Reverse, kArmS16x2Reverse) \
|
| + V(S8x8Reverse, kArmS8x8Reverse) \
|
| + V(S8x4Reverse, kArmS8x4Reverse) \
|
| + V(S8x2Reverse, kArmS8x2Reverse) \
|
| V(S1x4Not, kArmS128Not) \
|
| V(S1x4AnyTrue, kArmS1x4AnyTrue) \
|
| V(S1x4AllTrue, kArmS1x4AllTrue) \
|
| @@ -2490,6 +2517,26 @@ VISIT_ATOMIC_BINOP(Xor)
|
| V(S1x16Or, kArmS128Or) \
|
| V(S1x16Xor, kArmS128Xor)
|
|
|
| +#define SIMD_SHUFFLE_OP_LIST(V) \
|
| + V(S32x4ZipLeft) \
|
| + V(S32x4ZipRight) \
|
| + V(S32x4UnzipLeft) \
|
| + V(S32x4UnzipRight) \
|
| + V(S32x4TransposeLeft) \
|
| + V(S32x4TransposeRight) \
|
| + V(S16x8ZipLeft) \
|
| + V(S16x8ZipRight) \
|
| + V(S16x8UnzipLeft) \
|
| + V(S16x8UnzipRight) \
|
| + V(S16x8TransposeLeft) \
|
| + V(S16x8TransposeRight) \
|
| + V(S8x16ZipLeft) \
|
| + V(S8x16ZipRight) \
|
| + V(S8x16UnzipLeft) \
|
| + V(S8x16UnzipRight) \
|
| + V(S8x16TransposeLeft) \
|
| + V(S8x16TransposeRight)
|
| +
|
| #define SIMD_VISIT_SPLAT(Type) \
|
| void InstructionSelector::Visit##Type##Splat(Node* node) { \
|
| VisitRR(this, kArm##Type##Splat, node); \
|
| @@ -2547,6 +2594,21 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP)
|
| SIMD_FORMAT_LIST(SIMD_VISIT_SELECT_OP)
|
| #undef SIMD_VISIT_SELECT_OP
|
|
|
| +#define SIMD_VISIT_SHUFFLE_OP(Name) \
|
| + void InstructionSelector::Visit##Name(Node* node) { \
|
| + VisitRRRShuffle(this, kArm##Name, node); \
|
| + }
|
| +SIMD_SHUFFLE_OP_LIST(SIMD_VISIT_SHUFFLE_OP)
|
| +#undef SIMD_VISIT_SHUFFLE_OP
|
| +
|
| +void InstructionSelector::VisitS8x16Concat(Node* node) {
|
| + ArmOperandGenerator g(this);
|
| + int32_t imm = OpParameter<int32_t>(node);
|
| + Emit(kArmS8x16Concat, g.DefineAsRegister(node),
|
| + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)),
|
| + g.UseImmediate(imm));
|
| +}
|
| +
|
| void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
|
| UNREACHABLE();
|
| }
|
|
|