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