Bug 1874684 - Part 29: Update spec fixme notes. r=mgaudet
[gecko.git] / js / src / jit / ShuffleAnalysis.h
blob548c46a118fb61eed4c5d1f80c2ef3f9b66d236a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef jit_ShuffleAnalysis_h
7 #define jit_ShuffleAnalysis_h
9 #include "jit/IonTypes.h"
11 namespace js {
12 namespace jit {
14 class MDefinition;
16 // Permutation operations. NOTE: these may still be x86-centric, but the set
17 // can accomodate operations from other architectures.
19 // The "low-order" byte is in lane 0 of an 8x16 datum, the "high-order" byte
20 // in lane 15. The low-order byte is also the "rightmost". In wasm, the
21 // constant (v128.const i8x16 0 1 2 ... 15) has 0 in the low-order byte and 15
22 // in the high-order byte.
23 enum class SimdPermuteOp {
24 // A single byte lane is copied into all the other byte lanes. control_[0]
25 // has the source lane.
26 BROADCAST_8x16,
28 // A single word lane is copied into all the other word lanes. control_[0]
29 // has the source lane.
30 BROADCAST_16x8,
32 // Copy input to output.
33 MOVE,
35 // control_ has bytes in range 0..15 s.t. control_[i] holds the source lane
36 // for output lane i.
37 PERMUTE_8x16,
39 // control_ has int16s in range 0..7, as for 8x16. In addition, the high
40 // byte of control_[0] has flags detailing the operation, values taken
41 // from the Perm16x8Action enum below.
42 PERMUTE_16x8,
44 // control_ has int32s in range 0..3, as for 8x16.
45 PERMUTE_32x4,
47 // control_[0] has the number of places to rotate by.
48 ROTATE_RIGHT_8x16,
50 // Zeroes are shifted into high-order bytes and low-order bytes are lost.
51 // control_[0] has the number of places to shift by.
52 SHIFT_RIGHT_8x16,
54 // Zeroes are shifted into low-order bytes and high-order bytes are lost.
55 // control_[0] has the number of places to shift by.
56 SHIFT_LEFT_8x16,
58 // Reverse bytes of 16-bit lanes.
59 REVERSE_16x8,
61 // Reverse bytes of 32-bit lanes.
62 REVERSE_32x4,
64 // Reverse bytes of 64-bit lanes.
65 REVERSE_64x2,
67 // Zero extends.
68 ZERO_EXTEND_8x16_TO_16x8,
69 ZERO_EXTEND_8x16_TO_32x4,
70 ZERO_EXTEND_8x16_TO_64x2,
71 ZERO_EXTEND_16x8_TO_32x4,
72 ZERO_EXTEND_16x8_TO_64x2,
73 ZERO_EXTEND_32x4_TO_64x2,
76 // Shuffle operations. NOTE: these may still be x86-centric, but the set can
77 // accomodate operations from other architectures.
78 enum class SimdShuffleOp {
79 // Blend bytes. control_ has the blend mask as an I8x16: 0 to select from
80 // the lhs, -1 to select from the rhs.
81 BLEND_8x16,
83 // Blend words. control_ has the blend mask as an I16x8: 0 to select from
84 // the lhs, -1 to select from the rhs.
85 BLEND_16x8,
87 // Concat the lhs in front of the rhs and shift right by bytes, extracting
88 // the low 16 bytes; control_[0] has the shift count.
89 CONCAT_RIGHT_SHIFT_8x16,
91 // Interleave qwords/dwords/words/bytes from high/low halves of operands.
92 // The low-order item in the result comes from the lhs, then the next from
93 // the rhs, and so on. control_ is ignored.
94 INTERLEAVE_HIGH_8x16,
95 INTERLEAVE_HIGH_16x8,
96 INTERLEAVE_HIGH_32x4,
97 INTERLEAVE_HIGH_64x2,
98 INTERLEAVE_LOW_8x16,
99 INTERLEAVE_LOW_16x8,
100 INTERLEAVE_LOW_32x4,
101 INTERLEAVE_LOW_64x2,
103 // Fully general shuffle+blend. control_ has the shuffle mask.
104 SHUFFLE_BLEND_8x16,
107 // Representation of the result of the shuffle analysis.
108 struct SimdShuffle {
109 enum class Operand {
110 // Both inputs, in the original lhs-rhs order
111 BOTH,
112 // Both inputs, but in rhs-lhs order
113 BOTH_SWAPPED,
114 // Only the lhs input
115 LEFT,
116 // Only the rhs input
117 RIGHT,
120 Operand opd;
121 SimdConstant control;
122 mozilla::Maybe<SimdPermuteOp> permuteOp; // Single operands
123 mozilla::Maybe<SimdShuffleOp> shuffleOp; // Double operands
125 static SimdShuffle permute(Operand opd, SimdConstant control,
126 SimdPermuteOp op) {
127 MOZ_ASSERT(opd == Operand::LEFT || opd == Operand::RIGHT);
128 SimdShuffle s{opd, control, mozilla::Some(op), mozilla::Nothing()};
129 return s;
132 static SimdShuffle shuffle(Operand opd, SimdConstant control,
133 SimdShuffleOp op) {
134 MOZ_ASSERT(opd == Operand::BOTH || opd == Operand::BOTH_SWAPPED);
135 SimdShuffle s{opd, control, mozilla::Nothing(), mozilla::Some(op)};
136 return s;
139 bool equals(const SimdShuffle* other) const {
140 return permuteOp == other->permuteOp && shuffleOp == other->shuffleOp &&
141 opd == other->opd && control.bitwiseEqual(other->control);
145 #ifdef ENABLE_WASM_SIMD
147 SimdShuffle AnalyzeSimdShuffle(SimdConstant control, MDefinition* lhs,
148 MDefinition* rhs);
150 #endif
152 } // namespace jit
153 } // namespace js
155 #endif // jit_ShuffleAnalysis_h