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