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