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