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