machine-operator.h 24.6 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_MACHINE_OPERATOR_H_
#define V8_COMPILER_MACHINE_OPERATOR_H_

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 13 14 15 16

namespace v8 {
namespace internal {
namespace compiler {

17
// Forward declarations.
18
struct MachineOperatorGlobalCache;
19 20
class Operator;

21

22
// For operators that are not supported on all platforms.
23
class OptionalOperator final {
24
 public:
25 26
  OptionalOperator(bool supported, const Operator* op)
      : supported_(supported), op_(op) {}
27

28 29
  bool IsSupported() const { return supported_; }
  // Gets the operator only if it is supported.
30
  const Operator* op() const {
31
    DCHECK(supported_);
32 33
    return op_;
  }
34 35 36
  // Always gets the operator, even for unsupported operators. This is useful to
  // use the operator as a placeholder in a graph, for instance.
  const Operator* placeholder() const { return op_; }
37 38

 private:
39
  bool supported_;
40 41 42
  const Operator* const op_;
};

43

44
// A Load needs a MachineType.
45 46
typedef MachineType LoadRepresentation;

47
LoadRepresentation LoadRepresentationOf(Operator const*);
48

49 50
// A Store needs a MachineType and a WriteBarrierKind in order to emit the
// correct write barrier.
51
class StoreRepresentation final {
52
 public:
53
  StoreRepresentation(MachineRepresentation representation,
54
                      WriteBarrierKind write_barrier_kind)
55 56
      : representation_(representation),
        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
};

66
V8_EXPORT_PRIVATE bool operator==(StoreRepresentation, StoreRepresentation);
67
bool operator!=(StoreRepresentation, StoreRepresentation);
68

69
size_t hash_value(StoreRepresentation);
70

71
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, StoreRepresentation);
72

73 74
StoreRepresentation const& StoreRepresentationOf(Operator const*);

75 76 77 78 79 80 81 82 83
typedef MachineType UnalignedLoadRepresentation;

UnalignedLoadRepresentation UnalignedLoadRepresentationOf(Operator const*);

// An UnalignedStore needs a MachineType.
typedef MachineRepresentation UnalignedStoreRepresentation;

UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
    Operator const*);
84

85 86 87 88 89 90 91
// A CheckedLoad needs a MachineType.
typedef MachineType CheckedLoadRepresentation;

CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const*);


// A CheckedStore needs a MachineType.
92
typedef MachineRepresentation CheckedStoreRepresentation;
93 94 95

CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);

96
int StackSlotSizeOf(Operator const* op);
97

98 99
MachineRepresentation AtomicStoreRepresentationOf(Operator const* op);

100 101 102
// Interface for building machine-level operators. These operators are
// machine-level but machine-independent and thus define a language suitable
// for generating code to run on architectures such as ia32, x64, arm, etc.
103 104
class V8_EXPORT_PRIVATE MachineOperatorBuilder final
    : public NON_EXPORTED_BASE(ZoneObject) {
105
 public:
106 107
  // Flags that specify which operations are available. This is useful
  // for operations that are unsupported by some back-ends.
108
  enum Flag : unsigned {
109
    kNoFlags = 0u,
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    kFloat32RoundDown = 1u << 0,
    kFloat64RoundDown = 1u << 1,
    kFloat32RoundUp = 1u << 2,
    kFloat64RoundUp = 1u << 3,
    kFloat32RoundTruncate = 1u << 4,
    kFloat64RoundTruncate = 1u << 5,
    kFloat32RoundTiesEven = 1u << 6,
    kFloat64RoundTiesEven = 1u << 7,
    kFloat64RoundTiesAway = 1u << 8,
    kInt32DivIsSafe = 1u << 9,
    kUint32DivIsSafe = 1u << 10,
    kWord32ShiftIsSafe = 1u << 11,
    kWord32Ctz = 1u << 12,
    kWord64Ctz = 1u << 13,
    kWord32Popcnt = 1u << 14,
    kWord64Popcnt = 1u << 15,
    kWord32ReverseBits = 1u << 16,
    kWord64ReverseBits = 1u << 17,
    kWord32ReverseBytes = 1u << 18,
    kWord64ReverseBytes = 1u << 19,
    kAllOptionalOps = kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
                      kFloat64RoundUp | kFloat32RoundTruncate |
                      kFloat64RoundTruncate | kFloat64RoundTiesAway |
                      kFloat32RoundTiesEven | kFloat64RoundTiesEven |
                      kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
                      kWord32ReverseBits | kWord64ReverseBits |
                      kWord32ReverseBytes | kWord64ReverseBytes
137 138 139
  };
  typedef base::Flags<Flag, unsigned> Flags;

140 141 142 143 144 145
  class AlignmentRequirements {
   public:
    enum UnalignedAccessSupport { kNoSupport, kSomeSupport, kFullSupport };

    bool IsUnalignedLoadSupported(const MachineType& machineType,
                                  uint8_t alignment) const {
146
      return IsUnalignedSupported(unalignedLoadUnsupportedTypes_, machineType,
147 148 149 150 151
                                  alignment);
    }

    bool IsUnalignedStoreSupported(const MachineType& machineType,
                                   uint8_t alignment) const {
152
      return IsUnalignedSupported(unalignedStoreUnsupportedTypes_, machineType,
153 154 155 156 157 158 159 160 161
                                  alignment);
    }

    static AlignmentRequirements FullUnalignedAccessSupport() {
      return AlignmentRequirements(kFullSupport);
    }
    static AlignmentRequirements NoUnalignedAccessSupport() {
      return AlignmentRequirements(kNoSupport);
    }
162 163 164 165 166
    static AlignmentRequirements SomeUnalignedAccessUnsupported(
        const Vector<MachineType>& unalignedLoadUnsupportedTypes,
        const Vector<MachineType>& unalignedStoreUnsupportedTypes) {
      return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
                                   unalignedStoreUnsupportedTypes);
167 168 169 170 171
    }

   private:
    explicit AlignmentRequirements(
        AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
172
        Vector<MachineType> unalignedLoadUnsupportedTypes =
173
            Vector<MachineType>(NULL, 0),
174
        Vector<MachineType> unalignedStoreUnsupportedTypes =
175 176
            Vector<MachineType>(NULL, 0))
        : unalignedSupport_(unalignedAccessSupport),
177 178
          unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
          unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
179

180
    bool IsUnalignedSupported(const Vector<MachineType>& unsupported,
181 182 183 184 185 186 187
                              const MachineType& machineType,
                              uint8_t alignment) const {
      if (unalignedSupport_ == kFullSupport) {
        return true;
      } else if (unalignedSupport_ == kNoSupport) {
        return false;
      } 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 199
    const Vector<MachineType> unalignedLoadUnsupportedTypes_;
    const Vector<MachineType> unalignedStoreUnsupportedTypes_;
200 201
  };

202 203 204
  explicit MachineOperatorBuilder(
      Zone* zone,
      MachineRepresentation word = MachineType::PointerRepresentation(),
205 206
      Flags supportedOperators = kNoFlags,
      AlignmentRequirements alignmentRequirements =
207
          AlignmentRequirements::FullUnalignedAccessSupport());
208

209
  const Operator* Comment(const char* msg);
210
  const Operator* DebugBreak();
211
  const Operator* UnsafePointerAdd();
212

213 214 215 216 217 218 219 220
  const Operator* Word32And();
  const Operator* Word32Or();
  const Operator* Word32Xor();
  const Operator* Word32Shl();
  const Operator* Word32Shr();
  const Operator* Word32Sar();
  const Operator* Word32Ror();
  const Operator* Word32Equal();
221
  const Operator* Word32Clz();
222
  const OptionalOperator Word32Ctz();
223
  const OptionalOperator Word32Popcnt();
224
  const OptionalOperator Word64Popcnt();
225 226
  const OptionalOperator Word32ReverseBits();
  const OptionalOperator Word64ReverseBits();
227 228
  const OptionalOperator Word32ReverseBytes();
  const OptionalOperator Word64ReverseBytes();
229
  bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
230 231 232 233 234 235 236 237

  const Operator* Word64And();
  const Operator* Word64Or();
  const Operator* Word64Xor();
  const Operator* Word64Shl();
  const Operator* Word64Shr();
  const Operator* Word64Sar();
  const Operator* Word64Ror();
238
  const Operator* Word64Clz();
239
  const OptionalOperator Word64Ctz();
240 241
  const Operator* Word64Equal();

242
  const Operator* Int32PairAdd();
243
  const Operator* Int32PairSub();
244
  const Operator* Int32PairMul();
245
  const Operator* Word32PairShl();
246 247
  const Operator* Word32PairShr();
  const Operator* Word32PairSar();
248

249 250 251 252 253
  const Operator* Int32Add();
  const Operator* Int32AddWithOverflow();
  const Operator* Int32Sub();
  const Operator* Int32SubWithOverflow();
  const Operator* Int32Mul();
254
  const Operator* Int32MulWithOverflow();
255
  const Operator* Int32MulHigh();
256 257 258 259
  const Operator* Int32Div();
  const Operator* Int32Mod();
  const Operator* Int32LessThan();
  const Operator* Int32LessThanOrEqual();
260
  const Operator* Uint32Div();
261 262
  const Operator* Uint32LessThan();
  const Operator* Uint32LessThanOrEqual();
263
  const Operator* Uint32Mod();
264
  const Operator* Uint32MulHigh();
265 266
  bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
  bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
267 268

  const Operator* Int64Add();
269
  const Operator* Int64AddWithOverflow();
270
  const Operator* Int64Sub();
271
  const Operator* Int64SubWithOverflow();
272 273 274 275 276
  const Operator* Int64Mul();
  const Operator* Int64Div();
  const Operator* Int64Mod();
  const Operator* Int64LessThan();
  const Operator* Int64LessThanOrEqual();
277
  const Operator* Uint64Div();
278
  const Operator* Uint64LessThan();
279
  const Operator* Uint64LessThanOrEqual();
280
  const Operator* Uint64Mod();
281

282 283 284
  // This operator reinterprets the bits of a tagged pointer as word.
  const Operator* BitcastTaggedToWord();

285 286 287
  // This operator reinterprets the bits of a word as tagged pointer.
  const Operator* BitcastWordToTagged();

288 289 290
  // This operator reinterprets the bits of a word as a Smi.
  const Operator* BitcastWordToTaggedSigned();

291 292 293
  // JavaScript float64 to int32/uint32 truncation.
  const Operator* TruncateFloat64ToWord32();

294 295 296 297 298 299 300 301
  // These operators change the representation of numbers while preserving the
  // value of the number. Narrowing operators assume the input is representable
  // in the target type and are *not* defined for other inputs.
  // Use narrowing change operators only when there is a static guarantee that
  // the input value is representable in the target value.
  const Operator* ChangeFloat32ToFloat64();
  const Operator* ChangeFloat64ToInt32();   // narrowing
  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 310
  const Operator* ChangeInt32ToFloat64();
  const Operator* ChangeInt32ToInt64();
311
  const Operator* ChangeUint32ToFloat64();
312
  const Operator* ChangeUint32ToUint64();
313

314 315
  // These operators truncate or round numbers, both changing the representation
  // 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 327 328 329 330 331 332
  // These operators reinterpret the bits of a floating point number as an
  // integer and vice versa.
  const Operator* BitcastFloat32ToInt32();
  const Operator* BitcastFloat64ToInt64();
  const Operator* BitcastInt32ToFloat32();
  const Operator* BitcastInt64ToFloat64();

333 334 335 336 337 338 339 340 341 342
  // Floating point operators always operate with IEEE 754 round-to-nearest
  // (single-precision).
  const Operator* Float32Add();
  const Operator* Float32Sub();
  const Operator* Float32Mul();
  const Operator* Float32Div();
  const Operator* Float32Sqrt();

  // Floating point operators always operate with IEEE 754 round-to-nearest
  // (double-precision).
343 344 345 346 347
  const Operator* Float64Add();
  const Operator* Float64Sub();
  const Operator* Float64Mul();
  const Operator* Float64Div();
  const Operator* Float64Mod();
348
  const Operator* Float64Sqrt();
349

350 351 352 353 354 355
  // Floating point comparisons complying to IEEE 754 (single-precision).
  const Operator* Float32Equal();
  const Operator* Float32LessThan();
  const Operator* Float32LessThanOrEqual();

  // Floating point comparisons complying to IEEE 754 (double-precision).
356 357 358
  const Operator* Float64Equal();
  const Operator* Float64LessThan();
  const Operator* Float64LessThanOrEqual();
359

360 361 362
  // Floating point min/max complying to EcmaScript 6 (double-precision).
  const Operator* Float64Max();
  const Operator* Float64Min();
363 364 365
  // Floating point min/max complying to WebAssembly (single-precision).
  const Operator* Float32Max();
  const Operator* Float32Min();
366

367 368 369 370 371 372
  // Floating point abs complying to IEEE 754 (single-precision).
  const Operator* Float32Abs();

  // Floating point abs complying to IEEE 754 (double-precision).
  const Operator* Float64Abs();

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 380
  const OptionalOperator Float64RoundTruncate();
  const OptionalOperator Float64RoundTiesAway();
381
  const OptionalOperator Float32RoundTiesEven();
382
  const OptionalOperator Float64RoundTiesEven();
383

384
  // Floating point neg.
385 386
  const Operator* Float32Neg();
  const Operator* Float64Neg();
387

388
  // Floating point trigonometric functions (double-precision).
389 390 391 392
  const Operator* Float64Acos();
  const Operator* Float64Acosh();
  const Operator* Float64Asin();
  const Operator* Float64Asinh();
393 394
  const Operator* Float64Atan();
  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 406
  const Operator* Float64Expm1();
  const Operator* Float64Pow();
407

408 409
  // Floating point logarithm (double-precision).
  const Operator* Float64Log();
410
  const Operator* Float64Log1p();
411 412
  const Operator* Float64Log2();
  const Operator* Float64Log10();
413

414
  // Floating point cube root (double-precision).
415 416
  const Operator* Float64Cbrt();

417 418 419 420 421 422
  // Floating point bit representation.
  const Operator* Float64ExtractLowWord32();
  const Operator* Float64ExtractHighWord32();
  const Operator* Float64InsertLowWord32();
  const Operator* Float64InsertHighWord32();

423 424 425 426
  // Change signalling NaN to quiet NaN.
  // Identity for any input that is not signalling NaN.
  const Operator* Float64SilenceNaN();

427 428
  // SIMD operators.
  const Operator* CreateFloat32x4();
429 430
  const Operator* Float32x4ExtractLane(int32_t);
  const Operator* Float32x4ReplaceLane(int32_t);
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
  const Operator* Float32x4Abs();
  const Operator* Float32x4Neg();
  const Operator* Float32x4Sqrt();
  const Operator* Float32x4RecipApprox();
  const Operator* Float32x4RecipSqrtApprox();
  const Operator* Float32x4Add();
  const Operator* Float32x4Sub();
  const Operator* Float32x4Mul();
  const Operator* Float32x4Div();
  const Operator* Float32x4Min();
  const Operator* Float32x4Max();
  const Operator* Float32x4MinNum();
  const Operator* Float32x4MaxNum();
  const Operator* Float32x4Equal();
  const Operator* Float32x4NotEqual();
  const Operator* Float32x4LessThan();
  const Operator* Float32x4LessThanOrEqual();
  const Operator* Float32x4GreaterThan();
  const Operator* Float32x4GreaterThanOrEqual();
  const Operator* Float32x4FromInt32x4();
  const Operator* Float32x4FromUint32x4();

  const Operator* CreateInt32x4();
454 455
  const Operator* Int32x4ExtractLane(int32_t);
  const Operator* Int32x4ReplaceLane(int32_t);
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
  const Operator* Int32x4Neg();
  const Operator* Int32x4Add();
  const Operator* Int32x4Sub();
  const Operator* Int32x4Mul();
  const Operator* Int32x4Min();
  const Operator* Int32x4Max();
  const Operator* Int32x4ShiftLeftByScalar();
  const Operator* Int32x4ShiftRightByScalar();
  const Operator* Int32x4Equal();
  const Operator* Int32x4NotEqual();
  const Operator* Int32x4LessThan();
  const Operator* Int32x4LessThanOrEqual();
  const Operator* Int32x4GreaterThan();
  const Operator* Int32x4GreaterThanOrEqual();
  const Operator* Int32x4FromFloat32x4();

  const Operator* Uint32x4Min();
  const Operator* Uint32x4Max();
  const Operator* Uint32x4ShiftLeftByScalar();
  const Operator* Uint32x4ShiftRightByScalar();
  const Operator* Uint32x4LessThan();
  const Operator* Uint32x4LessThanOrEqual();
  const Operator* Uint32x4GreaterThan();
  const Operator* Uint32x4GreaterThanOrEqual();
  const Operator* Uint32x4FromFloat32x4();

  const Operator* CreateBool32x4();
  const Operator* Bool32x4ExtractLane();
  const Operator* Bool32x4ReplaceLane();
  const Operator* Bool32x4And();
  const Operator* Bool32x4Or();
  const Operator* Bool32x4Xor();
  const Operator* Bool32x4Not();
  const Operator* Bool32x4AnyTrue();
  const Operator* Bool32x4AllTrue();
  const Operator* Bool32x4Swizzle();
  const Operator* Bool32x4Shuffle();
  const Operator* Bool32x4Equal();
  const Operator* Bool32x4NotEqual();

  const Operator* CreateInt16x8();
497 498
  const Operator* Int16x8ExtractLane(int32_t);
  const Operator* Int16x8ReplaceLane(int32_t);
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
  const Operator* Int16x8Neg();
  const Operator* Int16x8Add();
  const Operator* Int16x8AddSaturate();
  const Operator* Int16x8Sub();
  const Operator* Int16x8SubSaturate();
  const Operator* Int16x8Mul();
  const Operator* Int16x8Min();
  const Operator* Int16x8Max();
  const Operator* Int16x8ShiftLeftByScalar();
  const Operator* Int16x8ShiftRightByScalar();
  const Operator* Int16x8Equal();
  const Operator* Int16x8NotEqual();
  const Operator* Int16x8LessThan();
  const Operator* Int16x8LessThanOrEqual();
  const Operator* Int16x8GreaterThan();
  const Operator* Int16x8GreaterThanOrEqual();
  const Operator* Int16x8Select();
  const Operator* Int16x8Swizzle();
  const Operator* Int16x8Shuffle();

  const Operator* Uint16x8AddSaturate();
  const Operator* Uint16x8SubSaturate();
  const Operator* Uint16x8Min();
  const Operator* Uint16x8Max();
  const Operator* Uint16x8ShiftLeftByScalar();
  const Operator* Uint16x8ShiftRightByScalar();
  const Operator* Uint16x8LessThan();
  const Operator* Uint16x8LessThanOrEqual();
  const Operator* Uint16x8GreaterThan();
  const Operator* Uint16x8GreaterThanOrEqual();

  const Operator* CreateBool16x8();
  const Operator* Bool16x8ExtractLane();
  const Operator* Bool16x8ReplaceLane();
  const Operator* Bool16x8And();
  const Operator* Bool16x8Or();
  const Operator* Bool16x8Xor();
  const Operator* Bool16x8Not();
  const Operator* Bool16x8AnyTrue();
  const Operator* Bool16x8AllTrue();
  const Operator* Bool16x8Swizzle();
  const Operator* Bool16x8Shuffle();
  const Operator* Bool16x8Equal();
  const Operator* Bool16x8NotEqual();

  const Operator* CreateInt8x16();
545 546
  const Operator* Int8x16ExtractLane(int32_t);
  const Operator* Int8x16ReplaceLane(int32_t);
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
  const Operator* Int8x16Neg();
  const Operator* Int8x16Add();
  const Operator* Int8x16AddSaturate();
  const Operator* Int8x16Sub();
  const Operator* Int8x16SubSaturate();
  const Operator* Int8x16Mul();
  const Operator* Int8x16Min();
  const Operator* Int8x16Max();
  const Operator* Int8x16ShiftLeftByScalar();
  const Operator* Int8x16ShiftRightByScalar();
  const Operator* Int8x16Equal();
  const Operator* Int8x16NotEqual();
  const Operator* Int8x16LessThan();
  const Operator* Int8x16LessThanOrEqual();
  const Operator* Int8x16GreaterThan();
  const Operator* Int8x16GreaterThanOrEqual();
  const Operator* Int8x16Select();
  const Operator* Int8x16Swizzle();
  const Operator* Int8x16Shuffle();

  const Operator* Uint8x16AddSaturate();
  const Operator* Uint8x16SubSaturate();
  const Operator* Uint8x16Min();
  const Operator* Uint8x16Max();
  const Operator* Uint8x16ShiftLeftByScalar();
  const Operator* Uint8x16ShiftRightByScalar();
  const Operator* Uint8x16LessThan();
  const Operator* Uint8x16LessThanOrEqual();
  const Operator* Uint8x16GreaterThan();
  const Operator* Uint8x16GreaterThanOrEqual();

  const Operator* CreateBool8x16();
  const Operator* Bool8x16ExtractLane();
  const Operator* Bool8x16ReplaceLane();
  const Operator* Bool8x16And();
  const Operator* Bool8x16Or();
  const Operator* Bool8x16Xor();
  const Operator* Bool8x16Not();
  const Operator* Bool8x16AnyTrue();
  const Operator* Bool8x16AllTrue();
  const Operator* Bool8x16Swizzle();
  const Operator* Bool8x16Shuffle();
  const Operator* Bool8x16Equal();
  const Operator* Bool8x16NotEqual();

  const Operator* Simd128Load();
  const Operator* Simd128Load1();
  const Operator* Simd128Load2();
  const Operator* Simd128Load3();
  const Operator* Simd128Store();
  const Operator* Simd128Store1();
  const Operator* Simd128Store2();
  const Operator* Simd128Store3();
  const Operator* Simd128And();
  const Operator* Simd128Or();
  const Operator* Simd128Xor();
  const Operator* Simd128Not();
604 605 606
  const Operator* Simd32x4Select();
  const Operator* Simd32x4Swizzle();
  const Operator* Simd32x4Shuffle();
607

608
  // load [base + index]
609
  const Operator* Load(LoadRepresentation rep);
610
  const Operator* ProtectedLoad(LoadRepresentation rep);
611

612
  // store [base + index], value
613
  const Operator* Store(StoreRepresentation rep);
614
  const Operator* ProtectedStore(MachineRepresentation rep);
615

616 617 618 619 620 621
  // unaligned load [base + index]
  const Operator* UnalignedLoad(UnalignedLoadRepresentation rep);

  // unaligned store [base + index], value
  const Operator* UnalignedStore(UnalignedStoreRepresentation rep);

622
  const Operator* StackSlot(int size);
623 624
  const Operator* StackSlot(MachineRepresentation rep);

625 626
  // Access to the machine stack.
  const Operator* LoadStackPointer();
627
  const Operator* LoadFramePointer();
628
  const Operator* LoadParentFramePointer();
629

630 631 632 633 634
  // checked-load heap, index, length
  const Operator* CheckedLoad(CheckedLoadRepresentation);
  // checked-store heap, index, length, value
  const Operator* CheckedStore(CheckedStoreRepresentation);

635 636
  // atomic-load [base + index]
  const Operator* AtomicLoad(LoadRepresentation rep);
637 638
  // atomic-store [base + index], value
  const Operator* AtomicStore(MachineRepresentation rep);
639

640
  // Target machine word-size assumed by this builder.
641 642 643
  bool Is32() const { return word() == MachineRepresentation::kWord32; }
  bool Is64() const { return word() == MachineRepresentation::kWord64; }
  MachineRepresentation word() const { return word_; }
644

645 646 647 648 649 650 651 652 653 654 655 656
  bool UnalignedLoadSupported(const MachineType& machineType,
                              uint8_t alignment) {
    return alignment_requirements_.IsUnalignedLoadSupported(machineType,
                                                            alignment);
  }

  bool UnalignedStoreSupported(const MachineType& machineType,
                               uint8_t alignment) {
    return alignment_requirements_.IsUnalignedStoreSupported(machineType,
                                                             alignment);
  }

657 658 659 660 661 662 663 664 665 666
// Pseudo operators that translate to 32/64-bit operators depending on the
// word-size of the target machine assumed by this builder.
#define PSEUDO_OP_LIST(V) \
  V(Word, And)            \
  V(Word, Or)             \
  V(Word, Xor)            \
  V(Word, Shl)            \
  V(Word, Shr)            \
  V(Word, Sar)            \
  V(Word, Ror)            \
667
  V(Word, Clz)            \
668 669 670 671 672 673 674
  V(Word, Equal)          \
  V(Int, Add)             \
  V(Int, Sub)             \
  V(Int, Mul)             \
  V(Int, Div)             \
  V(Int, Mod)             \
  V(Int, LessThan)        \
675
  V(Int, LessThanOrEqual) \
676 677 678
  V(Uint, Div)            \
  V(Uint, LessThan)       \
  V(Uint, Mod)
679
#define PSEUDO_OP(Prefix, Suffix)                                \
680
  const Operator* Prefix##Suffix() {                             \
681 682 683 684 685
    return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
  }
  PSEUDO_OP_LIST(PSEUDO_OP)
#undef PSEUDO_OP
#undef PSEUDO_OP_LIST
686 687

 private:
688
  Zone* zone_;
689
  MachineOperatorGlobalCache const& cache_;
690
  MachineRepresentation const word_;
691
  Flags const flags_;
692
  AlignmentRequirements const alignment_requirements_;
693

694
  DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
695
};
696

697 698

DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
699

700 701 702
}  // namespace compiler
}  // namespace internal
}  // namespace v8
703 704

#endif  // V8_COMPILER_MACHINE_OPERATOR_H_