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

History | View | Annotate | Download (82.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_IA32_LITHIUM_IA32_H_
29
#define V8_IA32_LITHIUM_IA32_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(ClampTToUint8NoSSE2)                        \
75
  V(ClassOfTestAndBranch)                       \
76
  V(ClobberDoubles)                             \
77
  V(CompareNumericAndBranch)                    \
78
  V(CmpObjectEqAndBranch)                       \
79
  V(CmpHoleAndBranch)                           \
80
  V(CmpMapAndBranch)                            \
81
  V(CmpT)                                       \
82
  V(ConstantD)                                  \
83
  V(ConstantE)                                  \
84
  V(ConstantI)                                  \
85
  V(ConstantS)                                  \
86
  V(ConstantT)                                  \
87
  V(Context)                                    \
88
  V(DateField)                                  \
89
  V(DebugBreak)                                 \
90
  V(DeclareGlobals)                             \
91
  V(Deoptimize)                                 \
92
  V(DivI)                                       \
93
  V(DoubleToI)                                  \
94
  V(DoubleToSmi)                                \
95
  V(Drop)                                       \
96
  V(DummyUse)                                   \
97
  V(ElementsKind)                               \
98
  V(ForInCacheArray)                            \
99
  V(ForInPrepareMap)                            \
100
  V(FunctionLiteral)                            \
101
  V(GetCachedArrayIndex)                        \
102
  V(GlobalObject)                               \
103
  V(GlobalReceiver)                             \
104
  V(Goto)                                       \
105
  V(HasCachedArrayIndexAndBranch)               \
106
  V(HasInstanceTypeAndBranch)                   \
107
  V(InnerAllocatedObject)                       \
108
  V(InstanceOf)                                 \
109
  V(InstanceOfKnownGlobal)                      \
110
  V(InstructionGap)                             \
111
  V(Integer32ToDouble)                          \
112
  V(Integer32ToSmi)                             \
113
  V(InvokeFunction)                             \
114
  V(IsConstructCallAndBranch)                   \
115
  V(IsObjectAndBranch)                          \
116
  V(IsStringAndBranch)                          \
117
  V(IsSmiAndBranch)                             \
118
  V(IsUndetectableAndBranch)                    \
119
  V(Label)                                      \
120
  V(LazyBailout)                                \
121
  V(LoadContextSlot)                            \
122
  V(LoadExternalArrayPointer)                   \
123
  V(LoadFieldByIndex)                           \
124
  V(LoadFunctionPrototype)                      \
125
  V(LoadGlobalCell)                             \
126
  V(LoadGlobalGeneric)                          \
127
  V(LoadKeyed)                                  \
128
  V(LoadKeyedGeneric)                           \
129
  V(LoadNamedField)                             \
130
  V(LoadNamedGeneric)                           \
131
  V(LoadRoot)                                   \
132
  V(MapEnumLength)                              \
133
  V(MathAbs)                                    \
134
  V(MathCos)                                    \
135
  V(MathExp)                                    \
136
  V(MathFloor)                                  \
137
  V(MathFloorOfDiv)                             \
138
  V(MathLog)                                    \
139
  V(MathMinMax)                                 \
140
  V(MathPowHalf)                                \
141
  V(MathRound)                                  \
142
  V(MathSin)                                    \
143
  V(MathSqrt)                                   \
144
  V(MathTan)                                    \
145
  V(ModI)                                       \
146
  V(MulI)                                       \
147
  V(NumberTagD)                                 \
148
  V(NumberTagI)                                 \
149
  V(NumberTagU)                                 \
150
  V(NumberUntagD)                               \
151
  V(OsrEntry)                                   \
152
  V(OuterContext)                               \
153
  V(Parameter)                                  \
154
  V(Power)                                      \
155
  V(Random)                                     \
156
  V(PushArgument)                               \
157
  V(RegExpLiteral)                              \
158
  V(Return)                                     \
159
  V(SeqStringSetChar)                           \
160
  V(ShiftI)                                     \
161
  V(SmiTag)                                     \
162
  V(SmiUntag)                                   \
163
  V(StackCheck)                                 \
164
  V(StoreCodeEntry)                             \
165
  V(StoreContextSlot)                           \
166
  V(StoreGlobalCell)                            \
167
  V(StoreGlobalGeneric)                         \
168
  V(StoreKeyed)                                 \
169
  V(StoreKeyedGeneric)                          \
170
  V(StoreNamedField)                            \
171
  V(StoreNamedGeneric)                          \
172
  V(StringAdd)                                  \
173
  V(StringCharCodeAt)                           \
174
  V(StringCharFromCode)                         \
175
  V(StringCompareAndBranch)                     \
176
  V(SubI)                                       \
177
  V(TaggedToI)                                  \
178
  V(ThisFunction)                               \
179
  V(Throw)                                      \
180
  V(ToFastProperties)                           \
181
  V(TransitionElementsKind)                     \
182
  V(TrapAllocationMemento)                      \
183
  V(Typeof)                                     \
184
  V(TypeofIsAndBranch)                          \
185
  V(Uint32ToDouble)                             \
186
  V(Uint32ToSmi)                                \
187
  V(UnknownOSRValue)                            \
188
  V(ValueOf)                                    \
189
  V(WrapReceiver)
190

    
191

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

    
205

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

    
211

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

    
220
  virtual ~LInstruction() {}
221

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

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

    
236
  virtual Opcode opcode() const = 0;
237

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

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

    
248
  virtual bool IsControl() const { return false; }
249

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

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

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

    
261
  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
262

    
263
  void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
264
  bool IsCall() const { return IsCallBits::decode(bit_field_); }
265

    
266
  // Interface to the register allocator and iterators.
267
  bool ClobbersTemps() const { return IsCall(); }
268
  bool ClobbersRegisters() const { return IsCall(); }
269
  virtual bool ClobbersDoubleRegisters() const {
270
    return IsCall() ||
271
           // We only have rudimentary X87Stack tracking, thus in general
272
           // cannot handle phi-nodes.
273
           (!CpuFeatures::IsSafeForSnapshot(SSE2) && IsControl());
274
  }
275

    
276
  virtual bool HasResult() const = 0;
277
  virtual LOperand* result() const = 0;
278

    
279
  bool HasDoubleRegisterResult();
280
  bool HasDoubleRegisterInput();
281
  bool IsDoubleInput(X87Register reg, LCodeGen* cgen);
282

    
283
  LOperand* FirstInput() { return InputAt(0); }
284
  LOperand* Output() { return HasResult() ? result() : NULL; }
285

    
286
  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
287

    
288
#ifdef DEBUG
289
  void VerifyCall();
290
#endif
291

    
292
 private:
293
  // Iterator support.
294
  friend class InputIterator;
295
  virtual int InputCount() = 0;
296
  virtual LOperand* InputAt(int i) = 0;
297

    
298
  friend class TempIterator;
299
  virtual int TempCount() = 0;
300
  virtual LOperand* TempAt(int i) = 0;
301

    
302
  class IsCallBits: public BitField<bool, 0, 1> {};
303

    
304
  LEnvironment* environment_;
305
  SetOncePointer<LPointerMap> pointer_map_;
306
  HValue* hydrogen_value_;
307
  int bit_field_;
308
};
309

    
310

    
311
// R = number of result operands (0 or 1).
312
// I = number of input operands.
313
// T = number of temporary operands.
314
template<int R, int I, int T>
315
class LTemplateInstruction : public LInstruction {
316
 public:
317
  // Allow 0 or 1 output operands.
318
  STATIC_ASSERT(R == 0 || R == 1);
319
  virtual bool HasResult() const V8_FINAL V8_OVERRIDE {
320
    return R != 0 && result() != NULL;
321
  }
322
  void set_result(LOperand* operand) { results_[0] = operand; }
323
  LOperand* result() const { return results_[0]; }
324

    
325
 protected:
326
  EmbeddedContainer<LOperand*, R> results_;
327
  EmbeddedContainer<LOperand*, I> inputs_;
328
  EmbeddedContainer<LOperand*, T> temps_;
329

    
330
 private:
331
  // Iterator support.
332
  virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
333
  virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
334

    
335
  virtual int TempCount() V8_FINAL V8_OVERRIDE { return T; }
336
  virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return temps_[i]; }
337
};
338

    
339

    
340
class LGap : public LTemplateInstruction<0, 0, 0> {
341
 public:
342
  explicit LGap(HBasicBlock* block) : block_(block) {
343
    parallel_moves_[BEFORE] = NULL;
344
    parallel_moves_[START] = NULL;
345
    parallel_moves_[END] = NULL;
346
    parallel_moves_[AFTER] = NULL;
347
  }
348

    
349
  // Can't use the DECLARE-macro here because of sub-classes.
350
  virtual bool IsGap() const V8_FINAL V8_OVERRIDE { return true; }
351
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
352
  static LGap* cast(LInstruction* instr) {
353
    ASSERT(instr->IsGap());
354
    return reinterpret_cast<LGap*>(instr);
355
  }
356

    
357
  bool IsRedundant() const;
358

    
359
  HBasicBlock* block() const { return block_; }
360

    
361
  enum InnerPosition {
362
    BEFORE,
363
    START,
364
    END,
365
    AFTER,
366
    FIRST_INNER_POSITION = BEFORE,
367
    LAST_INNER_POSITION = AFTER
368
  };
369

    
370
  LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone)  {
371
    if (parallel_moves_[pos] == NULL) {
372
      parallel_moves_[pos] = new(zone) LParallelMove(zone);
373
    }
374
    return parallel_moves_[pos];
375
  }
376

    
377
  LParallelMove* GetParallelMove(InnerPosition pos)  {
378
    return parallel_moves_[pos];
379
  }
380

    
381
 private:
382
  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
383
  HBasicBlock* block_;
384
};
385

    
386

    
387
class LInstructionGap V8_FINAL : public LGap {
388
 public:
389
  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
390

    
391
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
392
    return !IsRedundant();
393
  }
394

    
395
  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
396
};
397

    
398

    
399
class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> {
400
 public:
401
  LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); }
402

    
403
  virtual bool ClobbersDoubleRegisters() const { return true; }
404

    
405
  DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d")
406
};
407

    
408

    
409
class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
410
 public:
411
  explicit LGoto(HBasicBlock* block) : block_(block) { }
412

    
413
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
414
  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
415
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
416
  virtual bool IsControl() const V8_OVERRIDE { return true; }
417

    
418
  int block_id() const { return block_->block_id(); }
419
  virtual bool ClobbersDoubleRegisters() const { return false; }
420

    
421
  bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
422

    
423
 private:
424
  HBasicBlock* block_;
425
};
426

    
427

    
428
class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
429
 public:
430
  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
431
};
432

    
433

    
434
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
435
 public:
436
  explicit LDummyUse(LOperand* value) {
437
    inputs_[0] = value;
438
  }
439
  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
440
};
441

    
442

    
443
class LDeoptimize V8_FINAL : public LTemplateInstruction<0, 0, 0> {
444
 public:
445
  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
446
  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
447
};
448

    
449

    
450
class LLabel V8_FINAL : public LGap {
451
 public:
452
  explicit LLabel(HBasicBlock* block)
453
      : LGap(block), replacement_(NULL) { }
454

    
455
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
456
    return false;
457
  }
458
  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
459

    
460
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
461

    
462
  int block_id() const { return block()->block_id(); }
463
  bool is_loop_header() const { return block()->IsLoopHeader(); }
464
  bool is_osr_entry() const { return block()->is_osr_entry(); }
465
  Label* label() { return &label_; }
466
  LLabel* replacement() const { return replacement_; }
467
  void set_replacement(LLabel* label) { replacement_ = label; }
468
  bool HasReplacement() const { return replacement_ != NULL; }
469

    
470
 private:
471
  Label label_;
472
  LLabel* replacement_;
473
};
474

    
475

    
476
class LParameter V8_FINAL : public LTemplateInstruction<1, 0, 0> {
477
 public:
478
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
479
    return false;
480
  }
481
  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
482
};
483

    
484

    
485
class LCallStub V8_FINAL : public LTemplateInstruction<1, 1, 0> {
486
 public:
487
  explicit LCallStub(LOperand* context) {
488
    inputs_[0] = context;
489
  }
490

    
491
  LOperand* context() { return inputs_[0]; }
492

    
493
  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
494
  DECLARE_HYDROGEN_ACCESSOR(CallStub)
495

    
496
  TranscendentalCache::Type transcendental_type() {
497
    return hydrogen()->transcendental_type();
498
  }
499
};
500

    
501

    
502
class LUnknownOSRValue V8_FINAL : public LTemplateInstruction<1, 0, 0> {
503
 public:
504
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
505
    return false;
506
  }
507
  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
508
};
509

    
510

    
511
template<int I, int T>
512
class LControlInstruction: public LTemplateInstruction<0, I, T> {
513
 public:
514
  LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
515

    
516
  virtual bool IsControl() const V8_FINAL V8_OVERRIDE { return true; }
517

    
518
  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
519
  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
520

    
521
  int TrueDestination(LChunk* chunk) {
522
    return chunk->LookupDestination(true_block_id());
523
  }
524
  int FalseDestination(LChunk* chunk) {
525
    return chunk->LookupDestination(false_block_id());
526
  }
527

    
528
  Label* TrueLabel(LChunk* chunk) {
529
    if (true_label_ == NULL) {
530
      true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
531
    }
532
    return true_label_;
533
  }
534
  Label* FalseLabel(LChunk* chunk) {
535
    if (false_label_ == NULL) {
536
      false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
537
    }
538
    return false_label_;
539
  }
540

    
541
 protected:
542
  int true_block_id() { return SuccessorAt(0)->block_id(); }
543
  int false_block_id() { return SuccessorAt(1)->block_id(); }
544

    
545
 private:
546
  HControlInstruction* hydrogen() {
547
    return HControlInstruction::cast(this->hydrogen_value());
548
  }
549

    
550
  Label* false_label_;
551
  Label* true_label_;
552
};
553

    
554

    
555
class LWrapReceiver V8_FINAL : public LTemplateInstruction<1, 2, 1> {
556
 public:
557
  LWrapReceiver(LOperand* receiver,
558
                LOperand* function,
559
                LOperand* temp) {
560
    inputs_[0] = receiver;
561
    inputs_[1] = function;
562
    temps_[0] = temp;
563
  }
564

    
565
  LOperand* receiver() { return inputs_[0]; }
566
  LOperand* function() { return inputs_[1]; }
567
  LOperand* temp() { return temps_[0]; }
568

    
569
  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
570
};
571

    
572

    
573
class LApplyArguments V8_FINAL : public LTemplateInstruction<1, 4, 0> {
574
 public:
575
  LApplyArguments(LOperand* function,
576
                  LOperand* receiver,
577
                  LOperand* length,
578
                  LOperand* elements) {
579
    inputs_[0] = function;
580
    inputs_[1] = receiver;
581
    inputs_[2] = length;
582
    inputs_[3] = elements;
583
  }
584

    
585
  LOperand* function() { return inputs_[0]; }
586
  LOperand* receiver() { return inputs_[1]; }
587
  LOperand* length() { return inputs_[2]; }
588
  LOperand* elements() { return inputs_[3]; }
589

    
590
  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
591
};
592

    
593

    
594
class LAccessArgumentsAt V8_FINAL : public LTemplateInstruction<1, 3, 0> {
595
 public:
596
  LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
597
    inputs_[0] = arguments;
598
    inputs_[1] = length;
599
    inputs_[2] = index;
600
  }
601

    
602
  LOperand* arguments() { return inputs_[0]; }
603
  LOperand* length() { return inputs_[1]; }
604
  LOperand* index() { return inputs_[2]; }
605

    
606
  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
607

    
608
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
609
};
610

    
611

    
612
class LArgumentsLength V8_FINAL : public LTemplateInstruction<1, 1, 0> {
613
 public:
614
  explicit LArgumentsLength(LOperand* elements) {
615
    inputs_[0] = elements;
616
  }
617

    
618
  LOperand* elements() { return inputs_[0]; }
619

    
620
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
621
};
622

    
623

    
624
class LArgumentsElements V8_FINAL : public LTemplateInstruction<1, 0, 0> {
625
 public:
626
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
627
  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
628
};
629

    
630

    
631
class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> {
632
 public:
633
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
634
};
635

    
636

    
637
class LModI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
638
 public:
639
  LModI(LOperand* left, LOperand* right, LOperand* temp) {
640
    inputs_[0] = left;
641
    inputs_[1] = right;
642
    temps_[0] = temp;
643
  }
644

    
645
  LOperand* left() { return inputs_[0]; }
646
  LOperand* right() { return inputs_[1]; }
647
  LOperand* temp() { return temps_[0]; }
648

    
649
  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
650
  DECLARE_HYDROGEN_ACCESSOR(Mod)
651
};
652

    
653

    
654
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
655
 public:
656
  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
657
    inputs_[0] = left;
658
    inputs_[1] = right;
659
    temps_[0] = temp;
660
  }
661

    
662
  LOperand* left() { return inputs_[0]; }
663
  LOperand* right() { return inputs_[1]; }
664

    
665
  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
666

    
667
  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
668
  DECLARE_HYDROGEN_ACCESSOR(Div)
669
};
670

    
671

    
672
class LMathFloorOfDiv V8_FINAL : public LTemplateInstruction<1, 2, 1> {
673
 public:
674
  LMathFloorOfDiv(LOperand* left,
675
                  LOperand* right,
676
                  LOperand* temp = NULL) {
677
    inputs_[0] = left;
678
    inputs_[1] = right;
679
    temps_[0] = temp;
680
  }
681

    
682
  LOperand* left() { return inputs_[0]; }
683
  LOperand* right() { return inputs_[1]; }
684
  LOperand* temp() { return temps_[0]; }
685

    
686
  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
687
  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
688
};
689

    
690

    
691
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
692
 public:
693
  LMulI(LOperand* left, LOperand* right, LOperand* temp) {
694
    inputs_[0] = left;
695
    inputs_[1] = right;
696
    temps_[0] = temp;
697
  }
698

    
699
  LOperand* left() { return inputs_[0]; }
700
  LOperand* right() { return inputs_[1]; }
701
  LOperand* temp() { return temps_[0]; }
702

    
703
  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
704
  DECLARE_HYDROGEN_ACCESSOR(Mul)
705
};
706

    
707

    
708
class LCompareNumericAndBranch V8_FINAL : public LControlInstruction<2, 0> {
709
 public:
710
  LCompareNumericAndBranch(LOperand* left, LOperand* right) {
711
    inputs_[0] = left;
712
    inputs_[1] = right;
713
  }
714

    
715
  LOperand* left() { return inputs_[0]; }
716
  LOperand* right() { return inputs_[1]; }
717

    
718
  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
719
                               "compare-numeric-and-branch")
720
  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
721

    
722
  Token::Value op() const { return hydrogen()->token(); }
723
  bool is_double() const {
724
    return hydrogen()->representation().IsDouble();
725
  }
726

    
727
  virtual void PrintDataTo(StringStream* stream);
728
};
729

    
730

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

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

    
739
  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
740
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
741
};
742

    
743

    
744
class LMathRound V8_FINAL : public LTemplateInstruction<1, 2, 1> {
745
 public:
746
  LMathRound(LOperand* context, LOperand* value, LOperand* temp) {
747
    inputs_[1] = context;
748
    inputs_[0] = value;
749
    temps_[0] = temp;
750
  }
751

    
752
  LOperand* context() { return inputs_[1]; }
753
  LOperand* value() { return inputs_[0]; }
754
  LOperand* temp() { return temps_[0]; }
755

    
756
  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
757
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
758
};
759

    
760

    
761
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
762
 public:
763
  LMathAbs(LOperand* context, LOperand* value) {
764
    inputs_[1] = context;
765
    inputs_[0] = value;
766
  }
767

    
768
  LOperand* context() { return inputs_[1]; }
769
  LOperand* value() { return inputs_[0]; }
770

    
771
  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
772
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
773
};
774

    
775

    
776
class LMathLog V8_FINAL : public LTemplateInstruction<1, 1, 0> {
777
 public:
778
  explicit LMathLog(LOperand* value) {
779
    inputs_[0] = value;
780
  }
781

    
782
  LOperand* value() { return inputs_[0]; }
783

    
784
  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
785
};
786

    
787

    
788
class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
789
 public:
790
  explicit LMathSin(LOperand* value) {
791
    inputs_[0] = value;
792
  }
793

    
794
  LOperand* value() { return inputs_[0]; }
795

    
796
  DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
797
};
798

    
799

    
800
class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
801
 public:
802
  explicit LMathCos(LOperand* value) {
803
    inputs_[0] = value;
804
  }
805

    
806
  LOperand* value() { return inputs_[0]; }
807

    
808
  DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
809
};
810

    
811

    
812
class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
813
 public:
814
  explicit LMathTan(LOperand* value) {
815
    inputs_[0] = value;
816
  }
817

    
818
  LOperand* value() { return inputs_[0]; }
819

    
820
  DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
821
};
822

    
823

    
824
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
825
 public:
826
  LMathExp(LOperand* value,
827
           LOperand* temp1,
828
           LOperand* temp2) {
829
    inputs_[0] = value;
830
    temps_[0] = temp1;
831
    temps_[1] = temp2;
832
    ExternalReference::InitializeMathExpData();
833
  }
834

    
835
  LOperand* value() { return inputs_[0]; }
836
  LOperand* temp1() { return temps_[0]; }
837
  LOperand* temp2() { return temps_[1]; }
838

    
839
  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
840
};
841

    
842

    
843
class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
844
 public:
845
  explicit LMathSqrt(LOperand* value) {
846
    inputs_[0] = value;
847
  }
848

    
849
  LOperand* value() { return inputs_[0]; }
850

    
851
  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
852
};
853

    
854

    
855
class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 2, 1> {
856
 public:
857
  LMathPowHalf(LOperand* context, LOperand* value, LOperand* temp) {
858
    inputs_[1] = context;
859
    inputs_[0] = value;
860
    temps_[0] = temp;
861
  }
862

    
863
  LOperand* context() { return inputs_[1]; }
864
  LOperand* value() { return inputs_[0]; }
865
  LOperand* temp() { return temps_[0]; }
866

    
867
  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
868
};
869

    
870

    
871
class LCmpObjectEqAndBranch V8_FINAL : public LControlInstruction<2, 0> {
872
 public:
873
  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
874
    inputs_[0] = left;
875
    inputs_[1] = right;
876
  }
877

    
878
  LOperand* left() { return inputs_[0]; }
879
  LOperand* right() { return inputs_[1]; }
880

    
881
  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
882
};
883

    
884

    
885
class LCmpHoleAndBranch V8_FINAL : public LControlInstruction<1, 0> {
886
 public:
887
  explicit LCmpHoleAndBranch(LOperand* object) {
888
    inputs_[0] = object;
889
  }
890

    
891
  LOperand* object() { return inputs_[0]; }
892

    
893
  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
894
  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
895
};
896

    
897

    
898
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
899
 public:
900
  LIsObjectAndBranch(LOperand* value, LOperand* temp) {
901
    inputs_[0] = value;
902
    temps_[0] = temp;
903
  }
904

    
905
  LOperand* value() { return inputs_[0]; }
906
  LOperand* temp() { return temps_[0]; }
907

    
908
  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
909

    
910
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
911
};
912

    
913

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

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

    
924
  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
925
  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
926

    
927
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
928
};
929

    
930

    
931
class LIsSmiAndBranch V8_FINAL : public LControlInstruction<1, 0> {
932
 public:
933
  explicit LIsSmiAndBranch(LOperand* value) {
934
    inputs_[0] = value;
935
  }
936

    
937
  LOperand* value() { return inputs_[0]; }
938

    
939
  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
940
  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
941

    
942
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
943
};
944

    
945

    
946
class LIsUndetectableAndBranch V8_FINAL : public LControlInstruction<1, 1> {
947
 public:
948
  LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
949
    inputs_[0] = value;
950
    temps_[0] = temp;
951
  }
952

    
953
  LOperand* value() { return inputs_[0]; }
954
  LOperand* temp() { return temps_[0]; }
955

    
956
  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
957
                               "is-undetectable-and-branch")
958
  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
959

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

    
963

    
964
class LStringCompareAndBranch V8_FINAL : public LControlInstruction<3, 0> {
965
 public:
966
  LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
967
    inputs_[0] = context;
968
    inputs_[1] = left;
969
    inputs_[2] = right;
970
  }
971

    
972
  LOperand* left() { return inputs_[1]; }
973
  LOperand* right() { return inputs_[2]; }
974

    
975
  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
976
                               "string-compare-and-branch")
977
  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
978

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

    
981
  Token::Value op() const { return hydrogen()->token(); }
982
};
983

    
984

    
985
class LHasInstanceTypeAndBranch V8_FINAL : public LControlInstruction<1, 1> {
986
 public:
987
  LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) {
988
    inputs_[0] = value;
989
    temps_[0] = temp;
990
  }
991

    
992
  LOperand* value() { return inputs_[0]; }
993
  LOperand* temp() { return temps_[0]; }
994

    
995
  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
996
                               "has-instance-type-and-branch")
997
  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
998

    
999
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1000
};
1001

    
1002

    
1003
class LGetCachedArrayIndex V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1004
 public:
1005
  explicit LGetCachedArrayIndex(LOperand* value) {
1006
    inputs_[0] = value;
1007
  }
1008

    
1009
  LOperand* value() { return inputs_[0]; }
1010

    
1011
  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1012
  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1013
};
1014

    
1015

    
1016
class LHasCachedArrayIndexAndBranch V8_FINAL
1017
    : public LControlInstruction<1, 0> {
1018
 public:
1019
  explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
1020
    inputs_[0] = value;
1021
  }
1022

    
1023
  LOperand* value() { return inputs_[0]; }
1024

    
1025
  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1026
                               "has-cached-array-index-and-branch")
1027

    
1028
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1029
};
1030

    
1031

    
1032
class LIsConstructCallAndBranch V8_FINAL : public LControlInstruction<0, 1> {
1033
 public:
1034
  explicit LIsConstructCallAndBranch(LOperand* temp) {
1035
    temps_[0] = temp;
1036
  }
1037

    
1038
  LOperand* temp() { return temps_[0]; }
1039

    
1040
  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
1041
                               "is-construct-call-and-branch")
1042
};
1043

    
1044

    
1045
class LClassOfTestAndBranch V8_FINAL : public LControlInstruction<1, 2> {
1046
 public:
1047
  LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
1048
    inputs_[0] = value;
1049
    temps_[0] = temp;
1050
    temps_[1] = temp2;
1051
  }
1052

    
1053
  LOperand* value() { return inputs_[0]; }
1054
  LOperand* temp() { return temps_[0]; }
1055
  LOperand* temp2() { return temps_[1]; }
1056

    
1057
  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1058
                               "class-of-test-and-branch")
1059
  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1060

    
1061
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1062
};
1063

    
1064

    
1065
class LCmpT V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1066
 public:
1067
  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1068
    inputs_[0] = context;
1069
    inputs_[1] = left;
1070
    inputs_[2] = right;
1071
  }
1072

    
1073
  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1074
  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1075

    
1076
  Token::Value op() const { return hydrogen()->token(); }
1077
};
1078

    
1079

    
1080
class LInstanceOf V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1081
 public:
1082
  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1083
    inputs_[0] = context;
1084
    inputs_[1] = left;
1085
    inputs_[2] = right;
1086
  }
1087

    
1088
  LOperand* context() { return inputs_[0]; }
1089

    
1090
  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1091
};
1092

    
1093

    
1094
class LInstanceOfKnownGlobal V8_FINAL : public LTemplateInstruction<1, 2, 1> {
1095
 public:
1096
  LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
1097
    inputs_[0] = context;
1098
    inputs_[1] = value;
1099
    temps_[0] = temp;
1100
  }
1101

    
1102
  LOperand* value() { return inputs_[1]; }
1103
  LOperand* temp() { return temps_[0]; }
1104

    
1105
  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1106
                               "instance-of-known-global")
1107
  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1108

    
1109
  Handle<JSFunction> function() const { return hydrogen()->function(); }
1110
  LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
1111
    return lazy_deopt_env_;
1112
  }
1113
  virtual void SetDeferredLazyDeoptimizationEnvironment(
1114
      LEnvironment* env) V8_OVERRIDE {
1115
    lazy_deopt_env_ = env;
1116
  }
1117

    
1118
 private:
1119
  LEnvironment* lazy_deopt_env_;
1120
};
1121

    
1122

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

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

    
1133
  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1134
  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1135
};
1136

    
1137

    
1138
class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1139
 public:
1140
  LBitI(LOperand* left, LOperand* right) {
1141
    inputs_[0] = left;
1142
    inputs_[1] = right;
1143
  }
1144

    
1145
  LOperand* left() { return inputs_[0]; }
1146
  LOperand* right() { return inputs_[1]; }
1147

    
1148
  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1149
  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1150

    
1151
  Token::Value op() const { return hydrogen()->op(); }
1152
};
1153

    
1154

    
1155
class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1156
 public:
1157
  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1158
      : op_(op), can_deopt_(can_deopt) {
1159
    inputs_[0] = left;
1160
    inputs_[1] = right;
1161
  }
1162

    
1163
  LOperand* left() { return inputs_[0]; }
1164
  LOperand* right() { return inputs_[1]; }
1165

    
1166
  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1167

    
1168
  Token::Value op() const { return op_; }
1169
  bool can_deopt() const { return can_deopt_; }
1170

    
1171
 private:
1172
  Token::Value op_;
1173
  bool can_deopt_;
1174
};
1175

    
1176

    
1177
class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1178
 public:
1179
  LSubI(LOperand* left, LOperand* right) {
1180
    inputs_[0] = left;
1181
    inputs_[1] = right;
1182
  }
1183

    
1184
  LOperand* left() { return inputs_[0]; }
1185
  LOperand* right() { return inputs_[1]; }
1186

    
1187
  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1188
  DECLARE_HYDROGEN_ACCESSOR(Sub)
1189
};
1190

    
1191

    
1192
class LConstantI V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1193
 public:
1194
  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1195
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1196

    
1197
  int32_t value() const { return hydrogen()->Integer32Value(); }
1198
};
1199

    
1200

    
1201
class LConstantS V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1202
 public:
1203
  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1204
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1205

    
1206
  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1207
};
1208

    
1209

    
1210
class LConstantD V8_FINAL : public LTemplateInstruction<1, 0, 1> {
1211
 public:
1212
  explicit LConstantD(LOperand* temp) {
1213
    temps_[0] = temp;
1214
  }
1215

    
1216
  LOperand* temp() { return temps_[0]; }
1217

    
1218
  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1219
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1220

    
1221
  double value() const { return hydrogen()->DoubleValue(); }
1222
};
1223

    
1224

    
1225
class LConstantE V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1226
 public:
1227
  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1228
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1229

    
1230
  ExternalReference value() const {
1231
    return hydrogen()->ExternalReferenceValue();
1232
  }
1233
};
1234

    
1235

    
1236
class LConstantT V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1237
 public:
1238
  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1239
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1240

    
1241
  Handle<Object> value(Isolate* isolate) const {
1242
    return hydrogen()->handle(isolate);
1243
  }
1244
};
1245

    
1246

    
1247
class LBranch V8_FINAL : public LControlInstruction<1, 1> {
1248
 public:
1249
  LBranch(LOperand* value, LOperand* temp) {
1250
    inputs_[0] = value;
1251
    temps_[0] = temp;
1252
  }
1253

    
1254
  LOperand* value() { return inputs_[0]; }
1255
  LOperand* temp() { return temps_[0]; }
1256

    
1257
  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1258
  DECLARE_HYDROGEN_ACCESSOR(Branch)
1259

    
1260
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1261
};
1262

    
1263

    
1264
class LCmpMapAndBranch V8_FINAL : public LControlInstruction<1, 0> {
1265
 public:
1266
  explicit LCmpMapAndBranch(LOperand* value) {
1267
    inputs_[0] = value;
1268
  }
1269

    
1270
  LOperand* value() { return inputs_[0]; }
1271

    
1272
  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1273
  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1274

    
1275
  Handle<Map> map() const { return hydrogen()->map().handle(); }
1276
};
1277

    
1278

    
1279
class LMapEnumLength V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1280
 public:
1281
  explicit LMapEnumLength(LOperand* value) {
1282
    inputs_[0] = value;
1283
  }
1284

    
1285
  LOperand* value() { return inputs_[0]; }
1286

    
1287
  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1288
};
1289

    
1290

    
1291
class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1292
 public:
1293
  explicit LElementsKind(LOperand* value) {
1294
    inputs_[0] = value;
1295
  }
1296

    
1297
  LOperand* value() { return inputs_[0]; }
1298

    
1299
  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
1300
  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
1301
};
1302

    
1303

    
1304
class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1305
 public:
1306
  LValueOf(LOperand* value, LOperand* temp) {
1307
    inputs_[0] = value;
1308
    temps_[0] = temp;
1309
  }
1310

    
1311
  LOperand* value() { return inputs_[0]; }
1312
  LOperand* temp() { return temps_[0]; }
1313

    
1314
  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1315
  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1316
};
1317

    
1318

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

    
1327
  LOperand* date() { return inputs_[0]; }
1328
  LOperand* temp() { return temps_[0]; }
1329

    
1330
  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1331
  DECLARE_HYDROGEN_ACCESSOR(DateField)
1332

    
1333
  Smi* index() const { return index_; }
1334

    
1335
 private:
1336
  Smi* index_;
1337
};
1338

    
1339

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

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

    
1356
  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1357
  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1358

    
1359
 private:
1360
  String::Encoding encoding_;
1361
};
1362

    
1363

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

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

    
1374
  DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1375
};
1376

    
1377

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

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

    
1388
  static bool UseLea(HAdd* add) {
1389
    return !add->CheckFlag(HValue::kCanOverflow) &&
1390
        add->BetterLeftOperand()->UseCount() > 1;
1391
  }
1392

    
1393
  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1394
  DECLARE_HYDROGEN_ACCESSOR(Add)
1395
};
1396

    
1397

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

    
1405
  LOperand* left() { return inputs_[0]; }
1406
  LOperand* right() { return inputs_[1]; }
1407

    
1408
  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1409
  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1410
};
1411

    
1412

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

    
1420
  LOperand* left() { return inputs_[0]; }
1421
  LOperand* right() { return inputs_[1]; }
1422

    
1423
  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1424
  DECLARE_HYDROGEN_ACCESSOR(Power)
1425
};
1426

    
1427

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

    
1440
  LOperand* global_object() const { return inputs_[0]; }
1441
  LOperand* scratch() const { return temps_[0]; }
1442
  LOperand* scratch2() const { return temps_[1]; }
1443
  LOperand* scratch3() const { return temps_[2]; }
1444

    
1445
  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
1446
  DECLARE_HYDROGEN_ACCESSOR(Random)
1447
};
1448

    
1449

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

    
1458
  LOperand* left() { return inputs_[0]; }
1459
  LOperand* right() { return inputs_[1]; }
1460

    
1461
  Token::Value op() const { return op_; }
1462

    
1463
  virtual Opcode opcode() const V8_OVERRIDE {
1464
    return LInstruction::kArithmeticD;
1465
  }
1466
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1467
  virtual const char* Mnemonic() const V8_OVERRIDE;
1468

    
1469
 private:
1470
  Token::Value op_;
1471
};
1472

    
1473

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

    
1486
  LOperand* context() { return inputs_[0]; }
1487
  LOperand* left() { return inputs_[1]; }
1488
  LOperand* right() { return inputs_[2]; }
1489

    
1490
  virtual Opcode opcode() const V8_OVERRIDE {
1491
    return LInstruction::kArithmeticT;
1492
  }
1493
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1494
  virtual const char* Mnemonic() const V8_OVERRIDE;
1495

    
1496
  Token::Value op() const { return op_; }
1497

    
1498
 private:
1499
  Token::Value op_;
1500
};
1501

    
1502

    
1503
class LReturn V8_FINAL : public LTemplateInstruction<0, 3, 0> {
1504
 public:
1505
  explicit LReturn(LOperand* value, LOperand* context,
1506
                   LOperand* parameter_count) {
1507
    inputs_[0] = value;
1508
    inputs_[1] = context;
1509
    inputs_[2] = parameter_count;
1510
  }
1511

    
1512
  bool has_constant_parameter_count() {
1513
    return parameter_count()->IsConstantOperand();
1514
  }
1515
  LConstantOperand* constant_parameter_count() {
1516
    ASSERT(has_constant_parameter_count());
1517
    return LConstantOperand::cast(parameter_count());
1518
  }
1519
  LOperand* parameter_count() { return inputs_[2]; }
1520

    
1521
  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1522
  DECLARE_HYDROGEN_ACCESSOR(Return)
1523
};
1524

    
1525

    
1526
class LLoadNamedField V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1527
 public:
1528
  explicit LLoadNamedField(LOperand* object) {
1529
    inputs_[0] = object;
1530
  }
1531

    
1532
  LOperand* object() { return inputs_[0]; }
1533

    
1534
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1535
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1536
};
1537

    
1538

    
1539
class LLoadNamedGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1540
 public:
1541
  LLoadNamedGeneric(LOperand* context, LOperand* object) {
1542
    inputs_[0] = context;
1543
    inputs_[1] = object;
1544
  }
1545

    
1546
  LOperand* context() { return inputs_[0]; }
1547
  LOperand* object() { return inputs_[1]; }
1548

    
1549
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1550
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1551

    
1552
  Handle<Object> name() const { return hydrogen()->name(); }
1553
};
1554

    
1555

    
1556
class LLoadFunctionPrototype V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1557
 public:
1558
  LLoadFunctionPrototype(LOperand* function, LOperand* temp) {
1559
    inputs_[0] = function;
1560
    temps_[0] = temp;
1561
  }
1562

    
1563
  LOperand* function() { return inputs_[0]; }
1564
  LOperand* temp() { return temps_[0]; }
1565

    
1566
  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1567
  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1568
};
1569

    
1570

    
1571
class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1572
 public:
1573
  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1574
  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1575

    
1576
  Heap::RootListIndex index() const { return hydrogen()->index(); }
1577
};
1578

    
1579

    
1580
class LLoadExternalArrayPointer V8_FINAL
1581
    : public LTemplateInstruction<1, 1, 0> {
1582
 public:
1583
  explicit LLoadExternalArrayPointer(LOperand* object) {
1584
    inputs_[0] = object;
1585
  }
1586

    
1587
  LOperand* object() { return inputs_[0]; }
1588

    
1589
  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1590
                               "load-external-array-pointer")
1591
};
1592

    
1593

    
1594
class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1595
 public:
1596
  LLoadKeyed(LOperand* elements, LOperand* key) {
1597
    inputs_[0] = elements;
1598
    inputs_[1] = key;
1599
  }
1600
  LOperand* elements() { return inputs_[0]; }
1601
  LOperand* key() { return inputs_[1]; }
1602
  ElementsKind elements_kind() const {
1603
    return hydrogen()->elements_kind();
1604
  }
1605
  bool is_external() const {
1606
    return hydrogen()->is_external();
1607
  }
1608

    
1609
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1610
  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1611

    
1612
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1613
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1614
  bool key_is_smi() {
1615
    return hydrogen()->key()->representation().IsTagged();
1616
  }
1617
};
1618

    
1619

    
1620
inline static bool ExternalArrayOpRequiresTemp(
1621
    Representation key_representation,
1622
    ElementsKind elements_kind) {
1623
  // Operations that require the key to be divided by two to be converted into
1624
  // an index cannot fold the scale operation into a load and need an extra
1625
  // temp register to do the work.
1626
  return key_representation.IsSmi() &&
1627
      (elements_kind == EXTERNAL_BYTE_ELEMENTS ||
1628
       elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
1629
       elements_kind == EXTERNAL_PIXEL_ELEMENTS);
1630
}
1631

    
1632

    
1633
class LLoadKeyedGeneric V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1634
 public:
1635
  LLoadKeyedGeneric(LOperand* context, LOperand* obj, LOperand* key) {
1636
    inputs_[0] = context;
1637
    inputs_[1] = obj;
1638
    inputs_[2] = key;
1639
  }
1640

    
1641
  LOperand* context() { return inputs_[0]; }
1642
  LOperand* object() { return inputs_[1]; }
1643
  LOperand* key() { return inputs_[2]; }
1644

    
1645
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1646
};
1647

    
1648

    
1649
class LLoadGlobalCell V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1650
 public:
1651
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1652
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1653
};
1654

    
1655

    
1656
class LLoadGlobalGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1657
 public:
1658
  LLoadGlobalGeneric(LOperand* context, LOperand* global_object) {
1659
    inputs_[0] = context;
1660
    inputs_[1] = global_object;
1661
  }
1662

    
1663
  LOperand* context() { return inputs_[0]; }
1664
  LOperand* global_object() { return inputs_[1]; }
1665

    
1666
  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1667
  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1668

    
1669
  Handle<Object> name() const { return hydrogen()->name(); }
1670
  bool for_typeof() const { return hydrogen()->for_typeof(); }
1671
};
1672

    
1673

    
1674
class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 0> {
1675
 public:
1676
  explicit LStoreGlobalCell(LOperand* value) {
1677
    inputs_[0] = value;
1678
  }
1679

    
1680
  LOperand* value() { return inputs_[0]; }
1681

    
1682
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1683
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1684
};
1685

    
1686

    
1687
class LStoreGlobalGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
1688
 public:
1689
  LStoreGlobalGeneric(LOperand* context,
1690
                      LOperand* global_object,
1691
                      LOperand* value) {
1692
    inputs_[0] = context;
1693
    inputs_[1] = global_object;
1694
    inputs_[2] = value;
1695
  }
1696

    
1697
  LOperand* context() { return inputs_[0]; }
1698
  LOperand* global_object() { return inputs_[1]; }
1699
  LOperand* value() { return inputs_[2]; }
1700

    
1701
  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
1702
  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
1703

    
1704
  Handle<Object> name() const { return hydrogen()->name(); }
1705
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1706
};
1707

    
1708

    
1709
class LLoadContextSlot V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1710
 public:
1711
  explicit LLoadContextSlot(LOperand* context) {
1712
    inputs_[0] = context;
1713
  }
1714

    
1715
  LOperand* context() { return inputs_[0]; }
1716

    
1717
  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1718
  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1719

    
1720
  int slot_index() { return hydrogen()->slot_index(); }
1721

    
1722
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1723
};
1724

    
1725

    
1726
class LStoreContextSlot V8_FINAL : public LTemplateInstruction<0, 2, 1> {
1727
 public:
1728
  LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
1729
    inputs_[0] = context;
1730
    inputs_[1] = value;
1731
    temps_[0] = temp;
1732
  }
1733

    
1734
  LOperand* context() { return inputs_[0]; }
1735
  LOperand* value() { return inputs_[1]; }
1736
  LOperand* temp() { return temps_[0]; }
1737

    
1738
  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1739
  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1740

    
1741
  int slot_index() { return hydrogen()->slot_index(); }
1742

    
1743
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1744
};
1745

    
1746

    
1747
class LPushArgument V8_FINAL : public LTemplateInstruction<0, 1, 0> {
1748
 public:
1749
  explicit LPushArgument(LOperand* value) {
1750
    inputs_[0] = value;
1751
  }
1752

    
1753
  LOperand* value() { return inputs_[0]; }
1754

    
1755
  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1756
};
1757

    
1758

    
1759
class LDrop V8_FINAL : public LTemplateInstruction<0, 0, 0> {
1760
 public:
1761
  explicit LDrop(int count) : count_(count) { }
1762

    
1763
  int count() const { return count_; }
1764

    
1765
  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1766

    
1767
 private:
1768
  int count_;
1769
};
1770

    
1771

    
1772
class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
1773
 public:
1774
  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1775
    inputs_[0] = function;
1776
    temps_[0] = code_object;
1777
  }
1778

    
1779
  LOperand* function() { return inputs_[0]; }
1780
  LOperand* code_object() { return temps_[0]; }
1781

    
1782
  virtual void PrintDataTo(StringStream* stream);
1783

    
1784
  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1785
  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1786
};
1787

    
1788

    
1789
class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
1790
 public:
1791
  explicit LInnerAllocatedObject(LOperand* base_object) {
1792
    inputs_[0] = base_object;
1793
  }
1794

    
1795
  LOperand* base_object() { return inputs_[0]; }
1796
  int offset() { return hydrogen()->offset(); }
1797

    
1798
  virtual void PrintDataTo(StringStream* stream);
1799

    
1800
  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
1801
  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
1802
};
1803

    
1804

    
1805
class LThisFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1806
 public:
1807
  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1808
  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1809
};
1810

    
1811

    
1812
class LContext V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1813
 public:
1814
  DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1815
  DECLARE_HYDROGEN_ACCESSOR(Context)
1816
};
1817

    
1818

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

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

    
1827
  DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
1828
};
1829

    
1830

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

    
1837
  LOperand* context() { return inputs_[0]; }
1838

    
1839
  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1840
  DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1841
};
1842

    
1843

    
1844
class LGlobalObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1845
 public:
1846
  explicit LGlobalObject(LOperand* context) {
1847
    inputs_[0] = context;
1848
  }
1849

    
1850
  LOperand* context() { return inputs_[0]; }
1851

    
1852
  DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1853
};
1854

    
1855

    
1856
class LGlobalReceiver V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1857
 public:
1858
  explicit LGlobalReceiver(LOperand* global_object) {
1859
    inputs_[0] = global_object;
1860
  }
1861

    
1862
  LOperand* global() { return inputs_[0]; }
1863

    
1864
  DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1865
};
1866

    
1867

    
1868
class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1869
 public:
1870
  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1871
  DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1872

    
1873
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1874

    
1875
  Handle<JSFunction> function() { return hydrogen()->function(); }
1876
  int arity() const { return hydrogen()->argument_count() - 1; }
1877
};
1878

    
1879

    
1880
class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1881
 public:
1882
  LInvokeFunction(LOperand* context, LOperand* function) {
1883
    inputs_[0] = context;
1884
    inputs_[1] = function;
1885
  }
1886

    
1887
  LOperand* context() { return inputs_[0]; }
1888
  LOperand* function() { return inputs_[1]; }
1889

    
1890
  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1891
  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1892

    
1893
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1894

    
1895
  int arity() const { return hydrogen()->argument_count() - 1; }
1896
};
1897

    
1898

    
1899
class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1900
 public:
1901
  LCallKeyed(LOperand* context, LOperand* key) {
1902
    inputs_[0] = context;
1903
    inputs_[1] = key;
1904
  }
1905

    
1906
  LOperand* context() { return inputs_[0]; }
1907
  LOperand* key() { return inputs_[1]; }
1908

    
1909
  DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1910
  DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1911

    
1912
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1913

    
1914
  int arity() const { return hydrogen()->argument_count() - 1; }
1915
};
1916

    
1917

    
1918
class LCallNamed V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1919
 public:
1920
  explicit LCallNamed(LOperand* context) {
1921
    inputs_[0] = context;
1922
  }
1923

    
1924
  LOperand* context() { return inputs_[0]; }
1925

    
1926
  DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1927
  DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1928

    
1929
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1930

    
1931
  Handle<String> name() const { return hydrogen()->name(); }
1932
  int arity() const { return hydrogen()->argument_count() - 1; }
1933
};
1934

    
1935

    
1936
class LCallFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1937
 public:
1938
  explicit LCallFunction(LOperand* context, LOperand* function) {
1939
    inputs_[0] = context;
1940
    inputs_[1] = function;
1941
  }
1942

    
1943
  LOperand* context() { return inputs_[0]; }
1944
  LOperand* function() { return inputs_[1]; }
1945

    
1946
  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1947
  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1948

    
1949
  int arity() const { return hydrogen()->argument_count() - 1; }
1950
};
1951

    
1952

    
1953
class LCallGlobal V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1954
 public:
1955
  explicit LCallGlobal(LOperand* context) {
1956
    inputs_[0] = context;
1957
  }
1958

    
1959
  LOperand* context() { return inputs_[0]; }
1960

    
1961
  DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1962
  DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1963

    
1964
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1965

    
1966
  Handle<String> name() const {return hydrogen()->name(); }
1967
  int arity() const { return hydrogen()->argument_count() - 1; }
1968
};
1969

    
1970

    
1971
class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1972
 public:
1973
  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1974
  DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1975

    
1976
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1977

    
1978
  int arity() const { return hydrogen()->argument_count() - 1;  }
1979
};
1980

    
1981

    
1982
class LCallNew V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1983
 public:
1984
  LCallNew(LOperand* context, LOperand* constructor) {
1985
    inputs_[0] = context;
1986
    inputs_[1] = constructor;
1987
  }
1988

    
1989
  LOperand* context() { return inputs_[0]; }
1990
  LOperand* constructor() { return inputs_[1]; }
1991

    
1992
  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1993
  DECLARE_HYDROGEN_ACCESSOR(CallNew)
1994

    
1995
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1996

    
1997
  int arity() const { return hydrogen()->argument_count() - 1; }
1998
};
1999

    
2000

    
2001
class LCallNewArray V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2002
 public:
2003
  LCallNewArray(LOperand* context, LOperand* constructor) {
2004
    inputs_[0] = context;
2005
    inputs_[1] = constructor;
2006
  }
2007

    
2008
  LOperand* context() { return inputs_[0]; }
2009
  LOperand* constructor() { return inputs_[1]; }
2010

    
2011
  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
2012
  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
2013

    
2014
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2015

    
2016
  int arity() const { return hydrogen()->argument_count() - 1; }
2017
};
2018

    
2019

    
2020
class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2021
 public:
2022
  explicit LCallRuntime(LOperand* context) {
2023
    inputs_[0] = context;
2024
  }
2025

    
2026
  LOperand* context() { return inputs_[0]; }
2027

    
2028
  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
2029
  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
2030

    
2031
  virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
2032
    return save_doubles() == kDontSaveFPRegs;
2033
  }
2034

    
2035
  const Runtime::Function* function() const { return hydrogen()->function(); }
2036
  int arity() const { return hydrogen()->argument_count(); }
2037
  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
2038
};
2039

    
2040

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

    
2047
  LOperand* value() { return inputs_[0]; }
2048

    
2049
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
2050
};
2051

    
2052

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

    
2059
  LOperand* value() { return inputs_[0]; }
2060

    
2061
  DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
2062
  DECLARE_HYDROGEN_ACCESSOR(Change)
2063
};
2064

    
2065

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

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

    
2076
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
2077
};
2078

    
2079

    
2080
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2081
 public:
2082
  explicit LUint32ToSmi(LOperand* value) {
2083
    inputs_[0] = value;
2084
  }
2085

    
2086
  LOperand* value() { return inputs_[0]; }
2087

    
2088
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
2089
  DECLARE_HYDROGEN_ACCESSOR(Change)
2090
};
2091

    
2092

    
2093
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2094
 public:
2095
  explicit LNumberTagI(LOperand* value) {
2096
    inputs_[0] = value;
2097
  }
2098

    
2099
  LOperand* value() { return inputs_[0]; }
2100

    
2101
  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
2102
};
2103

    
2104

    
2105
class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2106
 public:
2107
  LNumberTagU(LOperand* value, LOperand* temp) {
2108
    inputs_[0] = value;
2109
    temps_[0] = temp;
2110
  }
2111

    
2112
  LOperand* value() { return inputs_[0]; }
2113
  LOperand* temp() { return temps_[0]; }
2114

    
2115
  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
2116
};
2117

    
2118

    
2119
class LNumberTagD V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2120
 public:
2121
  LNumberTagD(LOperand* value, LOperand* temp) {
2122
    inputs_[0] = value;
2123
    temps_[0] = temp;
2124
  }
2125

    
2126
  LOperand* value() { return inputs_[0]; }
2127
  LOperand* temp() { return temps_[0]; }
2128

    
2129
  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
2130
  DECLARE_HYDROGEN_ACCESSOR(Change)
2131
};
2132

    
2133

    
2134
// Sometimes truncating conversion from a tagged value to an int32.
2135
class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2136
 public:
2137
  LDoubleToI(LOperand* value, LOperand* temp) {
2138
    inputs_[0] = value;
2139
    temps_[0] = temp;
2140
  }
2141

    
2142
  LOperand* value() { return inputs_[0]; }
2143
  LOperand* temp() { return temps_[0]; }
2144

    
2145
  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2146
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2147

    
2148
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2149
};
2150

    
2151

    
2152
class LDoubleToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2153
 public:
2154
  explicit LDoubleToSmi(LOperand* value) {
2155
    inputs_[0] = value;
2156
  }
2157

    
2158
  LOperand* value() { return inputs_[0]; }
2159

    
2160
  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2161
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2162
};
2163

    
2164

    
2165
// Truncating conversion from a tagged value to an int32.
2166
class LTaggedToI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2167
 public:
2168
  LTaggedToI(LOperand* value, LOperand* temp) {
2169
    inputs_[0] = value;
2170
    temps_[0] = temp;
2171
  }
2172

    
2173
  LOperand* value() { return inputs_[0]; }
2174
  LOperand* temp() { return temps_[0]; }
2175

    
2176
  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2177
  DECLARE_HYDROGEN_ACCESSOR(Change)
2178

    
2179
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2180
};
2181

    
2182

    
2183
class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2184
 public:
2185
  explicit LSmiTag(LOperand* value) {
2186
    inputs_[0] = value;
2187
  }
2188

    
2189
  LOperand* value() { return inputs_[0]; }
2190

    
2191
  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2192
};
2193

    
2194

    
2195
class LNumberUntagD V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2196
 public:
2197
  explicit LNumberUntagD(LOperand* value, LOperand* temp) {
2198
    inputs_[0] = value;
2199
    temps_[0] = temp;
2200
  }
2201

    
2202
  LOperand* value() { return inputs_[0]; }
2203
  LOperand* temp() { return temps_[0]; }
2204

    
2205
  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2206
  DECLARE_HYDROGEN_ACCESSOR(Change);
2207
};
2208

    
2209

    
2210
class LSmiUntag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2211
 public:
2212
  LSmiUntag(LOperand* value, bool needs_check)
2213
      : needs_check_(needs_check) {
2214
    inputs_[0] = value;
2215
  }
2216

    
2217
  LOperand* value() { return inputs_[0]; }
2218

    
2219
  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2220

    
2221
  bool needs_check() const { return needs_check_; }
2222

    
2223
 private:
2224
  bool needs_check_;
2225
};
2226

    
2227

    
2228
class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 2> {
2229
 public:
2230
  LStoreNamedField(LOperand* obj,
2231
                   LOperand* val,
2232
                   LOperand* temp,
2233
                   LOperand* temp_map) {
2234
    inputs_[0] = obj;
2235
    inputs_[1] = val;
2236
    temps_[0] = temp;
2237
    temps_[1] = temp_map;
2238
  }
2239

    
2240
  LOperand* object() { return inputs_[0]; }
2241
  LOperand* value() { return inputs_[1]; }
2242
  LOperand* temp() { return temps_[0]; }
2243
  LOperand* temp_map() { return temps_[1]; }
2244

    
2245
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2246
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2247

    
2248
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2249

    
2250
  Handle<Map> transition() const { return hydrogen()->transition_map(); }
2251
  Representation representation() const {
2252
    return hydrogen()->field_representation();
2253
  }
2254
};
2255

    
2256

    
2257
class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2258
 public:
2259
  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2260
    inputs_[0] = context;
2261
    inputs_[1] = object;
2262
    inputs_[2] = value;
2263
  }
2264

    
2265
  LOperand* context() { return inputs_[0]; }
2266
  LOperand* object() { return inputs_[1]; }
2267
  LOperand* value() { return inputs_[2]; }
2268

    
2269
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2270
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2271

    
2272
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2273
  Handle<Object> name() const { return hydrogen()->name(); }
2274
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2275
};
2276

    
2277

    
2278
class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2279
 public:
2280
  LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
2281
    inputs_[0] = obj;
2282
    inputs_[1] = key;
2283
    inputs_[2] = val;
2284
  }
2285

    
2286
  bool is_external() const { return hydrogen()->is_external(); }
2287
  LOperand* elements() { return inputs_[0]; }
2288
  LOperand* key() { return inputs_[1]; }
2289
  LOperand* value() { return inputs_[2]; }
2290
  ElementsKind elements_kind() const {
2291
    return hydrogen()->elements_kind();
2292
  }
2293

    
2294
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2295
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2296

    
2297
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2298
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
2299
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2300
};
2301

    
2302

    
2303
class LStoreKeyedGeneric V8_FINAL : public LTemplateInstruction<0, 4, 0> {
2304
 public:
2305
  LStoreKeyedGeneric(LOperand* context,
2306
                     LOperand* object,
2307
                     LOperand* key,
2308
                     LOperand* value) {
2309
    inputs_[0] = context;
2310
    inputs_[1] = object;
2311
    inputs_[2] = key;
2312
    inputs_[3] = value;
2313
  }
2314

    
2315
  LOperand* context() { return inputs_[0]; }
2316
  LOperand* object() { return inputs_[1]; }
2317
  LOperand* key() { return inputs_[2]; }
2318
  LOperand* value() { return inputs_[3]; }
2319

    
2320
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2321
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2322

    
2323
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2324

    
2325
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2326
};
2327

    
2328

    
2329
class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
2330
 public:
2331
  LTransitionElementsKind(LOperand* object,
2332
                          LOperand* context,
2333
                          LOperand* new_map_temp,
2334
                          LOperand* temp) {
2335
    inputs_[0] = object;
2336
    inputs_[1] = context;
2337
    temps_[0] = new_map_temp;
2338
    temps_[1] = temp;
2339
  }
2340

    
2341
  LOperand* context() { return inputs_[1]; }
2342
  LOperand* object() { return inputs_[0]; }
2343
  LOperand* new_map_temp() { return temps_[0]; }
2344
  LOperand* temp() { return temps_[1]; }
2345

    
2346
  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2347
                               "transition-elements-kind")
2348
  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2349

    
2350
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2351

    
2352
  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2353
  Handle<Map> transitioned_map() {
2354
    return hydrogen()->transitioned_map().handle();
2355
  }
2356
  ElementsKind from_kind() { return hydrogen()->from_kind(); }
2357
  ElementsKind to_kind() { return hydrogen()->to_kind(); }
2358
};
2359

    
2360

    
2361
class LTrapAllocationMemento V8_FINAL  : public LTemplateInstruction<0, 1, 1> {
2362
 public:
2363
  LTrapAllocationMemento(LOperand* object,
2364
                         LOperand* temp) {
2365
    inputs_[0] = object;
2366
    temps_[0] = temp;
2367
  }
2368

    
2369
  LOperand* object() { return inputs_[0]; }
2370
  LOperand* temp() { return temps_[0]; }
2371

    
2372
  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2373
                               "trap-allocation-memento")
2374
};
2375

    
2376

    
2377
class LStringAdd V8_FINAL : public LTemplateInstruction<1, 3, 0> {
2378
 public:
2379
  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2380
    inputs_[0] = context;
2381
    inputs_[1] = left;
2382
    inputs_[2] = right;
2383
  }
2384

    
2385
  LOperand* context() { return inputs_[0]; }
2386
  LOperand* left() { return inputs_[1]; }
2387
  LOperand* right() { return inputs_[2]; }
2388

    
2389
  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2390
  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2391
};
2392

    
2393

    
2394
class LStringCharCodeAt V8_FINAL : public LTemplateInstruction<1, 3, 0> {
2395
 public:
2396
  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2397
    inputs_[0] = context;
2398
    inputs_[1] = string;
2399
    inputs_[2] = index;
2400
  }
2401

    
2402
  LOperand* context() { return inputs_[0]; }
2403
  LOperand* string() { return inputs_[1]; }
2404
  LOperand* index() { return inputs_[2]; }
2405

    
2406
  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2407
  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2408
};
2409

    
2410

    
2411
class LStringCharFromCode V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2412
 public:
2413
  LStringCharFromCode(LOperand* context, LOperand* char_code) {
2414
    inputs_[0] = context;
2415
    inputs_[1] = char_code;
2416
  }
2417

    
2418
  LOperand* context() { return inputs_[0]; }
2419
  LOperand* char_code() { return inputs_[1]; }
2420

    
2421
  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2422
  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2423
};
2424

    
2425

    
2426
class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2427
 public:
2428
  explicit LCheckValue(LOperand* value) {
2429
    inputs_[0] = value;
2430
  }
2431

    
2432
  LOperand* value() { return inputs_[0]; }
2433

    
2434
  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2435
  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2436
};
2437

    
2438

    
2439
class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 1> {
2440
 public:
2441
  LCheckInstanceType(LOperand* value, LOperand* temp) {
2442
    inputs_[0] = value;
2443
    temps_[0] = temp;
2444
  }
2445

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

    
2449
  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2450
  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2451
};
2452

    
2453

    
2454
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2455
 public:
2456
  explicit LCheckMaps(LOperand* value) {
2457
    inputs_[0] = value;
2458
  }
2459

    
2460
  LOperand* value() { return inputs_[0]; }
2461

    
2462
  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2463
  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2464
};
2465

    
2466

    
2467
class LCheckSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2468
 public:
2469
  explicit LCheckSmi(LOperand* value) {
2470
    inputs_[0] = value;
2471
  }
2472

    
2473
  LOperand* value() { return inputs_[0]; }
2474

    
2475
  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2476
};
2477

    
2478

    
2479
class LClampDToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2480
 public:
2481
  explicit LClampDToUint8(LOperand* value) {
2482
    inputs_[0] = value;
2483
  }
2484

    
2485
  LOperand* unclamped() { return inputs_[0]; }
2486

    
2487
  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2488
};
2489

    
2490

    
2491
class LClampIToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2492
 public:
2493
  explicit LClampIToUint8(LOperand* value) {
2494
    inputs_[0] = value;
2495
  }
2496

    
2497
  LOperand* unclamped() { return inputs_[0]; }
2498

    
2499
  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2500
};
2501

    
2502

    
2503
class LClampTToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2504
 public:
2505
  LClampTToUint8(LOperand* value, LOperand* temp_xmm) {
2506
    inputs_[0] = value;
2507
    temps_[0] = temp_xmm;
2508
  }
2509

    
2510
  LOperand* unclamped() { return inputs_[0]; }
2511
  LOperand* temp_xmm() { return temps_[0]; }
2512

    
2513
  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2514
};
2515

    
2516

    
2517
// Truncating conversion from a tagged value to an int32.
2518
class LClampTToUint8NoSSE2 V8_FINAL : public LTemplateInstruction<1, 1, 3> {
2519
 public:
2520
  LClampTToUint8NoSSE2(LOperand* unclamped,
2521
                       LOperand* temp1,
2522
                       LOperand* temp2,
2523
                       LOperand* temp3) {
2524
    inputs_[0] = unclamped;
2525
    temps_[0] = temp1;
2526
    temps_[1] = temp2;
2527
    temps_[2] = temp3;
2528
  }
2529

    
2530
  LOperand* unclamped() { return inputs_[0]; }
2531
  LOperand* scratch() { return temps_[0]; }
2532
  LOperand* scratch2() { return temps_[1]; }
2533
  LOperand* scratch3() { return temps_[2]; }
2534

    
2535
  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8NoSSE2,
2536
                               "clamp-t-to-uint8-nosse2")
2537
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2538
};
2539

    
2540

    
2541
class LCheckNonSmi V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2542
 public:
2543
  explicit LCheckNonSmi(LOperand* value) {
2544
    inputs_[0] = value;
2545
  }
2546

    
2547
  LOperand* value() { return inputs_[0]; }
2548

    
2549
  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2550
  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2551
};
2552

    
2553

    
2554
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 1> {
2555
 public:
2556
  LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
2557
    inputs_[0] = context;
2558
    inputs_[1] = size;
2559
    temps_[0] = temp;
2560
  }
2561

    
2562
  LOperand* context() { return inputs_[0]; }
2563
  LOperand* size() { return inputs_[1]; }
2564
  LOperand* temp() { return temps_[0]; }
2565

    
2566
  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2567
  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2568
};
2569

    
2570

    
2571
class LRegExpLiteral V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2572
 public:
2573
  explicit LRegExpLiteral(LOperand* context) {
2574
    inputs_[0] = context;
2575
  }
2576

    
2577
  LOperand* context() { return inputs_[0]; }
2578

    
2579
  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2580
  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2581
};
2582

    
2583

    
2584
class LFunctionLiteral V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2585
 public:
2586
  explicit LFunctionLiteral(LOperand* context) {
2587
    inputs_[0] = context;
2588
  }
2589

    
2590
  LOperand* context() { return inputs_[0]; }
2591

    
2592
  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2593
  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2594
};
2595

    
2596

    
2597
class LToFastProperties V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2598
 public:
2599
  explicit LToFastProperties(LOperand* value) {
2600
    inputs_[0] = value;
2601
  }
2602

    
2603
  LOperand* value() { return inputs_[0]; }
2604

    
2605
  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2606
  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2607
};
2608

    
2609

    
2610
class LTypeof V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2611
 public:
2612
  LTypeof(LOperand* context, LOperand* value) {
2613
    inputs_[0] = context;
2614
    inputs_[1] = value;
2615
  }
2616

    
2617
  LOperand* context() { return inputs_[0]; }
2618
  LOperand* value() { return inputs_[1]; }
2619

    
2620
  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2621
};
2622

    
2623

    
2624
class LTypeofIsAndBranch V8_FINAL : public LControlInstruction<1, 0> {
2625
 public:
2626
  explicit LTypeofIsAndBranch(LOperand* value) {
2627
    inputs_[0] = value;
2628
  }
2629

    
2630
  LOperand* value() { return inputs_[0]; }
2631

    
2632
  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2633
  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2634

    
2635
  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2636

    
2637
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2638
};
2639

    
2640

    
2641
class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
2642
 public:
2643
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
2644
    return false;
2645
  }
2646
  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2647
};
2648

    
2649

    
2650
class LStackCheck V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2651
 public:
2652
  explicit LStackCheck(LOperand* context) {
2653
    inputs_[0] = context;
2654
  }
2655

    
2656
  LOperand* context() { return inputs_[0]; }
2657

    
2658
  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2659
  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2660

    
2661
  Label* done_label() { return &done_label_; }
2662

    
2663
 private:
2664
  Label done_label_;
2665
};
2666

    
2667

    
2668
class LForInPrepareMap V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2669
 public:
2670
  LForInPrepareMap(LOperand* context, LOperand* object) {
2671
    inputs_[0] = context;
2672
    inputs_[1] = object;
2673
  }
2674

    
2675
  LOperand* context() { return inputs_[0]; }
2676
  LOperand* object() { return inputs_[1]; }
2677

    
2678
  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2679
};
2680

    
2681

    
2682
class LForInCacheArray V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2683
 public:
2684
  explicit LForInCacheArray(LOperand* map) {
2685
    inputs_[0] = map;
2686
  }
2687

    
2688
  LOperand* map() { return inputs_[0]; }
2689

    
2690
  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2691

    
2692
  int idx() {
2693
    return HForInCacheArray::cast(this->hydrogen_value())->idx();
2694
  }
2695
};
2696

    
2697

    
2698
class LCheckMapValue V8_FINAL : public LTemplateInstruction<0, 2, 0> {
2699
 public:
2700
  LCheckMapValue(LOperand* value, LOperand* map) {
2701
    inputs_[0] = value;
2702
    inputs_[1] = map;
2703
  }
2704

    
2705
  LOperand* value() { return inputs_[0]; }
2706
  LOperand* map() { return inputs_[1]; }
2707

    
2708
  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2709
};
2710

    
2711

    
2712
class LLoadFieldByIndex V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2713
 public:
2714
  LLoadFieldByIndex(LOperand* object, LOperand* index) {
2715
    inputs_[0] = object;
2716
    inputs_[1] = index;
2717
  }
2718

    
2719
  LOperand* object() { return inputs_[0]; }
2720
  LOperand* index() { return inputs_[1]; }
2721

    
2722
  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2723
};
2724

    
2725

    
2726
class LChunkBuilder;
2727
class LPlatformChunk V8_FINAL : public LChunk {
2728
 public:
2729
  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2730
      : LChunk(info, graph),
2731
        num_double_slots_(0) { }
2732

    
2733
  int GetNextSpillIndex(RegisterKind kind);
2734
  LOperand* GetNextSpillSlot(RegisterKind kind);
2735

    
2736
  int num_double_slots() const { return num_double_slots_; }
2737

    
2738
 private:
2739
  int num_double_slots_;
2740
};
2741

    
2742

    
2743
class LChunkBuilder V8_FINAL BASE_EMBEDDED {
2744
 public:
2745
  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2746
      : chunk_(NULL),
2747
        info_(info),
2748
        graph_(graph),
2749
        zone_(graph->zone()),
2750
        status_(UNUSED),
2751
        current_instruction_(NULL),
2752
        current_block_(NULL),
2753
        next_block_(NULL),
2754
        argument_count_(0),
2755
        allocator_(allocator),
2756
        instruction_pending_deoptimization_environment_(NULL),
2757
        pending_deoptimization_ast_id_(BailoutId::None()) { }
2758

    
2759
  // Build the sequence for the graph.
2760
  LPlatformChunk* Build();
2761

    
2762
  LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
2763

    
2764
  // Declare methods that deal with the individual node types.
2765
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2766
  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2767
#undef DECLARE_DO
2768

    
2769
  static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2770

    
2771
  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2772
  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2773
  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2774
  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2775
  LInstruction* DoMathSin(HUnaryMathOperation* instr);
2776
  LInstruction* DoMathCos(HUnaryMathOperation* instr);
2777
  LInstruction* DoMathTan(HUnaryMathOperation* instr);
2778
  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2779
  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2780
  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2781

    
2782
 private:
2783
  enum Status {
2784
    UNUSED,
2785
    BUILDING,
2786
    DONE,
2787
    ABORTED
2788
  };
2789

    
2790
  LPlatformChunk* chunk() const { return chunk_; }
2791
  CompilationInfo* info() const { return info_; }
2792
  HGraph* graph() const { return graph_; }
2793
  Zone* zone() const { return zone_; }
2794

    
2795
  bool is_unused() const { return status_ == UNUSED; }
2796
  bool is_building() const { return status_ == BUILDING; }
2797
  bool is_done() const { return status_ == DONE; }
2798
  bool is_aborted() const { return status_ == ABORTED; }
2799

    
2800
  void Abort(BailoutReason reason);
2801

    
2802
  // Methods for getting operands for Use / Define / Temp.
2803
  LUnallocated* ToUnallocated(Register reg);
2804
  LUnallocated* ToUnallocated(XMMRegister reg);
2805
  LUnallocated* ToUnallocated(X87Register reg);
2806

    
2807
  // Methods for setting up define-use relationships.
2808
  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2809
  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2810
  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2811
                                           XMMRegister fixed_register);
2812

    
2813
  // A value that is guaranteed to be allocated to a register.
2814
  // Operand created by UseRegister is guaranteed to be live until the end of
2815
  // instruction. This means that register allocator will not reuse it's
2816
  // register for any other operand inside instruction.
2817
  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2818
  // instruction start. Register allocator is free to assign the same register
2819
  // to some other operand used inside instruction (i.e. temporary or
2820
  // output).
2821
  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2822
  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2823

    
2824
  // An input operand in a register that may be trashed.
2825
  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2826

    
2827
  // An input operand in a register or stack slot.
2828
  MUST_USE_RESULT LOperand* Use(HValue* value);
2829
  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2830

    
2831
  // An input operand in a register, stack slot or a constant operand.
2832
  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2833
  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2834

    
2835
  // An input operand in a register or a constant operand.
2836
  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2837
  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2838

    
2839
  // An input operand in a constant operand.
2840
  MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2841

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

    
2846
  // Temporary operand that must be in a register.
2847
  MUST_USE_RESULT LUnallocated* TempRegister();
2848
  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2849
  MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
2850

    
2851
  // Methods for setting up define-use relationships.
2852
  // Return the same instruction that they are passed.
2853
  template<int I, int T>
2854
      LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2855
                           LUnallocated* result);
2856
  template<int I, int T>
2857
      LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2858
  template<int I, int T>
2859
      LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2860
                                    int index);
2861
  template<int I, int T>
2862
      LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2863
  template<int I, int T>
2864
      LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2865
                                Register reg);
2866
  template<int I, int T>
2867
      LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2868
                                      XMMRegister reg);
2869
  template<int I, int T>
2870
      LInstruction* DefineX87TOS(LTemplateInstruction<1, I, T>* instr);
2871
  // Assigns an environment to an instruction.  An instruction which can
2872
  // deoptimize must have an environment.
2873
  LInstruction* AssignEnvironment(LInstruction* instr);
2874
  // Assigns a pointer map to an instruction.  An instruction which can
2875
  // trigger a GC or a lazy deoptimization must have a pointer map.
2876
  LInstruction* AssignPointerMap(LInstruction* instr);
2877

    
2878
  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2879

    
2880
  // Marks a call for the register allocator.  Assigns a pointer map to
2881
  // support GC and lazy deoptimization.  Assigns an environment to support
2882
  // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
2883
  LInstruction* MarkAsCall(
2884
      LInstruction* instr,
2885
      HInstruction* hinstr,
2886
      CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2887

    
2888
  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2889
                                  int* argument_index_accumulator,
2890
                                  ZoneList<HValue*>* objects_to_materialize);
2891

    
2892
  void VisitInstruction(HInstruction* current);
2893

    
2894
  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2895
  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2896
  LInstruction* DoArithmeticD(Token::Value op,
2897
                              HArithmeticBinaryOperation* instr);
2898
  LInstruction* DoArithmeticT(Token::Value op,
2899
                              HBinaryOperation* instr);
2900

    
2901
  LOperand* GetStoreKeyedValueOperand(HStoreKeyed* instr);
2902

    
2903
  LPlatformChunk* chunk_;
2904
  CompilationInfo* info_;
2905
  HGraph* const graph_;
2906
  Zone* zone_;
2907
  Status status_;
2908
  HInstruction* current_instruction_;
2909
  HBasicBlock* current_block_;
2910
  HBasicBlock* next_block_;
2911
  int argument_count_;
2912
  LAllocator* allocator_;
2913
  LInstruction* instruction_pending_deoptimization_environment_;
2914
  BailoutId pending_deoptimization_ast_id_;
2915

    
2916
  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2917
};
2918

    
2919
#undef DECLARE_HYDROGEN_ACCESSOR
2920
#undef DECLARE_CONCRETE_INSTRUCTION
2921

    
2922
} }  // namespace v8::internal
2923

    
2924
#endif  // V8_IA32_LITHIUM_IA32_H_