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 / x64 / lithium-x64.h @ f230a1cf

History | View | Annotate | Download (76.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_X64_LITHIUM_X64_H_
29
#define V8_X64_LITHIUM_X64_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(NumberTagD)                                 \
146
  V(NumberTagI)                                 \
147
  V(NumberTagU)                                 \
148
  V(NumberUntagD)                               \
149
  V(OsrEntry)                                   \
150
  V(OuterContext)                               \
151
  V(Parameter)                                  \
152
  V(Power)                                      \
153
  V(PushArgument)                               \
154
  V(Random)                                     \
155
  V(RegExpLiteral)                              \
156
  V(Return)                                     \
157
  V(SeqStringSetChar)                           \
158
  V(ShiftI)                                     \
159
  V(SmiTag)                                     \
160
  V(SmiUntag)                                   \
161
  V(StackCheck)                                 \
162
  V(StoreCodeEntry)                             \
163
  V(StoreContextSlot)                           \
164
  V(StoreGlobalCell)                            \
165
  V(StoreGlobalGeneric)                         \
166
  V(StoreKeyed)                                 \
167
  V(StoreKeyedGeneric)                          \
168
  V(StoreNamedField)                            \
169
  V(StoreNamedGeneric)                          \
170
  V(StringAdd)                                  \
171
  V(StringCharCodeAt)                           \
172
  V(StringCharFromCode)                         \
173
  V(StringCompareAndBranch)                     \
174
  V(SubI)                                       \
175
  V(TaggedToI)                                  \
176
  V(ThisFunction)                               \
177
  V(Throw)                                      \
178
  V(ToFastProperties)                           \
179
  V(TransitionElementsKind)                     \
180
  V(TrapAllocationMemento)                      \
181
  V(Typeof)                                     \
182
  V(TypeofIsAndBranch)                          \
183
  V(Uint32ToDouble)                             \
184
  V(Uint32ToSmi)                                \
185
  V(UnknownOSRValue)                            \
186
  V(ValueOf)                                    \
187
  V(WrapReceiver)
188

    
189

    
190
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
191
  virtual Opcode opcode() const V8_FINAL V8_OVERRIDE {                      \
192
    return LInstruction::k##type;                                           \
193
  }                                                                         \
194
  virtual void CompileToNative(LCodeGen* generator) V8_FINAL V8_OVERRIDE;   \
195
  virtual const char* Mnemonic() const V8_FINAL V8_OVERRIDE {               \
196
    return mnemonic;                                                        \
197
  }                                                                         \
198
  static L##type* cast(LInstruction* instr) {                               \
199
    ASSERT(instr->Is##type());                                              \
200
    return reinterpret_cast<L##type*>(instr);                               \
201
  }
202

    
203

    
204
#define DECLARE_HYDROGEN_ACCESSOR(type)     \
205
  H##type* hydrogen() const {               \
206
    return H##type::cast(hydrogen_value()); \
207
  }
208

    
209

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

    
218
  virtual ~LInstruction() {}
219

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

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

    
234
  virtual Opcode opcode() const = 0;
235

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

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

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

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

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

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

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

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

    
267
  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
268

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

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

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

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

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

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

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

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

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

    
302

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

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

    
322
 private:
323
  // Iterator support.
324
  virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
325
  virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
326

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

    
331

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

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

    
350
  bool IsRedundant() const;
351

    
352
  HBasicBlock* block() const { return block_; }
353

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

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

    
371
  LParallelMove* GetParallelMove(InnerPosition pos)  {
372
    return parallel_moves_[pos];
373
  }
374

    
375
 private:
376
  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
377
  HBasicBlock* block_;
378
};
379

    
380

    
381
class LInstructionGap V8_FINAL : public LGap {
382
 public:
383
  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
384

    
385
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
386
    return !IsRedundant();
387
  }
388

    
389
  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
390
};
391

    
392

    
393
class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
394
 public:
395
  explicit LGoto(HBasicBlock* block) : block_(block) { }
396

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

    
402
  int block_id() const { return block_->block_id(); }
403

    
404
 private:
405
  HBasicBlock* block_;
406
};
407

    
408

    
409
class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
410
 public:
411
  LLazyBailout() : gap_instructions_size_(0) { }
412

    
413
  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
414

    
415
  void set_gap_instructions_size(int gap_instructions_size) {
416
    gap_instructions_size_ = gap_instructions_size;
417
  }
418
  int gap_instructions_size() { return gap_instructions_size_; }
419

    
420
 private:
421
  int gap_instructions_size_;
422
};
423

    
424

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

    
433

    
434
class LDeoptimize V8_FINAL : public LTemplateInstruction<0, 0, 0> {
435
 public:
436
  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
437
  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
438
};
439

    
440

    
441
class LLabel V8_FINAL : public LGap {
442
 public:
443
  explicit LLabel(HBasicBlock* block)
444
      : LGap(block), replacement_(NULL) { }
445

    
446
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
447
    return false;
448
  }
449
  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
450

    
451
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
452

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

    
461
 private:
462
  Label label_;
463
  LLabel* replacement_;
464
};
465

    
466

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

    
475

    
476
class LCallStub V8_FINAL : public LTemplateInstruction<1, 0, 0> {
477
 public:
478
  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
479
  DECLARE_HYDROGEN_ACCESSOR(CallStub)
480

    
481
  TranscendentalCache::Type transcendental_type() {
482
    return hydrogen()->transcendental_type();
483
  }
484
};
485

    
486

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

    
495

    
496
template<int I, int T>
497
class LControlInstruction : public LTemplateInstruction<0, I, T> {
498
 public:
499
  LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
500

    
501
  virtual bool IsControl() const V8_FINAL V8_OVERRIDE { return true; }
502

    
503
  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
504
  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
505

    
506
  int TrueDestination(LChunk* chunk) {
507
    return chunk->LookupDestination(true_block_id());
508
  }
509
  int FalseDestination(LChunk* chunk) {
510
    return chunk->LookupDestination(false_block_id());
511
  }
512

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

    
526
 protected:
527
  int true_block_id() { return SuccessorAt(0)->block_id(); }
528
  int false_block_id() { return SuccessorAt(1)->block_id(); }
529

    
530
 private:
531
  HControlInstruction* hydrogen() {
532
    return HControlInstruction::cast(this->hydrogen_value());
533
  }
534

    
535
  Label* false_label_;
536
  Label* true_label_;
537
};
538

    
539

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

    
547
  LOperand* receiver() { return inputs_[0]; }
548
  LOperand* function() { return inputs_[1]; }
549

    
550
  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
551
};
552

    
553

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

    
566
  LOperand* function() { return inputs_[0]; }
567
  LOperand* receiver() { return inputs_[1]; }
568
  LOperand* length() { return inputs_[2]; }
569
  LOperand* elements() { return inputs_[3]; }
570

    
571
  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
572
};
573

    
574

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

    
583
  LOperand* arguments() { return inputs_[0]; }
584
  LOperand* length() { return inputs_[1]; }
585
  LOperand* index() { return inputs_[2]; }
586

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

    
589
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
590
};
591

    
592

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

    
599
  LOperand* elements() { return inputs_[0]; }
600

    
601
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
602
};
603

    
604

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

    
611

    
612
class LModI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
613
 public:
614
  LModI(LOperand* left, LOperand* right, LOperand* temp) {
615
    inputs_[0] = left;
616
    inputs_[1] = right;
617
    temps_[0] = temp;
618
  }
619

    
620
  LOperand* left() { return inputs_[0]; }
621
  LOperand* right() { return inputs_[1]; }
622
  LOperand* temp() { return temps_[0]; }
623

    
624
  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
625
  DECLARE_HYDROGEN_ACCESSOR(Mod)
626
};
627

    
628

    
629
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
630
 public:
631
  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
632
    inputs_[0] = left;
633
    inputs_[1] = right;
634
    temps_[0] = temp;
635
  }
636

    
637
  LOperand* left() { return inputs_[0]; }
638
  LOperand* right() { return inputs_[1]; }
639
  LOperand* temp() { return temps_[0]; }
640

    
641
  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
642

    
643
  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
644
  DECLARE_HYDROGEN_ACCESSOR(Div)
645
};
646

    
647

    
648
class LMathFloorOfDiv V8_FINAL : public LTemplateInstruction<1, 2, 1> {
649
 public:
650
  LMathFloorOfDiv(LOperand* left,
651
                  LOperand* right,
652
                  LOperand* temp = NULL) {
653
    inputs_[0] = left;
654
    inputs_[1] = right;
655
    temps_[0] = temp;
656
  }
657

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

    
662
  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
663
  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
664
};
665

    
666

    
667
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
668
 public:
669
  LMulI(LOperand* left, LOperand* right) {
670
    inputs_[0] = left;
671
    inputs_[1] = right;
672
  }
673

    
674
  LOperand* left() { return inputs_[0]; }
675
  LOperand* right() { return inputs_[1]; }
676

    
677
  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
678
  DECLARE_HYDROGEN_ACCESSOR(Mul)
679
};
680

    
681

    
682
class LCompareNumericAndBranch V8_FINAL : public LControlInstruction<2, 0> {
683
 public:
684
  LCompareNumericAndBranch(LOperand* left, LOperand* right) {
685
    inputs_[0] = left;
686
    inputs_[1] = right;
687
  }
688

    
689
  LOperand* left() { return inputs_[0]; }
690
  LOperand* right() { return inputs_[1]; }
691

    
692
  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
693
                               "compare-numeric-and-branch")
694
  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
695

    
696
  Token::Value op() const { return hydrogen()->token(); }
697
  bool is_double() const {
698
    return hydrogen()->representation().IsDouble();
699
  }
700

    
701
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
702
};
703

    
704

    
705
class LMathFloor V8_FINAL : public LTemplateInstruction<1, 1, 0> {
706
 public:
707
  explicit LMathFloor(LOperand* value) {
708
    inputs_[0] = value;
709
  }
710

    
711
  LOperand* value() { return inputs_[0]; }
712

    
713
  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
714
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
715
};
716

    
717

    
718
class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 0> {
719
 public:
720
  explicit LMathRound(LOperand* value) {
721
    inputs_[0] = value;
722
  }
723

    
724
  LOperand* value() { return inputs_[0]; }
725

    
726
  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
727
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
728
};
729

    
730

    
731
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 1, 0> {
732
 public:
733
  explicit LMathAbs(LOperand* value) {
734
    inputs_[0] = value;
735
  }
736

    
737
  LOperand* value() { return inputs_[0]; }
738

    
739
  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
740
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
741
};
742

    
743

    
744
class LMathLog V8_FINAL : public LTemplateInstruction<1, 1, 0> {
745
 public:
746
  explicit LMathLog(LOperand* value) {
747
    inputs_[0] = value;
748
  }
749

    
750
  LOperand* value() { return inputs_[0]; }
751

    
752
  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
753
};
754

    
755

    
756
class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
757
 public:
758
  explicit LMathSin(LOperand* value) {
759
    inputs_[0] = value;
760
  }
761

    
762
  LOperand* value() { return inputs_[0]; }
763

    
764
  DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
765
};
766

    
767

    
768
class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
769
 public:
770
  explicit LMathCos(LOperand* value) {
771
    inputs_[0] = value;
772
  }
773

    
774
  LOperand* value() { return inputs_[0]; }
775

    
776
  DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
777
};
778

    
779

    
780
class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
781
 public:
782
  explicit LMathTan(LOperand* value) {
783
    inputs_[0] = value;
784
  }
785

    
786
  LOperand* value() { return inputs_[0]; }
787

    
788
  DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
789
};
790

    
791

    
792
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
793
 public:
794
  LMathExp(LOperand* value, LOperand* temp1, LOperand* temp2) {
795
    inputs_[0] = value;
796
    temps_[0] = temp1;
797
    temps_[1] = temp2;
798
    ExternalReference::InitializeMathExpData();
799
  }
800

    
801
  LOperand* value() { return inputs_[0]; }
802
  LOperand* temp1() { return temps_[0]; }
803
  LOperand* temp2() { return temps_[1]; }
804

    
805
  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
806
};
807

    
808

    
809
class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
810
 public:
811
  explicit LMathSqrt(LOperand* value) {
812
    inputs_[0] = value;
813
  }
814

    
815
  LOperand* value() { return inputs_[0]; }
816

    
817
  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
818
};
819

    
820

    
821
class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 0> {
822
 public:
823
  explicit LMathPowHalf(LOperand* value) {
824
    inputs_[0] = value;
825
  }
826

    
827
  LOperand* value() { return inputs_[0]; }
828

    
829
  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
830
};
831

    
832

    
833
class LCmpObjectEqAndBranch V8_FINAL : public LControlInstruction<2, 0> {
834
 public:
835
  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
836
    inputs_[0] = left;
837
    inputs_[1] = right;
838
  }
839

    
840
  LOperand* left() { return inputs_[0]; }
841
  LOperand* right() { return inputs_[1]; }
842

    
843
  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
844
};
845

    
846

    
847
class LCmpHoleAndBranch V8_FINAL : public LControlInstruction<1, 0> {
848
 public:
849
  explicit LCmpHoleAndBranch(LOperand* object) {
850
    inputs_[0] = object;
851
  }
852

    
853
  LOperand* object() { return inputs_[0]; }
854

    
855
  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
856
  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
857
};
858

    
859

    
860
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 0> {
861
 public:
862
  explicit LIsObjectAndBranch(LOperand* value) {
863
    inputs_[0] = value;
864
  }
865

    
866
  LOperand* value() { return inputs_[0]; }
867

    
868
  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
869
  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
870

    
871
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
872
};
873

    
874

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

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

    
885
  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
886
  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
887

    
888
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
889
};
890

    
891

    
892
class LIsSmiAndBranch V8_FINAL : public LControlInstruction<1, 0> {
893
 public:
894
  explicit LIsSmiAndBranch(LOperand* value) {
895
    inputs_[0] = value;
896
  }
897

    
898
  LOperand* value() { return inputs_[0]; }
899

    
900
  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
901
  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
902

    
903
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
904
};
905

    
906

    
907
class LIsUndetectableAndBranch V8_FINAL : public LControlInstruction<1, 1> {
908
 public:
909
  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
910
    inputs_[0] = value;
911
    temps_[0] = temp;
912
  }
913

    
914
  LOperand* value() { return inputs_[0]; }
915
  LOperand* temp() { return temps_[0]; }
916

    
917
  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
918
                               "is-undetectable-and-branch")
919
  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
920

    
921
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
922
};
923

    
924

    
925
class LStringCompareAndBranch V8_FINAL : public LControlInstruction<2, 0> {
926
 public:
927
  explicit LStringCompareAndBranch(LOperand* left, LOperand* right) {
928
    inputs_[0] = left;
929
    inputs_[1] = right;
930
  }
931

    
932
  LOperand* left() { return inputs_[0]; }
933
  LOperand* right() { return inputs_[1]; }
934

    
935
  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
936
                               "string-compare-and-branch")
937
  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
938

    
939
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
940

    
941
  Token::Value op() const { return hydrogen()->token(); }
942
};
943

    
944

    
945
class LHasInstanceTypeAndBranch V8_FINAL : public LControlInstruction<1, 0> {
946
 public:
947
  explicit LHasInstanceTypeAndBranch(LOperand* value) {
948
    inputs_[0] = value;
949
  }
950

    
951
  LOperand* value() { return inputs_[0]; }
952

    
953
  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
954
                               "has-instance-type-and-branch")
955
  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
956

    
957
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
958
};
959

    
960

    
961
class LGetCachedArrayIndex V8_FINAL : public LTemplateInstruction<1, 1, 0> {
962
 public:
963
  explicit LGetCachedArrayIndex(LOperand* value) {
964
    inputs_[0] = value;
965
  }
966

    
967
  LOperand* value() { return inputs_[0]; }
968

    
969
  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
970
  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
971
};
972

    
973

    
974
class LHasCachedArrayIndexAndBranch V8_FINAL
975
    : public LControlInstruction<1, 0> {
976
 public:
977
  explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
978
    inputs_[0] = value;
979
  }
980

    
981
  LOperand* value() { return inputs_[0]; }
982

    
983
  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
984
                               "has-cached-array-index-and-branch")
985
  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
986

    
987
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
988
};
989

    
990

    
991
class LClassOfTestAndBranch V8_FINAL : public LControlInstruction<1, 2> {
992
 public:
993
  LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
994
    inputs_[0] = value;
995
    temps_[0] = temp;
996
    temps_[1] = temp2;
997
  }
998

    
999
  LOperand* value() { return inputs_[0]; }
1000
  LOperand* temp() { return temps_[0]; }
1001
  LOperand* temp2() { return temps_[1]; }
1002

    
1003
  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1004
                               "class-of-test-and-branch")
1005
  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1006

    
1007
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1008
};
1009

    
1010

    
1011
class LCmpT V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1012
 public:
1013
  LCmpT(LOperand* left, LOperand* right) {
1014
    inputs_[0] = left;
1015
    inputs_[1] = right;
1016
  }
1017

    
1018
  LOperand* left() { return inputs_[0]; }
1019
  LOperand* right() { return inputs_[1]; }
1020

    
1021
  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1022
  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1023

    
1024
  Token::Value op() const { return hydrogen()->token(); }
1025
};
1026

    
1027

    
1028
class LInstanceOf V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1029
 public:
1030
  LInstanceOf(LOperand* left, LOperand* right) {
1031
    inputs_[0] = left;
1032
    inputs_[1] = right;
1033
  }
1034

    
1035
  LOperand* left() { return inputs_[0]; }
1036
  LOperand* right() { return inputs_[1]; }
1037

    
1038
  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1039
};
1040

    
1041

    
1042
class LInstanceOfKnownGlobal V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1043
 public:
1044
  LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
1045
    inputs_[0] = value;
1046
    temps_[0] = temp;
1047
  }
1048

    
1049
  LOperand* value() { return inputs_[0]; }
1050
  LOperand* temp() { return temps_[0]; }
1051

    
1052
  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1053
                               "instance-of-known-global")
1054
  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1055

    
1056
  Handle<JSFunction> function() const { return hydrogen()->function(); }
1057
  LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
1058
    return lazy_deopt_env_;
1059
  }
1060
  virtual void SetDeferredLazyDeoptimizationEnvironment(
1061
      LEnvironment* env) V8_OVERRIDE {
1062
    lazy_deopt_env_ = env;
1063
  }
1064

    
1065
 private:
1066
  LEnvironment* lazy_deopt_env_;
1067
};
1068

    
1069

    
1070
class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1071
 public:
1072
  LBoundsCheck(LOperand* index, LOperand* length) {
1073
    inputs_[0] = index;
1074
    inputs_[1] = length;
1075
  }
1076

    
1077
  LOperand* index() { return inputs_[0]; }
1078
  LOperand* length() { return inputs_[1]; }
1079

    
1080
  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1081
  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1082
};
1083

    
1084

    
1085
class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1086
 public:
1087
  LBitI(LOperand* left, LOperand* right) {
1088
    inputs_[0] = left;
1089
    inputs_[1] = right;
1090
  }
1091

    
1092
  LOperand* left() { return inputs_[0]; }
1093
  LOperand* right() { return inputs_[1]; }
1094

    
1095
  Token::Value op() const { return hydrogen()->op(); }
1096

    
1097
  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1098
  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1099
};
1100

    
1101

    
1102
class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1103
 public:
1104
  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1105
      : op_(op), can_deopt_(can_deopt) {
1106
    inputs_[0] = left;
1107
    inputs_[1] = right;
1108
  }
1109

    
1110
  Token::Value op() const { return op_; }
1111
  LOperand* left() { return inputs_[0]; }
1112
  LOperand* right() { return inputs_[1]; }
1113
  bool can_deopt() const { return can_deopt_; }
1114

    
1115
  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1116

    
1117
 private:
1118
  Token::Value op_;
1119
  bool can_deopt_;
1120
};
1121

    
1122

    
1123
class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1124
 public:
1125
  LSubI(LOperand* left, LOperand* right) {
1126
    inputs_[0] = left;
1127
    inputs_[1] = right;
1128
  }
1129

    
1130
  LOperand* left() { return inputs_[0]; }
1131
  LOperand* right() { return inputs_[1]; }
1132

    
1133
  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1134
  DECLARE_HYDROGEN_ACCESSOR(Sub)
1135
};
1136

    
1137

    
1138
class LConstantI V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1139
 public:
1140
  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1141
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1142

    
1143
  int32_t value() const { return hydrogen()->Integer32Value(); }
1144
};
1145

    
1146

    
1147
class LConstantS V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1148
 public:
1149
  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1150
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1151

    
1152
  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1153
};
1154

    
1155

    
1156
class LConstantD V8_FINAL : public LTemplateInstruction<1, 0, 1> {
1157
 public:
1158
  explicit LConstantD(LOperand* temp) {
1159
    temps_[0] = temp;
1160
  }
1161

    
1162
  LOperand* temp() { return temps_[0]; }
1163

    
1164
  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1165
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1166

    
1167
  double value() const { return hydrogen()->DoubleValue(); }
1168
};
1169

    
1170

    
1171
class LConstantE V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1172
 public:
1173
  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1174
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1175

    
1176
  ExternalReference value() const {
1177
    return hydrogen()->ExternalReferenceValue();
1178
  }
1179
};
1180

    
1181

    
1182
class LConstantT V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1183
 public:
1184
  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1185
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1186

    
1187
  Handle<Object> value(Isolate* isolate) const {
1188
    return hydrogen()->handle(isolate);
1189
  }
1190
};
1191

    
1192

    
1193
class LBranch V8_FINAL : public LControlInstruction<1, 0> {
1194
 public:
1195
  explicit LBranch(LOperand* value) {
1196
    inputs_[0] = value;
1197
  }
1198

    
1199
  LOperand* value() { return inputs_[0]; }
1200

    
1201
  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1202
  DECLARE_HYDROGEN_ACCESSOR(Branch)
1203

    
1204
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1205
};
1206

    
1207

    
1208
class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> {
1209
 public:
1210
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
1211
};
1212

    
1213

    
1214
class LCmpMapAndBranch V8_FINAL : public LControlInstruction<1, 0> {
1215
 public:
1216
  explicit LCmpMapAndBranch(LOperand* value) {
1217
    inputs_[0] = value;
1218
  }
1219

    
1220
  LOperand* value() { return inputs_[0]; }
1221

    
1222
  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1223
  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1224

    
1225
  Handle<Map> map() const { return hydrogen()->map().handle(); }
1226
};
1227

    
1228

    
1229
class LMapEnumLength V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1230
 public:
1231
  explicit LMapEnumLength(LOperand* value) {
1232
    inputs_[0] = value;
1233
  }
1234

    
1235
  LOperand* value() { return inputs_[0]; }
1236

    
1237
  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1238
};
1239

    
1240

    
1241
class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1242
 public:
1243
  explicit LElementsKind(LOperand* value) {
1244
    inputs_[0] = value;
1245
  }
1246

    
1247
  LOperand* value() { return inputs_[0]; }
1248

    
1249
  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
1250
  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
1251
};
1252

    
1253

    
1254
class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1255
 public:
1256
  explicit LValueOf(LOperand* value) {
1257
    inputs_[0] = value;
1258
  }
1259

    
1260
  LOperand* value() { return inputs_[0]; }
1261

    
1262
  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1263
  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1264
};
1265

    
1266

    
1267
class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1268
 public:
1269
  LDateField(LOperand* date, Smi* index) : index_(index) {
1270
    inputs_[0] = date;
1271
  }
1272

    
1273
  LOperand* date() { return inputs_[0]; }
1274
  Smi* index() const { return index_; }
1275

    
1276
  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1277
  DECLARE_HYDROGEN_ACCESSOR(DateField)
1278

    
1279
 private:
1280
  Smi* index_;
1281
};
1282

    
1283

    
1284
class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1285
 public:
1286
  LSeqStringSetChar(String::Encoding encoding,
1287
                    LOperand* string,
1288
                    LOperand* index,
1289
                    LOperand* value) : encoding_(encoding) {
1290
    inputs_[0] = string;
1291
    inputs_[1] = index;
1292
    inputs_[2] = value;
1293
  }
1294

    
1295
  String::Encoding encoding() { return encoding_; }
1296
  LOperand* string() { return inputs_[0]; }
1297
  LOperand* index() { return inputs_[1]; }
1298
  LOperand* value() { return inputs_[2]; }
1299

    
1300
  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1301
  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1302

    
1303
 private:
1304
  String::Encoding encoding_;
1305
};
1306

    
1307

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

    
1314
  LOperand* value() { return inputs_[0]; }
1315

    
1316
  DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1317
};
1318

    
1319

    
1320
class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1321
 public:
1322
  LAddI(LOperand* left, LOperand* right) {
1323
    inputs_[0] = left;
1324
    inputs_[1] = right;
1325
  }
1326

    
1327
  LOperand* left() { return inputs_[0]; }
1328
  LOperand* right() { return inputs_[1]; }
1329

    
1330
  static bool UseLea(HAdd* add) {
1331
    return !add->CheckFlag(HValue::kCanOverflow) &&
1332
        add->BetterLeftOperand()->UseCount() > 1;
1333
  }
1334

    
1335
  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1336
  DECLARE_HYDROGEN_ACCESSOR(Add)
1337
};
1338

    
1339

    
1340
class LMathMinMax V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1341
 public:
1342
  LMathMinMax(LOperand* left, LOperand* right) {
1343
    inputs_[0] = left;
1344
    inputs_[1] = right;
1345
  }
1346

    
1347
  LOperand* left() { return inputs_[0]; }
1348
  LOperand* right() { return inputs_[1]; }
1349

    
1350
  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1351
  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1352
};
1353

    
1354

    
1355
class LPower V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1356
 public:
1357
  LPower(LOperand* left, LOperand* right) {
1358
    inputs_[0] = left;
1359
    inputs_[1] = right;
1360
  }
1361

    
1362
  LOperand* left() { return inputs_[0]; }
1363
  LOperand* right() { return inputs_[1]; }
1364

    
1365
  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1366
  DECLARE_HYDROGEN_ACCESSOR(Power)
1367
};
1368

    
1369

    
1370
class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
1371
 public:
1372
  LRandom(LOperand* global_object,
1373
          LOperand* scratch,
1374
          LOperand* scratch2,
1375
          LOperand* scratch3) {
1376
    inputs_[0] = global_object;
1377
    temps_[0] = scratch;
1378
    temps_[1] = scratch2;
1379
    temps_[2] = scratch3;
1380
  }
1381

    
1382
  LOperand* global_object() { return inputs_[0]; }
1383
  LOperand* scratch() const { return temps_[0]; }
1384
  LOperand* scratch2() const { return temps_[1]; }
1385
  LOperand* scratch3() const { return temps_[2]; }
1386

    
1387
  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
1388
  DECLARE_HYDROGEN_ACCESSOR(Random)
1389
};
1390

    
1391

    
1392
class LArithmeticD V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1393
 public:
1394
  LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1395
      : op_(op) {
1396
    inputs_[0] = left;
1397
    inputs_[1] = right;
1398
  }
1399

    
1400
  Token::Value op() const { return op_; }
1401
  LOperand* left() { return inputs_[0]; }
1402
  LOperand* right() { return inputs_[1]; }
1403

    
1404
  virtual Opcode opcode() const V8_OVERRIDE {
1405
    return LInstruction::kArithmeticD;
1406
  }
1407
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1408
  virtual const char* Mnemonic() const V8_OVERRIDE;
1409

    
1410
 private:
1411
  Token::Value op_;
1412
};
1413

    
1414

    
1415
class LArithmeticT V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1416
 public:
1417
  LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
1418
      : op_(op) {
1419
    inputs_[0] = left;
1420
    inputs_[1] = right;
1421
  }
1422

    
1423
  Token::Value op() const { return op_; }
1424
  LOperand* left() { return inputs_[0]; }
1425
  LOperand* right() { return inputs_[1]; }
1426

    
1427
  virtual Opcode opcode() const V8_OVERRIDE {
1428
    return LInstruction::kArithmeticT;
1429
  }
1430
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1431
  virtual const char* Mnemonic() const V8_OVERRIDE;
1432

    
1433
 private:
1434
  Token::Value op_;
1435
};
1436

    
1437

    
1438
class LReturn V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1439
 public:
1440
  explicit LReturn(LOperand* value, LOperand* parameter_count) {
1441
    inputs_[0] = value;
1442
    inputs_[1] = parameter_count;
1443
  }
1444

    
1445
  LOperand* value() { return inputs_[0]; }
1446

    
1447
  bool has_constant_parameter_count() {
1448
    return parameter_count()->IsConstantOperand();
1449
  }
1450
  LConstantOperand* constant_parameter_count() {
1451
    ASSERT(has_constant_parameter_count());
1452
    return LConstantOperand::cast(parameter_count());
1453
  }
1454
  LOperand* parameter_count() { return inputs_[1]; }
1455

    
1456
  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1457
  DECLARE_HYDROGEN_ACCESSOR(Return)
1458
};
1459

    
1460

    
1461
class LLoadNamedField V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1462
 public:
1463
  explicit LLoadNamedField(LOperand* object) {
1464
    inputs_[0] = object;
1465
  }
1466

    
1467
  LOperand* object() { return inputs_[0]; }
1468

    
1469
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1470
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1471
};
1472

    
1473

    
1474
class LLoadNamedGeneric V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1475
 public:
1476
  explicit LLoadNamedGeneric(LOperand* object) {
1477
    inputs_[0] = object;
1478
  }
1479

    
1480
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1481
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1482

    
1483
  LOperand* object() { return inputs_[0]; }
1484
  Handle<Object> name() const { return hydrogen()->name(); }
1485
};
1486

    
1487

    
1488
class LLoadFunctionPrototype V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1489
 public:
1490
  explicit LLoadFunctionPrototype(LOperand* function) {
1491
    inputs_[0] = function;
1492
  }
1493

    
1494
  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1495
  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1496

    
1497
  LOperand* function() { return inputs_[0]; }
1498
};
1499

    
1500

    
1501
class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1502
 public:
1503
  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1504
  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1505

    
1506
  Heap::RootListIndex index() const { return hydrogen()->index(); }
1507
};
1508

    
1509

    
1510
class LLoadExternalArrayPointer V8_FINAL
1511
    : public LTemplateInstruction<1, 1, 0> {
1512
 public:
1513
  explicit LLoadExternalArrayPointer(LOperand* object) {
1514
    inputs_[0] = object;
1515
  }
1516

    
1517
  LOperand* object() { return inputs_[0]; }
1518

    
1519
  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1520
                               "load-external-array-pointer")
1521
};
1522

    
1523

    
1524
class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1525
 public:
1526
  LLoadKeyed(LOperand* elements, LOperand* key) {
1527
    inputs_[0] = elements;
1528
    inputs_[1] = key;
1529
  }
1530

    
1531
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1532
  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1533

    
1534
  bool is_external() const {
1535
    return hydrogen()->is_external();
1536
  }
1537
  LOperand* elements() { return inputs_[0]; }
1538
  LOperand* key() { return inputs_[1]; }
1539
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1540
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1541
  ElementsKind elements_kind() const {
1542
    return hydrogen()->elements_kind();
1543
  }
1544
};
1545

    
1546

    
1547
class LLoadKeyedGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1548
 public:
1549
  LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
1550
    inputs_[0] = obj;
1551
    inputs_[1] = key;
1552
  }
1553

    
1554
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1555

    
1556
  LOperand* object() { return inputs_[0]; }
1557
  LOperand* key() { return inputs_[1]; }
1558
};
1559

    
1560

    
1561
class LLoadGlobalCell V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1562
 public:
1563
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1564
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1565
};
1566

    
1567

    
1568
class LLoadGlobalGeneric V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1569
 public:
1570
  explicit LLoadGlobalGeneric(LOperand* global_object) {
1571
    inputs_[0] = global_object;
1572
  }
1573

    
1574
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1575
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1576

    
1577
  LOperand* global_object() { return inputs_[0]; }
1578
  Handle<Object> name() const { return hydrogen()->name(); }
1579
  bool for_typeof() const { return hydrogen()->for_typeof(); }
1580
};
1581

    
1582

    
1583
class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 1> {
1584
 public:
1585
  explicit LStoreGlobalCell(LOperand* value, LOperand* temp) {
1586
    inputs_[0] = value;
1587
    temps_[0] = temp;
1588
  }
1589

    
1590
  LOperand* value() { return inputs_[0]; }
1591
  LOperand* temp() { return temps_[0]; }
1592

    
1593
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1594
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1595
};
1596

    
1597

    
1598
class LStoreGlobalGeneric V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1599
 public:
1600
  explicit LStoreGlobalGeneric(LOperand* global_object,
1601
                               LOperand* value) {
1602
    inputs_[0] = global_object;
1603
    inputs_[1] = value;
1604
  }
1605

    
1606
  LOperand* global_object() { return inputs_[0]; }
1607
  LOperand* value() { return inputs_[1]; }
1608

    
1609
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
1610
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
1611

    
1612
  Handle<Object> name() const { return hydrogen()->name(); }
1613
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1614
};
1615

    
1616

    
1617
class LLoadContextSlot V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1618
 public:
1619
  explicit LLoadContextSlot(LOperand* context) {
1620
    inputs_[0] = context;
1621
  }
1622

    
1623
  LOperand* context() { return inputs_[0]; }
1624

    
1625
  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1626
  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1627

    
1628
  int slot_index() { return hydrogen()->slot_index(); }
1629

    
1630
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1631
};
1632

    
1633

    
1634
class LStoreContextSlot V8_FINAL : public LTemplateInstruction<0, 2, 1> {
1635
 public:
1636
  LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
1637
    inputs_[0] = context;
1638
    inputs_[1] = value;
1639
    temps_[0] = temp;
1640
  }
1641

    
1642
  LOperand* context() { return inputs_[0]; }
1643
  LOperand* value() { return inputs_[1]; }
1644
  LOperand* temp() { return temps_[0]; }
1645

    
1646
  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1647
  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1648

    
1649
  int slot_index() { return hydrogen()->slot_index(); }
1650

    
1651
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1652
};
1653

    
1654

    
1655
class LPushArgument V8_FINAL : public LTemplateInstruction<0, 1, 0> {
1656
 public:
1657
  explicit LPushArgument(LOperand* value) {
1658
    inputs_[0] = value;
1659
  }
1660

    
1661
  LOperand* value() { return inputs_[0]; }
1662

    
1663
  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1664
};
1665

    
1666

    
1667
class LDrop V8_FINAL : public LTemplateInstruction<0, 0, 0> {
1668
 public:
1669
  explicit LDrop(int count) : count_(count) { }
1670

    
1671
  int count() const { return count_; }
1672

    
1673
  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1674

    
1675
 private:
1676
  int count_;
1677
};
1678

    
1679

    
1680
class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
1681
 public:
1682
  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1683
    inputs_[0] = function;
1684
    temps_[0] = code_object;
1685
  }
1686

    
1687
  LOperand* function() { return inputs_[0]; }
1688
  LOperand* code_object() { return temps_[0]; }
1689

    
1690
  virtual void PrintDataTo(StringStream* stream);
1691

    
1692
  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1693
  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1694
};
1695

    
1696

    
1697
class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
1698
 public:
1699
  explicit LInnerAllocatedObject(LOperand* base_object) {
1700
    inputs_[0] = base_object;
1701
  }
1702

    
1703
  LOperand* base_object() { return inputs_[0]; }
1704
  int offset() { return hydrogen()->offset(); }
1705

    
1706
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1707

    
1708
  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
1709
  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
1710
};
1711

    
1712

    
1713
class LThisFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1714
 public:
1715
  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1716
  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1717
};
1718

    
1719

    
1720
class LContext V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1721
 public:
1722
  DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1723
  DECLARE_HYDROGEN_ACCESSOR(Context)
1724
};
1725

    
1726

    
1727
class LOuterContext V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1728
 public:
1729
  explicit LOuterContext(LOperand* context) {
1730
    inputs_[0] = context;
1731
  }
1732

    
1733
  LOperand* context() { return inputs_[0]; }
1734

    
1735
  DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
1736
};
1737

    
1738

    
1739
class LDeclareGlobals V8_FINAL : public LTemplateInstruction<0, 0, 0> {
1740
 public:
1741
  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1742
  DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1743
};
1744

    
1745

    
1746
class LGlobalObject V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1747
 public:
1748
  DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1749
};
1750

    
1751

    
1752
class LGlobalReceiver V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1753
 public:
1754
  explicit LGlobalReceiver(LOperand* global_object) {
1755
    inputs_[0] = global_object;
1756
  }
1757

    
1758
  LOperand* global() { return inputs_[0]; }
1759

    
1760
  DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1761
};
1762

    
1763

    
1764
class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1765
 public:
1766
  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1767
  DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1768

    
1769
  virtual void PrintDataTo(StringStream* stream);
1770

    
1771
  Handle<JSFunction> function() { return hydrogen()->function(); }
1772
  int arity() const { return hydrogen()->argument_count() - 1; }
1773
};
1774

    
1775

    
1776
class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1777
 public:
1778
  explicit LInvokeFunction(LOperand* function) {
1779
    inputs_[0] = function;
1780
  }
1781

    
1782
  LOperand* function() { return inputs_[0]; }
1783

    
1784
  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1785
  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1786

    
1787
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1788

    
1789
  int arity() const { return hydrogen()->argument_count() - 1; }
1790
};
1791

    
1792

    
1793
class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1794
 public:
1795
  explicit LCallKeyed(LOperand* key) {
1796
    inputs_[0] = key;
1797
  }
1798

    
1799
  DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1800
  DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1801

    
1802
  LOperand* key() { return inputs_[0]; }
1803

    
1804
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1805

    
1806
  int arity() const { return hydrogen()->argument_count() - 1; }
1807
};
1808

    
1809

    
1810
class LCallNamed V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1811
 public:
1812
  DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1813
  DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1814

    
1815
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1816

    
1817
  Handle<String> name() const { return hydrogen()->name(); }
1818
  int arity() const { return hydrogen()->argument_count() - 1; }
1819
};
1820

    
1821

    
1822
class LCallFunction V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1823
 public:
1824
  explicit LCallFunction(LOperand* function) {
1825
    inputs_[0] = function;
1826
  }
1827

    
1828
  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1829
  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1830

    
1831
  LOperand* function() { return inputs_[0]; }
1832
  int arity() const { return hydrogen()->argument_count() - 1; }
1833
};
1834

    
1835

    
1836
class LCallGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1837
 public:
1838
  DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1839
  DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1840

    
1841
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1842

    
1843
  Handle<String> name() const {return hydrogen()->name(); }
1844
  int arity() const { return hydrogen()->argument_count() - 1; }
1845
};
1846

    
1847

    
1848
class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1849
 public:
1850
  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1851
  DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1852

    
1853
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1854

    
1855
  int arity() const { return hydrogen()->argument_count() - 1;  }
1856
};
1857

    
1858

    
1859
class LCallNew V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1860
 public:
1861
  explicit LCallNew(LOperand* constructor) {
1862
    inputs_[0] = constructor;
1863
  }
1864

    
1865
  LOperand* constructor() { return inputs_[0]; }
1866

    
1867
  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1868
  DECLARE_HYDROGEN_ACCESSOR(CallNew)
1869

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

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

    
1875

    
1876
class LCallNewArray V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1877
 public:
1878
  explicit LCallNewArray(LOperand* constructor) {
1879
    inputs_[0] = constructor;
1880
  }
1881

    
1882
  LOperand* constructor() { return inputs_[0]; }
1883

    
1884
  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
1885
  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
1886

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

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

    
1892

    
1893
class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1894
 public:
1895
  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1896
  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1897

    
1898
  virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
1899
    return save_doubles() == kDontSaveFPRegs;
1900
  }
1901

    
1902
  const Runtime::Function* function() const { return hydrogen()->function(); }
1903
  int arity() const { return hydrogen()->argument_count(); }
1904
  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
1905
};
1906

    
1907

    
1908
class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1909
 public:
1910
  explicit LInteger32ToDouble(LOperand* value) {
1911
    inputs_[0] = value;
1912
  }
1913

    
1914
  LOperand* value() { return inputs_[0]; }
1915

    
1916
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1917
};
1918

    
1919

    
1920
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1921
 public:
1922
  explicit LInteger32ToSmi(LOperand* value) {
1923
    inputs_[0] = value;
1924
  }
1925

    
1926
  LOperand* value() { return inputs_[0]; }
1927

    
1928
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
1929
  DECLARE_HYDROGEN_ACCESSOR(Change)
1930
};
1931

    
1932

    
1933
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1934
 public:
1935
  explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
1936
    inputs_[0] = value;
1937
    temps_[0] = temp;
1938
  }
1939

    
1940
  LOperand* value() { return inputs_[0]; }
1941
  LOperand* temp() { return temps_[0]; }
1942

    
1943
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
1944
};
1945

    
1946

    
1947
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1948
 public:
1949
  explicit LUint32ToSmi(LOperand* value) {
1950
    inputs_[0] = value;
1951
  }
1952

    
1953
  LOperand* value() { return inputs_[0]; }
1954

    
1955
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
1956
  DECLARE_HYDROGEN_ACCESSOR(Change)
1957
};
1958

    
1959

    
1960
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1961
 public:
1962
  explicit LNumberTagI(LOperand* value) {
1963
    inputs_[0] = value;
1964
  }
1965

    
1966
  LOperand* value() { return inputs_[0]; }
1967

    
1968
  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1969
};
1970

    
1971

    
1972
class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1973
 public:
1974
  explicit LNumberTagU(LOperand* value, LOperand* temp) {
1975
    inputs_[0] = value;
1976
    temps_[0] = temp;
1977
  }
1978

    
1979
  LOperand* value() { return inputs_[0]; }
1980
  LOperand* temp() { return temps_[0]; }
1981

    
1982
  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
1983
};
1984

    
1985

    
1986
class LNumberTagD V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1987
 public:
1988
  explicit LNumberTagD(LOperand* value, LOperand* temp) {
1989
    inputs_[0] = value;
1990
    temps_[0] = temp;
1991
  }
1992

    
1993
  LOperand* value() { return inputs_[0]; }
1994
  LOperand* temp() { return temps_[0]; }
1995

    
1996
  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1997
  DECLARE_HYDROGEN_ACCESSOR(Change)
1998
};
1999

    
2000

    
2001
// Sometimes truncating conversion from a tagged value to an int32.
2002
class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2003
 public:
2004
  explicit LDoubleToI(LOperand* value) {
2005
    inputs_[0] = value;
2006
  }
2007

    
2008
  LOperand* value() { return inputs_[0]; }
2009

    
2010
  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2011
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2012

    
2013
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2014
};
2015

    
2016

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

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

    
2025
  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2026
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2027
};
2028

    
2029

    
2030
// Truncating conversion from a tagged value to an int32.
2031
class LTaggedToI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2032
 public:
2033
  LTaggedToI(LOperand* value, LOperand* temp) {
2034
    inputs_[0] = value;
2035
    temps_[0] = temp;
2036
  }
2037

    
2038
  LOperand* value() { return inputs_[0]; }
2039
  LOperand* temp() { return temps_[0]; }
2040

    
2041
  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2042
  DECLARE_HYDROGEN_ACCESSOR(Change)
2043

    
2044
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2045
};
2046

    
2047

    
2048
class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2049
 public:
2050
  explicit LSmiTag(LOperand* value) {
2051
    inputs_[0] = value;
2052
  }
2053

    
2054
  LOperand* value() { return inputs_[0]; }
2055

    
2056
  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2057
};
2058

    
2059

    
2060
class LNumberUntagD V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2061
 public:
2062
  explicit LNumberUntagD(LOperand* value) {
2063
    inputs_[0] = value;
2064
  }
2065

    
2066
  LOperand* value() { return inputs_[0]; }
2067

    
2068
  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2069
  DECLARE_HYDROGEN_ACCESSOR(Change);
2070
};
2071

    
2072

    
2073
class LSmiUntag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2074
 public:
2075
  LSmiUntag(LOperand* value, bool needs_check)
2076
      : needs_check_(needs_check) {
2077
    inputs_[0] = value;
2078
  }
2079

    
2080
  LOperand* value() { return inputs_[0]; }
2081
  bool needs_check() const { return needs_check_; }
2082

    
2083
  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2084

    
2085
 private:
2086
  bool needs_check_;
2087
};
2088

    
2089

    
2090
class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
2091
 public:
2092
  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
2093
    inputs_[0] = object;
2094
    inputs_[1] = value;
2095
    temps_[0] = temp;
2096
  }
2097

    
2098
  LOperand* object() { return inputs_[0]; }
2099
  LOperand* value() { return inputs_[1]; }
2100
  LOperand* temp() { return temps_[0]; }
2101

    
2102
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2103
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2104

    
2105
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2106

    
2107
  Handle<Map> transition() const { return hydrogen()->transition_map(); }
2108
  Representation representation() const {
2109
    return hydrogen()->field_representation();
2110
  }
2111
};
2112

    
2113

    
2114
class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 2, 0> {
2115
 public:
2116
  LStoreNamedGeneric(LOperand* object, LOperand* value) {
2117
    inputs_[0] = object;
2118
    inputs_[1] = value;
2119
  }
2120

    
2121
  LOperand* object() { return inputs_[0]; }
2122
  LOperand* value() { return inputs_[1]; }
2123

    
2124
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2125
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2126

    
2127
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2128

    
2129
  Handle<Object> name() const { return hydrogen()->name(); }
2130
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2131
};
2132

    
2133

    
2134
class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2135
 public:
2136
  LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
2137
    inputs_[0] = object;
2138
    inputs_[1] = key;
2139
    inputs_[2] = value;
2140
  }
2141

    
2142
  bool is_external() const { return hydrogen()->is_external(); }
2143
  LOperand* elements() { return inputs_[0]; }
2144
  LOperand* key() { return inputs_[1]; }
2145
  LOperand* value() { return inputs_[2]; }
2146
  ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
2147

    
2148
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2149
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2150

    
2151
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2152
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2153
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
2154
};
2155

    
2156

    
2157
class LStoreKeyedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2158
 public:
2159
  LStoreKeyedGeneric(LOperand* object, LOperand* key, LOperand* value) {
2160
    inputs_[0] = object;
2161
    inputs_[1] = key;
2162
    inputs_[2] = value;
2163
  }
2164

    
2165
  LOperand* object() { return inputs_[0]; }
2166
  LOperand* key() { return inputs_[1]; }
2167
  LOperand* value() { return inputs_[2]; }
2168

    
2169
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2170
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2171

    
2172
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2173

    
2174
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2175
};
2176

    
2177

    
2178
class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 1, 2> {
2179
 public:
2180
  LTransitionElementsKind(LOperand* object,
2181
                          LOperand* new_map_temp,
2182
                          LOperand* temp) {
2183
    inputs_[0] = object;
2184
    temps_[0] = new_map_temp;
2185
    temps_[1] = temp;
2186
  }
2187

    
2188
  LOperand* object() { return inputs_[0]; }
2189
  LOperand* new_map_temp() { return temps_[0]; }
2190
  LOperand* temp() { return temps_[1]; }
2191

    
2192
  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2193
                               "transition-elements-kind")
2194
  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2195

    
2196
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2197

    
2198
  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2199
  Handle<Map> transitioned_map() {
2200
    return hydrogen()->transitioned_map().handle();
2201
  }
2202
  ElementsKind from_kind() { return hydrogen()->from_kind(); }
2203
  ElementsKind to_kind() { return hydrogen()->to_kind(); }
2204
};
2205

    
2206

    
2207
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
2208
 public:
2209
  LTrapAllocationMemento(LOperand* object,
2210
                         LOperand* temp) {
2211
    inputs_[0] = object;
2212
    temps_[0] = temp;
2213
  }
2214

    
2215
  LOperand* object() { return inputs_[0]; }
2216
  LOperand* temp() { return temps_[0]; }
2217

    
2218
  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2219
                               "trap-allocation-memento")
2220
};
2221

    
2222

    
2223
class LStringAdd V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2224
 public:
2225
  LStringAdd(LOperand* left, LOperand* right) {
2226
    inputs_[0] = left;
2227
    inputs_[1] = right;
2228
  }
2229

    
2230
  LOperand* left() { return inputs_[0]; }
2231
  LOperand* right() { return inputs_[1]; }
2232

    
2233
  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2234
  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2235
};
2236

    
2237

    
2238
class LStringCharCodeAt V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2239
 public:
2240
  LStringCharCodeAt(LOperand* string, LOperand* index) {
2241
    inputs_[0] = string;
2242
    inputs_[1] = index;
2243
  }
2244

    
2245
  LOperand* string() { return inputs_[0]; }
2246
  LOperand* index() { return inputs_[1]; }
2247

    
2248
  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2249
  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2250
};
2251

    
2252

    
2253
class LStringCharFromCode V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2254
 public:
2255
  explicit LStringCharFromCode(LOperand* char_code) {
2256
    inputs_[0] = char_code;
2257
  }
2258

    
2259
  LOperand* char_code() { return inputs_[0]; }
2260

    
2261
  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2262
  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2263
};
2264

    
2265

    
2266
class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2267
 public:
2268
  explicit LCheckValue(LOperand* value) {
2269
    inputs_[0] = value;
2270
  }
2271

    
2272
  LOperand* value() { return inputs_[0]; }
2273

    
2274
  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2275
  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2276
};
2277

    
2278

    
2279
class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2280
 public:
2281
  explicit LCheckInstanceType(LOperand* value) {
2282
    inputs_[0] = value;
2283
  }
2284

    
2285
  LOperand* value() { return inputs_[0]; }
2286

    
2287
  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2288
  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2289
};
2290

    
2291

    
2292
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2293
 public:
2294
  explicit LCheckMaps(LOperand* value) {
2295
    inputs_[0] = value;
2296
  }
2297

    
2298
  LOperand* value() { return inputs_[0]; }
2299

    
2300
  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2301
  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2302
};
2303

    
2304

    
2305
class LCheckSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2306
 public:
2307
  explicit LCheckSmi(LOperand* value) {
2308
    inputs_[0] = value;
2309
  }
2310

    
2311
  LOperand* value() { return inputs_[0]; }
2312

    
2313
  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2314
};
2315

    
2316

    
2317
class LClampDToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2318
 public:
2319
  explicit LClampDToUint8(LOperand* unclamped) {
2320
    inputs_[0] = unclamped;
2321
  }
2322

    
2323
  LOperand* unclamped() { return inputs_[0]; }
2324

    
2325
  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2326
};
2327

    
2328

    
2329
class LClampIToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2330
 public:
2331
  explicit LClampIToUint8(LOperand* unclamped) {
2332
    inputs_[0] = unclamped;
2333
  }
2334

    
2335
  LOperand* unclamped() { return inputs_[0]; }
2336

    
2337
  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2338
};
2339

    
2340

    
2341
class LClampTToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2342
 public:
2343
  LClampTToUint8(LOperand* unclamped,
2344
                 LOperand* temp_xmm) {
2345
    inputs_[0] = unclamped;
2346
    temps_[0] = temp_xmm;
2347
  }
2348

    
2349
  LOperand* unclamped() { return inputs_[0]; }
2350
  LOperand* temp_xmm() { return temps_[0]; }
2351

    
2352
  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2353
};
2354

    
2355

    
2356
class LCheckNonSmi V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2357
 public:
2358
  explicit LCheckNonSmi(LOperand* value) {
2359
    inputs_[0] = value;
2360
  }
2361

    
2362
  LOperand* value() { return inputs_[0]; }
2363

    
2364
  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2365
  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2366
};
2367

    
2368

    
2369
class LAllocate V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2370
 public:
2371
  LAllocate(LOperand* size, LOperand* temp) {
2372
    inputs_[0] = size;
2373
    temps_[0] = temp;
2374
  }
2375

    
2376
  LOperand* size() { return inputs_[0]; }
2377
  LOperand* temp() { return temps_[0]; }
2378

    
2379
  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2380
  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2381
};
2382

    
2383

    
2384
class LRegExpLiteral V8_FINAL : public LTemplateInstruction<1, 0, 0> {
2385
 public:
2386
  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2387
  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2388
};
2389

    
2390

    
2391
class LFunctionLiteral V8_FINAL : public LTemplateInstruction<1, 0, 0> {
2392
 public:
2393
  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2394
  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2395
};
2396

    
2397

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

    
2404
  LOperand* value() { return inputs_[0]; }
2405

    
2406
  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2407
  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2408
};
2409

    
2410

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

    
2417
  LOperand* value() { return inputs_[0]; }
2418

    
2419
  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2420
};
2421

    
2422

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

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

    
2431
  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2432
  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2433

    
2434
  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2435

    
2436
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2437
};
2438

    
2439

    
2440
class LIsConstructCallAndBranch V8_FINAL : public LControlInstruction<0, 1> {
2441
 public:
2442
  explicit LIsConstructCallAndBranch(LOperand* temp) {
2443
    temps_[0] = temp;
2444
  }
2445

    
2446
  LOperand* temp() { return temps_[0]; }
2447

    
2448
  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2449
                               "is-construct-call-and-branch")
2450
  DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch)
2451
};
2452

    
2453

    
2454
class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
2455
 public:
2456
  LOsrEntry() {}
2457

    
2458
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
2459
    return false;
2460
  }
2461
  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2462
};
2463

    
2464

    
2465
class LStackCheck V8_FINAL : public LTemplateInstruction<0, 0, 0> {
2466
 public:
2467
  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2468
  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2469

    
2470
  Label* done_label() { return &done_label_; }
2471

    
2472
 private:
2473
  Label done_label_;
2474
};
2475

    
2476

    
2477
class LForInPrepareMap V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2478
 public:
2479
  explicit LForInPrepareMap(LOperand* object) {
2480
    inputs_[0] = object;
2481
  }
2482

    
2483
  LOperand* object() { return inputs_[0]; }
2484

    
2485
  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2486
};
2487

    
2488

    
2489
class LForInCacheArray V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2490
 public:
2491
  explicit LForInCacheArray(LOperand* map) {
2492
    inputs_[0] = map;
2493
  }
2494

    
2495
  LOperand* map() { return inputs_[0]; }
2496

    
2497
  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2498

    
2499
  int idx() {
2500
    return HForInCacheArray::cast(this->hydrogen_value())->idx();
2501
  }
2502
};
2503

    
2504

    
2505
class LCheckMapValue V8_FINAL : public LTemplateInstruction<0, 2, 0> {
2506
 public:
2507
  LCheckMapValue(LOperand* value, LOperand* map) {
2508
    inputs_[0] = value;
2509
    inputs_[1] = map;
2510
  }
2511

    
2512
  LOperand* value() { return inputs_[0]; }
2513
  LOperand* map() { return inputs_[1]; }
2514

    
2515
  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2516
};
2517

    
2518

    
2519
class LLoadFieldByIndex V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2520
 public:
2521
  LLoadFieldByIndex(LOperand* object, LOperand* index) {
2522
    inputs_[0] = object;
2523
    inputs_[1] = index;
2524
  }
2525

    
2526
  LOperand* object() { return inputs_[0]; }
2527
  LOperand* index() { return inputs_[1]; }
2528

    
2529
  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2530
};
2531

    
2532

    
2533
class LChunkBuilder;
2534
class LPlatformChunk V8_FINAL : public LChunk {
2535
 public:
2536
  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2537
      : LChunk(info, graph) { }
2538

    
2539
  int GetNextSpillIndex(RegisterKind kind);
2540
  LOperand* GetNextSpillSlot(RegisterKind kind);
2541
};
2542

    
2543

    
2544
class LChunkBuilder V8_FINAL BASE_EMBEDDED {
2545
 public:
2546
  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2547
      : chunk_(NULL),
2548
        info_(info),
2549
        graph_(graph),
2550
        zone_(graph->zone()),
2551
        status_(UNUSED),
2552
        current_instruction_(NULL),
2553
        current_block_(NULL),
2554
        next_block_(NULL),
2555
        argument_count_(0),
2556
        allocator_(allocator),
2557
        instruction_pending_deoptimization_environment_(NULL),
2558
        pending_deoptimization_ast_id_(BailoutId::None()) { }
2559

    
2560
  // Build the sequence for the graph.
2561
  LPlatformChunk* Build();
2562

    
2563
  LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
2564

    
2565
  // Declare methods that deal with the individual node types.
2566
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2567
  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2568
#undef DECLARE_DO
2569

    
2570
  static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2571

    
2572
  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2573
  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2574
  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2575
  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2576
  LInstruction* DoMathSin(HUnaryMathOperation* instr);
2577
  LInstruction* DoMathCos(HUnaryMathOperation* instr);
2578
  LInstruction* DoMathTan(HUnaryMathOperation* instr);
2579
  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2580
  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2581
  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2582

    
2583
 private:
2584
  enum Status {
2585
    UNUSED,
2586
    BUILDING,
2587
    DONE,
2588
    ABORTED
2589
  };
2590

    
2591
  LPlatformChunk* chunk() const { return chunk_; }
2592
  CompilationInfo* info() const { return info_; }
2593
  HGraph* graph() const { return graph_; }
2594
  Zone* zone() const { return zone_; }
2595

    
2596
  bool is_unused() const { return status_ == UNUSED; }
2597
  bool is_building() const { return status_ == BUILDING; }
2598
  bool is_done() const { return status_ == DONE; }
2599
  bool is_aborted() const { return status_ == ABORTED; }
2600

    
2601
  void Abort(BailoutReason reason);
2602

    
2603
  // Methods for getting operands for Use / Define / Temp.
2604
  LUnallocated* ToUnallocated(Register reg);
2605
  LUnallocated* ToUnallocated(XMMRegister reg);
2606

    
2607
  // Methods for setting up define-use relationships.
2608
  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2609
  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2610
  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2611
                                           XMMRegister fixed_register);
2612

    
2613
  // A value that is guaranteed to be allocated to a register.
2614
  // Operand created by UseRegister is guaranteed to be live until the end of
2615
  // instruction. This means that register allocator will not reuse it's
2616
  // register for any other operand inside instruction.
2617
  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2618
  // instruction start. Register allocator is free to assign the same register
2619
  // to some other operand used inside instruction (i.e. temporary or
2620
  // output).
2621
  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2622
  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2623

    
2624
  // An input operand in a register that may be trashed.
2625
  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2626

    
2627
  // An input operand in a register or stack slot.
2628
  MUST_USE_RESULT LOperand* Use(HValue* value);
2629
  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2630

    
2631
  // An input operand in a register, stack slot or a constant operand.
2632
  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2633
  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2634

    
2635
  // An input operand in a register or a constant operand.
2636
  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2637
  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2638

    
2639
  // An input operand in a constant operand.
2640
  MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2641

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

    
2646
  // Temporary operand that must be in a register.
2647
  MUST_USE_RESULT LUnallocated* TempRegister();
2648
  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2649
  MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
2650

    
2651
  // Methods for setting up define-use relationships.
2652
  // Return the same instruction that they are passed.
2653
  template<int I, int T>
2654
      LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2655
                           LUnallocated* result);
2656
  template<int I, int T>
2657
      LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2658
  template<int I, int T>
2659
      LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2660
                                    int index);
2661
  template<int I, int T>
2662
      LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2663
  template<int I, int T>
2664
      LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2665
                                Register reg);
2666
  template<int I, int T>
2667
      LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2668
                                      XMMRegister reg);
2669
  // Assigns an environment to an instruction.  An instruction which can
2670
  // deoptimize must have an environment.
2671
  LInstruction* AssignEnvironment(LInstruction* instr);
2672
  // Assigns a pointer map to an instruction.  An instruction which can
2673
  // trigger a GC or a lazy deoptimization must have a pointer map.
2674
  LInstruction* AssignPointerMap(LInstruction* instr);
2675

    
2676
  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2677

    
2678
  // Marks a call for the register allocator.  Assigns a pointer map to
2679
  // support GC and lazy deoptimization.  Assigns an environment to support
2680
  // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
2681
  LInstruction* MarkAsCall(
2682
      LInstruction* instr,
2683
      HInstruction* hinstr,
2684
      CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2685

    
2686
  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2687
                                  int* argument_index_accumulator,
2688
                                  ZoneList<HValue*>* objects_to_materialize);
2689

    
2690
  void VisitInstruction(HInstruction* current);
2691

    
2692
  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2693
  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2694
  LInstruction* DoArithmeticD(Token::Value op,
2695
                              HArithmeticBinaryOperation* instr);
2696
  LInstruction* DoArithmeticT(Token::Value op,
2697
                              HBinaryOperation* instr);
2698

    
2699
  LPlatformChunk* chunk_;
2700
  CompilationInfo* info_;
2701
  HGraph* const graph_;
2702
  Zone* zone_;
2703
  Status status_;
2704
  HInstruction* current_instruction_;
2705
  HBasicBlock* current_block_;
2706
  HBasicBlock* next_block_;
2707
  int argument_count_;
2708
  LAllocator* allocator_;
2709
  LInstruction* instruction_pending_deoptimization_environment_;
2710
  BailoutId pending_deoptimization_ast_id_;
2711

    
2712
  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2713
};
2714

    
2715
#undef DECLARE_HYDROGEN_ACCESSOR
2716
#undef DECLARE_CONCRETE_INSTRUCTION
2717

    
2718
} }  // namespace v8::int
2719

    
2720
#endif  // V8_X64_LITHIUM_X64_H_