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