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