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