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: LInstruction()187 LInstruction() 188 : environment_(NULL), 189 hydrogen_value_(NULL), 190 bit_field_(IsCallBits::encode(false)) { 191 } 192 ~LInstruction()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; } LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)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 IsControl()221 virtual bool IsControl() const { return false; } 222 223 // Try deleting this instruction if possible. TryDelete()224 virtual bool TryDelete() { return false; } 225 set_environment(LEnvironment * env)226 void set_environment(LEnvironment* env) { environment_ = env; } environment()227 LEnvironment* environment() const { return environment_; } HasEnvironment()228 bool HasEnvironment() const { return environment_ != NULL; } 229 set_pointer_map(LPointerMap * p)230 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } pointer_map()231 LPointerMap* pointer_map() const { return pointer_map_.get(); } HasPointerMap()232 bool HasPointerMap() const { return pointer_map_.is_set(); } 233 set_hydrogen_value(HValue * value)234 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } hydrogen_value()235 HValue* hydrogen_value() const { return hydrogen_value_; } 236 SetDeferredLazyDeoptimizationEnvironment(LEnvironment * env)237 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } 238 MarkAsCall()239 void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } IsCall()240 bool IsCall() const { return IsCallBits::decode(bit_field_); } 241 242 // Interface to the register allocator and iterators. ClobbersTemps()243 bool ClobbersTemps() const { return IsCall(); } ClobbersRegisters()244 bool ClobbersRegisters() const { return IsCall(); } ClobbersDoubleRegisters(Isolate * isolate)245 virtual bool ClobbersDoubleRegisters(Isolate* isolate) const { 246 return IsCall(); 247 } 248 249 // Interface to the register allocator and iterators. IsMarkedAsCall()250 bool IsMarkedAsCall() const { return IsCall(); } 251 252 virtual bool HasResult() const = 0; 253 virtual LOperand* result() const = 0; 254 FirstInput()255 LOperand* FirstInput() { return InputAt(0); } Output()256 LOperand* Output() { return HasResult() ? result() : NULL; } 257 HasInterestingComment(LCodeGen * gen)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); HasResult()290 virtual bool HasResult() const FINAL OVERRIDE { 291 return R != 0 && result() != NULL; 292 } set_result(LOperand * operand)293 void set_result(LOperand* operand) { results_[0] = operand; } result()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. InputCount()312 virtual int InputCount() FINAL OVERRIDE { return I; } InputAt(int i)313 virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; } 314 TempCount()315 virtual int TempCount() FINAL OVERRIDE { return T; } TempAt(int i)316 virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; } 317 }; 318 319 320 class LGap : public LTemplateInstruction<0, 0, 0> { 321 public: LGap(HBasicBlock * block)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. IsGap()331 virtual bool IsGap() const FINAL OVERRIDE { return true; } 332 virtual void PrintDataTo(StringStream* stream) OVERRIDE; cast(LInstruction * instr)333 static LGap* cast(LInstruction* instr) { 334 DCHECK(instr->IsGap()); 335 return reinterpret_cast<LGap*>(instr); 336 } 337 338 bool IsRedundant() const; 339 block()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 GetOrCreateParallelMove(InnerPosition pos,Zone * zone)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 GetParallelMove(InnerPosition pos)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: LInstructionGap(HBasicBlock * block)370 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } 371 HasInterestingComment(LCodeGen * gen)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: LGoto(HBasicBlock * block)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; IsControl()387 virtual bool IsControl() const OVERRIDE { return true; } 388 block_id()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: LLazyBailout()398 LLazyBailout() : gap_instructions_size_(0) { } 399 400 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 401 set_gap_instructions_size(int gap_instructions_size)402 void set_gap_instructions_size(int gap_instructions_size) { 403 gap_instructions_size_ = gap_instructions_size; 404 } gap_instructions_size()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: LDummy()414 LDummy() {} 415 DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") 416 }; 417 418 419 class LDummyUse FINAL : public LTemplateInstruction<1, 1, 0> { 420 public: LDummyUse(LOperand * value)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: IsControl()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: LLabel(HBasicBlock * block)438 explicit LLabel(HBasicBlock* block) 439 : LGap(block), replacement_(NULL) { } 440 HasInterestingComment(LCodeGen * gen)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 block_id()448 int block_id() const { return block()->block_id(); } is_loop_header()449 bool is_loop_header() const { return block()->IsLoopHeader(); } is_osr_entry()450 bool is_osr_entry() const { return block()->is_osr_entry(); } label()451 Label* label() { return &label_; } replacement()452 LLabel* replacement() const { return replacement_; } set_replacement(LLabel * label)453 void set_replacement(LLabel* label) { replacement_ = label; } HasReplacement()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: HasInterestingComment(LCodeGen * gen)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: LCallStub(LOperand * context)473 explicit LCallStub(LOperand* context) { 474 inputs_[0] = context; 475 } 476 context()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: LTailCallThroughMegamorphicCache(LOperand * context,LOperand * receiver,LOperand * name)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 context()495 LOperand* context() { return inputs_[0]; } receiver()496 LOperand* receiver() { return inputs_[1]; } name()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: HasInterestingComment(LCodeGen * gen)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: LControlInstruction()517 LControlInstruction() : false_label_(NULL), true_label_(NULL) { } 518 IsControl()519 virtual bool IsControl() const FINAL OVERRIDE { return true; } 520 SuccessorCount()521 int SuccessorCount() { return hydrogen()->SuccessorCount(); } SuccessorAt(int i)522 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } 523 TrueDestination(LChunk * chunk)524 int TrueDestination(LChunk* chunk) { 525 return chunk->LookupDestination(true_block_id()); 526 } FalseDestination(LChunk * chunk)527 int FalseDestination(LChunk* chunk) { 528 return chunk->LookupDestination(false_block_id()); 529 } 530 TrueLabel(LChunk * chunk)531 Label* TrueLabel(LChunk* chunk) { 532 if (true_label_ == NULL) { 533 true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); 534 } 535 return true_label_; 536 } FalseLabel(LChunk * chunk)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: true_block_id()545 int true_block_id() { return SuccessorAt(0)->block_id(); } false_block_id()546 int false_block_id() { return SuccessorAt(1)->block_id(); } 547 548 private: hydrogen()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: LWrapReceiver(LOperand * receiver,LOperand * function)560 LWrapReceiver(LOperand* receiver, LOperand* function) { 561 inputs_[0] = receiver; 562 inputs_[1] = function; 563 } 564 565 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)566 DECLARE_HYDROGEN_ACCESSOR(WrapReceiver) 567 568 LOperand* receiver() { return inputs_[0]; } function()569 LOperand* function() { return inputs_[1]; } 570 }; 571 572 573 class LApplyArguments FINAL : public LTemplateInstruction<1, 4, 0> { 574 public: LApplyArguments(LOperand * function,LOperand * receiver,LOperand * length,LOperand * elements)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 function()587 LOperand* function() { return inputs_[0]; } receiver()588 LOperand* receiver() { return inputs_[1]; } length()589 LOperand* length() { return inputs_[2]; } elements()590 LOperand* elements() { return inputs_[3]; } 591 }; 592 593 594 class LAccessArgumentsAt FINAL : public LTemplateInstruction<1, 3, 0> { 595 public: LAccessArgumentsAt(LOperand * arguments,LOperand * length,LOperand * index)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 arguments()604 LOperand* arguments() { return inputs_[0]; } length()605 LOperand* length() { return inputs_[1]; } index()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: LArgumentsLength(LOperand * elements)614 explicit LArgumentsLength(LOperand* elements) { 615 inputs_[0] = elements; 616 } 617 elements()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: LModByPowerOf2I(LOperand * dividend,int32_t divisor)633 LModByPowerOf2I(LOperand* dividend, int32_t divisor) { 634 inputs_[0] = dividend; 635 divisor_ = divisor; 636 } 637 dividend()638 LOperand* dividend() { return inputs_[0]; } divisor()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: LModByConstI(LOperand * dividend,int32_t divisor)651 LModByConstI(LOperand* dividend, int32_t divisor) { 652 inputs_[0] = dividend; 653 divisor_ = divisor; 654 } 655 dividend()656 LOperand* dividend() { return inputs_[0]; } divisor()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: LModI(LOperand * left,LOperand * right)669 LModI(LOperand* left, 670 LOperand* right) { 671 inputs_[0] = left; 672 inputs_[1] = right; 673 } 674 left()675 LOperand* left() { return inputs_[0]; } right()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: LDivByPowerOf2I(LOperand * dividend,int32_t divisor)685 LDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 686 inputs_[0] = dividend; 687 divisor_ = divisor; 688 } 689 dividend()690 LOperand* dividend() { return inputs_[0]; } divisor()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: LDivByConstI(LOperand * dividend,int32_t divisor)703 LDivByConstI(LOperand* dividend, int32_t divisor) { 704 inputs_[0] = dividend; 705 divisor_ = divisor; 706 } 707 dividend()708 LOperand* dividend() { return inputs_[0]; } divisor()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: LDivI(LOperand * dividend,LOperand * divisor,LOperand * temp)721 LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) { 722 inputs_[0] = dividend; 723 inputs_[1] = divisor; 724 temps_[0] = temp; 725 } 726 dividend()727 LOperand* dividend() { return inputs_[0]; } divisor()728 LOperand* divisor() { return inputs_[1]; } temp()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: LFlooringDivByPowerOf2I(LOperand * dividend,int32_t divisor)738 LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 739 inputs_[0] = dividend; 740 divisor_ = divisor; 741 } 742 dividend()743 LOperand* dividend() { return inputs_[0]; } divisor()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: LFlooringDivByConstI(LOperand * dividend,int32_t divisor,LOperand * temp)757 LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) { 758 inputs_[0] = dividend; 759 divisor_ = divisor; 760 temps_[0] = temp; 761 } 762 dividend()763 LOperand* dividend() { return inputs_[0]; } divisor()764 int32_t divisor() const { return divisor_; } temp()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: LFlooringDivI(LOperand * dividend,LOperand * divisor)777 LFlooringDivI(LOperand* dividend, LOperand* divisor) { 778 inputs_[0] = dividend; 779 inputs_[1] = divisor; 780 } 781 dividend()782 LOperand* dividend() { return inputs_[0]; } divisor()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: LMulI(LOperand * left,LOperand * right)792 LMulI(LOperand* left, LOperand* right) { 793 inputs_[0] = left; 794 inputs_[1] = right; 795 } 796 left()797 LOperand* left() { return inputs_[0]; } right()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: LMultiplyAddD(LOperand * addend,LOperand * multiplier,LOperand * multiplicand)808 LMultiplyAddD(LOperand* addend, LOperand* multiplier, 809 LOperand* multiplicand) { 810 inputs_[0] = addend; 811 inputs_[1] = multiplier; 812 inputs_[2] = multiplicand; 813 } 814 addend()815 LOperand* addend() { return inputs_[0]; } multiplier()816 LOperand* multiplier() { return inputs_[1]; } multiplicand()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: LCompareNumericAndBranch(LOperand * left,LOperand * right)831 LCompareNumericAndBranch(LOperand* left, LOperand* right) { 832 inputs_[0] = left; 833 inputs_[1] = right; 834 } 835 left()836 LOperand* left() { return inputs_[0]; } right()837 LOperand* right() { return inputs_[1]; } 838 839 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch, 840 "compare-numeric-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)841 DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch) 842 843 Token::Value op() const { return hydrogen()->token(); } is_double()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: LMathFloor(LOperand * value,LOperand * temp)854 LMathFloor(LOperand* value, LOperand* temp) { 855 inputs_[0] = value; 856 temps_[0] = temp; 857 } 858 value()859 LOperand* value() { return inputs_[0]; } temp()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: LMathRound(LOperand * value,LOperand * temp)869 LMathRound(LOperand* value, LOperand* temp) { 870 inputs_[0] = value; 871 temps_[0] = temp; 872 } 873 value()874 LOperand* value() { return inputs_[0]; } temp()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: LMathFround(LOperand * value)884 explicit LMathFround(LOperand* value) { inputs_[0] = value; } 885 value()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: LMathAbs(LOperand * context,LOperand * value)894 LMathAbs(LOperand* context, LOperand* value) { 895 inputs_[1] = context; 896 inputs_[0] = value; 897 } 898 context()899 LOperand* context() { return inputs_[1]; } value()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: LMathLog(LOperand * value)909 explicit LMathLog(LOperand* value) { 910 inputs_[0] = value; 911 } 912 value()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: LMathClz32(LOperand * value)921 explicit LMathClz32(LOperand* value) { 922 inputs_[0] = value; 923 } 924 value()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: LMathExp(LOperand * value,LOperand * double_temp,LOperand * temp1,LOperand * temp2)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 value()944 LOperand* value() { return inputs_[0]; } temp1()945 LOperand* temp1() { return temps_[0]; } temp2()946 LOperand* temp2() { return temps_[1]; } double_temp()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: LMathSqrt(LOperand * value)955 explicit LMathSqrt(LOperand* value) { 956 inputs_[0] = value; 957 } 958 value()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: LMathPowHalf(LOperand * value,LOperand * temp)967 LMathPowHalf(LOperand* value, LOperand* temp) { 968 inputs_[0] = value; 969 temps_[0] = temp; 970 } 971 value()972 LOperand* value() { return inputs_[0]; } temp()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: LCmpObjectEqAndBranch(LOperand * left,LOperand * right)981 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) { 982 inputs_[0] = left; 983 inputs_[1] = right; 984 } 985 left()986 LOperand* left() { return inputs_[0]; } right()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: LCmpHoleAndBranch(LOperand * object)996 explicit LCmpHoleAndBranch(LOperand* object) { 997 inputs_[0] = object; 998 } 999 object()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: LCompareMinusZeroAndBranch(LOperand * value,LOperand * temp)1009 LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) { 1010 inputs_[0] = value; 1011 temps_[0] = temp; 1012 } 1013 value()1014 LOperand* value() { return inputs_[0]; } temp()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: LIsObjectAndBranch(LOperand * value,LOperand * temp)1025 LIsObjectAndBranch(LOperand* value, LOperand* temp) { 1026 inputs_[0] = value; 1027 temps_[0] = temp; 1028 } 1029 value()1030 LOperand* value() { return inputs_[0]; } temp()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: LIsStringAndBranch(LOperand * value,LOperand * temp)1042 LIsStringAndBranch(LOperand* value, LOperand* temp) { 1043 inputs_[0] = value; 1044 temps_[0] = temp; 1045 } 1046 value()1047 LOperand* value() { return inputs_[0]; } temp()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: LIsSmiAndBranch(LOperand * value)1059 explicit LIsSmiAndBranch(LOperand* value) { 1060 inputs_[0] = value; 1061 } 1062 value()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: LIsUndetectableAndBranch(LOperand * value,LOperand * temp)1074 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { 1075 inputs_[0] = value; 1076 temps_[0] = temp; 1077 } 1078 value()1079 LOperand* value() { return inputs_[0]; } temp()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: LStringCompareAndBranch(LOperand * context,LOperand * left,LOperand * right)1092 LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) { 1093 inputs_[0] = context; 1094 inputs_[1] = left; 1095 inputs_[2] = right; 1096 } 1097 context()1098 LOperand* context() { return inputs_[0]; } left()1099 LOperand* left() { return inputs_[1]; } right()1100 LOperand* right() { return inputs_[2]; } 1101 1102 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, 1103 "string-compare-and-branch") DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)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: LHasInstanceTypeAndBranch(LOperand * value)1114 explicit LHasInstanceTypeAndBranch(LOperand* value) { 1115 inputs_[0] = value; 1116 } 1117 value()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: LGetCachedArrayIndex(LOperand * value)1130 explicit LGetCachedArrayIndex(LOperand* value) { 1131 inputs_[0] = value; 1132 } 1133 value()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: LHasCachedArrayIndexAndBranch(LOperand * value)1144 explicit LHasCachedArrayIndexAndBranch(LOperand* value) { 1145 inputs_[0] = value; 1146 } 1147 value()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: LClassOfTestAndBranch(LOperand * value,LOperand * temp)1160 LClassOfTestAndBranch(LOperand* value, LOperand* temp) { 1161 inputs_[0] = value; 1162 temps_[0] = temp; 1163 } 1164 value()1165 LOperand* value() { return inputs_[0]; } temp()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: LCmpT(LOperand * context,LOperand * left,LOperand * right)1178 LCmpT(LOperand* context, LOperand* left, LOperand* right) { 1179 inputs_[0] = context; 1180 inputs_[1] = left; 1181 inputs_[2] = right; 1182 } 1183 context()1184 LOperand* context() { return inputs_[0]; } left()1185 LOperand* left() { return inputs_[1]; } right()1186 LOperand* right() { return inputs_[2]; } 1187 1188 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)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: LInstanceOf(LOperand * context,LOperand * left,LOperand * right)1197 LInstanceOf(LOperand* context, LOperand* left, LOperand* right) { 1198 inputs_[0] = context; 1199 inputs_[1] = left; 1200 inputs_[2] = right; 1201 } 1202 context()1203 LOperand* context() { return inputs_[0]; } left()1204 LOperand* left() { return inputs_[1]; } right()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: LInstanceOfKnownGlobal(LOperand * context,LOperand * value,LOperand * temp)1213 LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) { 1214 inputs_[0] = context; 1215 inputs_[1] = value; 1216 temps_[0] = temp; 1217 } 1218 context()1219 LOperand* context() { return inputs_[0]; } value()1220 LOperand* value() { return inputs_[1]; } temp()1221 LOperand* temp() { return temps_[0]; } 1222 1223 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, 1224 "instance-of-known-global") DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)1225 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) 1226 1227 Handle<JSFunction> function() const { return hydrogen()->function(); } GetDeferredLazyDeoptimizationEnvironment()1228 LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { 1229 return lazy_deopt_env_; 1230 } SetDeferredLazyDeoptimizationEnvironment(LEnvironment * env)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: LBoundsCheck(LOperand * index,LOperand * length)1243 LBoundsCheck(LOperand* index, LOperand* length) { 1244 inputs_[0] = index; 1245 inputs_[1] = length; 1246 } 1247 index()1248 LOperand* index() { return inputs_[0]; } length()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: LBitI(LOperand * left,LOperand * right)1258 LBitI(LOperand* left, LOperand* right) { 1259 inputs_[0] = left; 1260 inputs_[1] = right; 1261 } 1262 left()1263 LOperand* left() { return inputs_[0]; } right()1264 LOperand* right() { return inputs_[1]; } 1265 op()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: LShiftI(Token::Value op,LOperand * left,LOperand * right,bool can_deopt)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 op()1281 Token::Value op() const { return op_; } left()1282 LOperand* left() { return inputs_[0]; } right()1283 LOperand* right() { return inputs_[1]; } can_deopt()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: LSubI(LOperand * left,LOperand * right)1296 LSubI(LOperand* left, LOperand* right) { 1297 inputs_[0] = left; 1298 inputs_[1] = right; 1299 } 1300 left()1301 LOperand* left() { return inputs_[0]; } right()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") DECLARE_HYDROGEN_ACCESSOR(Constant)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") DECLARE_HYDROGEN_ACCESSOR(Constant)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") DECLARE_HYDROGEN_ACCESSOR(Constant)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") DECLARE_HYDROGEN_ACCESSOR(Constant)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") DECLARE_HYDROGEN_ACCESSOR(Constant)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: LBranch(LOperand * value)1360 explicit LBranch(LOperand* value) { 1361 inputs_[0] = value; 1362 } 1363 value()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: LCmpMapAndBranch(LOperand * value,LOperand * temp)1375 LCmpMapAndBranch(LOperand* value, LOperand* temp) { 1376 inputs_[0] = value; 1377 temps_[0] = temp; 1378 } 1379 value()1380 LOperand* value() { return inputs_[0]; } temp()1381 LOperand* temp() { return temps_[0]; } 1382 1383 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMap)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: LMapEnumLength(LOperand * value)1392 explicit LMapEnumLength(LOperand* value) { 1393 inputs_[0] = value; 1394 } 1395 value()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: LDateField(LOperand * date,LOperand * temp,Smi * index)1404 LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) { 1405 inputs_[0] = date; 1406 temps_[0] = temp; 1407 } 1408 date()1409 LOperand* date() { return inputs_[0]; } temp()1410 LOperand* temp() { return temps_[0]; } index()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: LSeqStringGetChar(LOperand * string,LOperand * index)1423 LSeqStringGetChar(LOperand* string, LOperand* index) { 1424 inputs_[0] = string; 1425 inputs_[1] = index; 1426 } 1427 string()1428 LOperand* string() const { return inputs_[0]; } index()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: LSeqStringSetChar(LOperand * context,LOperand * string,LOperand * index,LOperand * value)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 string()1448 LOperand* string() { return inputs_[1]; } index()1449 LOperand* index() { return inputs_[2]; } value()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: LAddI(LOperand * left,LOperand * right)1459 LAddI(LOperand* left, LOperand* right) { 1460 inputs_[0] = left; 1461 inputs_[1] = right; 1462 } 1463 left()1464 LOperand* left() { return inputs_[0]; } right()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: LMathMinMax(LOperand * left,LOperand * right)1474 LMathMinMax(LOperand* left, LOperand* right) { 1475 inputs_[0] = left; 1476 inputs_[1] = right; 1477 } 1478 left()1479 LOperand* left() { return inputs_[0]; } right()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: LPower(LOperand * left,LOperand * right)1489 LPower(LOperand* left, LOperand* right) { 1490 inputs_[0] = left; 1491 inputs_[1] = right; 1492 } 1493 left()1494 LOperand* left() { return inputs_[0]; } right()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: LArithmeticD(Token::Value op,LOperand * left,LOperand * right)1504 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) 1505 : op_(op) { 1506 inputs_[0] = left; 1507 inputs_[1] = right; 1508 } 1509 op()1510 Token::Value op() const { return op_; } left()1511 LOperand* left() { return inputs_[0]; } right()1512 LOperand* right() { return inputs_[1]; } 1513 opcode()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: LArithmeticT(Token::Value op,LOperand * context,LOperand * left,LOperand * right)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 context()1537 LOperand* context() { return inputs_[0]; } left()1538 LOperand* left() { return inputs_[1]; } right()1539 LOperand* right() { return inputs_[2]; } op()1540 Token::Value op() const { return op_; } 1541 opcode()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: LReturn(LOperand * value,LOperand * context,LOperand * parameter_count)1553 LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) { 1554 inputs_[0] = value; 1555 inputs_[1] = context; 1556 inputs_[2] = parameter_count; 1557 } 1558 value()1559 LOperand* value() { return inputs_[0]; } 1560 has_constant_parameter_count()1561 bool has_constant_parameter_count() { 1562 return parameter_count()->IsConstantOperand(); 1563 } constant_parameter_count()1564 LConstantOperand* constant_parameter_count() { 1565 DCHECK(has_constant_parameter_count()); 1566 return LConstantOperand::cast(parameter_count()); 1567 } parameter_count()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: LLoadNamedField(LOperand * object)1576 explicit LLoadNamedField(LOperand* object) { 1577 inputs_[0] = object; 1578 } 1579 object()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: LLoadNamedGeneric(LOperand * context,LOperand * object,LOperand * vector)1589 LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) { 1590 inputs_[0] = context; 1591 inputs_[1] = object; 1592 temps_[0] = vector; 1593 } 1594 context()1595 LOperand* context() { return inputs_[0]; } object()1596 LOperand* object() { return inputs_[1]; } temp_vector()1597 LOperand* temp_vector() { return temps_[0]; } 1598 1599 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)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: LLoadFunctionPrototype(LOperand * function)1608 explicit LLoadFunctionPrototype(LOperand* function) { 1609 inputs_[0] = function; 1610 } 1611 function()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") DECLARE_HYDROGEN_ACCESSOR(LoadRoot)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: LLoadKeyed(LOperand * elements,LOperand * key)1630 LLoadKeyed(LOperand* elements, LOperand* key) { 1631 inputs_[0] = elements; 1632 inputs_[1] = key; 1633 } 1634 elements()1635 LOperand* elements() { return inputs_[0]; } key()1636 LOperand* key() { return inputs_[1]; } elements_kind()1637 ElementsKind elements_kind() const { 1638 return hydrogen()->elements_kind(); 1639 } is_external()1640 bool is_external() const { 1641 return hydrogen()->is_external(); 1642 } is_fixed_typed_array()1643 bool is_fixed_typed_array() const { 1644 return hydrogen()->is_fixed_typed_array(); 1645 } is_typed_elements()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); base_offset()1654 uint32_t base_offset() const { return hydrogen()->base_offset(); } 1655 }; 1656 1657 1658 class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> { 1659 public: LLoadKeyedGeneric(LOperand * context,LOperand * object,LOperand * key,LOperand * vector)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 context()1668 LOperand* context() { return inputs_[0]; } object()1669 LOperand* object() { return inputs_[1]; } key()1670 LOperand* key() { return inputs_[2]; } temp_vector()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: LLoadGlobalGeneric(LOperand * context,LOperand * global_object,LOperand * vector)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 context()1694 LOperand* context() { return inputs_[0]; } global_object()1695 LOperand* global_object() { return inputs_[1]; } temp_vector()1696 LOperand* temp_vector() { return temps_[0]; } 1697 1698 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic") DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)1699 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric) 1700 1701 Handle<Object> name() const { return hydrogen()->name(); } for_typeof()1702 bool for_typeof() const { return hydrogen()->for_typeof(); } 1703 }; 1704 1705 1706 class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 1> { 1707 public: LStoreGlobalCell(LOperand * value,LOperand * temp)1708 LStoreGlobalCell(LOperand* value, LOperand* temp) { 1709 inputs_[0] = value; 1710 temps_[0] = temp; 1711 } 1712 value()1713 LOperand* value() { return inputs_[0]; } temp()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: LLoadContextSlot(LOperand * context)1723 explicit LLoadContextSlot(LOperand* context) { 1724 inputs_[0] = context; 1725 } 1726 context()1727 LOperand* context() { return inputs_[0]; } 1728 1729 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)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: LStoreContextSlot(LOperand * context,LOperand * value)1740 LStoreContextSlot(LOperand* context, LOperand* value) { 1741 inputs_[0] = context; 1742 inputs_[1] = value; 1743 } 1744 context()1745 LOperand* context() { return inputs_[0]; } value()1746 LOperand* value() { return inputs_[1]; } 1747 1748 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot") DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)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: LPushArgument(LOperand * value)1759 explicit LPushArgument(LOperand* value) { 1760 inputs_[0] = value; 1761 } 1762 value()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: LDrop(int count)1771 explicit LDrop(int count) : count_(count) { } 1772 count()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: LStoreCodeEntry(LOperand * function,LOperand * code_object)1784 LStoreCodeEntry(LOperand* function, LOperand* code_object) { 1785 inputs_[0] = function; 1786 inputs_[1] = code_object; 1787 } 1788 function()1789 LOperand* function() { return inputs_[0]; } code_object()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: LInnerAllocatedObject(LOperand * base_object,LOperand * offset)1801 LInnerAllocatedObject(LOperand* base_object, LOperand* offset) { 1802 inputs_[0] = base_object; 1803 inputs_[1] = offset; 1804 } 1805 base_object()1806 LOperand* base_object() const { return inputs_[0]; } offset()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: LDeclareGlobals(LOperand * context)1831 explicit LDeclareGlobals(LOperand* context) { 1832 inputs_[0] = context; 1833 } 1834 context()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: LCallJSFunction(LOperand * function)1844 explicit LCallJSFunction(LOperand* function) { 1845 inputs_[0] = function; 1846 } 1847 function()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 arity()1855 int arity() const { return hydrogen()->argument_count() - 1; } 1856 }; 1857 1858 1859 class LCallWithDescriptor FINAL : public LTemplateResultInstruction<1> { 1860 public: LCallWithDescriptor(CallInterfaceDescriptor descriptor,const ZoneList<LOperand * > & operands,Zone * zone)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 target()1869 LOperand* target() const { return inputs_[0]; } 1870 descriptor()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 arity()1879 int arity() const { return hydrogen()->argument_count() - 1; } 1880 1881 CallInterfaceDescriptor descriptor_; 1882 ZoneList<LOperand*> inputs_; 1883 1884 // Iterator support. InputCount()1885 virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); } InputAt(int i)1886 virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; } 1887 TempCount()1888 virtual int TempCount() FINAL OVERRIDE { return 0; } TempAt(int i)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: LInvokeFunction(LOperand * context,LOperand * function)1896 LInvokeFunction(LOperand* context, LOperand* function) { 1897 inputs_[0] = context; 1898 inputs_[1] = function; 1899 } 1900 context()1901 LOperand* context() { return inputs_[0]; } function()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 arity()1909 int arity() const { return hydrogen()->argument_count() - 1; } 1910 }; 1911 1912 1913 class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> { 1914 public: LCallFunction(LOperand * context,LOperand * function)1915 LCallFunction(LOperand* context, LOperand* function) { 1916 inputs_[0] = context; 1917 inputs_[1] = function; 1918 } 1919 context()1920 LOperand* context() { return inputs_[0]; } function()1921 LOperand* function() { return inputs_[1]; } 1922 1923 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function") DECLARE_HYDROGEN_ACCESSOR(CallFunction)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: LCallNew(LOperand * context,LOperand * constructor)1932 LCallNew(LOperand* context, LOperand* constructor) { 1933 inputs_[0] = context; 1934 inputs_[1] = constructor; 1935 } 1936 context()1937 LOperand* context() { return inputs_[0]; } constructor()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 arity()1945 int arity() const { return hydrogen()->argument_count() - 1; } 1946 }; 1947 1948 1949 class LCallNewArray FINAL : public LTemplateInstruction<1, 2, 0> { 1950 public: LCallNewArray(LOperand * context,LOperand * constructor)1951 LCallNewArray(LOperand* context, LOperand* constructor) { 1952 inputs_[0] = context; 1953 inputs_[1] = constructor; 1954 } 1955 context()1956 LOperand* context() { return inputs_[0]; } constructor()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 arity()1964 int arity() const { return hydrogen()->argument_count() - 1; } 1965 }; 1966 1967 1968 class LCallRuntime FINAL : public LTemplateInstruction<1, 1, 0> { 1969 public: LCallRuntime(LOperand * context)1970 explicit LCallRuntime(LOperand* context) { 1971 inputs_[0] = context; 1972 } 1973 context()1974 LOperand* context() { return inputs_[0]; } 1975 1976 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") DECLARE_HYDROGEN_ACCESSOR(CallRuntime)1977 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1978 1979 virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE { 1980 return save_doubles() == kDontSaveFPRegs; 1981 } 1982 function()1983 const Runtime::Function* function() const { return hydrogen()->function(); } arity()1984 int arity() const { return hydrogen()->argument_count(); } save_doubles()1985 SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); } 1986 }; 1987 1988 1989 class LInteger32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> { 1990 public: LInteger32ToDouble(LOperand * value)1991 explicit LInteger32ToDouble(LOperand* value) { 1992 inputs_[0] = value; 1993 } 1994 value()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: LUint32ToDouble(LOperand * value)2003 explicit LUint32ToDouble(LOperand* value) { 2004 inputs_[0] = value; 2005 } 2006 value()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: LNumberTagU(LOperand * value,LOperand * temp1,LOperand * temp2)2015 LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) { 2016 inputs_[0] = value; 2017 temps_[0] = temp1; 2018 temps_[1] = temp2; 2019 } 2020 value()2021 LOperand* value() { return inputs_[0]; } temp1()2022 LOperand* temp1() { return temps_[0]; } temp2()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: LNumberTagD(LOperand * value,LOperand * temp,LOperand * temp2)2031 LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) { 2032 inputs_[0] = value; 2033 temps_[0] = temp; 2034 temps_[1] = temp2; 2035 } 2036 value()2037 LOperand* value() { return inputs_[0]; } temp()2038 LOperand* temp() { return temps_[0]; } temp2()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: LDoubleToSmi(LOperand * value)2048 explicit LDoubleToSmi(LOperand* value) { 2049 inputs_[0] = value; 2050 } 2051 value()2052 LOperand* value() { return inputs_[0]; } 2053 2054 DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi") DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)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: LDoubleToI(LOperand * value)2064 explicit LDoubleToI(LOperand* value) { 2065 inputs_[0] = value; 2066 } 2067 value()2068 LOperand* value() { return inputs_[0]; } 2069 2070 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)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: LTaggedToI(LOperand * value,LOperand * temp,LOperand * temp2)2080 LTaggedToI(LOperand* value, 2081 LOperand* temp, 2082 LOperand* temp2) { 2083 inputs_[0] = value; 2084 temps_[0] = temp; 2085 temps_[1] = temp2; 2086 } 2087 value()2088 LOperand* value() { return inputs_[0]; } temp()2089 LOperand* temp() { return temps_[0]; } temp2()2090 LOperand* temp2() { return temps_[1]; } 2091 2092 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") DECLARE_HYDROGEN_ACCESSOR(Change)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: LSmiTag(LOperand * value)2101 explicit LSmiTag(LOperand* value) { 2102 inputs_[0] = value; 2103 } 2104 value()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: LNumberUntagD(LOperand * value)2114 explicit LNumberUntagD(LOperand* value) { 2115 inputs_[0] = value; 2116 } 2117 value()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: LSmiUntag(LOperand * value,bool needs_check)2127 LSmiUntag(LOperand* value, bool needs_check) 2128 : needs_check_(needs_check) { 2129 inputs_[0] = value; 2130 } 2131 value()2132 LOperand* value() { return inputs_[0]; } needs_check()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: LStoreNamedField(LOperand * object,LOperand * value,LOperand * temp)2144 LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) { 2145 inputs_[0] = object; 2146 inputs_[1] = value; 2147 temps_[0] = temp; 2148 } 2149 object()2150 LOperand* object() { return inputs_[0]; } value()2151 LOperand* value() { return inputs_[1]; } temp()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 representation()2159 Representation representation() const { 2160 return hydrogen()->field_representation(); 2161 } 2162 }; 2163 2164 2165 class LStoreNamedGeneric FINAL : public LTemplateInstruction<0, 3, 0> { 2166 public: LStoreNamedGeneric(LOperand * context,LOperand * object,LOperand * value)2167 LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) { 2168 inputs_[0] = context; 2169 inputs_[1] = object; 2170 inputs_[2] = value; 2171 } 2172 context()2173 LOperand* context() { return inputs_[0]; } object()2174 LOperand* object() { return inputs_[1]; } value()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 name()2182 Handle<Object> name() const { return hydrogen()->name(); } strict_mode()2183 StrictMode strict_mode() { return hydrogen()->strict_mode(); } 2184 }; 2185 2186 2187 class LStoreKeyed FINAL : public LTemplateInstruction<0, 3, 0> { 2188 public: LStoreKeyed(LOperand * object,LOperand * key,LOperand * value)2189 LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) { 2190 inputs_[0] = object; 2191 inputs_[1] = key; 2192 inputs_[2] = value; 2193 } 2194 is_external()2195 bool is_external() const { return hydrogen()->is_external(); } is_fixed_typed_array()2196 bool is_fixed_typed_array() const { 2197 return hydrogen()->is_fixed_typed_array(); 2198 } is_typed_elements()2199 bool is_typed_elements() const { 2200 return is_external() || is_fixed_typed_array(); 2201 } elements()2202 LOperand* elements() { return inputs_[0]; } key()2203 LOperand* key() { return inputs_[1]; } value()2204 LOperand* value() { return inputs_[2]; } elements_kind()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; NeedsCanonicalization()2213 bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } base_offset()2214 uint32_t base_offset() const { return hydrogen()->base_offset(); } 2215 }; 2216 2217 2218 class LStoreKeyedGeneric FINAL : public LTemplateInstruction<0, 4, 0> { 2219 public: LStoreKeyedGeneric(LOperand * context,LOperand * obj,LOperand * key,LOperand * value)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 context()2230 LOperand* context() { return inputs_[0]; } object()2231 LOperand* object() { return inputs_[1]; } key()2232 LOperand* key() { return inputs_[2]; } value()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 strict_mode()2240 StrictMode strict_mode() { return hydrogen()->strict_mode(); } 2241 }; 2242 2243 2244 class LTransitionElementsKind FINAL : public LTemplateInstruction<0, 2, 1> { 2245 public: LTransitionElementsKind(LOperand * object,LOperand * context,LOperand * new_map_temp)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 context()2254 LOperand* context() { return inputs_[1]; } object()2255 LOperand* object() { return inputs_[0]; } new_map_temp()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 original_map()2264 Handle<Map> original_map() { return hydrogen()->original_map().handle(); } transitioned_map()2265 Handle<Map> transitioned_map() { 2266 return hydrogen()->transitioned_map().handle(); 2267 } from_kind()2268 ElementsKind from_kind() { return hydrogen()->from_kind(); } to_kind()2269 ElementsKind to_kind() { return hydrogen()->to_kind(); } 2270 }; 2271 2272 2273 class LTrapAllocationMemento FINAL : public LTemplateInstruction<0, 1, 1> { 2274 public: LTrapAllocationMemento(LOperand * object,LOperand * temp)2275 LTrapAllocationMemento(LOperand* object, 2276 LOperand* temp) { 2277 inputs_[0] = object; 2278 temps_[0] = temp; 2279 } 2280 object()2281 LOperand* object() { return inputs_[0]; } temp()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: LStringAdd(LOperand * context,LOperand * left,LOperand * right)2291 LStringAdd(LOperand* context, LOperand* left, LOperand* right) { 2292 inputs_[0] = context; 2293 inputs_[1] = left; 2294 inputs_[2] = right; 2295 } 2296 context()2297 LOperand* context() { return inputs_[0]; } left()2298 LOperand* left() { return inputs_[1]; } right()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: LStringCharCodeAt(LOperand * context,LOperand * string,LOperand * index)2309 LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) { 2310 inputs_[0] = context; 2311 inputs_[1] = string; 2312 inputs_[2] = index; 2313 } 2314 context()2315 LOperand* context() { return inputs_[0]; } string()2316 LOperand* string() { return inputs_[1]; } index()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: LStringCharFromCode(LOperand * context,LOperand * char_code)2326 explicit LStringCharFromCode(LOperand* context, LOperand* char_code) { 2327 inputs_[0] = context; 2328 inputs_[1] = char_code; 2329 } 2330 context()2331 LOperand* context() { return inputs_[0]; } char_code()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: LCheckValue(LOperand * value)2341 explicit LCheckValue(LOperand* value) { 2342 inputs_[0] = value; 2343 } 2344 value()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: LCheckInstanceType(LOperand * value)2354 explicit LCheckInstanceType(LOperand* value) { 2355 inputs_[0] = value; 2356 } 2357 value()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 value()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: LCheckSmi(LOperand * value)2380 explicit LCheckSmi(LOperand* value) { 2381 inputs_[0] = value; 2382 } 2383 value()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: LCheckNonSmi(LOperand * value)2392 explicit LCheckNonSmi(LOperand* value) { 2393 inputs_[0] = value; 2394 } 2395 value()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: LClampDToUint8(LOperand * unclamped,LOperand * temp)2405 LClampDToUint8(LOperand* unclamped, LOperand* temp) { 2406 inputs_[0] = unclamped; 2407 temps_[0] = temp; 2408 } 2409 unclamped()2410 LOperand* unclamped() { return inputs_[0]; } temp()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: LClampIToUint8(LOperand * unclamped)2419 explicit LClampIToUint8(LOperand* unclamped) { 2420 inputs_[0] = unclamped; 2421 } 2422 unclamped()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: LClampTToUint8(LOperand * unclamped,LOperand * temp)2431 LClampTToUint8(LOperand* unclamped, LOperand* temp) { 2432 inputs_[0] = unclamped; 2433 temps_[0] = temp; 2434 } 2435 unclamped()2436 LOperand* unclamped() { return inputs_[0]; } temp()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: LDoubleBits(LOperand * value)2445 explicit LDoubleBits(LOperand* value) { 2446 inputs_[0] = value; 2447 } 2448 value()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: LConstructDouble(LOperand * hi,LOperand * lo)2458 LConstructDouble(LOperand* hi, LOperand* lo) { 2459 inputs_[0] = hi; 2460 inputs_[1] = lo; 2461 } 2462 hi()2463 LOperand* hi() { return inputs_[0]; } lo()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: LAllocate(LOperand * context,LOperand * size,LOperand * temp1,LOperand * temp2)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 context()2482 LOperand* context() { return inputs_[0]; } size()2483 LOperand* size() { return inputs_[1]; } temp1()2484 LOperand* temp1() { return temps_[0]; } temp2()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: LRegExpLiteral(LOperand * context)2494 explicit LRegExpLiteral(LOperand* context) { 2495 inputs_[0] = context; 2496 } 2497 context()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: LFunctionLiteral(LOperand * context)2507 explicit LFunctionLiteral(LOperand* context) { 2508 inputs_[0] = context; 2509 } 2510 context()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: LToFastProperties(LOperand * value)2520 explicit LToFastProperties(LOperand* value) { 2521 inputs_[0] = value; 2522 } 2523 value()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: LTypeof(LOperand * context,LOperand * value)2533 LTypeof(LOperand* context, LOperand* value) { 2534 inputs_[0] = context; 2535 inputs_[1] = value; 2536 } 2537 context()2538 LOperand* context() { return inputs_[0]; } value()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: LTypeofIsAndBranch(LOperand * value)2547 explicit LTypeofIsAndBranch(LOperand* value) { 2548 inputs_[0] = value; 2549 } 2550 value()2551 LOperand* value() { return inputs_[0]; } 2552 2553 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)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: LIsConstructCallAndBranch(LOperand * temp)2564 explicit LIsConstructCallAndBranch(LOperand* temp) { 2565 temps_[0] = temp; 2566 } 2567 temp()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: LOsrEntry()2577 LOsrEntry() {} 2578 HasInterestingComment(LCodeGen * gen)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: LStackCheck(LOperand * context)2588 explicit LStackCheck(LOperand* context) { 2589 inputs_[0] = context; 2590 } 2591 context()2592 LOperand* context() { return inputs_[0]; } 2593 2594 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") DECLARE_HYDROGEN_ACCESSOR(StackCheck)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: LForInPrepareMap(LOperand * context,LOperand * object)2606 LForInPrepareMap(LOperand* context, LOperand* object) { 2607 inputs_[0] = context; 2608 inputs_[1] = object; 2609 } 2610 context()2611 LOperand* context() { return inputs_[0]; } object()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: LForInCacheArray(LOperand * map)2620 explicit LForInCacheArray(LOperand* map) { 2621 inputs_[0] = map; 2622 } 2623 map()2624 LOperand* map() { return inputs_[0]; } 2625 2626 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array") 2627 idx()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: LCheckMapValue(LOperand * value,LOperand * map)2636 LCheckMapValue(LOperand* value, LOperand* map) { 2637 inputs_[0] = value; 2638 inputs_[1] = map; 2639 } 2640 value()2641 LOperand* value() { return inputs_[0]; } map()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: LLoadFieldByIndex(LOperand * object,LOperand * index)2650 LLoadFieldByIndex(LOperand* object, LOperand* index) { 2651 inputs_[0] = object; 2652 inputs_[1] = index; 2653 } 2654 object()2655 LOperand* object() { return inputs_[0]; } index()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: LStoreFrameContext(LOperand * context)2664 explicit LStoreFrameContext(LOperand* context) { 2665 inputs_[0] = context; 2666 } 2667 context()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: LAllocateBlockContext(LOperand * context,LOperand * function)2676 LAllocateBlockContext(LOperand* context, LOperand* function) { 2677 inputs_[0] = context; 2678 inputs_[1] = function; 2679 } 2680 context()2681 LOperand* context() { return inputs_[0]; } function()2682 LOperand* function() { return inputs_[1]; } 2683 scope_info()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: LPlatformChunk(CompilationInfo * info,HGraph * graph)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: LChunkBuilder(CompilationInfo * info,HGraph * graph,LAllocator * allocator)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