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