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