• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
OptionalOperator(bool supported,const Operator * op)27   OptionalOperator(bool supported, const Operator* op)
28       : supported_(supported), op_(op) {}
29 
IsSupported()30   bool IsSupported() const { return supported_; }
31   // Gets the operator only if it is supported.
op()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.
placeholder()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:
StoreRepresentation(MachineRepresentation representation,WriteBarrierKind write_barrier_kind)56   StoreRepresentation(MachineRepresentation representation,
57                       WriteBarrierKind write_barrier_kind)
58       : representation_(representation),
59         write_barrier_kind_(write_barrier_kind) {}
60 
representation()61   MachineRepresentation representation() const { return representation_; }
write_barrier_kind()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:
StackSlotRepresentation(int size,int alignment)87   StackSlotRepresentation(int size, int alignment)
88       : size_(size), alignment_(alignment) {}
89 
size()90   int size() const { return size_; }
alignment()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
NON_EXPORTED_BASE(ZoneObject)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