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