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