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