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