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