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