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