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