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