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