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