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