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