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