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