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