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