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