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