The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / mips / lithium-mips.h @ f230a1cf

History | View | Annotate | Download (80.6 KB)

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_MIPS_LITHIUM_MIPS_H_
29
#define V8_MIPS_LITHIUM_MIPS_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

    
37
namespace v8 {
38
namespace internal {
39

    
40
// Forward declarations.
41
class 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(CheckMaps)                                  \
67
  V(CheckMapValue)                              \
68
  V(CheckNonSmi)                                \
69
  V(CheckSmi)                                   \
70
  V(CheckValue)                                 \
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(InstructionGap)                             \
109
  V(Integer32ToDouble)                          \
110
  V(Integer32ToSmi)                             \
111
  V(InvokeFunction)                             \
112
  V(IsConstructCallAndBranch)                   \
113
  V(IsObjectAndBranch)                          \
114
  V(IsStringAndBranch)                          \
115
  V(IsSmiAndBranch)                             \
116
  V(IsUndetectableAndBranch)                    \
117
  V(Label)                                      \
118
  V(LazyBailout)                                \
119
  V(LoadContextSlot)                            \
120
  V(LoadExternalArrayPointer)                   \
121
  V(LoadRoot)                                   \
122
  V(LoadFieldByIndex)                           \
123
  V(LoadFunctionPrototype)                      \
124
  V(LoadGlobalCell)                             \
125
  V(LoadGlobalGeneric)                          \
126
  V(LoadKeyed)                                  \
127
  V(LoadKeyedGeneric)                           \
128
  V(LoadNamedField)                             \
129
  V(LoadNamedGeneric)                           \
130
  V(MapEnumLength)                              \
131
  V(MathAbs)                                    \
132
  V(MathCos)                                    \
133
  V(MathExp)                                    \
134
  V(MathFloor)                                  \
135
  V(MathFloorOfDiv)                             \
136
  V(MathLog)                                    \
137
  V(MathMinMax)                                 \
138
  V(MathPowHalf)                                \
139
  V(MathRound)                                  \
140
  V(MathSin)                                    \
141
  V(MathSqrt)                                   \
142
  V(MathTan)                                    \
143
  V(ModI)                                       \
144
  V(MulI)                                       \
145
  V(MultiplyAddD)                               \
146
  V(NumberTagD)                                 \
147
  V(NumberTagI)                                 \
148
  V(NumberTagU)                                 \
149
  V(NumberUntagD)                               \
150
  V(OsrEntry)                                   \
151
  V(OuterContext)                               \
152
  V(Parameter)                                  \
153
  V(Power)                                      \
154
  V(PushArgument)                               \
155
  V(Random)                                     \
156
  V(RegExpLiteral)                              \
157
  V(Return)                                     \
158
  V(SeqStringSetChar)                           \
159
  V(ShiftI)                                     \
160
  V(SmiTag)                                     \
161
  V(SmiUntag)                                   \
162
  V(StackCheck)                                 \
163
  V(StoreCodeEntry)                             \
164
  V(StoreContextSlot)                           \
165
  V(StoreGlobalCell)                            \
166
  V(StoreGlobalGeneric)                         \
167
  V(StoreKeyed)                                 \
168
  V(StoreKeyedGeneric)                          \
169
  V(StoreNamedField)                            \
170
  V(StoreNamedGeneric)                          \
171
  V(StringAdd)                                  \
172
  V(StringCharCodeAt)                           \
173
  V(StringCharFromCode)                         \
174
  V(StringCompareAndBranch)                     \
175
  V(SubI)                                       \
176
  V(TaggedToI)                                  \
177
  V(ThisFunction)                               \
178
  V(Throw)                                      \
179
  V(ToFastProperties)                           \
180
  V(TransitionElementsKind)                     \
181
  V(TrapAllocationMemento)                      \
182
  V(Typeof)                                     \
183
  V(TypeofIsAndBranch)                          \
184
  V(Uint32ToDouble)                             \
185
  V(UnknownOSRValue)                            \
186
  V(ValueOf)                                    \
187
  V(WrapReceiver)
188

    
189
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
190
  virtual Opcode opcode() const V8_FINAL V8_OVERRIDE {                      \
191
    return LInstruction::k##type;                                           \
192
  }                                                                         \
193
  virtual void CompileToNative(LCodeGen* generator) V8_FINAL V8_OVERRIDE;   \
194
  virtual const char* Mnemonic() const V8_FINAL V8_OVERRIDE {               \
195
    return mnemonic;                                                        \
196
  }                                                                         \
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

    
209
class LInstruction : public ZoneObject {
210
 public:
211
  LInstruction()
212
      : environment_(NULL),
213
        hydrogen_value_(NULL),
214
        bit_field_(IsCallBits::encode(false)) {
215
  }
216

    
217
  virtual ~LInstruction() {}
218

    
219
  virtual void CompileToNative(LCodeGen* generator) = 0;
220
  virtual const char* Mnemonic() const = 0;
221
  virtual void PrintTo(StringStream* stream);
222
  virtual void PrintDataTo(StringStream* stream);
223
  virtual void PrintOutputOperandTo(StringStream* stream);
224

    
225
  enum Opcode {
226
    // Declare a unique enum value for each instruction.
227
#define DECLARE_OPCODE(type) k##type,
228
    LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
229
    kNumberOfInstructions
230
#undef DECLARE_OPCODE
231
  };
232

    
233
  virtual Opcode opcode() const = 0;
234

    
235
  // Declare non-virtual type testers for all leaf IR classes.
236
#define DECLARE_PREDICATE(type) \
237
  bool Is##type() const { return opcode() == k##type; }
238
  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
239
#undef DECLARE_PREDICATE
240

    
241
  // Declare virtual predicates for instructions that don't have
242
  // an opcode.
243
  virtual bool IsGap() const { return false; }
244

    
245
  virtual bool IsControl() const { return false; }
246

    
247
  void set_environment(LEnvironment* env) { environment_ = env; }
248
  LEnvironment* environment() const { return environment_; }
249
  bool HasEnvironment() const { return environment_ != NULL; }
250

    
251
  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
252
  LPointerMap* pointer_map() const { return pointer_map_.get(); }
253
  bool HasPointerMap() const { return pointer_map_.is_set(); }
254

    
255
  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
256
  HValue* hydrogen_value() const { return hydrogen_value_; }
257

    
258
  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
259

    
260
  void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
261
  bool IsCall() const { return IsCallBits::decode(bit_field_); }
262

    
263
  // Interface to the register allocator and iterators.
264
  bool ClobbersTemps() const { return IsCall(); }
265
  bool ClobbersRegisters() const { return IsCall(); }
266
  virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
267

    
268
  // Interface to the register allocator and iterators.
269
  bool IsMarkedAsCall() const { return IsCall(); }
270

    
271
  virtual bool HasResult() const = 0;
272
  virtual LOperand* result() const = 0;
273

    
274
  LOperand* FirstInput() { return InputAt(0); }
275
  LOperand* Output() { return HasResult() ? result() : NULL; }
276

    
277
  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
278

    
279
#ifdef DEBUG
280
  void VerifyCall();
281
#endif
282

    
283
 private:
284
  // Iterator interface.
285
  friend class InputIterator;
286
  virtual int InputCount() = 0;
287
  virtual LOperand* InputAt(int i) = 0;
288

    
289
  friend class TempIterator;
290
  virtual int TempCount() = 0;
291
  virtual LOperand* TempAt(int i) = 0;
292

    
293
  class IsCallBits: public BitField<bool, 0, 1> {};
294

    
295
  LEnvironment* environment_;
296
  SetOncePointer<LPointerMap> pointer_map_;
297
  HValue* hydrogen_value_;
298
  int bit_field_;
299
};
300

    
301

    
302
// R = number of result operands (0 or 1).
303
// I = number of input operands.
304
// T = number of temporary operands.
305
template<int R, int I, int T>
306
class LTemplateInstruction : public LInstruction {
307
 public:
308
  // Allow 0 or 1 output operands.
309
  STATIC_ASSERT(R == 0 || R == 1);
310
  virtual bool HasResult() const V8_FINAL V8_OVERRIDE {
311
    return R != 0 && result() != NULL;
312
  }
313
  void set_result(LOperand* operand) { results_[0] = operand; }
314
  LOperand* result() const { return results_[0]; }
315

    
316
 protected:
317
  EmbeddedContainer<LOperand*, R> results_;
318
  EmbeddedContainer<LOperand*, I> inputs_;
319
  EmbeddedContainer<LOperand*, T> temps_;
320

    
321
 private:
322
  virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
323
  virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
324

    
325
  virtual int TempCount() V8_FINAL V8_OVERRIDE { return T; }
326
  virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return temps_[i]; }
327
};
328

    
329

    
330
class LGap : public LTemplateInstruction<0, 0, 0> {
331
 public:
332
  explicit LGap(HBasicBlock* block)
333
      : block_(block) {
334
    parallel_moves_[BEFORE] = NULL;
335
    parallel_moves_[START] = NULL;
336
    parallel_moves_[END] = NULL;
337
    parallel_moves_[AFTER] = NULL;
338
  }
339

    
340
  // Can't use the DECLARE-macro here because of sub-classes.
341
  virtual bool IsGap() const V8_FINAL V8_OVERRIDE { return true; }
342
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
343
  static LGap* cast(LInstruction* instr) {
344
    ASSERT(instr->IsGap());
345
    return reinterpret_cast<LGap*>(instr);
346
  }
347

    
348
  bool IsRedundant() const;
349

    
350
  HBasicBlock* block() const { return block_; }
351

    
352
  enum InnerPosition {
353
    BEFORE,
354
    START,
355
    END,
356
    AFTER,
357
    FIRST_INNER_POSITION = BEFORE,
358
    LAST_INNER_POSITION = AFTER
359
  };
360

    
361
  LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone)  {
362
    if (parallel_moves_[pos] == NULL) {
363
      parallel_moves_[pos] = new(zone) LParallelMove(zone);
364
    }
365
    return parallel_moves_[pos];
366
  }
367

    
368
  LParallelMove* GetParallelMove(InnerPosition pos)  {
369
    return parallel_moves_[pos];
370
  }
371

    
372
 private:
373
  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
374
  HBasicBlock* block_;
375
};
376

    
377

    
378
class LInstructionGap V8_FINAL : public LGap {
379
 public:
380
  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
381

    
382
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
383
    return !IsRedundant();
384
  }
385

    
386
  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
387
};
388

    
389

    
390
class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
391
 public:
392
  explicit LGoto(HBasicBlock* block) : block_(block) { }
393

    
394
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
395
  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
396
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
397
  virtual bool IsControl() const V8_OVERRIDE { return true; }
398

    
399
  int block_id() const { return block_->block_id(); }
400

    
401
 private:
402
  HBasicBlock* block_;
403
};
404

    
405

    
406
class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
407
 public:
408
  LLazyBailout() : gap_instructions_size_(0) { }
409

    
410
  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
411

    
412
  void set_gap_instructions_size(int gap_instructions_size) {
413
    gap_instructions_size_ = gap_instructions_size;
414
  }
415
  int gap_instructions_size() { return gap_instructions_size_; }
416

    
417
 private:
418
  int gap_instructions_size_;
419
};
420

    
421

    
422
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
423
 public:
424
  explicit LDummyUse(LOperand* value) {
425
    inputs_[0] = value;
426
  }
427
  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
428
};
429

    
430

    
431
class LDeoptimize V8_FINAL : public LTemplateInstruction<0, 0, 0> {
432
 public:
433
  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
434
  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
435
};
436

    
437

    
438
class LLabel V8_FINAL : public LGap {
439
 public:
440
  explicit LLabel(HBasicBlock* block)
441
      : LGap(block), replacement_(NULL) { }
442

    
443
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
444
    return false;
445
  }
446
  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
447

    
448
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
449

    
450
  int block_id() const { return block()->block_id(); }
451
  bool is_loop_header() const { return block()->IsLoopHeader(); }
452
  bool is_osr_entry() const { return block()->is_osr_entry(); }
453
  Label* label() { return &label_; }
454
  LLabel* replacement() const { return replacement_; }
455
  void set_replacement(LLabel* label) { replacement_ = label; }
456
  bool HasReplacement() const { return replacement_ != NULL; }
457

    
458
 private:
459
  Label label_;
460
  LLabel* replacement_;
461
};
462

    
463

    
464
class LParameter V8_FINAL : public LTemplateInstruction<1, 0, 0> {
465
 public:
466
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
467
    return false;
468
  }
469
  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
470
};
471

    
472

    
473
class LCallStub V8_FINAL : public LTemplateInstruction<1, 1, 0> {
474
 public:
475
  explicit LCallStub(LOperand* context) {
476
    inputs_[0] = context;
477
  }
478

    
479
  LOperand* context() { return inputs_[0]; }
480

    
481
  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
482
  DECLARE_HYDROGEN_ACCESSOR(CallStub)
483

    
484
  TranscendentalCache::Type transcendental_type() {
485
    return hydrogen()->transcendental_type();
486
  }
487
};
488

    
489

    
490
class LUnknownOSRValue V8_FINAL : public LTemplateInstruction<1, 0, 0> {
491
 public:
492
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
493
    return false;
494
  }
495
  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
496
};
497

    
498

    
499
template<int I, int T>
500
class LControlInstruction : public LTemplateInstruction<0, I, T> {
501
 public:
502
  LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
503

    
504
  virtual bool IsControl() const V8_FINAL V8_OVERRIDE { return true; }
505

    
506
  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
507
  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
508

    
509
  int TrueDestination(LChunk* chunk) {
510
    return chunk->LookupDestination(true_block_id());
511
  }
512
  int FalseDestination(LChunk* chunk) {
513
    return chunk->LookupDestination(false_block_id());
514
  }
515

    
516
  Label* TrueLabel(LChunk* chunk) {
517
    if (true_label_ == NULL) {
518
      true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
519
    }
520
    return true_label_;
521
  }
522
  Label* FalseLabel(LChunk* chunk) {
523
    if (false_label_ == NULL) {
524
      false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
525
    }
526
    return false_label_;
527
  }
528

    
529
 protected:
530
  int true_block_id() { return SuccessorAt(0)->block_id(); }
531
  int false_block_id() { return SuccessorAt(1)->block_id(); }
532

    
533
 private:
534
  HControlInstruction* hydrogen() {
535
    return HControlInstruction::cast(this->hydrogen_value());
536
  }
537

    
538
  Label* false_label_;
539
  Label* true_label_;
540
};
541

    
542

    
543
class LWrapReceiver V8_FINAL : public LTemplateInstruction<1, 2, 0> {
544
 public:
545
  LWrapReceiver(LOperand* receiver, LOperand* function) {
546
    inputs_[0] = receiver;
547
    inputs_[1] = function;
548
  }
549

    
550
  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
551

    
552
  LOperand* receiver() { return inputs_[0]; }
553
  LOperand* function() { return inputs_[1]; }
554
};
555

    
556

    
557
class LApplyArguments V8_FINAL : public LTemplateInstruction<1, 4, 0> {
558
 public:
559
  LApplyArguments(LOperand* function,
560
                  LOperand* receiver,
561
                  LOperand* length,
562
                  LOperand* elements) {
563
    inputs_[0] = function;
564
    inputs_[1] = receiver;
565
    inputs_[2] = length;
566
    inputs_[3] = elements;
567
  }
568

    
569
  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
570

    
571
  LOperand* function() { return inputs_[0]; }
572
  LOperand* receiver() { return inputs_[1]; }
573
  LOperand* length() { return inputs_[2]; }
574
  LOperand* elements() { return inputs_[3]; }
575
};
576

    
577

    
578
class LAccessArgumentsAt V8_FINAL : public LTemplateInstruction<1, 3, 0> {
579
 public:
580
  LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
581
    inputs_[0] = arguments;
582
    inputs_[1] = length;
583
    inputs_[2] = index;
584
  }
585

    
586
  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
587

    
588
  LOperand* arguments() { return inputs_[0]; }
589
  LOperand* length() { return inputs_[1]; }
590
  LOperand* index() { return inputs_[2]; }
591

    
592
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
593
};
594

    
595

    
596
class LArgumentsLength V8_FINAL : public LTemplateInstruction<1, 1, 0> {
597
 public:
598
  explicit LArgumentsLength(LOperand* elements) {
599
    inputs_[0] = elements;
600
  }
601

    
602
  LOperand* elements() { return inputs_[0]; }
603

    
604
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
605
};
606

    
607

    
608
class LArgumentsElements V8_FINAL : public LTemplateInstruction<1, 0, 0> {
609
 public:
610
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
611
  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
612
};
613

    
614

    
615
class LModI V8_FINAL : public LTemplateInstruction<1, 2, 3> {
616
 public:
617
  // Used when the right hand is a constant power of 2.
618
  LModI(LOperand* left,
619
        LOperand* right) {
620
    inputs_[0] = left;
621
    inputs_[1] = right;
622
    temps_[0] = NULL;
623
    temps_[1] = NULL;
624
    temps_[2] = NULL;
625
  }
626

    
627
  // Used for the standard case.
628
  LModI(LOperand* left,
629
        LOperand* right,
630
        LOperand* temp,
631
        LOperand* temp2,
632
        LOperand* temp3) {
633
    inputs_[0] = left;
634
    inputs_[1] = right;
635
    temps_[0] = temp;
636
    temps_[1] = temp2;
637
    temps_[2] = temp3;
638
  }
639

    
640
  LOperand* left() { return inputs_[0]; }
641
  LOperand* right() { return inputs_[1]; }
642
  LOperand* temp() { return temps_[0]; }
643
  LOperand* temp2() { return temps_[1]; }
644
  LOperand* temp3() { return temps_[2]; }
645

    
646
  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
647
  DECLARE_HYDROGEN_ACCESSOR(Mod)
648
};
649

    
650

    
651
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
652
 public:
653
  LDivI(LOperand* left, LOperand* right) {
654
    inputs_[0] = left;
655
    inputs_[1] = right;
656
  }
657

    
658
  LOperand* left() { return inputs_[0]; }
659
  LOperand* right() { return inputs_[1]; }
660

    
661
  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
662
  DECLARE_HYDROGEN_ACCESSOR(Div)
663
};
664

    
665

    
666
class LMathFloorOfDiv V8_FINAL : public LTemplateInstruction<1, 2, 1> {
667
 public:
668
  LMathFloorOfDiv(LOperand* left,
669
                  LOperand* right,
670
                  LOperand* temp = NULL) {
671
    inputs_[0] = left;
672
    inputs_[1] = right;
673
    temps_[0] = temp;
674
  }
675

    
676
  LOperand* left() { return inputs_[0]; }
677
  LOperand* right() { return inputs_[1]; }
678
  LOperand* temp() { return temps_[0]; }
679

    
680
  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
681
  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
682
};
683

    
684

    
685
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
686
 public:
687
  LMulI(LOperand* left, LOperand* right) {
688
    inputs_[0] = left;
689
    inputs_[1] = right;
690
  }
691

    
692
  LOperand* left() { return inputs_[0]; }
693
  LOperand* right() { return inputs_[1]; }
694

    
695
  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
696
  DECLARE_HYDROGEN_ACCESSOR(Mul)
697
};
698

    
699

    
700
// Instruction for computing multiplier * multiplicand + addend.
701
class LMultiplyAddD V8_FINAL : public LTemplateInstruction<1, 3, 0> {
702
 public:
703
  LMultiplyAddD(LOperand* addend, LOperand* multiplier,
704
                LOperand* multiplicand) {
705
    inputs_[0] = addend;
706
    inputs_[1] = multiplier;
707
    inputs_[2] = multiplicand;
708
  }
709

    
710
  LOperand* addend() { return inputs_[0]; }
711
  LOperand* multiplier() { return inputs_[1]; }
712
  LOperand* multiplicand() { return inputs_[2]; }
713

    
714
  DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
715
};
716

    
717

    
718
class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> {
719
 public:
720
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
721
};
722

    
723

    
724
class LCompareNumericAndBranch V8_FINAL : public LControlInstruction<2, 0> {
725
 public:
726
  LCompareNumericAndBranch(LOperand* left, LOperand* right) {
727
    inputs_[0] = left;
728
    inputs_[1] = right;
729
  }
730

    
731
  LOperand* left() { return inputs_[0]; }
732
  LOperand* right() { return inputs_[1]; }
733

    
734
  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
735
                               "compare-numeric-and-branch")
736
  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
737

    
738
  Token::Value op() const { return hydrogen()->token(); }
739
  bool is_double() const {
740
    return hydrogen()->representation().IsDouble();
741
  }
742

    
743
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
744
};
745

    
746

    
747
class LMathFloor V8_FINAL : public LTemplateInstruction<1, 1, 1> {
748
 public:
749
  LMathFloor(LOperand* value, LOperand* temp) {
750
    inputs_[0] = value;
751
    temps_[0] = temp;
752
  }
753

    
754
  LOperand* value() { return inputs_[0]; }
755
  LOperand* temp() { return temps_[0]; }
756

    
757
  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
758
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
759
};
760

    
761

    
762
class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 1> {
763
 public:
764
  LMathRound(LOperand* value, LOperand* temp) {
765
    inputs_[0] = value;
766
    temps_[0] = temp;
767
  }
768

    
769
  LOperand* value() { return inputs_[0]; }
770
  LOperand* temp() { return temps_[0]; }
771

    
772
  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
773
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
774
};
775

    
776

    
777
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
778
 public:
779
  LMathAbs(LOperand* context, LOperand* value) {
780
    inputs_[1] = context;
781
    inputs_[0] = value;
782
  }
783

    
784
  LOperand* context() { return inputs_[1]; }
785
  LOperand* value() { return inputs_[0]; }
786

    
787
  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
788
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
789
};
790

    
791

    
792
class LMathLog V8_FINAL : public LTemplateInstruction<1, 1, 0> {
793
 public:
794
  explicit LMathLog(LOperand* value) {
795
    inputs_[0] = value;
796
  }
797

    
798
  LOperand* value() { return inputs_[0]; }
799

    
800
  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
801
};
802

    
803

    
804
class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
805
 public:
806
  explicit LMathSin(LOperand* value) {
807
    inputs_[0] = value;
808
  }
809

    
810
  LOperand* value() { return inputs_[0]; }
811

    
812
  DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
813
};
814

    
815

    
816
class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
817
 public:
818
  explicit LMathCos(LOperand* value) {
819
    inputs_[0] = value;
820
  }
821

    
822
  LOperand* value() { return inputs_[0]; }
823

    
824
  DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
825
};
826

    
827

    
828
class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
829
 public:
830
  explicit LMathTan(LOperand* value) {
831
    inputs_[0] = value;
832
  }
833

    
834
  LOperand* value() { return inputs_[0]; }
835

    
836
  DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
837
};
838

    
839

    
840
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 3> {
841
 public:
842
  LMathExp(LOperand* value,
843
           LOperand* double_temp,
844
           LOperand* temp1,
845
           LOperand* temp2) {
846
    inputs_[0] = value;
847
    temps_[0] = temp1;
848
    temps_[1] = temp2;
849
    temps_[2] = double_temp;
850
    ExternalReference::InitializeMathExpData();
851
  }
852

    
853
  LOperand* value() { return inputs_[0]; }
854
  LOperand* temp1() { return temps_[0]; }
855
  LOperand* temp2() { return temps_[1]; }
856
  LOperand* double_temp() { return temps_[2]; }
857

    
858
  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
859
};
860

    
861

    
862
class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
863
 public:
864
  explicit LMathSqrt(LOperand* value) {
865
    inputs_[0] = value;
866
  }
867

    
868
  LOperand* value() { return inputs_[0]; }
869

    
870
  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
871
};
872

    
873

    
874
class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
875
 public:
876
  LMathPowHalf(LOperand* value, LOperand* temp) {
877
    inputs_[0] = value;
878
    temps_[0] = temp;
879
  }
880

    
881
  LOperand* value() { return inputs_[0]; }
882
  LOperand* temp() { return temps_[0]; }
883

    
884
  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
885
};
886

    
887

    
888
class LCmpObjectEqAndBranch V8_FINAL : public LControlInstruction<2, 0> {
889
 public:
890
  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
891
    inputs_[0] = left;
892
    inputs_[1] = right;
893
  }
894

    
895
  LOperand* left() { return inputs_[0]; }
896
  LOperand* right() { return inputs_[1]; }
897

    
898
  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
899
  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
900
};
901

    
902

    
903
class LCmpHoleAndBranch V8_FINAL : public LControlInstruction<1, 0> {
904
 public:
905
  explicit LCmpHoleAndBranch(LOperand* object) {
906
    inputs_[0] = object;
907
  }
908

    
909
  LOperand* object() { return inputs_[0]; }
910

    
911
  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
912
  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
913
};
914

    
915

    
916
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
917
 public:
918
  LIsObjectAndBranch(LOperand* value, LOperand* temp) {
919
    inputs_[0] = value;
920
    temps_[0] = temp;
921
  }
922

    
923
  LOperand* value() { return inputs_[0]; }
924
  LOperand* temp() { return temps_[0]; }
925

    
926
  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
927
  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
928

    
929
  virtual void PrintDataTo(StringStream* stream);
930
};
931

    
932

    
933
class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
934
 public:
935
  LIsStringAndBranch(LOperand* value, LOperand* temp) {
936
    inputs_[0] = value;
937
    temps_[0] = temp;
938
  }
939

    
940
  LOperand* value() { return inputs_[0]; }
941
  LOperand* temp() { return temps_[0]; }
942

    
943
  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
944
  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
945

    
946
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
947
};
948

    
949

    
950
class LIsSmiAndBranch V8_FINAL : public LControlInstruction<1, 0> {
951
 public:
952
  explicit LIsSmiAndBranch(LOperand* value) {
953
    inputs_[0] = value;
954
  }
955

    
956
  LOperand* value() { return inputs_[0]; }
957

    
958
  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
959
  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
960

    
961
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
962
};
963

    
964

    
965
class LIsUndetectableAndBranch V8_FINAL : public LControlInstruction<1, 1> {
966
 public:
967
  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
968
    inputs_[0] = value;
969
    temps_[0] = temp;
970
  }
971

    
972
  LOperand* value() { return inputs_[0]; }
973
  LOperand* temp() { return temps_[0]; }
974

    
975
  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
976
                               "is-undetectable-and-branch")
977
  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
978

    
979
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
980
};
981

    
982

    
983
class LStringCompareAndBranch V8_FINAL : public LControlInstruction<3, 0> {
984
 public:
985
  LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
986
    inputs_[0] = context;
987
    inputs_[1] = left;
988
    inputs_[2] = right;
989
  }
990

    
991
  LOperand* context() { return inputs_[0]; }
992
  LOperand* left() { return inputs_[1]; }
993
  LOperand* right() { return inputs_[2]; }
994

    
995
  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
996
                               "string-compare-and-branch")
997
  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
998

    
999
  Token::Value op() const { return hydrogen()->token(); }
1000

    
1001
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1002
};
1003

    
1004

    
1005
class LHasInstanceTypeAndBranch V8_FINAL : public LControlInstruction<1, 0> {
1006
 public:
1007
  explicit LHasInstanceTypeAndBranch(LOperand* value) {
1008
    inputs_[0] = value;
1009
  }
1010

    
1011
  LOperand* value() { return inputs_[0]; }
1012

    
1013
  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1014
                               "has-instance-type-and-branch")
1015
  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1016

    
1017
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1018
};
1019

    
1020

    
1021
class LGetCachedArrayIndex V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1022
 public:
1023
  explicit LGetCachedArrayIndex(LOperand* value) {
1024
    inputs_[0] = value;
1025
  }
1026

    
1027
  LOperand* value() { return inputs_[0]; }
1028

    
1029
  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1030
  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1031
};
1032

    
1033

    
1034
class LHasCachedArrayIndexAndBranch V8_FINAL
1035
    : public LControlInstruction<1, 0> {
1036
 public:
1037
  explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
1038
    inputs_[0] = value;
1039
  }
1040

    
1041
  LOperand* value() { return inputs_[0]; }
1042

    
1043
  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1044
                               "has-cached-array-index-and-branch")
1045
  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
1046

    
1047
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1048
};
1049

    
1050

    
1051
class LClassOfTestAndBranch V8_FINAL : public LControlInstruction<1, 1> {
1052
 public:
1053
  LClassOfTestAndBranch(LOperand* value, LOperand* temp) {
1054
    inputs_[0] = value;
1055
    temps_[0] = temp;
1056
  }
1057

    
1058
  LOperand* value() { return inputs_[0]; }
1059
  LOperand* temp() { return temps_[0]; }
1060

    
1061
  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1062
                               "class-of-test-and-branch")
1063
  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1064

    
1065
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1066
};
1067

    
1068

    
1069
class LCmpT V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1070
 public:
1071
  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1072
    inputs_[0] = context;
1073
    inputs_[1] = left;
1074
    inputs_[2] = right;
1075
  }
1076

    
1077
  LOperand* context() { return inputs_[0]; }
1078
  LOperand* left() { return inputs_[1]; }
1079
  LOperand* right() { return inputs_[2]; }
1080

    
1081
  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1082
  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1083

    
1084
  Token::Value op() const { return hydrogen()->token(); }
1085
};
1086

    
1087

    
1088
class LInstanceOf V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1089
 public:
1090
  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1091
    inputs_[0] = context;
1092
    inputs_[1] = left;
1093
    inputs_[2] = right;
1094
  }
1095

    
1096
  LOperand* context() { return inputs_[0]; }
1097
  LOperand* left() { return inputs_[1]; }
1098
  LOperand* right() { return inputs_[2]; }
1099

    
1100
  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1101
};
1102

    
1103

    
1104
class LInstanceOfKnownGlobal V8_FINAL : public LTemplateInstruction<1, 2, 1> {
1105
 public:
1106
  LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
1107
    inputs_[0] = context;
1108
    inputs_[1] = value;
1109
    temps_[0] = temp;
1110
  }
1111

    
1112
  LOperand* context() { return inputs_[0]; }
1113
  LOperand* value() { return inputs_[1]; }
1114
  LOperand* temp() { return temps_[0]; }
1115

    
1116
  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1117
                               "instance-of-known-global")
1118
  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1119

    
1120
  Handle<JSFunction> function() const { return hydrogen()->function(); }
1121
  LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
1122
    return lazy_deopt_env_;
1123
  }
1124
  virtual void SetDeferredLazyDeoptimizationEnvironment(
1125
      LEnvironment* env) V8_OVERRIDE {
1126
    lazy_deopt_env_ = env;
1127
  }
1128

    
1129
 private:
1130
  LEnvironment* lazy_deopt_env_;
1131
};
1132

    
1133

    
1134
class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1135
 public:
1136
  LBoundsCheck(LOperand* index, LOperand* length) {
1137
    inputs_[0] = index;
1138
    inputs_[1] = length;
1139
  }
1140

    
1141
  LOperand* index() { return inputs_[0]; }
1142
  LOperand* length() { return inputs_[1]; }
1143

    
1144
  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1145
  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1146
};
1147

    
1148

    
1149
class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1150
 public:
1151
  LBitI(LOperand* left, LOperand* right) {
1152
    inputs_[0] = left;
1153
    inputs_[1] = right;
1154
  }
1155

    
1156
  LOperand* left() { return inputs_[0]; }
1157
  LOperand* right() { return inputs_[1]; }
1158

    
1159
  Token::Value op() const { return hydrogen()->op(); }
1160

    
1161
  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1162
  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1163
};
1164

    
1165

    
1166
class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1167
 public:
1168
  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1169
      : op_(op), can_deopt_(can_deopt) {
1170
    inputs_[0] = left;
1171
    inputs_[1] = right;
1172
  }
1173

    
1174
  Token::Value op() const { return op_; }
1175
  LOperand* left() { return inputs_[0]; }
1176
  LOperand* right() { return inputs_[1]; }
1177
  bool can_deopt() const { return can_deopt_; }
1178

    
1179
  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1180

    
1181
 private:
1182
  Token::Value op_;
1183
  bool can_deopt_;
1184
};
1185

    
1186

    
1187
class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1188
 public:
1189
  LSubI(LOperand* left, LOperand* right) {
1190
    inputs_[0] = left;
1191
    inputs_[1] = right;
1192
  }
1193

    
1194
  LOperand* left() { return inputs_[0]; }
1195
  LOperand* right() { return inputs_[1]; }
1196

    
1197
  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1198
  DECLARE_HYDROGEN_ACCESSOR(Sub)
1199
};
1200

    
1201

    
1202
class LConstantI V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1203
 public:
1204
  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1205
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1206

    
1207
  int32_t value() const { return hydrogen()->Integer32Value(); }
1208
};
1209

    
1210

    
1211
class LConstantS V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1212
 public:
1213
  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1214
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1215

    
1216
  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1217
};
1218

    
1219

    
1220
class LConstantD V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1221
 public:
1222
  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1223
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1224

    
1225
  double value() const { return hydrogen()->DoubleValue(); }
1226
};
1227

    
1228

    
1229
class LConstantE V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1230
 public:
1231
  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1232
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1233

    
1234
  ExternalReference value() const {
1235
    return hydrogen()->ExternalReferenceValue();
1236
  }
1237
};
1238

    
1239

    
1240
class LConstantT V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1241
 public:
1242
  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1243
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1244

    
1245
  Handle<Object> value(Isolate* isolate) const {
1246
    return hydrogen()->handle(isolate);
1247
  }
1248
};
1249

    
1250

    
1251
class LBranch V8_FINAL : public LControlInstruction<1, 0> {
1252
 public:
1253
  explicit LBranch(LOperand* value) {
1254
    inputs_[0] = value;
1255
  }
1256

    
1257
  LOperand* value() { return inputs_[0]; }
1258

    
1259
  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1260
  DECLARE_HYDROGEN_ACCESSOR(Branch)
1261

    
1262
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1263
};
1264

    
1265

    
1266
class LCmpMapAndBranch V8_FINAL : public LControlInstruction<1, 1> {
1267
 public:
1268
  LCmpMapAndBranch(LOperand* value, LOperand* temp) {
1269
    inputs_[0] = value;
1270
    temps_[0] = temp;
1271
  }
1272

    
1273
  LOperand* value() { return inputs_[0]; }
1274
  LOperand* temp() { return temps_[0]; }
1275

    
1276
  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1277
  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1278

    
1279
  Handle<Map> map() const { return hydrogen()->map().handle(); }
1280
};
1281

    
1282

    
1283
class LMapEnumLength V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1284
 public:
1285
  explicit LMapEnumLength(LOperand* value) {
1286
    inputs_[0] = value;
1287
  }
1288

    
1289
  LOperand* value() { return inputs_[0]; }
1290

    
1291
  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1292
};
1293

    
1294

    
1295
class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1296
 public:
1297
  explicit LElementsKind(LOperand* value) {
1298
    inputs_[0] = value;
1299
  }
1300

    
1301
  LOperand* value() { return inputs_[0]; }
1302

    
1303
  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
1304
  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
1305
};
1306

    
1307

    
1308
class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1309
 public:
1310
  LValueOf(LOperand* value, LOperand* temp) {
1311
    inputs_[0] = value;
1312
    temps_[0] = temp;
1313
  }
1314

    
1315
  LOperand* value() { return inputs_[0]; }
1316
  LOperand* temp() { return temps_[0]; }
1317

    
1318
  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1319
  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1320
};
1321

    
1322

    
1323
class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1324
 public:
1325
  LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
1326
    inputs_[0] = date;
1327
    temps_[0] = temp;
1328
  }
1329

    
1330
  LOperand* date() { return inputs_[0]; }
1331
  LOperand* temp() { return temps_[0]; }
1332
  Smi* index() const { return index_; }
1333

    
1334
  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1335
  DECLARE_HYDROGEN_ACCESSOR(DateField)
1336

    
1337
 private:
1338
  Smi* index_;
1339
};
1340

    
1341

    
1342
class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1343
 public:
1344
  LSeqStringSetChar(String::Encoding encoding,
1345
                    LOperand* string,
1346
                    LOperand* index,
1347
                    LOperand* value) : encoding_(encoding) {
1348
    inputs_[0] = string;
1349
    inputs_[1] = index;
1350
    inputs_[2] = value;
1351
  }
1352

    
1353
  String::Encoding encoding() { return encoding_; }
1354
  LOperand* string() { return inputs_[0]; }
1355
  LOperand* index() { return inputs_[1]; }
1356
  LOperand* value() { return inputs_[2]; }
1357

    
1358
  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1359
  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1360

    
1361
 private:
1362
  String::Encoding encoding_;
1363
};
1364

    
1365

    
1366
class LThrow V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1367
 public:
1368
  LThrow(LOperand* context, LOperand* value) {
1369
    inputs_[0] = context;
1370
    inputs_[1] = value;
1371
  }
1372

    
1373
  LOperand* context() { return inputs_[0]; }
1374
  LOperand* value() { return inputs_[1]; }
1375

    
1376
  DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1377
};
1378

    
1379

    
1380
class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1381
 public:
1382
  LAddI(LOperand* left, LOperand* right) {
1383
    inputs_[0] = left;
1384
    inputs_[1] = right;
1385
  }
1386

    
1387
  LOperand* left() { return inputs_[0]; }
1388
  LOperand* right() { return inputs_[1]; }
1389

    
1390
  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1391
  DECLARE_HYDROGEN_ACCESSOR(Add)
1392
};
1393

    
1394

    
1395
class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1396
 public:
1397
  LMathMinMax(LOperand* left, LOperand* right) {
1398
    inputs_[0] = left;
1399
    inputs_[1] = right;
1400
  }
1401

    
1402
  LOperand* left() { return inputs_[0]; }
1403
  LOperand* right() { return inputs_[1]; }
1404

    
1405
  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1406
  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1407
};
1408

    
1409

    
1410
class LPower V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1411
 public:
1412
  LPower(LOperand* left, LOperand* right) {
1413
    inputs_[0] = left;
1414
    inputs_[1] = right;
1415
  }
1416

    
1417
  LOperand* left() { return inputs_[0]; }
1418
  LOperand* right() { return inputs_[1]; }
1419

    
1420
  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1421
  DECLARE_HYDROGEN_ACCESSOR(Power)
1422
};
1423

    
1424

    
1425
class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
1426
 public:
1427
  LRandom(LOperand* global_object,
1428
          LOperand* scratch,
1429
          LOperand* scratch2,
1430
          LOperand* scratch3) {
1431
    inputs_[0] = global_object;
1432
    temps_[0] = scratch;
1433
    temps_[1] = scratch2;
1434
    temps_[2] = scratch3;
1435
  }
1436

    
1437
  LOperand* global_object() const { return inputs_[0]; }
1438
  LOperand* scratch() const { return temps_[0]; }
1439
  LOperand* scratch2() const { return temps_[1]; }
1440
  LOperand* scratch3() const { return temps_[2]; }
1441

    
1442
  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
1443
  DECLARE_HYDROGEN_ACCESSOR(Random)
1444
};
1445

    
1446

    
1447
class LArithmeticD V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1448
 public:
1449
  LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1450
      : op_(op) {
1451
    inputs_[0] = left;
1452
    inputs_[1] = right;
1453
  }
1454

    
1455
  Token::Value op() const { return op_; }
1456
  LOperand* left() { return inputs_[0]; }
1457
  LOperand* right() { return inputs_[1]; }
1458

    
1459
  virtual Opcode opcode() const V8_OVERRIDE {
1460
    return LInstruction::kArithmeticD;
1461
  }
1462
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1463
  virtual const char* Mnemonic() const V8_OVERRIDE;
1464

    
1465
 private:
1466
  Token::Value op_;
1467
};
1468

    
1469

    
1470
class LArithmeticT V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1471
 public:
1472
  LArithmeticT(Token::Value op,
1473
               LOperand* context,
1474
               LOperand* left,
1475
               LOperand* right)
1476
      : op_(op) {
1477
    inputs_[0] = context;
1478
    inputs_[1] = left;
1479
    inputs_[2] = right;
1480
  }
1481

    
1482
  LOperand* context() { return inputs_[0]; }
1483
  LOperand* left() { return inputs_[1]; }
1484
  LOperand* right() { return inputs_[2]; }
1485
  Token::Value op() const { return op_; }
1486

    
1487
  virtual Opcode opcode() const V8_FINAL  { return LInstruction::kArithmeticT; }
1488
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1489
  virtual const char* Mnemonic() const V8_OVERRIDE;
1490

    
1491
 private:
1492
  Token::Value op_;
1493
};
1494

    
1495

    
1496
class LReturn V8_FINAL : public LTemplateInstruction<0, 3, 0> {
1497
 public:
1498
  LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) {
1499
    inputs_[0] = value;
1500
    inputs_[1] = context;
1501
    inputs_[2] = parameter_count;
1502
  }
1503

    
1504
  LOperand* value() { return inputs_[0]; }
1505

    
1506
  bool has_constant_parameter_count() {
1507
    return parameter_count()->IsConstantOperand();
1508
  }
1509
  LConstantOperand* constant_parameter_count() {
1510
    ASSERT(has_constant_parameter_count());
1511
    return LConstantOperand::cast(parameter_count());
1512
  }
1513
  LOperand* parameter_count() { return inputs_[2]; }
1514

    
1515
  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1516
};
1517

    
1518

    
1519
class LLoadNamedField V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1520
 public:
1521
  explicit LLoadNamedField(LOperand* object) {
1522
    inputs_[0] = object;
1523
  }
1524

    
1525
  LOperand* object() { return inputs_[0]; }
1526

    
1527
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1528
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1529
};
1530

    
1531

    
1532
class LLoadNamedGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1533
 public:
1534
  LLoadNamedGeneric(LOperand* context, LOperand* object) {
1535
    inputs_[0] = context;
1536
    inputs_[1] = object;
1537
  }
1538

    
1539
  LOperand* context() { return inputs_[0]; }
1540
  LOperand* object() { return inputs_[1]; }
1541

    
1542
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1543
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1544

    
1545
  Handle<Object> name() const { return hydrogen()->name(); }
1546
};
1547

    
1548

    
1549
class LLoadFunctionPrototype V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1550
 public:
1551
  explicit LLoadFunctionPrototype(LOperand* function) {
1552
    inputs_[0] = function;
1553
  }
1554

    
1555
  LOperand* function() { return inputs_[0]; }
1556

    
1557
  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1558
  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1559
};
1560

    
1561

    
1562
class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1563
 public:
1564
  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1565
  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1566

    
1567
  Heap::RootListIndex index() const { return hydrogen()->index(); }
1568
};
1569

    
1570

    
1571
class LLoadExternalArrayPointer V8_FINAL
1572
    : public LTemplateInstruction<1, 1, 0> {
1573
 public:
1574
  explicit LLoadExternalArrayPointer(LOperand* object) {
1575
    inputs_[0] = object;
1576
  }
1577

    
1578
  LOperand* object() { return inputs_[0]; }
1579

    
1580
  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1581
                               "load-external-array-pointer")
1582
};
1583

    
1584

    
1585
class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1586
 public:
1587
  LLoadKeyed(LOperand* elements, LOperand* key) {
1588
    inputs_[0] = elements;
1589
    inputs_[1] = key;
1590
  }
1591

    
1592
  LOperand* elements() { return inputs_[0]; }
1593
  LOperand* key() { return inputs_[1]; }
1594
  ElementsKind elements_kind() const {
1595
    return hydrogen()->elements_kind();
1596
  }
1597
  bool is_external() const {
1598
    return hydrogen()->is_external();
1599
  }
1600

    
1601
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1602
  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1603

    
1604
  virtual void PrintDataTo(StringStream* stream);
1605
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1606
};
1607

    
1608

    
1609
class LLoadKeyedGeneric V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1610
 public:
1611
  LLoadKeyedGeneric(LOperand* context, LOperand* object, LOperand* key) {
1612
    inputs_[0] = context;
1613
    inputs_[1] = object;
1614
    inputs_[2] = key;
1615
  }
1616

    
1617
  LOperand* context() { return inputs_[0]; }
1618
  LOperand* object() { return inputs_[1]; }
1619
  LOperand* key() { return inputs_[2]; }
1620

    
1621
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1622
};
1623

    
1624

    
1625
class LLoadGlobalCell V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1626
 public:
1627
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1628
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1629
};
1630

    
1631

    
1632
class LLoadGlobalGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1633
 public:
1634
  LLoadGlobalGeneric(LOperand* context, LOperand* global_object) {
1635
    inputs_[0] = context;
1636
    inputs_[1] = global_object;
1637
  }
1638

    
1639
  LOperand* context() { return inputs_[0]; }
1640
  LOperand* global_object() { return inputs_[1]; }
1641

    
1642
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1643
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1644

    
1645
  Handle<Object> name() const { return hydrogen()->name(); }
1646
  bool for_typeof() const { return hydrogen()->for_typeof(); }
1647
};
1648

    
1649

    
1650
class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 1> {
1651
 public:
1652
  LStoreGlobalCell(LOperand* value, LOperand* temp) {
1653
    inputs_[0] = value;
1654
    temps_[0] = temp;
1655
  }
1656

    
1657
  LOperand* value() { return inputs_[0]; }
1658
  LOperand* temp() { return temps_[0]; }
1659

    
1660
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1661
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1662
};
1663

    
1664

    
1665
class LStoreGlobalGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
1666
 public:
1667
  LStoreGlobalGeneric(LOperand* context,
1668
                      LOperand* global_object,
1669
                      LOperand* value) {
1670
    inputs_[0] = context;
1671
    inputs_[1] = global_object;
1672
    inputs_[2] = value;
1673
  }
1674

    
1675
  LOperand* context() { return inputs_[0]; }
1676
  LOperand* global_object() { return inputs_[1]; }
1677
  LOperand* value() { return inputs_[2]; }
1678

    
1679
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
1680
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
1681

    
1682
  Handle<Object> name() const { return hydrogen()->name(); }
1683
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1684
};
1685

    
1686

    
1687
class LLoadContextSlot V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1688
 public:
1689
  explicit LLoadContextSlot(LOperand* context) {
1690
    inputs_[0] = context;
1691
  }
1692

    
1693
  LOperand* context() { return inputs_[0]; }
1694

    
1695
  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1696
  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1697

    
1698
  int slot_index() { return hydrogen()->slot_index(); }
1699

    
1700
  virtual void PrintDataTo(StringStream* stream);
1701
};
1702

    
1703

    
1704
class LStoreContextSlot V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1705
 public:
1706
  LStoreContextSlot(LOperand* context, LOperand* value) {
1707
    inputs_[0] = context;
1708
    inputs_[1] = value;
1709
  }
1710

    
1711
  LOperand* context() { return inputs_[0]; }
1712
  LOperand* value() { return inputs_[1]; }
1713

    
1714
  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1715
  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1716

    
1717
  int slot_index() { return hydrogen()->slot_index(); }
1718

    
1719
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1720
};
1721

    
1722

    
1723
class LPushArgument V8_FINAL : public LTemplateInstruction<0, 1, 0> {
1724
 public:
1725
  explicit LPushArgument(LOperand* value) {
1726
    inputs_[0] = value;
1727
  }
1728

    
1729
  LOperand* value() { return inputs_[0]; }
1730

    
1731
  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1732
};
1733

    
1734

    
1735
class LDrop V8_FINAL : public LTemplateInstruction<0, 0, 0> {
1736
 public:
1737
  explicit LDrop(int count) : count_(count) { }
1738

    
1739
  int count() const { return count_; }
1740

    
1741
  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1742

    
1743
 private:
1744
  int count_;
1745
};
1746

    
1747

    
1748
class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
1749
 public:
1750
  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1751
    inputs_[0] = function;
1752
    temps_[0] = code_object;
1753
  }
1754

    
1755
  LOperand* function() { return inputs_[0]; }
1756
  LOperand* code_object() { return temps_[0]; }
1757

    
1758
  virtual void PrintDataTo(StringStream* stream);
1759

    
1760
  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1761
  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1762
};
1763

    
1764

    
1765
class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
1766
 public:
1767
  explicit LInnerAllocatedObject(LOperand* base_object) {
1768
    inputs_[0] = base_object;
1769
  }
1770

    
1771
  LOperand* base_object() { return inputs_[0]; }
1772
  int offset() { return hydrogen()->offset(); }
1773

    
1774
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1775

    
1776
  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
1777
  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
1778
};
1779

    
1780

    
1781
class LThisFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1782
 public:
1783
  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1784
  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1785
};
1786

    
1787

    
1788
class LContext V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1789
 public:
1790
  DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1791
  DECLARE_HYDROGEN_ACCESSOR(Context)
1792
};
1793

    
1794

    
1795
class LOuterContext V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1796
 public:
1797
  explicit LOuterContext(LOperand* context) {
1798
    inputs_[0] = context;
1799
  }
1800

    
1801
  LOperand* context() { return inputs_[0]; }
1802

    
1803
  DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
1804
};
1805

    
1806

    
1807
class LDeclareGlobals V8_FINAL : public LTemplateInstruction<0, 1, 0> {
1808
 public:
1809
  explicit LDeclareGlobals(LOperand* context) {
1810
    inputs_[0] = context;
1811
  }
1812

    
1813
  LOperand* context() { return inputs_[0]; }
1814

    
1815
  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1816
  DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1817
};
1818

    
1819

    
1820
class LGlobalObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1821
 public:
1822
  explicit LGlobalObject(LOperand* context) {
1823
    inputs_[0] = context;
1824
  }
1825

    
1826
  LOperand* context() { return inputs_[0]; }
1827

    
1828
  DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1829
};
1830

    
1831

    
1832
class LGlobalReceiver V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1833
 public:
1834
  explicit LGlobalReceiver(LOperand* global_object) {
1835
    inputs_[0] = global_object;
1836
  }
1837

    
1838
  LOperand* global_object() { return inputs_[0]; }
1839

    
1840
  DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1841
};
1842

    
1843

    
1844
class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1845
 public:
1846
  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1847
  DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1848

    
1849
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1850

    
1851
  Handle<JSFunction> function() { return hydrogen()->function(); }
1852
  int arity() const { return hydrogen()->argument_count() - 1; }
1853
};
1854

    
1855

    
1856
class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1857
 public:
1858
  LInvokeFunction(LOperand* context, LOperand* function) {
1859
    inputs_[0] = context;
1860
    inputs_[1] = function;
1861
  }
1862

    
1863
  LOperand* context() { return inputs_[0]; }
1864
  LOperand* function() { return inputs_[1]; }
1865

    
1866
  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1867
  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1868

    
1869
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1870

    
1871
  int arity() const { return hydrogen()->argument_count() - 1; }
1872
};
1873

    
1874

    
1875
class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1876
 public:
1877
  LCallKeyed(LOperand* context, LOperand* key) {
1878
    inputs_[0] = context;
1879
    inputs_[1] = key;
1880
  }
1881

    
1882
  LOperand* context() { return inputs_[0]; }
1883
  LOperand* key() { return inputs_[1]; }
1884

    
1885
  DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1886
  DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1887

    
1888
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1889

    
1890
  int arity() const { return hydrogen()->argument_count() - 1; }
1891
};
1892

    
1893

    
1894

    
1895
class LCallNamed V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1896
 public:
1897
  explicit LCallNamed(LOperand* context) {
1898
    inputs_[0] = context;
1899
  }
1900

    
1901
  LOperand* context() { return inputs_[0]; }
1902

    
1903
  DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1904
  DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1905

    
1906
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1907

    
1908
  Handle<String> name() const { return hydrogen()->name(); }
1909
  int arity() const { return hydrogen()->argument_count() - 1; }
1910
};
1911

    
1912

    
1913
class LCallFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1914
 public:
1915
  LCallFunction(LOperand* context, LOperand* function) {
1916
    inputs_[0] = context;
1917
    inputs_[1] = function;
1918
  }
1919

    
1920
  LOperand* context() { return inputs_[0]; }
1921
  LOperand* function() { return inputs_[1]; }
1922

    
1923
  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1924
  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1925

    
1926
  int arity() const { return hydrogen()->argument_count() - 1; }
1927
};
1928

    
1929

    
1930
class LCallGlobal V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1931
 public:
1932
  explicit LCallGlobal(LOperand* context) {
1933
    inputs_[0] = context;
1934
  }
1935

    
1936
  LOperand* context() { return inputs_[0]; }
1937

    
1938
  DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1939
  DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1940

    
1941
  virtual void PrintDataTo(StringStream* stream);
1942

    
1943
  Handle<String> name() const {return hydrogen()->name(); }
1944
  int arity() const { return hydrogen()->argument_count() - 1; }
1945
};
1946

    
1947

    
1948
class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1949
 public:
1950
  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1951
  DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1952

    
1953
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1954

    
1955
  int arity() const { return hydrogen()->argument_count() - 1;  }
1956
};
1957

    
1958

    
1959
class LCallNew V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1960
 public:
1961
  LCallNew(LOperand* context, LOperand* constructor) {
1962
    inputs_[0] = context;
1963
    inputs_[1] = constructor;
1964
  }
1965

    
1966
  LOperand* context() { return inputs_[0]; }
1967
  LOperand* constructor() { return inputs_[1]; }
1968

    
1969
  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1970
  DECLARE_HYDROGEN_ACCESSOR(CallNew)
1971

    
1972
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1973

    
1974
  int arity() const { return hydrogen()->argument_count() - 1; }
1975
};
1976

    
1977

    
1978
class LCallNewArray V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1979
 public:
1980
  LCallNewArray(LOperand* context, LOperand* constructor) {
1981
    inputs_[0] = context;
1982
    inputs_[1] = constructor;
1983
  }
1984

    
1985
  LOperand* context() { return inputs_[0]; }
1986
  LOperand* constructor() { return inputs_[1]; }
1987

    
1988
  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
1989
  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
1990

    
1991
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1992

    
1993
  int arity() const { return hydrogen()->argument_count() - 1; }
1994
};
1995

    
1996

    
1997
class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1998
 public:
1999
  explicit LCallRuntime(LOperand* context) {
2000
    inputs_[0] = context;
2001
  }
2002

    
2003
  LOperand* context() { return inputs_[0]; }
2004

    
2005
  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
2006
  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
2007

    
2008
  virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
2009
    return save_doubles() == kDontSaveFPRegs;
2010
  }
2011

    
2012
  const Runtime::Function* function() const { return hydrogen()->function(); }
2013
  int arity() const { return hydrogen()->argument_count(); }
2014
  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
2015
};
2016

    
2017

    
2018
class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2019
 public:
2020
  explicit LInteger32ToDouble(LOperand* value) {
2021
    inputs_[0] = value;
2022
  }
2023

    
2024
  LOperand* value() { return inputs_[0]; }
2025

    
2026
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
2027
};
2028

    
2029

    
2030
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2031
 public:
2032
  explicit LInteger32ToSmi(LOperand* value) {
2033
    inputs_[0] = value;
2034
  }
2035

    
2036
  LOperand* value() { return inputs_[0]; }
2037

    
2038
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
2039
  DECLARE_HYDROGEN_ACCESSOR(Change)
2040
};
2041

    
2042

    
2043
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2044
 public:
2045
  explicit LUint32ToDouble(LOperand* value) {
2046
    inputs_[0] = value;
2047
  }
2048

    
2049
  LOperand* value() { return inputs_[0]; }
2050

    
2051
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
2052
};
2053

    
2054

    
2055
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2056
 public:
2057
  explicit LNumberTagI(LOperand* value) {
2058
    inputs_[0] = value;
2059
  }
2060

    
2061
  LOperand* value() { return inputs_[0]; }
2062

    
2063
  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
2064
};
2065

    
2066

    
2067
class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2068
 public:
2069
  explicit LNumberTagU(LOperand* value) {
2070
    inputs_[0] = value;
2071
  }
2072

    
2073
  LOperand* value() { return inputs_[0]; }
2074

    
2075
  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
2076
};
2077

    
2078

    
2079
class LNumberTagD V8_FINAL : public LTemplateInstruction<1, 1, 2> {
2080
 public:
2081
  LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
2082
    inputs_[0] = value;
2083
    temps_[0] = temp;
2084
    temps_[1] = temp2;
2085
  }
2086

    
2087
  LOperand* value() { return inputs_[0]; }
2088
  LOperand* temp() { return temps_[0]; }
2089
  LOperand* temp2() { return temps_[1]; }
2090

    
2091
  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
2092
  DECLARE_HYDROGEN_ACCESSOR(Change)
2093
};
2094

    
2095

    
2096
class LDoubleToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2097
 public:
2098
  explicit LDoubleToSmi(LOperand* value) {
2099
    inputs_[0] = value;
2100
  }
2101

    
2102
  LOperand* value() { return inputs_[0]; }
2103

    
2104
  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2105
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2106

    
2107
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2108
};
2109

    
2110

    
2111
// Sometimes truncating conversion from a tagged value to an int32.
2112
class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2113
 public:
2114
  explicit LDoubleToI(LOperand* value) {
2115
    inputs_[0] = value;
2116
  }
2117

    
2118
  LOperand* value() { return inputs_[0]; }
2119

    
2120
  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2121
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2122

    
2123
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2124
};
2125

    
2126

    
2127
// Truncating conversion from a tagged value to an int32.
2128
class LTaggedToI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
2129
 public:
2130
  LTaggedToI(LOperand* value,
2131
             LOperand* temp,
2132
             LOperand* temp2) {
2133
    inputs_[0] = value;
2134
    temps_[0] = temp;
2135
    temps_[1] = temp2;
2136
  }
2137

    
2138
  LOperand* value() { return inputs_[0]; }
2139
  LOperand* temp() { return temps_[0]; }
2140
  LOperand* temp2() { return temps_[1]; }
2141

    
2142
  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2143
  DECLARE_HYDROGEN_ACCESSOR(Change)
2144

    
2145
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2146
};
2147

    
2148

    
2149
class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2150
 public:
2151
  explicit LSmiTag(LOperand* value) {
2152
    inputs_[0] = value;
2153
  }
2154

    
2155
  LOperand* value() { return inputs_[0]; }
2156

    
2157
  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2158
};
2159

    
2160

    
2161
class LNumberUntagD V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2162
 public:
2163
  explicit LNumberUntagD(LOperand* value) {
2164
    inputs_[0] = value;
2165
  }
2166

    
2167
  LOperand* value() { return inputs_[0]; }
2168

    
2169
  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2170
  DECLARE_HYDROGEN_ACCESSOR(Change)
2171
};
2172

    
2173

    
2174
class LSmiUntag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2175
 public:
2176
  LSmiUntag(LOperand* value, bool needs_check)
2177
      : needs_check_(needs_check) {
2178
    inputs_[0] = value;
2179
  }
2180

    
2181
  LOperand* value() { return inputs_[0]; }
2182
  bool needs_check() const { return needs_check_; }
2183

    
2184
  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2185

    
2186
 private:
2187
  bool needs_check_;
2188
};
2189

    
2190

    
2191
class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
2192
 public:
2193
  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
2194
    inputs_[0] = object;
2195
    inputs_[1] = value;
2196
    temps_[0] = temp;
2197
  }
2198

    
2199
  LOperand* object() { return inputs_[0]; }
2200
  LOperand* value() { return inputs_[1]; }
2201
  LOperand* temp() { return temps_[0]; }
2202

    
2203
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2204
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2205

    
2206
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2207

    
2208
  Handle<Map> transition() const { return hydrogen()->transition_map(); }
2209
  Representation representation() const {
2210
    return hydrogen()->field_representation();
2211
  }
2212
};
2213

    
2214

    
2215
class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2216
 public:
2217
  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2218
    inputs_[0] = context;
2219
    inputs_[1] = object;
2220
    inputs_[2] = value;
2221
  }
2222

    
2223
  LOperand* context() { return inputs_[0]; }
2224
  LOperand* object() { return inputs_[1]; }
2225
  LOperand* value() { return inputs_[2]; }
2226

    
2227
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2228
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2229

    
2230
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2231

    
2232
  Handle<Object> name() const { return hydrogen()->name(); }
2233
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2234
};
2235

    
2236

    
2237
class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2238
 public:
2239
  LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
2240
    inputs_[0] = object;
2241
    inputs_[1] = key;
2242
    inputs_[2] = value;
2243
  }
2244

    
2245
  bool is_external() const { return hydrogen()->is_external(); }
2246
  LOperand* elements() { return inputs_[0]; }
2247
  LOperand* key() { return inputs_[1]; }
2248
  LOperand* value() { return inputs_[2]; }
2249
  ElementsKind elements_kind() const {
2250
    return hydrogen()->elements_kind();
2251
  }
2252

    
2253
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2254
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2255

    
2256
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2257
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2258
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
2259
};
2260

    
2261

    
2262
class LStoreKeyedGeneric V8_FINAL : public LTemplateInstruction<0, 4, 0> {
2263
 public:
2264
  LStoreKeyedGeneric(LOperand* context,
2265
                     LOperand* obj,
2266
                     LOperand* key,
2267
                     LOperand* value) {
2268
    inputs_[0] = context;
2269
    inputs_[1] = obj;
2270
    inputs_[2] = key;
2271
    inputs_[3] = value;
2272
  }
2273

    
2274
  LOperand* context() { return inputs_[0]; }
2275
  LOperand* object() { return inputs_[1]; }
2276
  LOperand* key() { return inputs_[2]; }
2277
  LOperand* value() { return inputs_[3]; }
2278

    
2279
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2280
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2281

    
2282
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2283

    
2284
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2285
};
2286

    
2287

    
2288
class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 1> {
2289
 public:
2290
  LTransitionElementsKind(LOperand* object,
2291
                          LOperand* context,
2292
                          LOperand* new_map_temp) {
2293
    inputs_[0] = object;
2294
    inputs_[1] = context;
2295
    temps_[0] = new_map_temp;
2296
  }
2297

    
2298
  LOperand* context() { return inputs_[1]; }
2299
  LOperand* object() { return inputs_[0]; }
2300
  LOperand* new_map_temp() { return temps_[0]; }
2301

    
2302
  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2303
                               "transition-elements-kind")
2304
  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2305

    
2306
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2307

    
2308
  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2309
  Handle<Map> transitioned_map() {
2310
    return hydrogen()->transitioned_map().handle();
2311
  }
2312
  ElementsKind from_kind() { return hydrogen()->from_kind(); }
2313
  ElementsKind to_kind() { return hydrogen()->to_kind(); }
2314
};
2315

    
2316

    
2317
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
2318
 public:
2319
  LTrapAllocationMemento(LOperand* object,
2320
                         LOperand* temp) {
2321
    inputs_[0] = object;
2322
    temps_[0] = temp;
2323
  }
2324

    
2325
  LOperand* object() { return inputs_[0]; }
2326
  LOperand* temp() { return temps_[0]; }
2327

    
2328
  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2329
                               "trap-allocation-memento")
2330
};
2331

    
2332

    
2333
class LStringAdd V8_FINAL : public LTemplateInstruction<1, 3, 0> {
2334
 public:
2335
  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2336
    inputs_[0] = context;
2337
    inputs_[1] = left;
2338
    inputs_[2] = right;
2339
  }
2340

    
2341
  LOperand* context() { return inputs_[0]; }
2342
  LOperand* left() { return inputs_[1]; }
2343
  LOperand* right() { return inputs_[2]; }
2344

    
2345
  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2346
  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2347
};
2348

    
2349

    
2350

    
2351
class LStringCharCodeAt V8_FINAL : public LTemplateInstruction<1, 3, 0> {
2352
 public:
2353
  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2354
    inputs_[0] = context;
2355
    inputs_[1] = string;
2356
    inputs_[2] = index;
2357
  }
2358

    
2359
  LOperand* context() { return inputs_[0]; }
2360
  LOperand* string() { return inputs_[1]; }
2361
  LOperand* index() { return inputs_[2]; }
2362

    
2363
  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2364
  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2365
};
2366

    
2367

    
2368
class LStringCharFromCode V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2369
 public:
2370
  explicit LStringCharFromCode(LOperand* context, LOperand* char_code) {
2371
    inputs_[0] = context;
2372
    inputs_[1] = char_code;
2373
  }
2374

    
2375
  LOperand* context() { return inputs_[0]; }
2376
  LOperand* char_code() { return inputs_[1]; }
2377

    
2378
  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2379
  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2380
};
2381

    
2382

    
2383
class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2384
 public:
2385
  explicit LCheckValue(LOperand* value) {
2386
    inputs_[0] = value;
2387
  }
2388

    
2389
  LOperand* value() { return inputs_[0]; }
2390

    
2391
  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2392
  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2393
};
2394

    
2395

    
2396
class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2397
 public:
2398
  explicit LCheckInstanceType(LOperand* value) {
2399
    inputs_[0] = value;
2400
  }
2401

    
2402
  LOperand* value() { return inputs_[0]; }
2403

    
2404
  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2405
  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2406
};
2407

    
2408

    
2409
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2410
 public:
2411
  explicit LCheckMaps(LOperand* value) {
2412
    inputs_[0] = value;
2413
  }
2414

    
2415
  LOperand* value() { return inputs_[0]; }
2416

    
2417
  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2418
  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2419
};
2420

    
2421

    
2422
class LCheckSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2423
 public:
2424
  explicit LCheckSmi(LOperand* value) {
2425
    inputs_[0] = value;
2426
  }
2427

    
2428
  LOperand* value() { return inputs_[0]; }
2429

    
2430
  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2431
};
2432

    
2433

    
2434
class LCheckNonSmi V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2435
 public:
2436
  explicit LCheckNonSmi(LOperand* value) {
2437
    inputs_[0] = value;
2438
  }
2439

    
2440
  LOperand* value() { return inputs_[0]; }
2441

    
2442
  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2443
  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2444
};
2445

    
2446

    
2447
class LClampDToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2448
 public:
2449
  LClampDToUint8(LOperand* unclamped, LOperand* temp) {
2450
    inputs_[0] = unclamped;
2451
    temps_[0] = temp;
2452
  }
2453

    
2454
  LOperand* unclamped() { return inputs_[0]; }
2455
  LOperand* temp() { return temps_[0]; }
2456

    
2457
  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2458
};
2459

    
2460

    
2461
class LClampIToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2462
 public:
2463
  explicit LClampIToUint8(LOperand* unclamped) {
2464
    inputs_[0] = unclamped;
2465
  }
2466

    
2467
  LOperand* unclamped() { return inputs_[0]; }
2468

    
2469
  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2470
};
2471

    
2472

    
2473
class LClampTToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2474
 public:
2475
  LClampTToUint8(LOperand* unclamped, LOperand* temp) {
2476
    inputs_[0] = unclamped;
2477
    temps_[0] = temp;
2478
  }
2479

    
2480
  LOperand* unclamped() { return inputs_[0]; }
2481
  LOperand* temp() { return temps_[0]; }
2482

    
2483
  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2484
};
2485

    
2486

    
2487
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 2> {
2488
 public:
2489
  LAllocate(LOperand* context,
2490
            LOperand* size,
2491
            LOperand* temp1,
2492
            LOperand* temp2) {
2493
    inputs_[0] = context;
2494
    inputs_[1] = size;
2495
    temps_[0] = temp1;
2496
    temps_[1] = temp2;
2497
  }
2498

    
2499
  LOperand* context() { return inputs_[0]; }
2500
  LOperand* size() { return inputs_[1]; }
2501
  LOperand* temp1() { return temps_[0]; }
2502
  LOperand* temp2() { return temps_[1]; }
2503

    
2504
  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2505
  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2506
};
2507

    
2508

    
2509
class LRegExpLiteral V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2510
 public:
2511
  explicit LRegExpLiteral(LOperand* context) {
2512
    inputs_[0] = context;
2513
  }
2514

    
2515
  LOperand* context() { return inputs_[0]; }
2516

    
2517
  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2518
  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2519
};
2520

    
2521

    
2522
class LFunctionLiteral V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2523
 public:
2524
  explicit LFunctionLiteral(LOperand* context) {
2525
    inputs_[0] = context;
2526
  }
2527

    
2528
  LOperand* context() { return inputs_[0]; }
2529

    
2530
  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2531
  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2532
};
2533

    
2534

    
2535
class LToFastProperties V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2536
 public:
2537
  explicit LToFastProperties(LOperand* value) {
2538
    inputs_[0] = value;
2539
  }
2540

    
2541
  LOperand* value() { return inputs_[0]; }
2542

    
2543
  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2544
  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2545
};
2546

    
2547

    
2548
class LTypeof V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2549
 public:
2550
  LTypeof(LOperand* context, LOperand* value) {
2551
    inputs_[0] = context;
2552
    inputs_[1] = value;
2553
  }
2554

    
2555
  LOperand* context() { return inputs_[0]; }
2556
  LOperand* value() { return inputs_[1]; }
2557

    
2558
  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2559
};
2560

    
2561

    
2562
class LTypeofIsAndBranch V8_FINAL : public LControlInstruction<1, 0> {
2563
 public:
2564
  explicit LTypeofIsAndBranch(LOperand* value) {
2565
    inputs_[0] = value;
2566
  }
2567

    
2568
  LOperand* value() { return inputs_[0]; }
2569

    
2570
  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2571
  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2572

    
2573
  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2574

    
2575
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2576
};
2577

    
2578

    
2579
class LIsConstructCallAndBranch V8_FINAL : public LControlInstruction<0, 1> {
2580
 public:
2581
  explicit LIsConstructCallAndBranch(LOperand* temp) {
2582
    temps_[0] = temp;
2583
  }
2584

    
2585
  LOperand* temp() { return temps_[0]; }
2586

    
2587
  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2588
                               "is-construct-call-and-branch")
2589
};
2590

    
2591

    
2592
class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
2593
 public:
2594
  LOsrEntry() {}
2595

    
2596
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
2597
    return false;
2598
  }
2599
  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2600
};
2601

    
2602

    
2603
class LStackCheck V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2604
 public:
2605
  explicit LStackCheck(LOperand* context) {
2606
    inputs_[0] = context;
2607
  }
2608

    
2609
  LOperand* context() { return inputs_[0]; }
2610

    
2611
  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2612
  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2613

    
2614
  Label* done_label() { return &done_label_; }
2615

    
2616
 private:
2617
  Label done_label_;
2618
};
2619

    
2620

    
2621
class LForInPrepareMap V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2622
 public:
2623
  LForInPrepareMap(LOperand* context, LOperand* object) {
2624
    inputs_[0] = context;
2625
    inputs_[1] = object;
2626
  }
2627

    
2628
  LOperand* context() { return inputs_[0]; }
2629
  LOperand* object() { return inputs_[1]; }
2630

    
2631
  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2632
};
2633

    
2634

    
2635
class LForInCacheArray V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2636
 public:
2637
  explicit LForInCacheArray(LOperand* map) {
2638
    inputs_[0] = map;
2639
  }
2640

    
2641
  LOperand* map() { return inputs_[0]; }
2642

    
2643
  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2644

    
2645
  int idx() {
2646
    return HForInCacheArray::cast(this->hydrogen_value())->idx();
2647
  }
2648
};
2649

    
2650

    
2651
class LCheckMapValue V8_FINAL : public LTemplateInstruction<0, 2, 0> {
2652
 public:
2653
  LCheckMapValue(LOperand* value, LOperand* map) {
2654
    inputs_[0] = value;
2655
    inputs_[1] = map;
2656
  }
2657

    
2658
  LOperand* value() { return inputs_[0]; }
2659
  LOperand* map() { return inputs_[1]; }
2660

    
2661
  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2662
};
2663

    
2664

    
2665
class LLoadFieldByIndex V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2666
 public:
2667
  LLoadFieldByIndex(LOperand* object, LOperand* index) {
2668
    inputs_[0] = object;
2669
    inputs_[1] = index;
2670
  }
2671

    
2672
  LOperand* object() { return inputs_[0]; }
2673
  LOperand* index() { return inputs_[1]; }
2674

    
2675
  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2676
};
2677

    
2678

    
2679
class LChunkBuilder;
2680
class LPlatformChunk V8_FINAL : public LChunk {
2681
 public:
2682
  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2683
      : LChunk(info, graph) { }
2684

    
2685
  int GetNextSpillIndex(RegisterKind kind);
2686
  LOperand* GetNextSpillSlot(RegisterKind kind);
2687
};
2688

    
2689

    
2690
class LChunkBuilder V8_FINAL BASE_EMBEDDED {
2691
 public:
2692
  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2693
      : chunk_(NULL),
2694
        info_(info),
2695
        graph_(graph),
2696
        zone_(graph->zone()),
2697
        status_(UNUSED),
2698
        current_instruction_(NULL),
2699
        current_block_(NULL),
2700
        next_block_(NULL),
2701
        argument_count_(0),
2702
        allocator_(allocator),
2703
        position_(RelocInfo::kNoPosition),
2704
        instruction_pending_deoptimization_environment_(NULL),
2705
        pending_deoptimization_ast_id_(BailoutId::None()) { }
2706

    
2707
  // Build the sequence for the graph.
2708
  LPlatformChunk* Build();
2709

    
2710
  LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
2711

    
2712
  // Declare methods that deal with the individual node types.
2713
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2714
  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2715
#undef DECLARE_DO
2716

    
2717
  LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
2718

    
2719
  static bool HasMagicNumberForDivisor(int32_t divisor);
2720
  static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2721

    
2722
  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2723
  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2724
  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2725
  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2726
  LInstruction* DoMathSin(HUnaryMathOperation* instr);
2727
  LInstruction* DoMathCos(HUnaryMathOperation* instr);
2728
  LInstruction* DoMathTan(HUnaryMathOperation* instr);
2729
  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2730
  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2731
  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2732

    
2733
 private:
2734
  enum Status {
2735
    UNUSED,
2736
    BUILDING,
2737
    DONE,
2738
    ABORTED
2739
  };
2740

    
2741
  LPlatformChunk* chunk() const { return chunk_; }
2742
  CompilationInfo* info() const { return info_; }
2743
  HGraph* graph() const { return graph_; }
2744
  Zone* zone() const { return zone_; }
2745

    
2746
  bool is_unused() const { return status_ == UNUSED; }
2747
  bool is_building() const { return status_ == BUILDING; }
2748
  bool is_done() const { return status_ == DONE; }
2749
  bool is_aborted() const { return status_ == ABORTED; }
2750

    
2751
  void Abort(BailoutReason reason);
2752

    
2753
  // Methods for getting operands for Use / Define / Temp.
2754
  LUnallocated* ToUnallocated(Register reg);
2755
  LUnallocated* ToUnallocated(DoubleRegister reg);
2756

    
2757
  // Methods for setting up define-use relationships.
2758
  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2759
  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2760
  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2761
                                           DoubleRegister fixed_register);
2762

    
2763
  // A value that is guaranteed to be allocated to a register.
2764
  // Operand created by UseRegister is guaranteed to be live until the end of
2765
  // instruction. This means that register allocator will not reuse it's
2766
  // register for any other operand inside instruction.
2767
  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2768
  // instruction start. Register allocator is free to assign the same register
2769
  // to some other operand used inside instruction (i.e. temporary or
2770
  // output).
2771
  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2772
  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2773

    
2774
  // An input operand in a register that may be trashed.
2775
  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2776

    
2777
  // An input operand in a register or stack slot.
2778
  MUST_USE_RESULT LOperand* Use(HValue* value);
2779
  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2780

    
2781
  // An input operand in a register, stack slot or a constant operand.
2782
  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2783
  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2784

    
2785
  // An input operand in a register or a constant operand.
2786
  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2787
  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2788

    
2789
  // An input operand in a constant operand.
2790
  MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2791

    
2792
  // An input operand in register, stack slot or a constant operand.
2793
  // Will not be moved to a register even if one is freely available.
2794
  MUST_USE_RESULT LOperand* UseAny(HValue* value);
2795

    
2796
  // Temporary operand that must be in a register.
2797
  MUST_USE_RESULT LUnallocated* TempRegister();
2798
  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2799
  MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
2800

    
2801
  // Methods for setting up define-use relationships.
2802
  // Return the same instruction that they are passed.
2803
  template<int I, int T>
2804
      LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2805
                           LUnallocated* result);
2806
  template<int I, int T>
2807
      LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2808
  template<int I, int T>
2809
      LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2810
                                    int index);
2811
  template<int I, int T>
2812
      LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2813
  template<int I, int T>
2814
      LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2815
                                Register reg);
2816
  template<int I, int T>
2817
      LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2818
                                      DoubleRegister reg);
2819
  LInstruction* AssignEnvironment(LInstruction* instr);
2820
  LInstruction* AssignPointerMap(LInstruction* instr);
2821

    
2822
  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2823

    
2824
  // By default we assume that instruction sequences generated for calls
2825
  // cannot deoptimize eagerly and we do not attach environment to this
2826
  // instruction.
2827
  LInstruction* MarkAsCall(
2828
      LInstruction* instr,
2829
      HInstruction* hinstr,
2830
      CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2831

    
2832
  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2833
                                  int* argument_index_accumulator,
2834
                                  ZoneList<HValue*>* objects_to_materialize);
2835

    
2836
  void VisitInstruction(HInstruction* current);
2837

    
2838
  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2839
  LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2840
  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2841
  LInstruction* DoArithmeticD(Token::Value op,
2842
                              HArithmeticBinaryOperation* instr);
2843
  LInstruction* DoArithmeticT(Token::Value op,
2844
                              HBinaryOperation* instr);
2845

    
2846
  LPlatformChunk* chunk_;
2847
  CompilationInfo* info_;
2848
  HGraph* const graph_;
2849
  Zone* zone_;
2850
  Status status_;
2851
  HInstruction* current_instruction_;
2852
  HBasicBlock* current_block_;
2853
  HBasicBlock* next_block_;
2854
  int argument_count_;
2855
  LAllocator* allocator_;
2856
  int position_;
2857
  LInstruction* instruction_pending_deoptimization_environment_;
2858
  BailoutId pending_deoptimization_ast_id_;
2859

    
2860
  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2861
};
2862

    
2863
#undef DECLARE_HYDROGEN_ACCESSOR
2864
#undef DECLARE_CONCRETE_INSTRUCTION
2865

    
2866
} }  // namespace v8::internal
2867

    
2868
#endif  // V8_MIPS_LITHIUM_MIPS_H_