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