tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShuffleAnalysis.h (4756B)


      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/. */
      5 
      6 #ifndef jit_ShuffleAnalysis_h
      7 #define jit_ShuffleAnalysis_h
      8 
      9 #include "jit/IonTypes.h"
     10 
     11 namespace js {
     12 namespace jit {
     13 
     14 class MDefinition;
     15 
     16 // Permutation operations.  NOTE: these may still be x86-centric, but the set
     17 // can accomodate operations from other architectures.
     18 //
     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,
     27 
     28  // A single word lane is copied into all the other word lanes.  control_[0]
     29  // has the source lane.
     30  BROADCAST_16x8,
     31 
     32  // Copy input to output.
     33  MOVE,
     34 
     35  // control_ has bytes in range 0..15 s.t. control_[i] holds the source lane
     36  // for output lane i.
     37  PERMUTE_8x16,
     38 
     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,
     43 
     44  // control_ has int32s in range 0..3, as for 8x16.
     45  PERMUTE_32x4,
     46 
     47  // control_[0] has the number of places to rotate by.
     48  ROTATE_RIGHT_8x16,
     49 
     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,
     53 
     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,
     57 
     58  // Reverse bytes of 16-bit lanes.
     59  REVERSE_16x8,
     60 
     61  // Reverse bytes of 32-bit lanes.
     62  REVERSE_32x4,
     63 
     64  // Reverse bytes of 64-bit lanes.
     65  REVERSE_64x2,
     66 
     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,
     74 };
     75 
     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,
     82 
     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,
     86 
     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,
     90 
     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,
    102 
    103  // Fully general shuffle+blend.  control_ has the shuffle mask.
    104  SHUFFLE_BLEND_8x16,
    105 };
    106 
    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,
    118  };
    119 
    120  Operand opd;
    121  SimdConstant control;
    122  mozilla::Maybe<SimdPermuteOp> permuteOp;  // Single operands
    123  mozilla::Maybe<SimdShuffleOp> shuffleOp;  // Double operands
    124 
    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;
    130  }
    131 
    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;
    137  }
    138 
    139  bool equals(const SimdShuffle* other) const {
    140    return permuteOp == other->permuteOp && shuffleOp == other->shuffleOp &&
    141           opd == other->opd && control.bitwiseEqual(other->control);
    142  }
    143 };
    144 
    145 #ifdef ENABLE_WASM_SIMD
    146 
    147 SimdShuffle AnalyzeSimdShuffle(SimdConstant control, MDefinition* lhs,
    148                               MDefinition* rhs);
    149 
    150 #endif
    151 
    152 }  // namespace jit
    153 }  // namespace js
    154 
    155 #endif  // jit_ShuffleAnalysis_h