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