summaryrefslogtreecommitdiffstats
path: root/js/src/jit/ShuffleAnalysis.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/ShuffleAnalysis.h')
-rw-r--r--js/src/jit/ShuffleAnalysis.h147
1 files changed, 147 insertions, 0 deletions
diff --git a/js/src/jit/ShuffleAnalysis.h b/js/src/jit/ShuffleAnalysis.h
new file mode 100644
index 0000000000..84133ccf5a
--- /dev/null
+++ b/js/src/jit/ShuffleAnalysis.h
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef jit_ShuffleAnalysis_h
+#define jit_ShuffleAnalysis_h
+
+#include "jit/IonTypes.h"
+
+namespace js {
+namespace jit {
+
+class MDefinition;
+
+// Permutation operations. NOTE: these may still be x86-centric, but the set
+// can accomodate operations from other architectures.
+//
+// The "low-order" byte is in lane 0 of an 8x16 datum, the "high-order" byte
+// in lane 15. The low-order byte is also the "rightmost". In wasm, the
+// constant (v128.const i8x16 0 1 2 ... 15) has 0 in the low-order byte and 15
+// in the high-order byte.
+enum class SimdPermuteOp {
+ // A single byte lane is copied into all the other byte lanes. control_[0]
+ // has the source lane.
+ BROADCAST_8x16,
+
+ // A single word lane is copied into all the other word lanes. control_[0]
+ // has the source lane.
+ BROADCAST_16x8,
+
+ // Copy input to output.
+ MOVE,
+
+ // control_ has bytes in range 0..15 s.t. control_[i] holds the source lane
+ // for output lane i.
+ PERMUTE_8x16,
+
+ // control_ has int16s in range 0..7, as for 8x16. In addition, the high
+ // byte of control_[0] has flags detailing the operation, values taken
+ // from the Perm16x8Action enum below.
+ PERMUTE_16x8,
+
+ // control_ has int32s in range 0..3, as for 8x16.
+ PERMUTE_32x4,
+
+ // control_[0] has the number of places to rotate by.
+ ROTATE_RIGHT_8x16,
+
+ // Zeroes are shifted into high-order bytes and low-order bytes are lost.
+ // control_[0] has the number of places to shift by.
+ SHIFT_RIGHT_8x16,
+
+ // Zeroes are shifted into low-order bytes and high-order bytes are lost.
+ // control_[0] has the number of places to shift by.
+ SHIFT_LEFT_8x16,
+
+ // Reverse bytes of 16-bit lanes.
+ REVERSE_16x8,
+
+ // Reverse bytes of 32-bit lanes.
+ REVERSE_32x4,
+
+ // Reverse bytes of 64-bit lanes.
+ REVERSE_64x2,
+};
+
+// Shuffle operations. NOTE: these may still be x86-centric, but the set can
+// accomodate operations from other architectures.
+enum class SimdShuffleOp {
+ // Blend bytes. control_ has the blend mask as an I8x16: 0 to select from
+ // the lhs, -1 to select from the rhs.
+ BLEND_8x16,
+
+ // Blend words. control_ has the blend mask as an I16x8: 0 to select from
+ // the lhs, -1 to select from the rhs.
+ BLEND_16x8,
+
+ // Concat the lhs in front of the rhs and shift right by bytes, extracting
+ // the low 16 bytes; control_[0] has the shift count.
+ CONCAT_RIGHT_SHIFT_8x16,
+
+ // Interleave qwords/dwords/words/bytes from high/low halves of operands.
+ // The low-order item in the result comes from the lhs, then the next from
+ // the rhs, and so on. control_ is ignored.
+ INTERLEAVE_HIGH_8x16,
+ INTERLEAVE_HIGH_16x8,
+ INTERLEAVE_HIGH_32x4,
+ INTERLEAVE_HIGH_64x2,
+ INTERLEAVE_LOW_8x16,
+ INTERLEAVE_LOW_16x8,
+ INTERLEAVE_LOW_32x4,
+ INTERLEAVE_LOW_64x2,
+
+ // Fully general shuffle+blend. control_ has the shuffle mask.
+ SHUFFLE_BLEND_8x16,
+};
+
+// Representation of the result of the shuffle analysis.
+struct SimdShuffle {
+ enum class Operand {
+ // Both inputs, in the original lhs-rhs order
+ BOTH,
+ // Both inputs, but in rhs-lhs order
+ BOTH_SWAPPED,
+ // Only the lhs input
+ LEFT,
+ // Only the rhs input
+ RIGHT,
+ };
+
+ Operand opd;
+ SimdConstant control;
+ mozilla::Maybe<SimdPermuteOp> permuteOp; // Single operands
+ mozilla::Maybe<SimdShuffleOp> shuffleOp; // Double operands
+
+ static SimdShuffle permute(Operand opd, SimdConstant control,
+ SimdPermuteOp op) {
+ MOZ_ASSERT(opd == Operand::LEFT || opd == Operand::RIGHT);
+ SimdShuffle s{opd, control, mozilla::Some(op), mozilla::Nothing()};
+ return s;
+ }
+
+ static SimdShuffle shuffle(Operand opd, SimdConstant control,
+ SimdShuffleOp op) {
+ MOZ_ASSERT(opd == Operand::BOTH || opd == Operand::BOTH_SWAPPED);
+ SimdShuffle s{opd, control, mozilla::Nothing(), mozilla::Some(op)};
+ return s;
+ }
+
+ bool equals(const SimdShuffle* other) const {
+ return permuteOp == other->permuteOp && shuffleOp == other->shuffleOp &&
+ opd == other->opd && control.bitwiseEqual(other->control);
+ }
+};
+
+#ifdef ENABLE_WASM_SIMD
+
+SimdShuffle AnalyzeSimdShuffle(SimdConstant control, MDefinition* lhs,
+ MDefinition* rhs);
+
+#endif
+
+} // namespace jit
+} // namespace js
+
+#endif // jit_ShuffleAnalysis_h