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