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