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