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