Home | History | Annotate | Download | only in compiler
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_COMPILER_MACHINE_OPERATOR_H_
      6 #define V8_COMPILER_MACHINE_OPERATOR_H_
      7 
      8 #include "src/base/compiler-specific.h"
      9 #include "src/base/flags.h"
     10 #include "src/globals.h"
     11 #include "src/machine-type.h"
     12 #include "src/utils.h"
     13 #include "src/zone/zone.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 // Forward declarations.
     20 struct MachineOperatorGlobalCache;
     21 class Operator;
     22 
     23 
     24 // For operators that are not supported on all platforms.
     25 class OptionalOperator final {
     26  public:
     27   OptionalOperator(bool supported, const Operator* op)
     28       : supported_(supported), op_(op) {}
     29 
     30   bool IsSupported() const { return supported_; }
     31   // Gets the operator only if it is supported.
     32   const Operator* op() const {
     33     DCHECK(supported_);
     34     return op_;
     35   }
     36   // Always gets the operator, even for unsupported operators. This is useful to
     37   // use the operator as a placeholder in a graph, for instance.
     38   const Operator* placeholder() const { return op_; }
     39 
     40  private:
     41   bool supported_;
     42   const Operator* const op_;
     43 };
     44 
     45 
     46 // A Load needs a MachineType.
     47 typedef MachineType LoadRepresentation;
     48 
     49 V8_EXPORT_PRIVATE LoadRepresentation LoadRepresentationOf(Operator const*)
     50     V8_WARN_UNUSED_RESULT;
     51 
     52 // A Store needs a MachineType and a WriteBarrierKind in order to emit the
     53 // correct write barrier.
     54 class StoreRepresentation final {
     55  public:
     56   StoreRepresentation(MachineRepresentation representation,
     57                       WriteBarrierKind write_barrier_kind)
     58       : representation_(representation),
     59         write_barrier_kind_(write_barrier_kind) {}
     60 
     61   MachineRepresentation representation() const { return representation_; }
     62   WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
     63 
     64  private:
     65   MachineRepresentation representation_;
     66   WriteBarrierKind write_barrier_kind_;
     67 };
     68 
     69 V8_EXPORT_PRIVATE bool operator==(StoreRepresentation, StoreRepresentation);
     70 bool operator!=(StoreRepresentation, StoreRepresentation);
     71 
     72 size_t hash_value(StoreRepresentation);
     73 
     74 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, StoreRepresentation);
     75 
     76 V8_EXPORT_PRIVATE StoreRepresentation const& StoreRepresentationOf(
     77     Operator const*) V8_WARN_UNUSED_RESULT;
     78 
     79 // An UnalignedStore needs a MachineType.
     80 typedef MachineRepresentation UnalignedStoreRepresentation;
     81 
     82 UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
     83     Operator const*) V8_WARN_UNUSED_RESULT;
     84 
     85 class StackSlotRepresentation final {
     86  public:
     87   StackSlotRepresentation(int size, int alignment)
     88       : size_(size), alignment_(alignment) {}
     89 
     90   int size() const { return size_; }
     91   int alignment() const { return alignment_; }
     92 
     93  private:
     94   int size_;
     95   int alignment_;
     96 };
     97 
     98 V8_EXPORT_PRIVATE bool operator==(StackSlotRepresentation,
     99                                   StackSlotRepresentation);
    100 bool operator!=(StackSlotRepresentation, StackSlotRepresentation);
    101 
    102 size_t hash_value(StackSlotRepresentation);
    103 
    104 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
    105                                            StackSlotRepresentation);
    106 
    107 V8_EXPORT_PRIVATE StackSlotRepresentation const& StackSlotRepresentationOf(
    108     Operator const* op) V8_WARN_UNUSED_RESULT;
    109 
    110 MachineRepresentation AtomicStoreRepresentationOf(Operator const* op)
    111     V8_WARN_UNUSED_RESULT;
    112 
    113 MachineType AtomicOpType(Operator const* op) V8_WARN_UNUSED_RESULT;
    114 
    115 // Interface for building machine-level operators. These operators are
    116 // machine-level but machine-independent and thus define a language suitable
    117 // for generating code to run on architectures such as ia32, x64, arm, etc.
    118 class V8_EXPORT_PRIVATE MachineOperatorBuilder final
    119     : public NON_EXPORTED_BASE(ZoneObject) {
    120  public:
    121   // Flags that specify which operations are available. This is useful
    122   // for operations that are unsupported by some back-ends.
    123   enum Flag : unsigned {
    124     kNoFlags = 0u,
    125     kFloat32RoundDown = 1u << 0,
    126     kFloat64RoundDown = 1u << 1,
    127     kFloat32RoundUp = 1u << 2,
    128     kFloat64RoundUp = 1u << 3,
    129     kFloat32RoundTruncate = 1u << 4,
    130     kFloat64RoundTruncate = 1u << 5,
    131     kFloat32RoundTiesEven = 1u << 6,
    132     kFloat64RoundTiesEven = 1u << 7,
    133     kFloat64RoundTiesAway = 1u << 8,
    134     kInt32DivIsSafe = 1u << 9,
    135     kUint32DivIsSafe = 1u << 10,
    136     kWord32ShiftIsSafe = 1u << 11,
    137     kWord32Ctz = 1u << 12,
    138     kWord64Ctz = 1u << 13,
    139     kWord32Popcnt = 1u << 14,
    140     kWord64Popcnt = 1u << 15,
    141     kWord32ReverseBits = 1u << 16,
    142     kWord64ReverseBits = 1u << 17,
    143     kInt32AbsWithOverflow = 1u << 20,
    144     kInt64AbsWithOverflow = 1u << 21,
    145     kSpeculationFence = 1u << 22,
    146     kAllOptionalOps =
    147         kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
    148         kFloat64RoundUp | kFloat32RoundTruncate | kFloat64RoundTruncate |
    149         kFloat64RoundTiesAway | kFloat32RoundTiesEven | kFloat64RoundTiesEven |
    150         kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
    151         kWord32ReverseBits | kWord64ReverseBits | kInt32AbsWithOverflow |
    152         kInt64AbsWithOverflow | kSpeculationFence
    153   };
    154   typedef base::Flags<Flag, unsigned> Flags;
    155 
    156   class AlignmentRequirements {
    157    public:
    158     enum UnalignedAccessSupport { kNoSupport, kSomeSupport, kFullSupport };
    159 
    160     bool IsUnalignedLoadSupported(MachineRepresentation rep) const {
    161       return IsUnalignedSupported(unalignedLoadUnsupportedTypes_, rep);
    162     }
    163 
    164     bool IsUnalignedStoreSupported(MachineRepresentation rep) const {
    165       return IsUnalignedSupported(unalignedStoreUnsupportedTypes_, rep);
    166     }
    167 
    168     static AlignmentRequirements FullUnalignedAccessSupport() {
    169       return AlignmentRequirements(kFullSupport);
    170     }
    171     static AlignmentRequirements NoUnalignedAccessSupport() {
    172       return AlignmentRequirements(kNoSupport);
    173     }
    174     static AlignmentRequirements SomeUnalignedAccessUnsupported(
    175         EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes,
    176         EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes) {
    177       return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
    178                                    unalignedStoreUnsupportedTypes);
    179     }
    180 
    181    private:
    182     explicit AlignmentRequirements(
    183         AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
    184         EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes =
    185             EnumSet<MachineRepresentation>(),
    186         EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes =
    187             EnumSet<MachineRepresentation>())
    188         : unalignedSupport_(unalignedAccessSupport),
    189           unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
    190           unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
    191 
    192     bool IsUnalignedSupported(EnumSet<MachineRepresentation> unsupported,
    193                               MachineRepresentation rep) const {
    194       // All accesses of bytes in memory are aligned.
    195       DCHECK_NE(MachineRepresentation::kWord8, rep);
    196       switch (unalignedSupport_) {
    197         case kFullSupport:
    198           return true;
    199         case kNoSupport:
    200           return false;
    201         case kSomeSupport:
    202           return !unsupported.Contains(rep);
    203       }
    204       UNREACHABLE();
    205     }
    206 
    207     const AlignmentRequirements::UnalignedAccessSupport unalignedSupport_;
    208     const EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes_;
    209     const EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes_;
    210   };
    211 
    212   explicit MachineOperatorBuilder(
    213       Zone* zone,
    214       MachineRepresentation word = MachineType::PointerRepresentation(),
    215       Flags supportedOperators = kNoFlags,
    216       AlignmentRequirements alignmentRequirements =
    217           AlignmentRequirements::FullUnalignedAccessSupport());
    218 
    219   const Operator* Comment(const char* msg);
    220   const Operator* DebugAbort();
    221   const Operator* DebugBreak();
    222   const Operator* UnsafePointerAdd();
    223 
    224   const Operator* Word32And();
    225   const Operator* Word32Or();
    226   const Operator* Word32Xor();
    227   const Operator* Word32Shl();
    228   const Operator* Word32Shr();
    229   const Operator* Word32Sar();
    230   const Operator* Word32Ror();
    231   const Operator* Word32Equal();
    232   const Operator* Word32Clz();
    233   const OptionalOperator Word32Ctz();
    234   const OptionalOperator Word32Popcnt();
    235   const OptionalOperator Word64Popcnt();
    236   const OptionalOperator Word32ReverseBits();
    237   const OptionalOperator Word64ReverseBits();
    238   const Operator* Word32ReverseBytes();
    239   const Operator* Word64ReverseBytes();
    240   const OptionalOperator Int32AbsWithOverflow();
    241   const OptionalOperator Int64AbsWithOverflow();
    242 
    243   // Return true if the target's Word32 shift implementation is directly
    244   // compatible with JavaScript's specification. Otherwise, we have to manually
    245   // generate a mask with 0x1f on the amount ahead of generating the shift.
    246   bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
    247 
    248   const Operator* Word64And();
    249   const Operator* Word64Or();
    250   const Operator* Word64Xor();
    251   const Operator* Word64Shl();
    252   const Operator* Word64Shr();
    253   const Operator* Word64Sar();
    254   const Operator* Word64Ror();
    255   const Operator* Word64Clz();
    256   const OptionalOperator Word64Ctz();
    257   const Operator* Word64Equal();
    258 
    259   const Operator* Int32PairAdd();
    260   const Operator* Int32PairSub();
    261   const Operator* Int32PairMul();
    262   const Operator* Word32PairShl();
    263   const Operator* Word32PairShr();
    264   const Operator* Word32PairSar();
    265 
    266   const Operator* Int32Add();
    267   const Operator* Int32AddWithOverflow();
    268   const Operator* Int32Sub();
    269   const Operator* Int32SubWithOverflow();
    270   const Operator* Int32Mul();
    271   const Operator* Int32MulWithOverflow();
    272   const Operator* Int32MulHigh();
    273   const Operator* Int32Div();
    274   const Operator* Int32Mod();
    275   const Operator* Int32LessThan();
    276   const Operator* Int32LessThanOrEqual();
    277   const Operator* Uint32Div();
    278   const Operator* Uint32LessThan();
    279   const Operator* Uint32LessThanOrEqual();
    280   const Operator* Uint32Mod();
    281   const Operator* Uint32MulHigh();
    282   bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
    283   bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
    284 
    285   const Operator* Int64Add();
    286   const Operator* Int64AddWithOverflow();
    287   const Operator* Int64Sub();
    288   const Operator* Int64SubWithOverflow();
    289   const Operator* Int64Mul();
    290   const Operator* Int64Div();
    291   const Operator* Int64Mod();
    292   const Operator* Int64LessThan();
    293   const Operator* Int64LessThanOrEqual();
    294   const Operator* Uint64Div();
    295   const Operator* Uint64LessThan();
    296   const Operator* Uint64LessThanOrEqual();
    297   const Operator* Uint64Mod();
    298 
    299   // This operator reinterprets the bits of a tagged pointer as word.
    300   const Operator* BitcastTaggedToWord();
    301 
    302   // This operator reinterprets the bits of a tagged MaybeObject pointer as
    303   // word.
    304   const Operator* BitcastMaybeObjectToWord();
    305 
    306   // This operator reinterprets the bits of a word as tagged pointer.
    307   const Operator* BitcastWordToTagged();
    308 
    309   // This operator reinterprets the bits of a word as a Smi.
    310   const Operator* BitcastWordToTaggedSigned();
    311 
    312   // JavaScript float64 to int32/uint32 truncation.
    313   const Operator* TruncateFloat64ToWord32();
    314 
    315   // These operators change the representation of numbers while preserving the
    316   // value of the number. Narrowing operators assume the input is representable
    317   // in the target type and are *not* defined for other inputs.
    318   // Use narrowing change operators only when there is a static guarantee that
    319   // the input value is representable in the target value.
    320   const Operator* ChangeFloat32ToFloat64();
    321   const Operator* ChangeFloat64ToInt32();   // narrowing
    322   const Operator* ChangeFloat64ToUint32();  // narrowing
    323   const Operator* ChangeFloat64ToUint64();
    324   const Operator* TruncateFloat64ToUint32();
    325   const Operator* TruncateFloat32ToInt32();
    326   const Operator* TruncateFloat32ToUint32();
    327   const Operator* TryTruncateFloat32ToInt64();
    328   const Operator* TryTruncateFloat64ToInt64();
    329   const Operator* TryTruncateFloat32ToUint64();
    330   const Operator* TryTruncateFloat64ToUint64();
    331   const Operator* ChangeInt32ToFloat64();
    332   const Operator* ChangeInt32ToInt64();
    333   const Operator* ChangeUint32ToFloat64();
    334   const Operator* ChangeUint32ToUint64();
    335 
    336   // These operators truncate or round numbers, both changing the representation
    337   // of the number and mapping multiple input values onto the same output value.
    338   const Operator* TruncateFloat64ToFloat32();
    339   const Operator* TruncateInt64ToInt32();
    340   const Operator* RoundFloat64ToInt32();
    341   const Operator* RoundInt32ToFloat32();
    342   const Operator* RoundInt64ToFloat32();
    343   const Operator* RoundInt64ToFloat64();
    344   const Operator* RoundUint32ToFloat32();
    345   const Operator* RoundUint64ToFloat32();
    346   const Operator* RoundUint64ToFloat64();
    347 
    348   // These operators reinterpret the bits of a floating point number as an
    349   // integer and vice versa.
    350   const Operator* BitcastFloat32ToInt32();
    351   const Operator* BitcastFloat64ToInt64();
    352   const Operator* BitcastInt32ToFloat32();
    353   const Operator* BitcastInt64ToFloat64();
    354 
    355   // These operators sign-extend to Int32/Int64
    356   const Operator* SignExtendWord8ToInt32();
    357   const Operator* SignExtendWord16ToInt32();
    358   const Operator* SignExtendWord8ToInt64();
    359   const Operator* SignExtendWord16ToInt64();
    360   const Operator* SignExtendWord32ToInt64();
    361 
    362   // Floating point operators always operate with IEEE 754 round-to-nearest
    363   // (single-precision).
    364   const Operator* Float32Add();
    365   const Operator* Float32Sub();
    366   const Operator* Float32Mul();
    367   const Operator* Float32Div();
    368   const Operator* Float32Sqrt();
    369 
    370   // Floating point operators always operate with IEEE 754 round-to-nearest
    371   // (double-precision).
    372   const Operator* Float64Add();
    373   const Operator* Float64Sub();
    374   const Operator* Float64Mul();
    375   const Operator* Float64Div();
    376   const Operator* Float64Mod();
    377   const Operator* Float64Sqrt();
    378 
    379   // Floating point comparisons complying to IEEE 754 (single-precision).
    380   const Operator* Float32Equal();
    381   const Operator* Float32LessThan();
    382   const Operator* Float32LessThanOrEqual();
    383 
    384   // Floating point comparisons complying to IEEE 754 (double-precision).
    385   const Operator* Float64Equal();
    386   const Operator* Float64LessThan();
    387   const Operator* Float64LessThanOrEqual();
    388 
    389   // Floating point min/max complying to EcmaScript 6 (double-precision).
    390   const Operator* Float64Max();
    391   const Operator* Float64Min();
    392   // Floating point min/max complying to WebAssembly (single-precision).
    393   const Operator* Float32Max();
    394   const Operator* Float32Min();
    395 
    396   // Floating point abs complying to IEEE 754 (single-precision).
    397   const Operator* Float32Abs();
    398 
    399   // Floating point abs complying to IEEE 754 (double-precision).
    400   const Operator* Float64Abs();
    401 
    402   // Floating point rounding.
    403   const OptionalOperator Float32RoundDown();
    404   const OptionalOperator Float64RoundDown();
    405   const OptionalOperator Float32RoundUp();
    406   const OptionalOperator Float64RoundUp();
    407   const OptionalOperator Float32RoundTruncate();
    408   const OptionalOperator Float64RoundTruncate();
    409   const OptionalOperator Float64RoundTiesAway();
    410   const OptionalOperator Float32RoundTiesEven();
    411   const OptionalOperator Float64RoundTiesEven();
    412 
    413   // Floating point neg.
    414   const Operator* Float32Neg();
    415   const Operator* Float64Neg();
    416 
    417   // Floating point trigonometric functions (double-precision).
    418   const Operator* Float64Acos();
    419   const Operator* Float64Acosh();
    420   const Operator* Float64Asin();
    421   const Operator* Float64Asinh();
    422   const Operator* Float64Atan();
    423   const Operator* Float64Atan2();
    424   const Operator* Float64Atanh();
    425   const Operator* Float64Cos();
    426   const Operator* Float64Cosh();
    427   const Operator* Float64Sin();
    428   const Operator* Float64Sinh();
    429   const Operator* Float64Tan();
    430   const Operator* Float64Tanh();
    431 
    432   // Floating point exponential functions (double-precision).
    433   const Operator* Float64Exp();
    434   const Operator* Float64Expm1();
    435   const Operator* Float64Pow();
    436 
    437   // Floating point logarithm (double-precision).
    438   const Operator* Float64Log();
    439   const Operator* Float64Log1p();
    440   const Operator* Float64Log2();
    441   const Operator* Float64Log10();
    442 
    443   // Floating point cube root (double-precision).
    444   const Operator* Float64Cbrt();
    445 
    446   // Floating point bit representation.
    447   const Operator* Float64ExtractLowWord32();
    448   const Operator* Float64ExtractHighWord32();
    449   const Operator* Float64InsertLowWord32();
    450   const Operator* Float64InsertHighWord32();
    451 
    452   // Change signalling NaN to quiet NaN.
    453   // Identity for any input that is not signalling NaN.
    454   const Operator* Float64SilenceNaN();
    455 
    456   // SIMD operators.
    457   const Operator* F32x4Splat();
    458   const Operator* F32x4ExtractLane(int32_t);
    459   const Operator* F32x4ReplaceLane(int32_t);
    460   const Operator* F32x4SConvertI32x4();
    461   const Operator* F32x4UConvertI32x4();
    462   const Operator* F32x4Abs();
    463   const Operator* F32x4Neg();
    464   const Operator* F32x4RecipApprox();
    465   const Operator* F32x4RecipSqrtApprox();
    466   const Operator* F32x4Add();
    467   const Operator* F32x4AddHoriz();
    468   const Operator* F32x4Sub();
    469   const Operator* F32x4Mul();
    470   const Operator* F32x4Div();
    471   const Operator* F32x4Min();
    472   const Operator* F32x4Max();
    473   const Operator* F32x4Eq();
    474   const Operator* F32x4Ne();
    475   const Operator* F32x4Lt();
    476   const Operator* F32x4Le();
    477 
    478   const Operator* I32x4Splat();
    479   const Operator* I32x4ExtractLane(int32_t);
    480   const Operator* I32x4ReplaceLane(int32_t);
    481   const Operator* I32x4SConvertF32x4();
    482   const Operator* I32x4SConvertI16x8Low();
    483   const Operator* I32x4SConvertI16x8High();
    484   const Operator* I32x4Neg();
    485   const Operator* I32x4Shl(int32_t);
    486   const Operator* I32x4ShrS(int32_t);
    487   const Operator* I32x4Add();
    488   const Operator* I32x4AddHoriz();
    489   const Operator* I32x4Sub();
    490   const Operator* I32x4Mul();
    491   const Operator* I32x4MinS();
    492   const Operator* I32x4MaxS();
    493   const Operator* I32x4Eq();
    494   const Operator* I32x4Ne();
    495   const Operator* I32x4GtS();
    496   const Operator* I32x4GeS();
    497 
    498   const Operator* I32x4UConvertF32x4();
    499   const Operator* I32x4UConvertI16x8Low();
    500   const Operator* I32x4UConvertI16x8High();
    501   const Operator* I32x4ShrU(int32_t);
    502   const Operator* I32x4MinU();
    503   const Operator* I32x4MaxU();
    504   const Operator* I32x4GtU();
    505   const Operator* I32x4GeU();
    506 
    507   const Operator* I16x8Splat();
    508   const Operator* I16x8ExtractLane(int32_t);
    509   const Operator* I16x8ReplaceLane(int32_t);
    510   const Operator* I16x8SConvertI8x16Low();
    511   const Operator* I16x8SConvertI8x16High();
    512   const Operator* I16x8Neg();
    513   const Operator* I16x8Shl(int32_t);
    514   const Operator* I16x8ShrS(int32_t);
    515   const Operator* I16x8SConvertI32x4();
    516   const Operator* I16x8Add();
    517   const Operator* I16x8AddSaturateS();
    518   const Operator* I16x8AddHoriz();
    519   const Operator* I16x8Sub();
    520   const Operator* I16x8SubSaturateS();
    521   const Operator* I16x8Mul();
    522   const Operator* I16x8MinS();
    523   const Operator* I16x8MaxS();
    524   const Operator* I16x8Eq();
    525   const Operator* I16x8Ne();
    526   const Operator* I16x8GtS();
    527   const Operator* I16x8GeS();
    528 
    529   const Operator* I16x8UConvertI8x16Low();
    530   const Operator* I16x8UConvertI8x16High();
    531   const Operator* I16x8ShrU(int32_t);
    532   const Operator* I16x8UConvertI32x4();
    533   const Operator* I16x8AddSaturateU();
    534   const Operator* I16x8SubSaturateU();
    535   const Operator* I16x8MinU();
    536   const Operator* I16x8MaxU();
    537   const Operator* I16x8GtU();
    538   const Operator* I16x8GeU();
    539 
    540   const Operator* I8x16Splat();
    541   const Operator* I8x16ExtractLane(int32_t);
    542   const Operator* I8x16ReplaceLane(int32_t);
    543   const Operator* I8x16Neg();
    544   const Operator* I8x16Shl(int32_t);
    545   const Operator* I8x16ShrS(int32_t);
    546   const Operator* I8x16SConvertI16x8();
    547   const Operator* I8x16Add();
    548   const Operator* I8x16AddSaturateS();
    549   const Operator* I8x16Sub();
    550   const Operator* I8x16SubSaturateS();
    551   const Operator* I8x16Mul();
    552   const Operator* I8x16MinS();
    553   const Operator* I8x16MaxS();
    554   const Operator* I8x16Eq();
    555   const Operator* I8x16Ne();
    556   const Operator* I8x16GtS();
    557   const Operator* I8x16GeS();
    558 
    559   const Operator* I8x16ShrU(int32_t);
    560   const Operator* I8x16UConvertI16x8();
    561   const Operator* I8x16AddSaturateU();
    562   const Operator* I8x16SubSaturateU();
    563   const Operator* I8x16MinU();
    564   const Operator* I8x16MaxU();
    565   const Operator* I8x16GtU();
    566   const Operator* I8x16GeU();
    567 
    568   const Operator* S128Load();
    569   const Operator* S128Store();
    570 
    571   const Operator* S128Zero();
    572   const Operator* S128And();
    573   const Operator* S128Or();
    574   const Operator* S128Xor();
    575   const Operator* S128Not();
    576   const Operator* S128Select();
    577 
    578   const Operator* S8x16Shuffle(const uint8_t shuffle[16]);
    579 
    580   const Operator* S1x4AnyTrue();
    581   const Operator* S1x4AllTrue();
    582   const Operator* S1x8AnyTrue();
    583   const Operator* S1x8AllTrue();
    584   const Operator* S1x16AnyTrue();
    585   const Operator* S1x16AllTrue();
    586 
    587   // load [base + index]
    588   const Operator* Load(LoadRepresentation rep);
    589   const Operator* PoisonedLoad(LoadRepresentation rep);
    590   const Operator* ProtectedLoad(LoadRepresentation rep);
    591 
    592   // store [base + index], value
    593   const Operator* Store(StoreRepresentation rep);
    594   const Operator* ProtectedStore(MachineRepresentation rep);
    595 
    596   // unaligned load [base + index]
    597   const Operator* UnalignedLoad(LoadRepresentation rep);
    598 
    599   // unaligned store [base + index], value
    600   const Operator* UnalignedStore(UnalignedStoreRepresentation rep);
    601 
    602   const Operator* StackSlot(int size, int alignment = 0);
    603   const Operator* StackSlot(MachineRepresentation rep, int alignment = 0);
    604 
    605   // Destroy value by masking when misspeculating.
    606   const Operator* TaggedPoisonOnSpeculation();
    607   const Operator* Word32PoisonOnSpeculation();
    608   const Operator* Word64PoisonOnSpeculation();
    609 
    610   // Access to the machine stack.
    611   const Operator* LoadStackPointer();
    612   const Operator* LoadFramePointer();
    613   const Operator* LoadParentFramePointer();
    614 
    615   // atomic-load [base + index]
    616   const Operator* Word32AtomicLoad(LoadRepresentation rep);
    617   // atomic-load [base + index]
    618   const Operator* Word64AtomicLoad(LoadRepresentation rep);
    619   // atomic-store [base + index], value
    620   const Operator* Word32AtomicStore(MachineRepresentation rep);
    621   // atomic-store [base + index], value
    622   const Operator* Word64AtomicStore(MachineRepresentation rep);
    623   // atomic-exchange [base + index], value
    624   const Operator* Word32AtomicExchange(MachineType type);
    625   // atomic-exchange [base + index], value
    626   const Operator* Word64AtomicExchange(MachineType type);
    627   // atomic-compare-exchange [base + index], old_value, new_value
    628   const Operator* Word32AtomicCompareExchange(MachineType type);
    629   // atomic-compare-exchange [base + index], old_value, new_value
    630   const Operator* Word64AtomicCompareExchange(MachineType type);
    631   // atomic-add [base + index], value
    632   const Operator* Word32AtomicAdd(MachineType type);
    633   // atomic-sub [base + index], value
    634   const Operator* Word32AtomicSub(MachineType type);
    635   // atomic-and [base + index], value
    636   const Operator* Word32AtomicAnd(MachineType type);
    637   // atomic-or [base + index], value
    638   const Operator* Word32AtomicOr(MachineType type);
    639   // atomic-xor [base + index], value
    640   const Operator* Word32AtomicXor(MachineType rep);
    641   // atomic-add [base + index], value
    642   const Operator* Word64AtomicAdd(MachineType rep);
    643   // atomic-sub [base + index], value
    644   const Operator* Word64AtomicSub(MachineType type);
    645   // atomic-and [base + index], value
    646   const Operator* Word64AtomicAnd(MachineType type);
    647   // atomic-or [base + index], value
    648   const Operator* Word64AtomicOr(MachineType type);
    649   // atomic-xor [base + index], value
    650   const Operator* Word64AtomicXor(MachineType rep);
    651   // atomic-narrow-add [base + index], value
    652   const Operator* Word64AtomicNarrowAdd(MachineType type);
    653   // atomic-narow-sub [base + index], value
    654   const Operator* Word64AtomicNarrowSub(MachineType type);
    655   // atomic-narrow-and [base + index], value
    656   const Operator* Word64AtomicNarrowAnd(MachineType type);
    657   // atomic-narrow-or [base + index], value
    658   const Operator* Word64AtomicNarrowOr(MachineType type);
    659   // atomic-narrow-xor [base + index], value
    660   const Operator* Word64AtomicNarrowXor(MachineType type);
    661   // atomic-narrow-exchange [base + index], value
    662   const Operator* Word64AtomicNarrowExchange(MachineType type);
    663   // atomic-narrow-compare-exchange [base + index], old_value, new_value
    664   const Operator* Word64AtomicNarrowCompareExchange(MachineType type);
    665   // atomic-pair-load [base + index]
    666   const Operator* Word32AtomicPairLoad();
    667   // atomic-pair-sub [base + index], value_high, value-low
    668   const Operator* Word32AtomicPairStore();
    669   // atomic-pair-add [base + index], value_high, value_low
    670   const Operator* Word32AtomicPairAdd();
    671   // atomic-pair-sub [base + index], value_high, value-low
    672   const Operator* Word32AtomicPairSub();
    673   // atomic-pair-and [base + index], value_high, value_low
    674   const Operator* Word32AtomicPairAnd();
    675   // atomic-pair-or [base + index], value_high, value_low
    676   const Operator* Word32AtomicPairOr();
    677   // atomic-pair-xor [base + index], value_high, value_low
    678   const Operator* Word32AtomicPairXor();
    679   // atomic-pair-exchange [base + index], value_high, value_low
    680   const Operator* Word32AtomicPairExchange();
    681   // atomic-pair-compare-exchange [base + index], old_value_high, old_value_low,
    682   // new_value_high, new_value_low
    683   const Operator* Word32AtomicPairCompareExchange();
    684 
    685   const OptionalOperator SpeculationFence();
    686 
    687   // Target machine word-size assumed by this builder.
    688   bool Is32() const { return word() == MachineRepresentation::kWord32; }
    689   bool Is64() const { return word() == MachineRepresentation::kWord64; }
    690   MachineRepresentation word() const { return word_; }
    691 
    692   bool UnalignedLoadSupported(MachineRepresentation rep) {
    693     return alignment_requirements_.IsUnalignedLoadSupported(rep);
    694   }
    695 
    696   bool UnalignedStoreSupported(MachineRepresentation rep) {
    697     return alignment_requirements_.IsUnalignedStoreSupported(rep);
    698   }
    699 
    700 // Pseudo operators that translate to 32/64-bit operators depending on the
    701 // word-size of the target machine assumed by this builder.
    702 #define PSEUDO_OP_LIST(V)      \
    703   V(Word, And)                 \
    704   V(Word, Or)                  \
    705   V(Word, Xor)                 \
    706   V(Word, Shl)                 \
    707   V(Word, Shr)                 \
    708   V(Word, Sar)                 \
    709   V(Word, Ror)                 \
    710   V(Word, Clz)                 \
    711   V(Word, Equal)               \
    712   V(Word, PoisonOnSpeculation) \
    713   V(Int, Add)                  \
    714   V(Int, Sub)                  \
    715   V(Int, Mul)                  \
    716   V(Int, Div)                  \
    717   V(Int, Mod)                  \
    718   V(Int, LessThan)             \
    719   V(Int, LessThanOrEqual)      \
    720   V(Uint, Div)                 \
    721   V(Uint, LessThan)            \
    722   V(Uint, Mod)
    723 #define PSEUDO_OP(Prefix, Suffix)                                \
    724   const Operator* Prefix##Suffix() {                             \
    725     return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
    726   }
    727   PSEUDO_OP_LIST(PSEUDO_OP)
    728 #undef PSEUDO_OP
    729 #undef PSEUDO_OP_LIST
    730 
    731  private:
    732   Zone* zone_;
    733   MachineOperatorGlobalCache const& cache_;
    734   MachineRepresentation const word_;
    735   Flags const flags_;
    736   AlignmentRequirements const alignment_requirements_;
    737 
    738   DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
    739 };
    740 
    741 
    742 DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
    743 
    744 }  // namespace compiler
    745 }  // namespace internal
    746 }  // namespace v8
    747 
    748 #endif  // V8_COMPILER_MACHINE_OPERATOR_H_
    749