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