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