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