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