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