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