lithium-arm.h revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
1// Copyright 2012 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_CRANKSHAFT_ARM_LITHIUM_ARM_H_ 6#define V8_CRANKSHAFT_ARM_LITHIUM_ARM_H_ 7 8#include "src/crankshaft/hydrogen.h" 9#include "src/crankshaft/lithium.h" 10#include "src/crankshaft/lithium-allocator.h" 11#include "src/safepoint-table.h" 12#include "src/utils.h" 13 14namespace v8 { 15namespace internal { 16 17// Forward declarations. 18class LCodeGen; 19 20#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ 21 V(AccessArgumentsAt) \ 22 V(AddI) \ 23 V(Allocate) \ 24 V(ApplyArguments) \ 25 V(ArgumentsElements) \ 26 V(ArgumentsLength) \ 27 V(ArithmeticD) \ 28 V(ArithmeticT) \ 29 V(BitI) \ 30 V(BoundsCheck) \ 31 V(Branch) \ 32 V(CallWithDescriptor) \ 33 V(CallNewArray) \ 34 V(CallRuntime) \ 35 V(CheckArrayBufferNotNeutered) \ 36 V(CheckInstanceType) \ 37 V(CheckNonSmi) \ 38 V(CheckMaps) \ 39 V(CheckMapValue) \ 40 V(CheckSmi) \ 41 V(CheckValue) \ 42 V(ClampDToUint8) \ 43 V(ClampIToUint8) \ 44 V(ClampTToUint8) \ 45 V(ClassOfTestAndBranch) \ 46 V(CompareNumericAndBranch) \ 47 V(CmpObjectEqAndBranch) \ 48 V(CmpHoleAndBranch) \ 49 V(CmpMapAndBranch) \ 50 V(CmpT) \ 51 V(ConstantD) \ 52 V(ConstantE) \ 53 V(ConstantI) \ 54 V(ConstantS) \ 55 V(ConstantT) \ 56 V(ConstructDouble) \ 57 V(Context) \ 58 V(DebugBreak) \ 59 V(DeclareGlobals) \ 60 V(Deoptimize) \ 61 V(DivByConstI) \ 62 V(DivByPowerOf2I) \ 63 V(DivI) \ 64 V(DoubleBits) \ 65 V(DoubleToI) \ 66 V(DoubleToSmi) \ 67 V(Drop) \ 68 V(Dummy) \ 69 V(DummyUse) \ 70 V(FastAllocate) \ 71 V(FlooringDivByConstI) \ 72 V(FlooringDivByPowerOf2I) \ 73 V(FlooringDivI) \ 74 V(ForInCacheArray) \ 75 V(ForInPrepareMap) \ 76 V(GetCachedArrayIndex) \ 77 V(Goto) \ 78 V(HasCachedArrayIndexAndBranch) \ 79 V(HasInPrototypeChainAndBranch) \ 80 V(HasInstanceTypeAndBranch) \ 81 V(InnerAllocatedObject) \ 82 V(InstructionGap) \ 83 V(Integer32ToDouble) \ 84 V(InvokeFunction) \ 85 V(IsStringAndBranch) \ 86 V(IsSmiAndBranch) \ 87 V(IsUndetectableAndBranch) \ 88 V(Label) \ 89 V(LazyBailout) \ 90 V(LoadContextSlot) \ 91 V(LoadRoot) \ 92 V(LoadFieldByIndex) \ 93 V(LoadFunctionPrototype) \ 94 V(LoadGlobalGeneric) \ 95 V(LoadKeyed) \ 96 V(LoadKeyedGeneric) \ 97 V(LoadNamedField) \ 98 V(LoadNamedGeneric) \ 99 V(MathAbs) \ 100 V(MathClz32) \ 101 V(MathExp) \ 102 V(MathFloor) \ 103 V(MathFround) \ 104 V(MathLog) \ 105 V(MathMinMax) \ 106 V(MathPowHalf) \ 107 V(MathRound) \ 108 V(MathSqrt) \ 109 V(MaybeGrowElements) \ 110 V(ModByConstI) \ 111 V(ModByPowerOf2I) \ 112 V(ModI) \ 113 V(MulI) \ 114 V(MultiplyAddD) \ 115 V(MultiplySubD) \ 116 V(NumberTagD) \ 117 V(NumberTagI) \ 118 V(NumberTagU) \ 119 V(NumberUntagD) \ 120 V(OsrEntry) \ 121 V(Parameter) \ 122 V(Power) \ 123 V(Prologue) \ 124 V(PushArgument) \ 125 V(Return) \ 126 V(SeqStringGetChar) \ 127 V(SeqStringSetChar) \ 128 V(ShiftI) \ 129 V(SmiTag) \ 130 V(SmiUntag) \ 131 V(StackCheck) \ 132 V(StoreCodeEntry) \ 133 V(StoreContextSlot) \ 134 V(StoreKeyed) \ 135 V(StoreKeyedGeneric) \ 136 V(StoreNamedField) \ 137 V(StoreNamedGeneric) \ 138 V(StringAdd) \ 139 V(StringCharCodeAt) \ 140 V(StringCharFromCode) \ 141 V(StringCompareAndBranch) \ 142 V(SubI) \ 143 V(RSubI) \ 144 V(TaggedToI) \ 145 V(ThisFunction) \ 146 V(TransitionElementsKind) \ 147 V(TrapAllocationMemento) \ 148 V(Typeof) \ 149 V(TypeofIsAndBranch) \ 150 V(Uint32ToDouble) \ 151 V(UnknownOSRValue) \ 152 V(WrapReceiver) 153 154#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 155 Opcode opcode() const final { return LInstruction::k##type; } \ 156 void CompileToNative(LCodeGen* generator) final; \ 157 const char* Mnemonic() const final { return mnemonic; } \ 158 static L##type* cast(LInstruction* instr) { \ 159 DCHECK(instr->Is##type()); \ 160 return reinterpret_cast<L##type*>(instr); \ 161 } 162 163 164#define DECLARE_HYDROGEN_ACCESSOR(type) \ 165 H##type* hydrogen() const { \ 166 return H##type::cast(hydrogen_value()); \ 167 } 168 169 170class LInstruction : public ZoneObject { 171 public: 172 LInstruction() 173 : environment_(NULL), 174 hydrogen_value_(NULL), 175 bit_field_(IsCallBits::encode(false)) { 176 } 177 178 virtual ~LInstruction() {} 179 180 virtual void CompileToNative(LCodeGen* generator) = 0; 181 virtual const char* Mnemonic() const = 0; 182 virtual void PrintTo(StringStream* stream); 183 virtual void PrintDataTo(StringStream* stream); 184 virtual void PrintOutputOperandTo(StringStream* stream); 185 186 enum Opcode { 187 // Declare a unique enum value for each instruction. 188#define DECLARE_OPCODE(type) k##type, 189 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 190 kNumberOfInstructions 191#undef DECLARE_OPCODE 192 }; 193 194 virtual Opcode opcode() const = 0; 195 196 // Declare non-virtual type testers for all leaf IR classes. 197#define DECLARE_PREDICATE(type) \ 198 bool Is##type() const { return opcode() == k##type; } 199 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) 200#undef DECLARE_PREDICATE 201 202 // Declare virtual predicates for instructions that don't have 203 // an opcode. 204 virtual bool IsGap() const { return false; } 205 206 virtual bool IsControl() const { return false; } 207 208 // Try deleting this instruction if possible. 209 virtual bool TryDelete() { return false; } 210 211 void set_environment(LEnvironment* env) { environment_ = env; } 212 LEnvironment* environment() const { return environment_; } 213 bool HasEnvironment() const { return environment_ != NULL; } 214 215 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } 216 LPointerMap* pointer_map() const { return pointer_map_.get(); } 217 bool HasPointerMap() const { return pointer_map_.is_set(); } 218 219 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } 220 HValue* hydrogen_value() const { return hydrogen_value_; } 221 222 void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } 223 bool IsCall() const { return IsCallBits::decode(bit_field_); } 224 225 void MarkAsSyntacticTailCall() { 226 bit_field_ = IsSyntacticTailCallBits::update(bit_field_, true); 227 } 228 bool IsSyntacticTailCall() const { 229 return IsSyntacticTailCallBits::decode(bit_field_); 230 } 231 232 // Interface to the register allocator and iterators. 233 bool ClobbersTemps() const { return IsCall(); } 234 bool ClobbersRegisters() const { return IsCall(); } 235 virtual bool ClobbersDoubleRegisters(Isolate* isolate) const { 236 return IsCall(); 237 } 238 239 // Interface to the register allocator and iterators. 240 bool IsMarkedAsCall() const { return IsCall(); } 241 242 virtual bool HasResult() const = 0; 243 virtual LOperand* result() const = 0; 244 245 LOperand* FirstInput() { return InputAt(0); } 246 LOperand* Output() { return HasResult() ? result() : NULL; } 247 248 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; } 249 250#ifdef DEBUG 251 void VerifyCall(); 252#endif 253 254 virtual int InputCount() = 0; 255 virtual LOperand* InputAt(int i) = 0; 256 257 private: 258 // Iterator support. 259 friend class InputIterator; 260 261 friend class TempIterator; 262 virtual int TempCount() = 0; 263 virtual LOperand* TempAt(int i) = 0; 264 265 class IsCallBits: public BitField<bool, 0, 1> {}; 266 class IsSyntacticTailCallBits : public BitField<bool, IsCallBits::kNext, 1> { 267 }; 268 269 LEnvironment* environment_; 270 SetOncePointer<LPointerMap> pointer_map_; 271 HValue* hydrogen_value_; 272 int bit_field_; 273}; 274 275 276// R = number of result operands (0 or 1). 277template<int R> 278class LTemplateResultInstruction : public LInstruction { 279 public: 280 // Allow 0 or 1 output operands. 281 STATIC_ASSERT(R == 0 || R == 1); 282 bool HasResult() const final { return R != 0 && result() != NULL; } 283 void set_result(LOperand* operand) { results_[0] = operand; } 284 LOperand* result() const override { return results_[0]; } 285 286 protected: 287 EmbeddedContainer<LOperand*, R> results_; 288}; 289 290 291// R = number of result operands (0 or 1). 292// I = number of input operands. 293// T = number of temporary operands. 294template<int R, int I, int T> 295class LTemplateInstruction : public LTemplateResultInstruction<R> { 296 protected: 297 EmbeddedContainer<LOperand*, I> inputs_; 298 EmbeddedContainer<LOperand*, T> temps_; 299 300 private: 301 // Iterator support. 302 int InputCount() final { return I; } 303 LOperand* InputAt(int i) final { return inputs_[i]; } 304 305 int TempCount() final { return T; } 306 LOperand* TempAt(int i) final { return temps_[i]; } 307}; 308 309 310class LGap : public LTemplateInstruction<0, 0, 0> { 311 public: 312 explicit LGap(HBasicBlock* block) 313 : block_(block) { 314 parallel_moves_[BEFORE] = NULL; 315 parallel_moves_[START] = NULL; 316 parallel_moves_[END] = NULL; 317 parallel_moves_[AFTER] = NULL; 318 } 319 320 // Can't use the DECLARE-macro here because of sub-classes. 321 bool IsGap() const override { return true; } 322 void PrintDataTo(StringStream* stream) override; 323 static LGap* cast(LInstruction* instr) { 324 DCHECK(instr->IsGap()); 325 return reinterpret_cast<LGap*>(instr); 326 } 327 328 bool IsRedundant() const; 329 330 HBasicBlock* block() const { return block_; } 331 332 enum InnerPosition { 333 BEFORE, 334 START, 335 END, 336 AFTER, 337 FIRST_INNER_POSITION = BEFORE, 338 LAST_INNER_POSITION = AFTER 339 }; 340 341 LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) { 342 if (parallel_moves_[pos] == NULL) { 343 parallel_moves_[pos] = new(zone) LParallelMove(zone); 344 } 345 return parallel_moves_[pos]; 346 } 347 348 LParallelMove* GetParallelMove(InnerPosition pos) { 349 return parallel_moves_[pos]; 350 } 351 352 private: 353 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 354 HBasicBlock* block_; 355}; 356 357 358class LInstructionGap final : public LGap { 359 public: 360 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } 361 362 bool HasInterestingComment(LCodeGen* gen) const override { 363 return !IsRedundant(); 364 } 365 366 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") 367}; 368 369 370class LGoto final : public LTemplateInstruction<0, 0, 0> { 371 public: 372 explicit LGoto(HBasicBlock* block) : block_(block) { } 373 374 bool HasInterestingComment(LCodeGen* gen) const override; 375 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 376 void PrintDataTo(StringStream* stream) override; 377 bool IsControl() const override { return true; } 378 379 int block_id() const { return block_->block_id(); } 380 381 private: 382 HBasicBlock* block_; 383}; 384 385 386class LPrologue final : public LTemplateInstruction<0, 0, 0> { 387 public: 388 DECLARE_CONCRETE_INSTRUCTION(Prologue, "prologue") 389}; 390 391 392class LLazyBailout final : public LTemplateInstruction<0, 0, 0> { 393 public: 394 LLazyBailout() : gap_instructions_size_(0) { } 395 396 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 397 398 void set_gap_instructions_size(int gap_instructions_size) { 399 gap_instructions_size_ = gap_instructions_size; 400 } 401 int gap_instructions_size() { return gap_instructions_size_; } 402 403 private: 404 int gap_instructions_size_; 405}; 406 407 408class LDummy final : public LTemplateInstruction<1, 0, 0> { 409 public: 410 LDummy() {} 411 DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") 412}; 413 414 415class LDummyUse final : public LTemplateInstruction<1, 1, 0> { 416 public: 417 explicit LDummyUse(LOperand* value) { 418 inputs_[0] = value; 419 } 420 DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use") 421}; 422 423 424class LDeoptimize final : public LTemplateInstruction<0, 0, 0> { 425 public: 426 bool IsControl() const override { return true; } 427 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 428 DECLARE_HYDROGEN_ACCESSOR(Deoptimize) 429}; 430 431 432class LLabel final : public LGap { 433 public: 434 explicit LLabel(HBasicBlock* block) 435 : LGap(block), replacement_(NULL) { } 436 437 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 438 DECLARE_CONCRETE_INSTRUCTION(Label, "label") 439 440 void PrintDataTo(StringStream* stream) override; 441 442 int block_id() const { return block()->block_id(); } 443 bool is_loop_header() const { return block()->IsLoopHeader(); } 444 bool is_osr_entry() const { return block()->is_osr_entry(); } 445 Label* label() { return &label_; } 446 LLabel* replacement() const { return replacement_; } 447 void set_replacement(LLabel* label) { replacement_ = label; } 448 bool HasReplacement() const { return replacement_ != NULL; } 449 450 private: 451 Label label_; 452 LLabel* replacement_; 453}; 454 455 456class LParameter final : public LTemplateInstruction<1, 0, 0> { 457 public: 458 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 459 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 460}; 461 462 463class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> { 464 public: 465 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 466 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value") 467}; 468 469 470template<int I, int T> 471class LControlInstruction : public LTemplateInstruction<0, I, T> { 472 public: 473 LControlInstruction() : false_label_(NULL), true_label_(NULL) { } 474 475 bool IsControl() const final { return true; } 476 477 int SuccessorCount() { return hydrogen()->SuccessorCount(); } 478 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } 479 480 int TrueDestination(LChunk* chunk) { 481 return chunk->LookupDestination(true_block_id()); 482 } 483 int FalseDestination(LChunk* chunk) { 484 return chunk->LookupDestination(false_block_id()); 485 } 486 487 Label* TrueLabel(LChunk* chunk) { 488 if (true_label_ == NULL) { 489 true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); 490 } 491 return true_label_; 492 } 493 Label* FalseLabel(LChunk* chunk) { 494 if (false_label_ == NULL) { 495 false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); 496 } 497 return false_label_; 498 } 499 500 protected: 501 int true_block_id() { return SuccessorAt(0)->block_id(); } 502 int false_block_id() { return SuccessorAt(1)->block_id(); } 503 504 private: 505 HControlInstruction* hydrogen() { 506 return HControlInstruction::cast(this->hydrogen_value()); 507 } 508 509 Label* false_label_; 510 Label* true_label_; 511}; 512 513 514class LWrapReceiver final : public LTemplateInstruction<1, 2, 0> { 515 public: 516 LWrapReceiver(LOperand* receiver, LOperand* function) { 517 inputs_[0] = receiver; 518 inputs_[1] = function; 519 } 520 521 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") 522 DECLARE_HYDROGEN_ACCESSOR(WrapReceiver) 523 524 LOperand* receiver() { return inputs_[0]; } 525 LOperand* function() { return inputs_[1]; } 526}; 527 528 529class LApplyArguments final : public LTemplateInstruction<1, 4, 0> { 530 public: 531 LApplyArguments(LOperand* function, 532 LOperand* receiver, 533 LOperand* length, 534 LOperand* elements) { 535 inputs_[0] = function; 536 inputs_[1] = receiver; 537 inputs_[2] = length; 538 inputs_[3] = elements; 539 } 540 541 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") 542 DECLARE_HYDROGEN_ACCESSOR(ApplyArguments) 543 544 LOperand* function() { return inputs_[0]; } 545 LOperand* receiver() { return inputs_[1]; } 546 LOperand* length() { return inputs_[2]; } 547 LOperand* elements() { return inputs_[3]; } 548}; 549 550 551class LAccessArgumentsAt final : public LTemplateInstruction<1, 3, 0> { 552 public: 553 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) { 554 inputs_[0] = arguments; 555 inputs_[1] = length; 556 inputs_[2] = index; 557 } 558 559 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") 560 561 LOperand* arguments() { return inputs_[0]; } 562 LOperand* length() { return inputs_[1]; } 563 LOperand* index() { return inputs_[2]; } 564 565 void PrintDataTo(StringStream* stream) override; 566}; 567 568 569class LArgumentsLength final : public LTemplateInstruction<1, 1, 0> { 570 public: 571 explicit LArgumentsLength(LOperand* elements) { 572 inputs_[0] = elements; 573 } 574 575 LOperand* elements() { return inputs_[0]; } 576 577 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") 578}; 579 580 581class LArgumentsElements final : public LTemplateInstruction<1, 0, 0> { 582 public: 583 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") 584 DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) 585}; 586 587 588class LModByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 589 public: 590 LModByPowerOf2I(LOperand* dividend, int32_t divisor) { 591 inputs_[0] = dividend; 592 divisor_ = divisor; 593 } 594 595 LOperand* dividend() { return inputs_[0]; } 596 int32_t divisor() const { return divisor_; } 597 598 DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i") 599 DECLARE_HYDROGEN_ACCESSOR(Mod) 600 601 private: 602 int32_t divisor_; 603}; 604 605 606class LModByConstI final : public LTemplateInstruction<1, 1, 0> { 607 public: 608 LModByConstI(LOperand* dividend, int32_t divisor) { 609 inputs_[0] = dividend; 610 divisor_ = divisor; 611 } 612 613 LOperand* dividend() { return inputs_[0]; } 614 int32_t divisor() const { return divisor_; } 615 616 DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i") 617 DECLARE_HYDROGEN_ACCESSOR(Mod) 618 619 private: 620 int32_t divisor_; 621}; 622 623 624class LModI final : public LTemplateInstruction<1, 2, 2> { 625 public: 626 LModI(LOperand* left, LOperand* right, LOperand* temp, LOperand* temp2) { 627 inputs_[0] = left; 628 inputs_[1] = right; 629 temps_[0] = temp; 630 temps_[1] = temp2; 631 } 632 633 LOperand* left() { return inputs_[0]; } 634 LOperand* right() { return inputs_[1]; } 635 LOperand* temp() { return temps_[0]; } 636 LOperand* temp2() { return temps_[1]; } 637 638 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") 639 DECLARE_HYDROGEN_ACCESSOR(Mod) 640}; 641 642 643class LDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 644 public: 645 LDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 646 inputs_[0] = dividend; 647 divisor_ = divisor; 648 } 649 650 LOperand* dividend() { return inputs_[0]; } 651 int32_t divisor() const { return divisor_; } 652 653 DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i") 654 DECLARE_HYDROGEN_ACCESSOR(Div) 655 656 private: 657 int32_t divisor_; 658}; 659 660 661class LDivByConstI final : public LTemplateInstruction<1, 1, 0> { 662 public: 663 LDivByConstI(LOperand* dividend, int32_t divisor) { 664 inputs_[0] = dividend; 665 divisor_ = divisor; 666 } 667 668 LOperand* dividend() { return inputs_[0]; } 669 int32_t divisor() const { return divisor_; } 670 671 DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i") 672 DECLARE_HYDROGEN_ACCESSOR(Div) 673 674 private: 675 int32_t divisor_; 676}; 677 678 679class LDivI final : public LTemplateInstruction<1, 2, 1> { 680 public: 681 LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) { 682 inputs_[0] = dividend; 683 inputs_[1] = divisor; 684 temps_[0] = temp; 685 } 686 687 LOperand* dividend() { return inputs_[0]; } 688 LOperand* divisor() { return inputs_[1]; } 689 LOperand* temp() { return temps_[0]; } 690 691 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") 692 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation) 693}; 694 695 696class LFlooringDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 697 public: 698 LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 699 inputs_[0] = dividend; 700 divisor_ = divisor; 701 } 702 703 LOperand* dividend() { return inputs_[0]; } 704 int32_t divisor() { return divisor_; } 705 706 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I, 707 "flooring-div-by-power-of-2-i") 708 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 709 710 private: 711 int32_t divisor_; 712}; 713 714 715class LFlooringDivByConstI final : public LTemplateInstruction<1, 1, 2> { 716 public: 717 LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) { 718 inputs_[0] = dividend; 719 divisor_ = divisor; 720 temps_[0] = temp; 721 } 722 723 LOperand* dividend() { return inputs_[0]; } 724 int32_t divisor() const { return divisor_; } 725 LOperand* temp() { return temps_[0]; } 726 727 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i") 728 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 729 730 private: 731 int32_t divisor_; 732}; 733 734 735class LFlooringDivI final : public LTemplateInstruction<1, 2, 1> { 736 public: 737 LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) { 738 inputs_[0] = dividend; 739 inputs_[1] = divisor; 740 temps_[0] = temp; 741 } 742 743 LOperand* dividend() { return inputs_[0]; } 744 LOperand* divisor() { return inputs_[1]; } 745 LOperand* temp() { return temps_[0]; } 746 747 DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i") 748 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 749}; 750 751 752class LMulI final : public LTemplateInstruction<1, 2, 0> { 753 public: 754 LMulI(LOperand* left, LOperand* right) { 755 inputs_[0] = left; 756 inputs_[1] = right; 757 } 758 759 LOperand* left() { return inputs_[0]; } 760 LOperand* right() { return inputs_[1]; } 761 762 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") 763 DECLARE_HYDROGEN_ACCESSOR(Mul) 764}; 765 766 767// Instruction for computing multiplier * multiplicand + addend. 768class LMultiplyAddD final : public LTemplateInstruction<1, 3, 0> { 769 public: 770 LMultiplyAddD(LOperand* addend, LOperand* multiplier, 771 LOperand* multiplicand) { 772 inputs_[0] = addend; 773 inputs_[1] = multiplier; 774 inputs_[2] = multiplicand; 775 } 776 777 LOperand* addend() { return inputs_[0]; } 778 LOperand* multiplier() { return inputs_[1]; } 779 LOperand* multiplicand() { return inputs_[2]; } 780 781 DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d") 782}; 783 784 785// Instruction for computing minuend - multiplier * multiplicand. 786class LMultiplySubD final : public LTemplateInstruction<1, 3, 0> { 787 public: 788 LMultiplySubD(LOperand* minuend, LOperand* multiplier, 789 LOperand* multiplicand) { 790 inputs_[0] = minuend; 791 inputs_[1] = multiplier; 792 inputs_[2] = multiplicand; 793 } 794 795 LOperand* minuend() { return inputs_[0]; } 796 LOperand* multiplier() { return inputs_[1]; } 797 LOperand* multiplicand() { return inputs_[2]; } 798 799 DECLARE_CONCRETE_INSTRUCTION(MultiplySubD, "multiply-sub-d") 800}; 801 802 803class LDebugBreak final : public LTemplateInstruction<0, 0, 0> { 804 public: 805 DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break") 806}; 807 808 809class LCompareNumericAndBranch final : public LControlInstruction<2, 0> { 810 public: 811 LCompareNumericAndBranch(LOperand* left, LOperand* right) { 812 inputs_[0] = left; 813 inputs_[1] = right; 814 } 815 816 LOperand* left() { return inputs_[0]; } 817 LOperand* right() { return inputs_[1]; } 818 819 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch, 820 "compare-numeric-and-branch") 821 DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch) 822 823 Token::Value op() const { return hydrogen()->token(); } 824 bool is_double() const { 825 return hydrogen()->representation().IsDouble(); 826 } 827 828 void PrintDataTo(StringStream* stream) override; 829}; 830 831 832class LMathFloor final : public LTemplateInstruction<1, 1, 0> { 833 public: 834 explicit LMathFloor(LOperand* value) { 835 inputs_[0] = value; 836 } 837 838 LOperand* value() { return inputs_[0]; } 839 840 DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor") 841 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 842}; 843 844 845class LMathRound final : public LTemplateInstruction<1, 1, 1> { 846 public: 847 LMathRound(LOperand* value, LOperand* temp) { 848 inputs_[0] = value; 849 temps_[0] = temp; 850 } 851 852 LOperand* value() { return inputs_[0]; } 853 LOperand* temp() { return temps_[0]; } 854 855 DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round") 856 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 857}; 858 859 860class LMathFround final : public LTemplateInstruction<1, 1, 0> { 861 public: 862 explicit LMathFround(LOperand* value) { inputs_[0] = value; } 863 864 LOperand* value() { return inputs_[0]; } 865 866 DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround") 867}; 868 869 870class LMathAbs final : public LTemplateInstruction<1, 2, 0> { 871 public: 872 LMathAbs(LOperand* context, LOperand* value) { 873 inputs_[1] = context; 874 inputs_[0] = value; 875 } 876 877 LOperand* context() { return inputs_[1]; } 878 LOperand* value() { return inputs_[0]; } 879 880 DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs") 881 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 882}; 883 884 885class LMathLog final : public LTemplateInstruction<1, 1, 0> { 886 public: 887 explicit LMathLog(LOperand* value) { 888 inputs_[0] = value; 889 } 890 891 LOperand* value() { return inputs_[0]; } 892 893 DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log") 894}; 895 896 897class LMathClz32 final : public LTemplateInstruction<1, 1, 0> { 898 public: 899 explicit LMathClz32(LOperand* value) { 900 inputs_[0] = value; 901 } 902 903 LOperand* value() { return inputs_[0]; } 904 905 DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32") 906}; 907 908 909class LMathExp final : public LTemplateInstruction<1, 1, 3> { 910 public: 911 LMathExp(LOperand* value, 912 LOperand* double_temp, 913 LOperand* temp1, 914 LOperand* temp2) { 915 inputs_[0] = value; 916 temps_[0] = temp1; 917 temps_[1] = temp2; 918 temps_[2] = double_temp; 919 ExternalReference::InitializeMathExpData(); 920 } 921 922 LOperand* value() { return inputs_[0]; } 923 LOperand* temp1() { return temps_[0]; } 924 LOperand* temp2() { return temps_[1]; } 925 LOperand* double_temp() { return temps_[2]; } 926 927 DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp") 928}; 929 930 931class LMathSqrt final : public LTemplateInstruction<1, 1, 0> { 932 public: 933 explicit LMathSqrt(LOperand* value) { 934 inputs_[0] = value; 935 } 936 937 LOperand* value() { return inputs_[0]; } 938 939 DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt") 940}; 941 942 943class LMathPowHalf final : public LTemplateInstruction<1, 1, 0> { 944 public: 945 explicit LMathPowHalf(LOperand* value) { 946 inputs_[0] = value; 947 } 948 949 LOperand* value() { return inputs_[0]; } 950 951 DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half") 952}; 953 954 955class LCmpObjectEqAndBranch final : public LControlInstruction<2, 0> { 956 public: 957 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) { 958 inputs_[0] = left; 959 inputs_[1] = right; 960 } 961 962 LOperand* left() { return inputs_[0]; } 963 LOperand* right() { return inputs_[1]; } 964 965 DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch") 966 DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch) 967}; 968 969 970class LCmpHoleAndBranch final : public LControlInstruction<1, 0> { 971 public: 972 explicit LCmpHoleAndBranch(LOperand* object) { 973 inputs_[0] = object; 974 } 975 976 LOperand* object() { return inputs_[0]; } 977 978 DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch") 979 DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch) 980}; 981 982 983class LIsStringAndBranch final : public LControlInstruction<1, 1> { 984 public: 985 LIsStringAndBranch(LOperand* value, LOperand* temp) { 986 inputs_[0] = value; 987 temps_[0] = temp; 988 } 989 990 LOperand* value() { return inputs_[0]; } 991 LOperand* temp() { return temps_[0]; } 992 993 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch") 994 DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch) 995 996 void PrintDataTo(StringStream* stream) override; 997}; 998 999 1000class LIsSmiAndBranch final : public LControlInstruction<1, 0> { 1001 public: 1002 explicit LIsSmiAndBranch(LOperand* value) { 1003 inputs_[0] = value; 1004 } 1005 1006 LOperand* value() { return inputs_[0]; } 1007 1008 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") 1009 DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch) 1010 1011 void PrintDataTo(StringStream* stream) override; 1012}; 1013 1014 1015class LIsUndetectableAndBranch final : public LControlInstruction<1, 1> { 1016 public: 1017 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { 1018 inputs_[0] = value; 1019 temps_[0] = temp; 1020 } 1021 1022 LOperand* value() { return inputs_[0]; } 1023 LOperand* temp() { return temps_[0]; } 1024 1025 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, 1026 "is-undetectable-and-branch") 1027 DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch) 1028 1029 void PrintDataTo(StringStream* stream) override; 1030}; 1031 1032 1033class LStringCompareAndBranch final : public LControlInstruction<3, 0> { 1034 public: 1035 LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) { 1036 inputs_[0] = context; 1037 inputs_[1] = left; 1038 inputs_[2] = right; 1039 } 1040 1041 LOperand* context() { return inputs_[0]; } 1042 LOperand* left() { return inputs_[1]; } 1043 LOperand* right() { return inputs_[2]; } 1044 1045 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, 1046 "string-compare-and-branch") 1047 DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch) 1048 1049 Token::Value op() const { return hydrogen()->token(); } 1050 1051 void PrintDataTo(StringStream* stream) override; 1052}; 1053 1054 1055class LHasInstanceTypeAndBranch final : public LControlInstruction<1, 0> { 1056 public: 1057 explicit LHasInstanceTypeAndBranch(LOperand* value) { 1058 inputs_[0] = value; 1059 } 1060 1061 LOperand* value() { return inputs_[0]; } 1062 1063 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, 1064 "has-instance-type-and-branch") 1065 DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch) 1066 1067 void PrintDataTo(StringStream* stream) override; 1068}; 1069 1070 1071class LGetCachedArrayIndex final : public LTemplateInstruction<1, 1, 0> { 1072 public: 1073 explicit LGetCachedArrayIndex(LOperand* value) { 1074 inputs_[0] = value; 1075 } 1076 1077 LOperand* value() { return inputs_[0]; } 1078 1079 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index") 1080 DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex) 1081}; 1082 1083 1084class LHasCachedArrayIndexAndBranch final : public LControlInstruction<1, 0> { 1085 public: 1086 explicit LHasCachedArrayIndexAndBranch(LOperand* value) { 1087 inputs_[0] = value; 1088 } 1089 1090 LOperand* value() { return inputs_[0]; } 1091 1092 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, 1093 "has-cached-array-index-and-branch") 1094 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch) 1095 1096 void PrintDataTo(StringStream* stream) override; 1097}; 1098 1099 1100class LClassOfTestAndBranch final : public LControlInstruction<1, 1> { 1101 public: 1102 LClassOfTestAndBranch(LOperand* value, LOperand* temp) { 1103 inputs_[0] = value; 1104 temps_[0] = temp; 1105 } 1106 1107 LOperand* value() { return inputs_[0]; } 1108 LOperand* temp() { return temps_[0]; } 1109 1110 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, 1111 "class-of-test-and-branch") 1112 DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch) 1113 1114 void PrintDataTo(StringStream* stream) override; 1115}; 1116 1117 1118class LCmpT final : public LTemplateInstruction<1, 3, 0> { 1119 public: 1120 LCmpT(LOperand* context, LOperand* left, LOperand* right) { 1121 inputs_[0] = context; 1122 inputs_[1] = left; 1123 inputs_[2] = right; 1124 } 1125 1126 LOperand* context() { return inputs_[0]; } 1127 LOperand* left() { return inputs_[1]; } 1128 LOperand* right() { return inputs_[2]; } 1129 1130 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") 1131 DECLARE_HYDROGEN_ACCESSOR(CompareGeneric) 1132 1133 Token::Value op() const { return hydrogen()->token(); } 1134}; 1135 1136 1137class LHasInPrototypeChainAndBranch final : public LControlInstruction<2, 0> { 1138 public: 1139 LHasInPrototypeChainAndBranch(LOperand* object, LOperand* prototype) { 1140 inputs_[0] = object; 1141 inputs_[1] = prototype; 1142 } 1143 1144 LOperand* object() const { return inputs_[0]; } 1145 LOperand* prototype() const { return inputs_[1]; } 1146 1147 DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch, 1148 "has-in-prototype-chain-and-branch") 1149 DECLARE_HYDROGEN_ACCESSOR(HasInPrototypeChainAndBranch) 1150}; 1151 1152 1153class LBoundsCheck final : public LTemplateInstruction<0, 2, 0> { 1154 public: 1155 LBoundsCheck(LOperand* index, LOperand* length) { 1156 inputs_[0] = index; 1157 inputs_[1] = length; 1158 } 1159 1160 LOperand* index() { return inputs_[0]; } 1161 LOperand* length() { return inputs_[1]; } 1162 1163 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") 1164 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) 1165}; 1166 1167 1168class LBitI final : public LTemplateInstruction<1, 2, 0> { 1169 public: 1170 LBitI(LOperand* left, LOperand* right) { 1171 inputs_[0] = left; 1172 inputs_[1] = right; 1173 } 1174 1175 LOperand* left() { return inputs_[0]; } 1176 LOperand* right() { return inputs_[1]; } 1177 1178 Token::Value op() const { return hydrogen()->op(); } 1179 1180 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") 1181 DECLARE_HYDROGEN_ACCESSOR(Bitwise) 1182}; 1183 1184 1185class LShiftI final : public LTemplateInstruction<1, 2, 0> { 1186 public: 1187 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) 1188 : op_(op), can_deopt_(can_deopt) { 1189 inputs_[0] = left; 1190 inputs_[1] = right; 1191 } 1192 1193 Token::Value op() const { return op_; } 1194 LOperand* left() { return inputs_[0]; } 1195 LOperand* right() { return inputs_[1]; } 1196 bool can_deopt() const { return can_deopt_; } 1197 1198 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") 1199 1200 private: 1201 Token::Value op_; 1202 bool can_deopt_; 1203}; 1204 1205 1206class LSubI final : public LTemplateInstruction<1, 2, 0> { 1207 public: 1208 LSubI(LOperand* left, LOperand* right) { 1209 inputs_[0] = left; 1210 inputs_[1] = right; 1211 } 1212 1213 LOperand* left() { return inputs_[0]; } 1214 LOperand* right() { return inputs_[1]; } 1215 1216 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") 1217 DECLARE_HYDROGEN_ACCESSOR(Sub) 1218}; 1219 1220 1221class LRSubI final : public LTemplateInstruction<1, 2, 0> { 1222 public: 1223 LRSubI(LOperand* left, LOperand* right) { 1224 inputs_[0] = left; 1225 inputs_[1] = right; 1226 } 1227 1228 LOperand* left() { return inputs_[0]; } 1229 LOperand* right() { return inputs_[1]; } 1230 1231 DECLARE_CONCRETE_INSTRUCTION(RSubI, "rsub-i") 1232 DECLARE_HYDROGEN_ACCESSOR(Sub) 1233}; 1234 1235 1236class LConstantI final : public LTemplateInstruction<1, 0, 0> { 1237 public: 1238 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i") 1239 DECLARE_HYDROGEN_ACCESSOR(Constant) 1240 1241 int32_t value() const { return hydrogen()->Integer32Value(); } 1242}; 1243 1244 1245class LConstantS final : public LTemplateInstruction<1, 0, 0> { 1246 public: 1247 DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s") 1248 DECLARE_HYDROGEN_ACCESSOR(Constant) 1249 1250 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); } 1251}; 1252 1253 1254class LConstantD final : public LTemplateInstruction<1, 0, 0> { 1255 public: 1256 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") 1257 DECLARE_HYDROGEN_ACCESSOR(Constant) 1258 1259 double value() const { return hydrogen()->DoubleValue(); } 1260 uint64_t bits() const { return hydrogen()->DoubleValueAsBits(); } 1261}; 1262 1263 1264class LConstantE final : public LTemplateInstruction<1, 0, 0> { 1265 public: 1266 DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e") 1267 DECLARE_HYDROGEN_ACCESSOR(Constant) 1268 1269 ExternalReference value() const { 1270 return hydrogen()->ExternalReferenceValue(); 1271 } 1272}; 1273 1274 1275class LConstantT final : public LTemplateInstruction<1, 0, 0> { 1276 public: 1277 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t") 1278 DECLARE_HYDROGEN_ACCESSOR(Constant) 1279 1280 Handle<Object> value(Isolate* isolate) const { 1281 return hydrogen()->handle(isolate); 1282 } 1283}; 1284 1285 1286class LBranch final : public LControlInstruction<1, 0> { 1287 public: 1288 explicit LBranch(LOperand* value) { 1289 inputs_[0] = value; 1290 } 1291 1292 LOperand* value() { return inputs_[0]; } 1293 1294 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") 1295 DECLARE_HYDROGEN_ACCESSOR(Branch) 1296 1297 void PrintDataTo(StringStream* stream) override; 1298}; 1299 1300 1301class LCmpMapAndBranch final : public LControlInstruction<1, 1> { 1302 public: 1303 LCmpMapAndBranch(LOperand* value, LOperand* temp) { 1304 inputs_[0] = value; 1305 temps_[0] = temp; 1306 } 1307 1308 LOperand* value() { return inputs_[0]; } 1309 LOperand* temp() { return temps_[0]; } 1310 1311 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") 1312 DECLARE_HYDROGEN_ACCESSOR(CompareMap) 1313 1314 Handle<Map> map() const { return hydrogen()->map().handle(); } 1315}; 1316 1317 1318class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> { 1319 public: 1320 LSeqStringGetChar(LOperand* string, LOperand* index) { 1321 inputs_[0] = string; 1322 inputs_[1] = index; 1323 } 1324 1325 LOperand* string() const { return inputs_[0]; } 1326 LOperand* index() const { return inputs_[1]; } 1327 1328 DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char") 1329 DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar) 1330}; 1331 1332 1333class LSeqStringSetChar final : public LTemplateInstruction<1, 4, 0> { 1334 public: 1335 LSeqStringSetChar(LOperand* context, 1336 LOperand* string, 1337 LOperand* index, 1338 LOperand* value) { 1339 inputs_[0] = context; 1340 inputs_[1] = string; 1341 inputs_[2] = index; 1342 inputs_[3] = value; 1343 } 1344 1345 LOperand* string() { return inputs_[1]; } 1346 LOperand* index() { return inputs_[2]; } 1347 LOperand* value() { return inputs_[3]; } 1348 1349 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") 1350 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) 1351}; 1352 1353 1354class LAddI final : public LTemplateInstruction<1, 2, 0> { 1355 public: 1356 LAddI(LOperand* left, LOperand* right) { 1357 inputs_[0] = left; 1358 inputs_[1] = right; 1359 } 1360 1361 LOperand* left() { return inputs_[0]; } 1362 LOperand* right() { return inputs_[1]; } 1363 1364 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") 1365 DECLARE_HYDROGEN_ACCESSOR(Add) 1366}; 1367 1368 1369class LMathMinMax final : public LTemplateInstruction<1, 2, 0> { 1370 public: 1371 LMathMinMax(LOperand* left, LOperand* right) { 1372 inputs_[0] = left; 1373 inputs_[1] = right; 1374 } 1375 1376 LOperand* left() { return inputs_[0]; } 1377 LOperand* right() { return inputs_[1]; } 1378 1379 DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max") 1380 DECLARE_HYDROGEN_ACCESSOR(MathMinMax) 1381}; 1382 1383 1384class LPower final : public LTemplateInstruction<1, 2, 0> { 1385 public: 1386 LPower(LOperand* left, LOperand* right) { 1387 inputs_[0] = left; 1388 inputs_[1] = right; 1389 } 1390 1391 LOperand* left() { return inputs_[0]; } 1392 LOperand* right() { return inputs_[1]; } 1393 1394 DECLARE_CONCRETE_INSTRUCTION(Power, "power") 1395 DECLARE_HYDROGEN_ACCESSOR(Power) 1396}; 1397 1398 1399class LArithmeticD final : public LTemplateInstruction<1, 2, 0> { 1400 public: 1401 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) 1402 : op_(op) { 1403 inputs_[0] = left; 1404 inputs_[1] = right; 1405 } 1406 1407 Token::Value op() const { return op_; } 1408 LOperand* left() { return inputs_[0]; } 1409 LOperand* right() { return inputs_[1]; } 1410 1411 Opcode opcode() const override { return LInstruction::kArithmeticD; } 1412 void CompileToNative(LCodeGen* generator) override; 1413 const char* Mnemonic() const override; 1414 1415 private: 1416 Token::Value op_; 1417}; 1418 1419 1420class LArithmeticT final : public LTemplateInstruction<1, 3, 0> { 1421 public: 1422 LArithmeticT(Token::Value op, 1423 LOperand* context, 1424 LOperand* left, 1425 LOperand* right) 1426 : op_(op) { 1427 inputs_[0] = context; 1428 inputs_[1] = left; 1429 inputs_[2] = right; 1430 } 1431 1432 LOperand* context() { return inputs_[0]; } 1433 LOperand* left() { return inputs_[1]; } 1434 LOperand* right() { return inputs_[2]; } 1435 Token::Value op() const { return op_; } 1436 1437 Opcode opcode() const override { return LInstruction::kArithmeticT; } 1438 void CompileToNative(LCodeGen* generator) override; 1439 const char* Mnemonic() const override; 1440 1441 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation) 1442 1443 private: 1444 Token::Value op_; 1445}; 1446 1447 1448class LReturn final : public LTemplateInstruction<0, 3, 0> { 1449 public: 1450 LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) { 1451 inputs_[0] = value; 1452 inputs_[1] = context; 1453 inputs_[2] = parameter_count; 1454 } 1455 1456 LOperand* value() { return inputs_[0]; } 1457 1458 bool has_constant_parameter_count() { 1459 return parameter_count()->IsConstantOperand(); 1460 } 1461 LConstantOperand* constant_parameter_count() { 1462 DCHECK(has_constant_parameter_count()); 1463 return LConstantOperand::cast(parameter_count()); 1464 } 1465 LOperand* parameter_count() { return inputs_[2]; } 1466 1467 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 1468}; 1469 1470 1471class LLoadNamedField final : public LTemplateInstruction<1, 1, 0> { 1472 public: 1473 explicit LLoadNamedField(LOperand* object) { 1474 inputs_[0] = object; 1475 } 1476 1477 LOperand* object() { return inputs_[0]; } 1478 1479 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") 1480 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) 1481}; 1482 1483 1484class LLoadNamedGeneric final : public LTemplateInstruction<1, 2, 1> { 1485 public: 1486 LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) { 1487 inputs_[0] = context; 1488 inputs_[1] = object; 1489 temps_[0] = vector; 1490 } 1491 1492 LOperand* context() { return inputs_[0]; } 1493 LOperand* object() { return inputs_[1]; } 1494 LOperand* temp_vector() { return temps_[0]; } 1495 1496 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") 1497 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric) 1498 1499 Handle<Object> name() const { return hydrogen()->name(); } 1500}; 1501 1502 1503class LLoadFunctionPrototype final : public LTemplateInstruction<1, 1, 0> { 1504 public: 1505 explicit LLoadFunctionPrototype(LOperand* function) { 1506 inputs_[0] = function; 1507 } 1508 1509 LOperand* function() { return inputs_[0]; } 1510 1511 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") 1512 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) 1513}; 1514 1515 1516class LLoadRoot final : public LTemplateInstruction<1, 0, 0> { 1517 public: 1518 DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root") 1519 DECLARE_HYDROGEN_ACCESSOR(LoadRoot) 1520 1521 Heap::RootListIndex index() const { return hydrogen()->index(); } 1522}; 1523 1524 1525class LLoadKeyed final : public LTemplateInstruction<1, 3, 0> { 1526 public: 1527 LLoadKeyed(LOperand* elements, LOperand* key, LOperand* backing_store_owner) { 1528 inputs_[0] = elements; 1529 inputs_[1] = key; 1530 inputs_[2] = backing_store_owner; 1531 } 1532 1533 LOperand* elements() { return inputs_[0]; } 1534 LOperand* key() { return inputs_[1]; } 1535 LOperand* backing_store_owner() { return inputs_[2]; } 1536 ElementsKind elements_kind() const { 1537 return hydrogen()->elements_kind(); 1538 } 1539 bool is_fixed_typed_array() const { 1540 return hydrogen()->is_fixed_typed_array(); 1541 } 1542 1543 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed") 1544 DECLARE_HYDROGEN_ACCESSOR(LoadKeyed) 1545 1546 void PrintDataTo(StringStream* stream) override; 1547 uint32_t base_offset() const { return hydrogen()->base_offset(); } 1548}; 1549 1550 1551class LLoadKeyedGeneric final : public LTemplateInstruction<1, 3, 1> { 1552 public: 1553 LLoadKeyedGeneric(LOperand* context, LOperand* object, LOperand* key, 1554 LOperand* vector) { 1555 inputs_[0] = context; 1556 inputs_[1] = object; 1557 inputs_[2] = key; 1558 temps_[0] = vector; 1559 } 1560 1561 LOperand* context() { return inputs_[0]; } 1562 LOperand* object() { return inputs_[1]; } 1563 LOperand* key() { return inputs_[2]; } 1564 LOperand* temp_vector() { return temps_[0]; } 1565 1566 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic") 1567 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric) 1568}; 1569 1570 1571class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> { 1572 public: 1573 LLoadGlobalGeneric(LOperand* context, LOperand* global_object, 1574 LOperand* vector) { 1575 inputs_[0] = context; 1576 inputs_[1] = global_object; 1577 temps_[0] = vector; 1578 } 1579 1580 LOperand* context() { return inputs_[0]; } 1581 LOperand* global_object() { return inputs_[1]; } 1582 LOperand* temp_vector() { return temps_[0]; } 1583 1584 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic") 1585 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric) 1586 1587 Handle<Object> name() const { return hydrogen()->name(); } 1588 TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); } 1589}; 1590 1591 1592class LLoadContextSlot final : public LTemplateInstruction<1, 1, 0> { 1593 public: 1594 explicit LLoadContextSlot(LOperand* context) { 1595 inputs_[0] = context; 1596 } 1597 1598 LOperand* context() { return inputs_[0]; } 1599 1600 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") 1601 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot) 1602 1603 int slot_index() { return hydrogen()->slot_index(); } 1604 1605 void PrintDataTo(StringStream* stream) override; 1606}; 1607 1608 1609class LStoreContextSlot final : public LTemplateInstruction<0, 2, 0> { 1610 public: 1611 LStoreContextSlot(LOperand* context, LOperand* value) { 1612 inputs_[0] = context; 1613 inputs_[1] = value; 1614 } 1615 1616 LOperand* context() { return inputs_[0]; } 1617 LOperand* value() { return inputs_[1]; } 1618 1619 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot") 1620 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot) 1621 1622 int slot_index() { return hydrogen()->slot_index(); } 1623 1624 void PrintDataTo(StringStream* stream) override; 1625}; 1626 1627 1628class LPushArgument final : public LTemplateInstruction<0, 1, 0> { 1629 public: 1630 explicit LPushArgument(LOperand* value) { 1631 inputs_[0] = value; 1632 } 1633 1634 LOperand* value() { return inputs_[0]; } 1635 1636 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") 1637}; 1638 1639 1640class LDrop final : public LTemplateInstruction<0, 0, 0> { 1641 public: 1642 explicit LDrop(int count) : count_(count) { } 1643 1644 int count() const { return count_; } 1645 1646 DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") 1647 1648 private: 1649 int count_; 1650}; 1651 1652 1653class LStoreCodeEntry final : public LTemplateInstruction<0, 2, 0> { 1654 public: 1655 LStoreCodeEntry(LOperand* function, LOperand* code_object) { 1656 inputs_[0] = function; 1657 inputs_[1] = code_object; 1658 } 1659 1660 LOperand* function() { return inputs_[0]; } 1661 LOperand* code_object() { return inputs_[1]; } 1662 1663 void PrintDataTo(StringStream* stream) override; 1664 1665 DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry") 1666 DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry) 1667}; 1668 1669 1670class LInnerAllocatedObject final : public LTemplateInstruction<1, 2, 0> { 1671 public: 1672 LInnerAllocatedObject(LOperand* base_object, LOperand* offset) { 1673 inputs_[0] = base_object; 1674 inputs_[1] = offset; 1675 } 1676 1677 LOperand* base_object() const { return inputs_[0]; } 1678 LOperand* offset() const { return inputs_[1]; } 1679 1680 void PrintDataTo(StringStream* stream) override; 1681 1682 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object") 1683}; 1684 1685 1686class LThisFunction final : public LTemplateInstruction<1, 0, 0> { 1687 public: 1688 DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") 1689 DECLARE_HYDROGEN_ACCESSOR(ThisFunction) 1690}; 1691 1692 1693class LContext final : public LTemplateInstruction<1, 0, 0> { 1694 public: 1695 DECLARE_CONCRETE_INSTRUCTION(Context, "context") 1696 DECLARE_HYDROGEN_ACCESSOR(Context) 1697}; 1698 1699 1700class LDeclareGlobals final : public LTemplateInstruction<0, 1, 0> { 1701 public: 1702 explicit LDeclareGlobals(LOperand* context) { 1703 inputs_[0] = context; 1704 } 1705 1706 LOperand* context() { return inputs_[0]; } 1707 1708 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals") 1709 DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals) 1710}; 1711 1712 1713class LCallWithDescriptor final : public LTemplateResultInstruction<1> { 1714 public: 1715 LCallWithDescriptor(CallInterfaceDescriptor descriptor, 1716 const ZoneList<LOperand*>& operands, Zone* zone) 1717 : descriptor_(descriptor), 1718 inputs_(descriptor.GetRegisterParameterCount() + 1719 kImplicitRegisterParameterCount, 1720 zone) { 1721 DCHECK(descriptor.GetRegisterParameterCount() + 1722 kImplicitRegisterParameterCount == 1723 operands.length()); 1724 inputs_.AddAll(operands, zone); 1725 } 1726 1727 LOperand* target() const { return inputs_[0]; } 1728 1729 const CallInterfaceDescriptor descriptor() { return descriptor_; } 1730 1731 DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor) 1732 1733 // The target and context are passed as implicit parameters that are not 1734 // explicitly listed in the descriptor. 1735 static const int kImplicitRegisterParameterCount = 2; 1736 1737 private: 1738 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor") 1739 1740 void PrintDataTo(StringStream* stream) override; 1741 1742 int arity() const { return hydrogen()->argument_count() - 1; } 1743 1744 CallInterfaceDescriptor descriptor_; 1745 ZoneList<LOperand*> inputs_; 1746 1747 // Iterator support. 1748 int InputCount() final { return inputs_.length(); } 1749 LOperand* InputAt(int i) final { return inputs_[i]; } 1750 1751 int TempCount() final { return 0; } 1752 LOperand* TempAt(int i) final { return NULL; } 1753}; 1754 1755 1756class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> { 1757 public: 1758 LInvokeFunction(LOperand* context, LOperand* function) { 1759 inputs_[0] = context; 1760 inputs_[1] = function; 1761 } 1762 1763 LOperand* context() { return inputs_[0]; } 1764 LOperand* function() { return inputs_[1]; } 1765 1766 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") 1767 DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) 1768 1769 void PrintDataTo(StringStream* stream) override; 1770 1771 int arity() const { return hydrogen()->argument_count() - 1; } 1772}; 1773 1774 1775class LCallNewArray final : public LTemplateInstruction<1, 2, 0> { 1776 public: 1777 LCallNewArray(LOperand* context, LOperand* constructor) { 1778 inputs_[0] = context; 1779 inputs_[1] = constructor; 1780 } 1781 1782 LOperand* context() { return inputs_[0]; } 1783 LOperand* constructor() { return inputs_[1]; } 1784 1785 DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array") 1786 DECLARE_HYDROGEN_ACCESSOR(CallNewArray) 1787 1788 void PrintDataTo(StringStream* stream) override; 1789 1790 int arity() const { return hydrogen()->argument_count() - 1; } 1791}; 1792 1793 1794class LCallRuntime final : public LTemplateInstruction<1, 1, 0> { 1795 public: 1796 explicit LCallRuntime(LOperand* context) { 1797 inputs_[0] = context; 1798 } 1799 1800 LOperand* context() { return inputs_[0]; } 1801 1802 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") 1803 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1804 1805 bool ClobbersDoubleRegisters(Isolate* isolate) const override { 1806 return save_doubles() == kDontSaveFPRegs; 1807 } 1808 1809 const Runtime::Function* function() const { return hydrogen()->function(); } 1810 int arity() const { return hydrogen()->argument_count(); } 1811 SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); } 1812}; 1813 1814 1815class LInteger32ToDouble final : public LTemplateInstruction<1, 1, 0> { 1816 public: 1817 explicit LInteger32ToDouble(LOperand* value) { 1818 inputs_[0] = value; 1819 } 1820 1821 LOperand* value() { return inputs_[0]; } 1822 1823 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") 1824}; 1825 1826 1827class LUint32ToDouble final : public LTemplateInstruction<1, 1, 0> { 1828 public: 1829 explicit LUint32ToDouble(LOperand* value) { 1830 inputs_[0] = value; 1831 } 1832 1833 LOperand* value() { return inputs_[0]; } 1834 1835 DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double") 1836}; 1837 1838 1839class LNumberTagI final : public LTemplateInstruction<1, 1, 2> { 1840 public: 1841 LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) { 1842 inputs_[0] = value; 1843 temps_[0] = temp1; 1844 temps_[1] = temp2; 1845 } 1846 1847 LOperand* value() { return inputs_[0]; } 1848 LOperand* temp1() { return temps_[0]; } 1849 LOperand* temp2() { return temps_[1]; } 1850 1851 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 1852}; 1853 1854 1855class LNumberTagU final : public LTemplateInstruction<1, 1, 2> { 1856 public: 1857 LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) { 1858 inputs_[0] = value; 1859 temps_[0] = temp1; 1860 temps_[1] = temp2; 1861 } 1862 1863 LOperand* value() { return inputs_[0]; } 1864 LOperand* temp1() { return temps_[0]; } 1865 LOperand* temp2() { return temps_[1]; } 1866 1867 DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u") 1868}; 1869 1870 1871class LNumberTagD final : public LTemplateInstruction<1, 1, 2> { 1872 public: 1873 LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) { 1874 inputs_[0] = value; 1875 temps_[0] = temp; 1876 temps_[1] = temp2; 1877 } 1878 1879 LOperand* value() { return inputs_[0]; } 1880 LOperand* temp() { return temps_[0]; } 1881 LOperand* temp2() { return temps_[1]; } 1882 1883 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") 1884 DECLARE_HYDROGEN_ACCESSOR(Change) 1885}; 1886 1887 1888class LDoubleToSmi final : public LTemplateInstruction<1, 1, 0> { 1889 public: 1890 explicit LDoubleToSmi(LOperand* value) { 1891 inputs_[0] = value; 1892 } 1893 1894 LOperand* value() { return inputs_[0]; } 1895 1896 DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi") 1897 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1898 1899 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1900}; 1901 1902 1903// Sometimes truncating conversion from a tagged value to an int32. 1904class LDoubleToI final : public LTemplateInstruction<1, 1, 0> { 1905 public: 1906 explicit LDoubleToI(LOperand* value) { 1907 inputs_[0] = value; 1908 } 1909 1910 LOperand* value() { return inputs_[0]; } 1911 1912 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") 1913 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1914 1915 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1916}; 1917 1918 1919// Truncating conversion from a tagged value to an int32. 1920class LTaggedToI final : public LTemplateInstruction<1, 1, 2> { 1921 public: 1922 LTaggedToI(LOperand* value, 1923 LOperand* temp, 1924 LOperand* temp2) { 1925 inputs_[0] = value; 1926 temps_[0] = temp; 1927 temps_[1] = temp2; 1928 } 1929 1930 LOperand* value() { return inputs_[0]; } 1931 LOperand* temp() { return temps_[0]; } 1932 LOperand* temp2() { return temps_[1]; } 1933 1934 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") 1935 DECLARE_HYDROGEN_ACCESSOR(Change) 1936 1937 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1938}; 1939 1940 1941class LSmiTag final : public LTemplateInstruction<1, 1, 0> { 1942 public: 1943 explicit LSmiTag(LOperand* value) { 1944 inputs_[0] = value; 1945 } 1946 1947 LOperand* value() { return inputs_[0]; } 1948 1949 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") 1950 DECLARE_HYDROGEN_ACCESSOR(Change) 1951}; 1952 1953 1954class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> { 1955 public: 1956 explicit LNumberUntagD(LOperand* value) { 1957 inputs_[0] = value; 1958 } 1959 1960 LOperand* value() { return inputs_[0]; } 1961 1962 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") 1963 DECLARE_HYDROGEN_ACCESSOR(Change) 1964}; 1965 1966 1967class LSmiUntag final : public LTemplateInstruction<1, 1, 0> { 1968 public: 1969 LSmiUntag(LOperand* value, bool needs_check) 1970 : needs_check_(needs_check) { 1971 inputs_[0] = value; 1972 } 1973 1974 LOperand* value() { return inputs_[0]; } 1975 bool needs_check() const { return needs_check_; } 1976 1977 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") 1978 1979 private: 1980 bool needs_check_; 1981}; 1982 1983 1984class LStoreNamedField final : public LTemplateInstruction<0, 2, 1> { 1985 public: 1986 LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) { 1987 inputs_[0] = object; 1988 inputs_[1] = value; 1989 temps_[0] = temp; 1990 } 1991 1992 LOperand* object() { return inputs_[0]; } 1993 LOperand* value() { return inputs_[1]; } 1994 LOperand* temp() { return temps_[0]; } 1995 1996 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") 1997 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) 1998 1999 void PrintDataTo(StringStream* stream) override; 2000 2001 Representation representation() const { 2002 return hydrogen()->field_representation(); 2003 } 2004}; 2005 2006 2007class LStoreNamedGeneric final : public LTemplateInstruction<0, 3, 2> { 2008 public: 2009 LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value, 2010 LOperand* slot, LOperand* vector) { 2011 inputs_[0] = context; 2012 inputs_[1] = object; 2013 inputs_[2] = value; 2014 temps_[0] = slot; 2015 temps_[1] = vector; 2016 } 2017 2018 LOperand* context() { return inputs_[0]; } 2019 LOperand* object() { return inputs_[1]; } 2020 LOperand* value() { return inputs_[2]; } 2021 LOperand* temp_slot() { return temps_[0]; } 2022 LOperand* temp_vector() { return temps_[1]; } 2023 2024 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic") 2025 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric) 2026 2027 void PrintDataTo(StringStream* stream) override; 2028 2029 Handle<Object> name() const { return hydrogen()->name(); } 2030 LanguageMode language_mode() { return hydrogen()->language_mode(); } 2031}; 2032 2033 2034class LStoreKeyed final : public LTemplateInstruction<0, 4, 0> { 2035 public: 2036 LStoreKeyed(LOperand* object, LOperand* key, LOperand* value, 2037 LOperand* backing_store_owner) { 2038 inputs_[0] = object; 2039 inputs_[1] = key; 2040 inputs_[2] = value; 2041 inputs_[3] = backing_store_owner; 2042 } 2043 2044 bool is_fixed_typed_array() const { 2045 return hydrogen()->is_fixed_typed_array(); 2046 } 2047 LOperand* elements() { return inputs_[0]; } 2048 LOperand* key() { return inputs_[1]; } 2049 LOperand* value() { return inputs_[2]; } 2050 LOperand* backing_store_owner() { return inputs_[3]; } 2051 ElementsKind elements_kind() const { 2052 return hydrogen()->elements_kind(); 2053 } 2054 2055 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed") 2056 DECLARE_HYDROGEN_ACCESSOR(StoreKeyed) 2057 2058 void PrintDataTo(StringStream* stream) override; 2059 bool NeedsCanonicalization() { 2060 if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() || 2061 hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) { 2062 return false; 2063 } 2064 return hydrogen()->NeedsCanonicalization(); 2065 } 2066 uint32_t base_offset() const { return hydrogen()->base_offset(); } 2067}; 2068 2069 2070class LStoreKeyedGeneric final : public LTemplateInstruction<0, 4, 2> { 2071 public: 2072 LStoreKeyedGeneric(LOperand* context, LOperand* object, LOperand* key, 2073 LOperand* value, LOperand* slot, LOperand* vector) { 2074 inputs_[0] = context; 2075 inputs_[1] = object; 2076 inputs_[2] = key; 2077 inputs_[3] = value; 2078 temps_[0] = slot; 2079 temps_[1] = vector; 2080 } 2081 2082 LOperand* context() { return inputs_[0]; } 2083 LOperand* object() { return inputs_[1]; } 2084 LOperand* key() { return inputs_[2]; } 2085 LOperand* value() { return inputs_[3]; } 2086 LOperand* temp_slot() { return temps_[0]; } 2087 LOperand* temp_vector() { return temps_[1]; } 2088 2089 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic") 2090 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric) 2091 2092 void PrintDataTo(StringStream* stream) override; 2093 2094 LanguageMode language_mode() { return hydrogen()->language_mode(); } 2095}; 2096 2097 2098class LTransitionElementsKind final : public LTemplateInstruction<0, 2, 1> { 2099 public: 2100 LTransitionElementsKind(LOperand* object, 2101 LOperand* context, 2102 LOperand* new_map_temp) { 2103 inputs_[0] = object; 2104 inputs_[1] = context; 2105 temps_[0] = new_map_temp; 2106 } 2107 2108 LOperand* context() { return inputs_[1]; } 2109 LOperand* object() { return inputs_[0]; } 2110 LOperand* new_map_temp() { return temps_[0]; } 2111 2112 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, 2113 "transition-elements-kind") 2114 DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind) 2115 2116 void PrintDataTo(StringStream* stream) override; 2117 2118 Handle<Map> original_map() { return hydrogen()->original_map().handle(); } 2119 Handle<Map> transitioned_map() { 2120 return hydrogen()->transitioned_map().handle(); 2121 } 2122 ElementsKind from_kind() { return hydrogen()->from_kind(); } 2123 ElementsKind to_kind() { return hydrogen()->to_kind(); } 2124}; 2125 2126 2127class LTrapAllocationMemento final : public LTemplateInstruction<0, 1, 1> { 2128 public: 2129 LTrapAllocationMemento(LOperand* object, 2130 LOperand* temp) { 2131 inputs_[0] = object; 2132 temps_[0] = temp; 2133 } 2134 2135 LOperand* object() { return inputs_[0]; } 2136 LOperand* temp() { return temps_[0]; } 2137 2138 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento, 2139 "trap-allocation-memento") 2140}; 2141 2142 2143class LMaybeGrowElements final : public LTemplateInstruction<1, 5, 0> { 2144 public: 2145 LMaybeGrowElements(LOperand* context, LOperand* object, LOperand* elements, 2146 LOperand* key, LOperand* current_capacity) { 2147 inputs_[0] = context; 2148 inputs_[1] = object; 2149 inputs_[2] = elements; 2150 inputs_[3] = key; 2151 inputs_[4] = current_capacity; 2152 } 2153 2154 LOperand* context() { return inputs_[0]; } 2155 LOperand* object() { return inputs_[1]; } 2156 LOperand* elements() { return inputs_[2]; } 2157 LOperand* key() { return inputs_[3]; } 2158 LOperand* current_capacity() { return inputs_[4]; } 2159 2160 DECLARE_HYDROGEN_ACCESSOR(MaybeGrowElements) 2161 DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements, "maybe-grow-elements") 2162}; 2163 2164 2165class LStringAdd final : public LTemplateInstruction<1, 3, 0> { 2166 public: 2167 LStringAdd(LOperand* context, LOperand* left, LOperand* right) { 2168 inputs_[0] = context; 2169 inputs_[1] = left; 2170 inputs_[2] = right; 2171 } 2172 2173 LOperand* context() { return inputs_[0]; } 2174 LOperand* left() { return inputs_[1]; } 2175 LOperand* right() { return inputs_[2]; } 2176 2177 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add") 2178 DECLARE_HYDROGEN_ACCESSOR(StringAdd) 2179}; 2180 2181 2182class LStringCharCodeAt final : public LTemplateInstruction<1, 3, 0> { 2183 public: 2184 LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) { 2185 inputs_[0] = context; 2186 inputs_[1] = string; 2187 inputs_[2] = index; 2188 } 2189 2190 LOperand* context() { return inputs_[0]; } 2191 LOperand* string() { return inputs_[1]; } 2192 LOperand* index() { return inputs_[2]; } 2193 2194 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at") 2195 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt) 2196}; 2197 2198 2199class LStringCharFromCode final : public LTemplateInstruction<1, 2, 0> { 2200 public: 2201 explicit LStringCharFromCode(LOperand* context, LOperand* char_code) { 2202 inputs_[0] = context; 2203 inputs_[1] = char_code; 2204 } 2205 2206 LOperand* context() { return inputs_[0]; } 2207 LOperand* char_code() { return inputs_[1]; } 2208 2209 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code") 2210 DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode) 2211}; 2212 2213 2214class LCheckValue final : public LTemplateInstruction<0, 1, 0> { 2215 public: 2216 explicit LCheckValue(LOperand* value) { 2217 inputs_[0] = value; 2218 } 2219 2220 LOperand* value() { return inputs_[0]; } 2221 2222 DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value") 2223 DECLARE_HYDROGEN_ACCESSOR(CheckValue) 2224}; 2225 2226 2227class LCheckArrayBufferNotNeutered final 2228 : public LTemplateInstruction<0, 1, 0> { 2229 public: 2230 explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } 2231 2232 LOperand* view() { return inputs_[0]; } 2233 2234 DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, 2235 "check-array-buffer-not-neutered") 2236 DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) 2237}; 2238 2239 2240class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { 2241 public: 2242 explicit LCheckInstanceType(LOperand* value) { 2243 inputs_[0] = value; 2244 } 2245 2246 LOperand* value() { return inputs_[0]; } 2247 2248 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") 2249 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) 2250}; 2251 2252 2253class LCheckMaps final : public LTemplateInstruction<0, 1, 0> { 2254 public: 2255 explicit LCheckMaps(LOperand* value = NULL) { 2256 inputs_[0] = value; 2257 } 2258 2259 LOperand* value() { return inputs_[0]; } 2260 2261 DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") 2262 DECLARE_HYDROGEN_ACCESSOR(CheckMaps) 2263}; 2264 2265 2266class LCheckSmi final : public LTemplateInstruction<1, 1, 0> { 2267 public: 2268 explicit LCheckSmi(LOperand* value) { 2269 inputs_[0] = value; 2270 } 2271 2272 LOperand* value() { return inputs_[0]; } 2273 2274 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi") 2275}; 2276 2277 2278class LCheckNonSmi final : public LTemplateInstruction<0, 1, 0> { 2279 public: 2280 explicit LCheckNonSmi(LOperand* value) { 2281 inputs_[0] = value; 2282 } 2283 2284 LOperand* value() { return inputs_[0]; } 2285 2286 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") 2287 DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject) 2288}; 2289 2290 2291class LClampDToUint8 final : public LTemplateInstruction<1, 1, 0> { 2292 public: 2293 explicit LClampDToUint8(LOperand* unclamped) { 2294 inputs_[0] = unclamped; 2295 } 2296 2297 LOperand* unclamped() { return inputs_[0]; } 2298 2299 DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8") 2300}; 2301 2302 2303class LClampIToUint8 final : public LTemplateInstruction<1, 1, 0> { 2304 public: 2305 explicit LClampIToUint8(LOperand* unclamped) { 2306 inputs_[0] = unclamped; 2307 } 2308 2309 LOperand* unclamped() { return inputs_[0]; } 2310 2311 DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8") 2312}; 2313 2314 2315class LClampTToUint8 final : public LTemplateInstruction<1, 1, 1> { 2316 public: 2317 LClampTToUint8(LOperand* unclamped, LOperand* temp) { 2318 inputs_[0] = unclamped; 2319 temps_[0] = temp; 2320 } 2321 2322 LOperand* unclamped() { return inputs_[0]; } 2323 LOperand* temp() { return temps_[0]; } 2324 2325 DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8") 2326}; 2327 2328 2329class LDoubleBits final : public LTemplateInstruction<1, 1, 0> { 2330 public: 2331 explicit LDoubleBits(LOperand* value) { 2332 inputs_[0] = value; 2333 } 2334 2335 LOperand* value() { return inputs_[0]; } 2336 2337 DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits") 2338 DECLARE_HYDROGEN_ACCESSOR(DoubleBits) 2339}; 2340 2341 2342class LConstructDouble final : public LTemplateInstruction<1, 2, 0> { 2343 public: 2344 LConstructDouble(LOperand* hi, LOperand* lo) { 2345 inputs_[0] = hi; 2346 inputs_[1] = lo; 2347 } 2348 2349 LOperand* hi() { return inputs_[0]; } 2350 LOperand* lo() { return inputs_[1]; } 2351 2352 DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double") 2353}; 2354 2355 2356class LAllocate final : public LTemplateInstruction<1, 2, 2> { 2357 public: 2358 LAllocate(LOperand* context, 2359 LOperand* size, 2360 LOperand* temp1, 2361 LOperand* temp2) { 2362 inputs_[0] = context; 2363 inputs_[1] = size; 2364 temps_[0] = temp1; 2365 temps_[1] = temp2; 2366 } 2367 2368 LOperand* context() { return inputs_[0]; } 2369 LOperand* size() { return inputs_[1]; } 2370 LOperand* temp1() { return temps_[0]; } 2371 LOperand* temp2() { return temps_[1]; } 2372 2373 DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate") 2374 DECLARE_HYDROGEN_ACCESSOR(Allocate) 2375}; 2376 2377class LFastAllocate final : public LTemplateInstruction<1, 1, 2> { 2378 public: 2379 LFastAllocate(LOperand* size, LOperand* temp1, LOperand* temp2) { 2380 inputs_[0] = size; 2381 temps_[0] = temp1; 2382 temps_[1] = temp2; 2383 } 2384 2385 LOperand* size() { return inputs_[0]; } 2386 LOperand* temp1() { return temps_[0]; } 2387 LOperand* temp2() { return temps_[1]; } 2388 2389 DECLARE_CONCRETE_INSTRUCTION(FastAllocate, "fast-allocate") 2390 DECLARE_HYDROGEN_ACCESSOR(Allocate) 2391}; 2392 2393class LTypeof final : public LTemplateInstruction<1, 2, 0> { 2394 public: 2395 LTypeof(LOperand* context, LOperand* value) { 2396 inputs_[0] = context; 2397 inputs_[1] = value; 2398 } 2399 2400 LOperand* context() { return inputs_[0]; } 2401 LOperand* value() { return inputs_[1]; } 2402 2403 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 2404}; 2405 2406 2407class LTypeofIsAndBranch final : public LControlInstruction<1, 0> { 2408 public: 2409 explicit LTypeofIsAndBranch(LOperand* value) { 2410 inputs_[0] = value; 2411 } 2412 2413 LOperand* value() { return inputs_[0]; } 2414 2415 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") 2416 DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch) 2417 2418 Handle<String> type_literal() { return hydrogen()->type_literal(); } 2419 2420 void PrintDataTo(StringStream* stream) override; 2421}; 2422 2423 2424class LOsrEntry final : public LTemplateInstruction<0, 0, 0> { 2425 public: 2426 LOsrEntry() {} 2427 2428 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 2429 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 2430}; 2431 2432 2433class LStackCheck final : public LTemplateInstruction<0, 1, 0> { 2434 public: 2435 explicit LStackCheck(LOperand* context) { 2436 inputs_[0] = context; 2437 } 2438 2439 LOperand* context() { return inputs_[0]; } 2440 2441 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") 2442 DECLARE_HYDROGEN_ACCESSOR(StackCheck) 2443 2444 Label* done_label() { return &done_label_; } 2445 2446 private: 2447 Label done_label_; 2448}; 2449 2450 2451class LForInPrepareMap final : public LTemplateInstruction<1, 2, 0> { 2452 public: 2453 LForInPrepareMap(LOperand* context, LOperand* object) { 2454 inputs_[0] = context; 2455 inputs_[1] = object; 2456 } 2457 2458 LOperand* context() { return inputs_[0]; } 2459 LOperand* object() { return inputs_[1]; } 2460 2461 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map") 2462}; 2463 2464 2465class LForInCacheArray final : public LTemplateInstruction<1, 1, 0> { 2466 public: 2467 explicit LForInCacheArray(LOperand* map) { 2468 inputs_[0] = map; 2469 } 2470 2471 LOperand* map() { return inputs_[0]; } 2472 2473 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array") 2474 2475 int idx() { 2476 return HForInCacheArray::cast(this->hydrogen_value())->idx(); 2477 } 2478}; 2479 2480 2481class LCheckMapValue final : public LTemplateInstruction<0, 2, 0> { 2482 public: 2483 LCheckMapValue(LOperand* value, LOperand* map) { 2484 inputs_[0] = value; 2485 inputs_[1] = map; 2486 } 2487 2488 LOperand* value() { return inputs_[0]; } 2489 LOperand* map() { return inputs_[1]; } 2490 2491 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value") 2492}; 2493 2494 2495class LLoadFieldByIndex final : public LTemplateInstruction<1, 2, 0> { 2496 public: 2497 LLoadFieldByIndex(LOperand* object, LOperand* index) { 2498 inputs_[0] = object; 2499 inputs_[1] = index; 2500 } 2501 2502 LOperand* object() { return inputs_[0]; } 2503 LOperand* index() { return inputs_[1]; } 2504 2505 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index") 2506}; 2507 2508 2509class LChunkBuilder; 2510class LPlatformChunk final : public LChunk { 2511 public: 2512 LPlatformChunk(CompilationInfo* info, HGraph* graph) 2513 : LChunk(info, graph) { } 2514 2515 int GetNextSpillIndex(RegisterKind kind); 2516 LOperand* GetNextSpillSlot(RegisterKind kind); 2517}; 2518 2519 2520class LChunkBuilder final : public LChunkBuilderBase { 2521 public: 2522 LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator) 2523 : LChunkBuilderBase(info, graph), 2524 current_instruction_(NULL), 2525 current_block_(NULL), 2526 next_block_(NULL), 2527 allocator_(allocator) {} 2528 2529 // Build the sequence for the graph. 2530 LPlatformChunk* Build(); 2531 2532 // Declare methods that deal with the individual node types. 2533#define DECLARE_DO(type) LInstruction* Do##type(H##type* node); 2534 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 2535#undef DECLARE_DO 2536 2537 LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend); 2538 LInstruction* DoMultiplySub(HValue* minuend, HMul* mul); 2539 LInstruction* DoRSub(HSub* instr); 2540 2541 static bool HasMagicNumberForDivisor(int32_t divisor); 2542 2543 LInstruction* DoMathFloor(HUnaryMathOperation* instr); 2544 LInstruction* DoMathRound(HUnaryMathOperation* instr); 2545 LInstruction* DoMathFround(HUnaryMathOperation* instr); 2546 LInstruction* DoMathAbs(HUnaryMathOperation* instr); 2547 LInstruction* DoMathLog(HUnaryMathOperation* instr); 2548 LInstruction* DoMathExp(HUnaryMathOperation* instr); 2549 LInstruction* DoMathSqrt(HUnaryMathOperation* instr); 2550 LInstruction* DoMathPowHalf(HUnaryMathOperation* instr); 2551 LInstruction* DoMathClz32(HUnaryMathOperation* instr); 2552 LInstruction* DoDivByPowerOf2I(HDiv* instr); 2553 LInstruction* DoDivByConstI(HDiv* instr); 2554 LInstruction* DoDivI(HDiv* instr); 2555 LInstruction* DoModByPowerOf2I(HMod* instr); 2556 LInstruction* DoModByConstI(HMod* instr); 2557 LInstruction* DoModI(HMod* instr); 2558 LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr); 2559 LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr); 2560 LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr); 2561 2562 private: 2563 // Methods for getting operands for Use / Define / Temp. 2564 LUnallocated* ToUnallocated(Register reg); 2565 LUnallocated* ToUnallocated(DoubleRegister reg); 2566 2567 // Methods for setting up define-use relationships. 2568 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); 2569 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); 2570 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, 2571 DoubleRegister fixed_register); 2572 2573 // A value that is guaranteed to be allocated to a register. 2574 // Operand created by UseRegister is guaranteed to be live until the end of 2575 // instruction. This means that register allocator will not reuse it's 2576 // register for any other operand inside instruction. 2577 // Operand created by UseRegisterAtStart is guaranteed to be live only at 2578 // instruction start. Register allocator is free to assign the same register 2579 // to some other operand used inside instruction (i.e. temporary or 2580 // output). 2581 MUST_USE_RESULT LOperand* UseRegister(HValue* value); 2582 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value); 2583 2584 // An input operand in a register that may be trashed. 2585 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value); 2586 2587 // An input operand in a register or stack slot. 2588 MUST_USE_RESULT LOperand* Use(HValue* value); 2589 MUST_USE_RESULT LOperand* UseAtStart(HValue* value); 2590 2591 // An input operand in a register, stack slot or a constant operand. 2592 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value); 2593 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value); 2594 2595 // An input operand in a register or a constant operand. 2596 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value); 2597 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value); 2598 2599 // An input operand in a constant operand. 2600 MUST_USE_RESULT LOperand* UseConstant(HValue* value); 2601 2602 // An input operand in register, stack slot or a constant operand. 2603 // Will not be moved to a register even if one is freely available. 2604 MUST_USE_RESULT LOperand* UseAny(HValue* value) override; 2605 2606 // Temporary operand that must be in a register. 2607 MUST_USE_RESULT LUnallocated* TempRegister(); 2608 MUST_USE_RESULT LUnallocated* TempDoubleRegister(); 2609 MUST_USE_RESULT LOperand* FixedTemp(Register reg); 2610 MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg); 2611 2612 // Methods for setting up define-use relationships. 2613 // Return the same instruction that they are passed. 2614 LInstruction* Define(LTemplateResultInstruction<1>* instr, 2615 LUnallocated* result); 2616 LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr); 2617 LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr, 2618 int index); 2619 LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr); 2620 LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr, 2621 Register reg); 2622 LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr, 2623 DoubleRegister reg); 2624 LInstruction* AssignEnvironment(LInstruction* instr); 2625 LInstruction* AssignPointerMap(LInstruction* instr); 2626 2627 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; 2628 2629 // By default we assume that instruction sequences generated for calls 2630 // cannot deoptimize eagerly and we do not attach environment to this 2631 // instruction. 2632 LInstruction* MarkAsCall( 2633 LInstruction* instr, 2634 HInstruction* hinstr, 2635 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); 2636 2637 void VisitInstruction(HInstruction* current); 2638 void AddInstruction(LInstruction* instr, HInstruction* current); 2639 2640 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 2641 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); 2642 LInstruction* DoArithmeticD(Token::Value op, 2643 HArithmeticBinaryOperation* instr); 2644 LInstruction* DoArithmeticT(Token::Value op, 2645 HBinaryOperation* instr); 2646 2647 HInstruction* current_instruction_; 2648 HBasicBlock* current_block_; 2649 HBasicBlock* next_block_; 2650 LAllocator* allocator_; 2651 2652 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2653}; 2654 2655#undef DECLARE_HYDROGEN_ACCESSOR 2656#undef DECLARE_CONCRETE_INSTRUCTION 2657 2658} // namespace internal 2659} // namespace v8 2660 2661#endif // V8_CRANKSHAFT_ARM_LITHIUM_ARM_H_ 2662