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