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