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