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