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