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