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
13namespace v8 {
14namespace internal {
15namespace compiler {
16
17// Forward declarations.
18struct MachineOperatorGlobalCache;
19class Operator;
20
21
22// For operators that are not supported on all platforms.
23class OptionalOperator final {
24 public:
25  OptionalOperator(bool supported, const Operator* op)
26      : supported_(supported), op_(op) {}
27
28  bool IsSupported() const { return supported_; }
29  // Gets the operator only if it is supported.
30  const Operator* op() const {
31    DCHECK(supported_);
32    return op_;
33  }
34  // Always gets the operator, even for unsupported operators. This is useful to
35  // use the operator as a placeholder in a graph, for instance.
36  const Operator* placeholder() const { return op_; }
37
38 private:
39  bool supported_;
40  const Operator* const op_;
41};
42
43
44// A Load needs a MachineType.
45typedef MachineType LoadRepresentation;
46
47LoadRepresentation LoadRepresentationOf(Operator const*);
48
49// A Store needs a MachineType and a WriteBarrierKind in order to emit the
50// correct write barrier.
51class StoreRepresentation final {
52 public:
53  StoreRepresentation(MachineRepresentation representation,
54                      WriteBarrierKind write_barrier_kind)
55      : representation_(representation),
56        write_barrier_kind_(write_barrier_kind) {}
57
58  MachineRepresentation representation() const { return representation_; }
59  WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
60
61 private:
62  MachineRepresentation representation_;
63  WriteBarrierKind write_barrier_kind_;
64};
65
66V8_EXPORT_PRIVATE bool operator==(StoreRepresentation, StoreRepresentation);
67bool operator!=(StoreRepresentation, StoreRepresentation);
68
69size_t hash_value(StoreRepresentation);
70
71V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, StoreRepresentation);
72
73StoreRepresentation const& StoreRepresentationOf(Operator const*);
74
75typedef MachineType UnalignedLoadRepresentation;
76
77UnalignedLoadRepresentation UnalignedLoadRepresentationOf(Operator const*);
78
79// An UnalignedStore needs a MachineType.
80typedef MachineRepresentation UnalignedStoreRepresentation;
81
82UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
83    Operator const*);
84
85// A CheckedLoad needs a MachineType.
86typedef MachineType CheckedLoadRepresentation;
87
88CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const*);
89
90
91// A CheckedStore needs a MachineType.
92typedef MachineRepresentation CheckedStoreRepresentation;
93
94CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
95
96int StackSlotSizeOf(Operator const* op);
97
98MachineRepresentation AtomicStoreRepresentationOf(Operator const* op);
99
100// Interface for building machine-level operators. These operators are
101// machine-level but machine-independent and thus define a language suitable
102// for generating code to run on architectures such as ia32, x64, arm, etc.
103class V8_EXPORT_PRIVATE MachineOperatorBuilder final
104    : public NON_EXPORTED_BASE(ZoneObject) {
105 public:
106  // Flags that specify which operations are available. This is useful
107  // for operations that are unsupported by some back-ends.
108  enum Flag : unsigned {
109    kNoFlags = 0u,
110    kFloat32RoundDown = 1u << 0,
111    kFloat64RoundDown = 1u << 1,
112    kFloat32RoundUp = 1u << 2,
113    kFloat64RoundUp = 1u << 3,
114    kFloat32RoundTruncate = 1u << 4,
115    kFloat64RoundTruncate = 1u << 5,
116    kFloat32RoundTiesEven = 1u << 6,
117    kFloat64RoundTiesEven = 1u << 7,
118    kFloat64RoundTiesAway = 1u << 8,
119    kInt32DivIsSafe = 1u << 9,
120    kUint32DivIsSafe = 1u << 10,
121    kWord32ShiftIsSafe = 1u << 11,
122    kWord32Ctz = 1u << 12,
123    kWord64Ctz = 1u << 13,
124    kWord32Popcnt = 1u << 14,
125    kWord64Popcnt = 1u << 15,
126    kWord32ReverseBits = 1u << 16,
127    kWord64ReverseBits = 1u << 17,
128    kWord32ReverseBytes = 1u << 18,
129    kWord64ReverseBytes = 1u << 19,
130    kAllOptionalOps = kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
131                      kFloat64RoundUp | kFloat32RoundTruncate |
132                      kFloat64RoundTruncate | kFloat64RoundTiesAway |
133                      kFloat32RoundTiesEven | kFloat64RoundTiesEven |
134                      kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
135                      kWord32ReverseBits | kWord64ReverseBits |
136                      kWord32ReverseBytes | kWord64ReverseBytes
137  };
138  typedef base::Flags<Flag, unsigned> Flags;
139
140  class AlignmentRequirements {
141   public:
142    enum UnalignedAccessSupport { kNoSupport, kSomeSupport, kFullSupport };
143
144    bool IsUnalignedLoadSupported(const MachineType& machineType,
145                                  uint8_t alignment) const {
146      return IsUnalignedSupported(unalignedLoadUnsupportedTypes_, machineType,
147                                  alignment);
148    }
149
150    bool IsUnalignedStoreSupported(const MachineType& machineType,
151                                   uint8_t alignment) const {
152      return IsUnalignedSupported(unalignedStoreUnsupportedTypes_, machineType,
153                                  alignment);
154    }
155
156    static AlignmentRequirements FullUnalignedAccessSupport() {
157      return AlignmentRequirements(kFullSupport);
158    }
159    static AlignmentRequirements NoUnalignedAccessSupport() {
160      return AlignmentRequirements(kNoSupport);
161    }
162    static AlignmentRequirements SomeUnalignedAccessUnsupported(
163        const Vector<MachineType>& unalignedLoadUnsupportedTypes,
164        const Vector<MachineType>& unalignedStoreUnsupportedTypes) {
165      return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
166                                   unalignedStoreUnsupportedTypes);
167    }
168
169   private:
170    explicit AlignmentRequirements(
171        AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
172        Vector<MachineType> unalignedLoadUnsupportedTypes =
173            Vector<MachineType>(NULL, 0),
174        Vector<MachineType> unalignedStoreUnsupportedTypes =
175            Vector<MachineType>(NULL, 0))
176        : unalignedSupport_(unalignedAccessSupport),
177          unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
178          unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
179
180    bool IsUnalignedSupported(const Vector<MachineType>& unsupported,
181                              const MachineType& machineType,
182                              uint8_t alignment) const {
183      if (unalignedSupport_ == kFullSupport) {
184        return true;
185      } else if (unalignedSupport_ == kNoSupport) {
186        return false;
187      } else {
188        for (MachineType m : unsupported) {
189          if (m == machineType) {
190            return false;
191          }
192        }
193        return true;
194      }
195    }
196
197    const AlignmentRequirements::UnalignedAccessSupport unalignedSupport_;
198    const Vector<MachineType> unalignedLoadUnsupportedTypes_;
199    const Vector<MachineType> unalignedStoreUnsupportedTypes_;
200  };
201
202  explicit MachineOperatorBuilder(
203      Zone* zone,
204      MachineRepresentation word = MachineType::PointerRepresentation(),
205      Flags supportedOperators = kNoFlags,
206      AlignmentRequirements alignmentRequirements =
207          AlignmentRequirements::FullUnalignedAccessSupport());
208
209  const Operator* Comment(const char* msg);
210  const Operator* DebugBreak();
211  const Operator* UnsafePointerAdd();
212
213  const Operator* Word32And();
214  const Operator* Word32Or();
215  const Operator* Word32Xor();
216  const Operator* Word32Shl();
217  const Operator* Word32Shr();
218  const Operator* Word32Sar();
219  const Operator* Word32Ror();
220  const Operator* Word32Equal();
221  const Operator* Word32Clz();
222  const OptionalOperator Word32Ctz();
223  const OptionalOperator Word32Popcnt();
224  const OptionalOperator Word64Popcnt();
225  const OptionalOperator Word32ReverseBits();
226  const OptionalOperator Word64ReverseBits();
227  const OptionalOperator Word32ReverseBytes();
228  const OptionalOperator Word64ReverseBytes();
229  bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
230
231  const Operator* Word64And();
232  const Operator* Word64Or();
233  const Operator* Word64Xor();
234  const Operator* Word64Shl();
235  const Operator* Word64Shr();
236  const Operator* Word64Sar();
237  const Operator* Word64Ror();
238  const Operator* Word64Clz();
239  const OptionalOperator Word64Ctz();
240  const Operator* Word64Equal();
241
242  const Operator* Int32PairAdd();
243  const Operator* Int32PairSub();
244  const Operator* Int32PairMul();
245  const Operator* Word32PairShl();
246  const Operator* Word32PairShr();
247  const Operator* Word32PairSar();
248
249  const Operator* Int32Add();
250  const Operator* Int32AddWithOverflow();
251  const Operator* Int32Sub();
252  const Operator* Int32SubWithOverflow();
253  const Operator* Int32Mul();
254  const Operator* Int32MulWithOverflow();
255  const Operator* Int32MulHigh();
256  const Operator* Int32Div();
257  const Operator* Int32Mod();
258  const Operator* Int32LessThan();
259  const Operator* Int32LessThanOrEqual();
260  const Operator* Uint32Div();
261  const Operator* Uint32LessThan();
262  const Operator* Uint32LessThanOrEqual();
263  const Operator* Uint32Mod();
264  const Operator* Uint32MulHigh();
265  bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
266  bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
267
268  const Operator* Int64Add();
269  const Operator* Int64AddWithOverflow();
270  const Operator* Int64Sub();
271  const Operator* Int64SubWithOverflow();
272  const Operator* Int64Mul();
273  const Operator* Int64Div();
274  const Operator* Int64Mod();
275  const Operator* Int64LessThan();
276  const Operator* Int64LessThanOrEqual();
277  const Operator* Uint64Div();
278  const Operator* Uint64LessThan();
279  const Operator* Uint64LessThanOrEqual();
280  const Operator* Uint64Mod();
281
282  // This operator reinterprets the bits of a tagged pointer as word.
283  const Operator* BitcastTaggedToWord();
284
285  // This operator reinterprets the bits of a word as tagged pointer.
286  const Operator* BitcastWordToTagged();
287
288  // This operator reinterprets the bits of a word as a Smi.
289  const Operator* BitcastWordToTaggedSigned();
290
291  // JavaScript float64 to int32/uint32 truncation.
292  const Operator* TruncateFloat64ToWord32();
293
294  // These operators change the representation of numbers while preserving the
295  // value of the number. Narrowing operators assume the input is representable
296  // in the target type and are *not* defined for other inputs.
297  // Use narrowing change operators only when there is a static guarantee that
298  // the input value is representable in the target value.
299  const Operator* ChangeFloat32ToFloat64();
300  const Operator* ChangeFloat64ToInt32();   // narrowing
301  const Operator* ChangeFloat64ToUint32();  // narrowing
302  const Operator* TruncateFloat64ToUint32();
303  const Operator* TruncateFloat32ToInt32();
304  const Operator* TruncateFloat32ToUint32();
305  const Operator* TryTruncateFloat32ToInt64();
306  const Operator* TryTruncateFloat64ToInt64();
307  const Operator* TryTruncateFloat32ToUint64();
308  const Operator* TryTruncateFloat64ToUint64();
309  const Operator* ChangeInt32ToFloat64();
310  const Operator* ChangeInt32ToInt64();
311  const Operator* ChangeUint32ToFloat64();
312  const Operator* ChangeUint32ToUint64();
313
314  // These operators truncate or round numbers, both changing the representation
315  // of the number and mapping multiple input values onto the same output value.
316  const Operator* TruncateFloat64ToFloat32();
317  const Operator* TruncateInt64ToInt32();
318  const Operator* RoundFloat64ToInt32();
319  const Operator* RoundInt32ToFloat32();
320  const Operator* RoundInt64ToFloat32();
321  const Operator* RoundInt64ToFloat64();
322  const Operator* RoundUint32ToFloat32();
323  const Operator* RoundUint64ToFloat32();
324  const Operator* RoundUint64ToFloat64();
325
326  // These operators reinterpret the bits of a floating point number as an
327  // integer and vice versa.
328  const Operator* BitcastFloat32ToInt32();
329  const Operator* BitcastFloat64ToInt64();
330  const Operator* BitcastInt32ToFloat32();
331  const Operator* BitcastInt64ToFloat64();
332
333  // Floating point operators always operate with IEEE 754 round-to-nearest
334  // (single-precision).
335  const Operator* Float32Add();
336  const Operator* Float32Sub();
337  const Operator* Float32Mul();
338  const Operator* Float32Div();
339  const Operator* Float32Sqrt();
340
341  // Floating point operators always operate with IEEE 754 round-to-nearest
342  // (double-precision).
343  const Operator* Float64Add();
344  const Operator* Float64Sub();
345  const Operator* Float64Mul();
346  const Operator* Float64Div();
347  const Operator* Float64Mod();
348  const Operator* Float64Sqrt();
349
350  // Floating point comparisons complying to IEEE 754 (single-precision).
351  const Operator* Float32Equal();
352  const Operator* Float32LessThan();
353  const Operator* Float32LessThanOrEqual();
354
355  // Floating point comparisons complying to IEEE 754 (double-precision).
356  const Operator* Float64Equal();
357  const Operator* Float64LessThan();
358  const Operator* Float64LessThanOrEqual();
359
360  // Floating point min/max complying to EcmaScript 6 (double-precision).
361  const Operator* Float64Max();
362  const Operator* Float64Min();
363  // Floating point min/max complying to WebAssembly (single-precision).
364  const Operator* Float32Max();
365  const Operator* Float32Min();
366
367  // Floating point abs complying to IEEE 754 (single-precision).
368  const Operator* Float32Abs();
369
370  // Floating point abs complying to IEEE 754 (double-precision).
371  const Operator* Float64Abs();
372
373  // Floating point rounding.
374  const OptionalOperator Float32RoundDown();
375  const OptionalOperator Float64RoundDown();
376  const OptionalOperator Float32RoundUp();
377  const OptionalOperator Float64RoundUp();
378  const OptionalOperator Float32RoundTruncate();
379  const OptionalOperator Float64RoundTruncate();
380  const OptionalOperator Float64RoundTiesAway();
381  const OptionalOperator Float32RoundTiesEven();
382  const OptionalOperator Float64RoundTiesEven();
383
384  // Floating point neg.
385  const Operator* Float32Neg();
386  const Operator* Float64Neg();
387
388  // Floating point trigonometric functions (double-precision).
389  const Operator* Float64Acos();
390  const Operator* Float64Acosh();
391  const Operator* Float64Asin();
392  const Operator* Float64Asinh();
393  const Operator* Float64Atan();
394  const Operator* Float64Atan2();
395  const Operator* Float64Atanh();
396  const Operator* Float64Cos();
397  const Operator* Float64Cosh();
398  const Operator* Float64Sin();
399  const Operator* Float64Sinh();
400  const Operator* Float64Tan();
401  const Operator* Float64Tanh();
402
403  // Floating point exponential functions (double-precision).
404  const Operator* Float64Exp();
405  const Operator* Float64Expm1();
406  const Operator* Float64Pow();
407
408  // Floating point logarithm (double-precision).
409  const Operator* Float64Log();
410  const Operator* Float64Log1p();
411  const Operator* Float64Log2();
412  const Operator* Float64Log10();
413
414  // Floating point cube root (double-precision).
415  const Operator* Float64Cbrt();
416
417  // Floating point bit representation.
418  const Operator* Float64ExtractLowWord32();
419  const Operator* Float64ExtractHighWord32();
420  const Operator* Float64InsertLowWord32();
421  const Operator* Float64InsertHighWord32();
422
423  // Change signalling NaN to quiet NaN.
424  // Identity for any input that is not signalling NaN.
425  const Operator* Float64SilenceNaN();
426
427  // SIMD operators.
428  const Operator* CreateFloat32x4();
429  const Operator* Float32x4ExtractLane(int32_t);
430  const Operator* Float32x4ReplaceLane(int32_t);
431  const Operator* Float32x4Abs();
432  const Operator* Float32x4Neg();
433  const Operator* Float32x4Sqrt();
434  const Operator* Float32x4RecipApprox();
435  const Operator* Float32x4RecipSqrtApprox();
436  const Operator* Float32x4Add();
437  const Operator* Float32x4Sub();
438  const Operator* Float32x4Mul();
439  const Operator* Float32x4Div();
440  const Operator* Float32x4Min();
441  const Operator* Float32x4Max();
442  const Operator* Float32x4MinNum();
443  const Operator* Float32x4MaxNum();
444  const Operator* Float32x4Equal();
445  const Operator* Float32x4NotEqual();
446  const Operator* Float32x4LessThan();
447  const Operator* Float32x4LessThanOrEqual();
448  const Operator* Float32x4GreaterThan();
449  const Operator* Float32x4GreaterThanOrEqual();
450  const Operator* Float32x4FromInt32x4();
451  const Operator* Float32x4FromUint32x4();
452
453  const Operator* CreateInt32x4();
454  const Operator* Int32x4ExtractLane(int32_t);
455  const Operator* Int32x4ReplaceLane(int32_t);
456  const Operator* Int32x4Neg();
457  const Operator* Int32x4Add();
458  const Operator* Int32x4Sub();
459  const Operator* Int32x4Mul();
460  const Operator* Int32x4Min();
461  const Operator* Int32x4Max();
462  const Operator* Int32x4ShiftLeftByScalar(int32_t);
463  const Operator* Int32x4ShiftRightByScalar(int32_t);
464  const Operator* Int32x4Equal();
465  const Operator* Int32x4NotEqual();
466  const Operator* Int32x4LessThan();
467  const Operator* Int32x4LessThanOrEqual();
468  const Operator* Int32x4GreaterThan();
469  const Operator* Int32x4GreaterThanOrEqual();
470  const Operator* Int32x4FromFloat32x4();
471
472  const Operator* Uint32x4Min();
473  const Operator* Uint32x4Max();
474  const Operator* Uint32x4ShiftRightByScalar(int32_t);
475  const Operator* Uint32x4LessThan();
476  const Operator* Uint32x4LessThanOrEqual();
477  const Operator* Uint32x4GreaterThan();
478  const Operator* Uint32x4GreaterThanOrEqual();
479  const Operator* Uint32x4FromFloat32x4();
480
481  const Operator* Bool32x4And();
482  const Operator* Bool32x4Or();
483  const Operator* Bool32x4Xor();
484  const Operator* Bool32x4Not();
485  const Operator* Bool32x4AnyTrue();
486  const Operator* Bool32x4AllTrue();
487
488  const Operator* CreateInt16x8();
489  const Operator* Int16x8ExtractLane(int32_t);
490  const Operator* Int16x8ReplaceLane(int32_t);
491  const Operator* Int16x8Neg();
492  const Operator* Int16x8Add();
493  const Operator* Int16x8AddSaturate();
494  const Operator* Int16x8Sub();
495  const Operator* Int16x8SubSaturate();
496  const Operator* Int16x8Mul();
497  const Operator* Int16x8Min();
498  const Operator* Int16x8Max();
499  const Operator* Int16x8ShiftLeftByScalar(int32_t);
500  const Operator* Int16x8ShiftRightByScalar(int32_t);
501  const Operator* Int16x8Equal();
502  const Operator* Int16x8NotEqual();
503  const Operator* Int16x8LessThan();
504  const Operator* Int16x8LessThanOrEqual();
505  const Operator* Int16x8GreaterThan();
506  const Operator* Int16x8GreaterThanOrEqual();
507
508  const Operator* Uint16x8AddSaturate();
509  const Operator* Uint16x8SubSaturate();
510  const Operator* Uint16x8Min();
511  const Operator* Uint16x8Max();
512  const Operator* Uint16x8ShiftRightByScalar(int32_t);
513  const Operator* Uint16x8LessThan();
514  const Operator* Uint16x8LessThanOrEqual();
515  const Operator* Uint16x8GreaterThan();
516  const Operator* Uint16x8GreaterThanOrEqual();
517
518  const Operator* Bool16x8And();
519  const Operator* Bool16x8Or();
520  const Operator* Bool16x8Xor();
521  const Operator* Bool16x8Not();
522  const Operator* Bool16x8AnyTrue();
523  const Operator* Bool16x8AllTrue();
524
525  const Operator* CreateInt8x16();
526  const Operator* Int8x16ExtractLane(int32_t);
527  const Operator* Int8x16ReplaceLane(int32_t);
528  const Operator* Int8x16Neg();
529  const Operator* Int8x16Add();
530  const Operator* Int8x16AddSaturate();
531  const Operator* Int8x16Sub();
532  const Operator* Int8x16SubSaturate();
533  const Operator* Int8x16Mul();
534  const Operator* Int8x16Min();
535  const Operator* Int8x16Max();
536  const Operator* Int8x16ShiftLeftByScalar(int32_t);
537  const Operator* Int8x16ShiftRightByScalar(int32_t);
538  const Operator* Int8x16Equal();
539  const Operator* Int8x16NotEqual();
540  const Operator* Int8x16LessThan();
541  const Operator* Int8x16LessThanOrEqual();
542  const Operator* Int8x16GreaterThan();
543  const Operator* Int8x16GreaterThanOrEqual();
544
545  const Operator* Uint8x16AddSaturate();
546  const Operator* Uint8x16SubSaturate();
547  const Operator* Uint8x16Min();
548  const Operator* Uint8x16Max();
549  const Operator* Uint8x16ShiftRightByScalar(int32_t);
550  const Operator* Uint8x16LessThan();
551  const Operator* Uint8x16LessThanOrEqual();
552  const Operator* Uint8x16GreaterThan();
553  const Operator* Uint8x16GreaterThanOrEqual();
554
555  const Operator* Bool8x16And();
556  const Operator* Bool8x16Or();
557  const Operator* Bool8x16Xor();
558  const Operator* Bool8x16Not();
559  const Operator* Bool8x16AnyTrue();
560  const Operator* Bool8x16AllTrue();
561
562  const Operator* Simd128Load();
563  const Operator* Simd128Load1();
564  const Operator* Simd128Load2();
565  const Operator* Simd128Load3();
566  const Operator* Simd128Store();
567  const Operator* Simd128Store1();
568  const Operator* Simd128Store2();
569  const Operator* Simd128Store3();
570  const Operator* Simd128And();
571  const Operator* Simd128Or();
572  const Operator* Simd128Xor();
573  const Operator* Simd128Not();
574  const Operator* Simd32x4Select();
575  const Operator* Simd32x4Swizzle(uint32_t);
576  const Operator* Simd32x4Shuffle();
577  const Operator* Simd16x8Select();
578  const Operator* Simd16x8Swizzle(uint32_t);
579  const Operator* Simd16x8Shuffle();
580  const Operator* Simd8x16Select();
581  const Operator* Simd8x16Swizzle(uint32_t);
582  const Operator* Simd8x16Shuffle();
583
584  // load [base + index]
585  const Operator* Load(LoadRepresentation rep);
586  const Operator* ProtectedLoad(LoadRepresentation rep);
587
588  // store [base + index], value
589  const Operator* Store(StoreRepresentation rep);
590  const Operator* ProtectedStore(MachineRepresentation rep);
591
592  // unaligned load [base + index]
593  const Operator* UnalignedLoad(UnalignedLoadRepresentation rep);
594
595  // unaligned store [base + index], value
596  const Operator* UnalignedStore(UnalignedStoreRepresentation rep);
597
598  const Operator* StackSlot(int size);
599  const Operator* StackSlot(MachineRepresentation rep);
600
601  // Access to the machine stack.
602  const Operator* LoadStackPointer();
603  const Operator* LoadFramePointer();
604  const Operator* LoadParentFramePointer();
605
606  // checked-load heap, index, length
607  const Operator* CheckedLoad(CheckedLoadRepresentation);
608  // checked-store heap, index, length, value
609  const Operator* CheckedStore(CheckedStoreRepresentation);
610
611  // atomic-load [base + index]
612  const Operator* AtomicLoad(LoadRepresentation rep);
613  // atomic-store [base + index], value
614  const Operator* AtomicStore(MachineRepresentation rep);
615
616  // Target machine word-size assumed by this builder.
617  bool Is32() const { return word() == MachineRepresentation::kWord32; }
618  bool Is64() const { return word() == MachineRepresentation::kWord64; }
619  MachineRepresentation word() const { return word_; }
620
621  bool UnalignedLoadSupported(const MachineType& machineType,
622                              uint8_t alignment) {
623    return alignment_requirements_.IsUnalignedLoadSupported(machineType,
624                                                            alignment);
625  }
626
627  bool UnalignedStoreSupported(const MachineType& machineType,
628                               uint8_t alignment) {
629    return alignment_requirements_.IsUnalignedStoreSupported(machineType,
630                                                             alignment);
631  }
632
633// Pseudo operators that translate to 32/64-bit operators depending on the
634// word-size of the target machine assumed by this builder.
635#define PSEUDO_OP_LIST(V) \
636  V(Word, And)            \
637  V(Word, Or)             \
638  V(Word, Xor)            \
639  V(Word, Shl)            \
640  V(Word, Shr)            \
641  V(Word, Sar)            \
642  V(Word, Ror)            \
643  V(Word, Clz)            \
644  V(Word, Equal)          \
645  V(Int, Add)             \
646  V(Int, Sub)             \
647  V(Int, Mul)             \
648  V(Int, Div)             \
649  V(Int, Mod)             \
650  V(Int, LessThan)        \
651  V(Int, LessThanOrEqual) \
652  V(Uint, Div)            \
653  V(Uint, LessThan)       \
654  V(Uint, Mod)
655#define PSEUDO_OP(Prefix, Suffix)                                \
656  const Operator* Prefix##Suffix() {                             \
657    return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
658  }
659  PSEUDO_OP_LIST(PSEUDO_OP)
660#undef PSEUDO_OP
661#undef PSEUDO_OP_LIST
662
663 private:
664  Zone* zone_;
665  MachineOperatorGlobalCache const& cache_;
666  MachineRepresentation const word_;
667  Flags const flags_;
668  AlignmentRequirements const alignment_requirements_;
669
670  DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
671};
672
673
674DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
675
676}  // namespace compiler
677}  // namespace internal
678}  // namespace v8
679
680#endif  // V8_COMPILER_MACHINE_OPERATOR_H_
681