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