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"
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.
28 // A single word lane is copied into all the other word lanes. control_[0]
29 // has the source lane.
32 // Copy input to output.
35 // control_ has bytes in range 0..15 s.t. control_[i] holds the source lane
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.
44 // control_ has int32s in range 0..3, as for 8x16.
47 // control_[0] has the number of places to rotate by.
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.
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.
58 // Reverse bytes of 16-bit lanes.
61 // Reverse bytes of 32-bit lanes.
64 // Reverse bytes of 64-bit lanes.
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.
83 // Blend words. control_ has the blend mask as an I16x8: 0 to select from
84 // the lhs, -1 to select from the rhs.
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.
103 // Fully general shuffle+blend. control_ has the shuffle mask.
107 // Representation of the result of the shuffle analysis.
110 // Both inputs, in the original lhs-rhs order
112 // Both inputs, but in rhs-lhs order
114 // Only the lhs input
116 // Only the rhs input
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
,
127 MOZ_ASSERT(opd
== Operand::LEFT
|| opd
== Operand::RIGHT
);
128 SimdShuffle s
{opd
, control
, mozilla::Some(op
), mozilla::Nothing()};
132 static SimdShuffle
shuffle(Operand opd
, SimdConstant control
,
134 MOZ_ASSERT(opd
== Operand::BOTH
|| opd
== Operand::BOTH_SWAPPED
);
135 SimdShuffle s
{opd
, control
, mozilla::Nothing(), mozilla::Some(op
)};
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
,
155 #endif // jit_ShuffleAnalysis_h