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