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