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