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

History | View | Annotate | Download (81.8 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_ARM_LITHIUM_ARM_H_
29
#define V8_ARM_LITHIUM_ARM_H_
30

    
31
#include "hydrogen.h"
32
#include "lithium-allocator.h"
33
#include "lithium.h"
34
#include "safepoint-table.h"
35
#include "utils.h"
36

    
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(CheckNonSmi)                                \
67
  V(CheckMaps)                                  \
68
  V(CheckMapValue)                              \
69
  V(CheckSmi)                                   \
70
  V(CheckValue)                                 \
71
  V(ClampDToUint8)                              \
72
  V(ClampIToUint8)                              \
73
  V(ClampTToUint8)                              \
74
  V(ClassOfTestAndBranch)                       \
75
  V(CompareNumericAndBranch)                    \
76
  V(CmpObjectEqAndBranch)                       \
77
  V(CmpHoleAndBranch)                           \
78
  V(CmpMapAndBranch)                            \
79
  V(CmpT)                                       \
80
  V(ConstantD)                                  \
81
  V(ConstantE)                                  \
82
  V(ConstantI)                                  \
83
  V(ConstantS)                                  \
84
  V(ConstantT)                                  \
85
  V(Context)                                    \
86
  V(DateField)                                  \
87
  V(DebugBreak)                                 \
88
  V(DeclareGlobals)                             \
89
  V(Deoptimize)                                 \
90
  V(DivI)                                       \
91
  V(DoubleToI)                                  \
92
  V(DoubleToSmi)                                \
93
  V(Drop)                                       \
94
  V(DummyUse)                                   \
95
  V(ElementsKind)                               \
96
  V(ForInCacheArray)                            \
97
  V(ForInPrepareMap)                            \
98
  V(FunctionLiteral)                            \
99
  V(GetCachedArrayIndex)                        \
100
  V(GlobalObject)                               \
101
  V(GlobalReceiver)                             \
102
  V(Goto)                                       \
103
  V(HasCachedArrayIndexAndBranch)               \
104
  V(HasInstanceTypeAndBranch)                   \
105
  V(InnerAllocatedObject)                       \
106
  V(InstanceOf)                                 \
107
  V(InstanceOfKnownGlobal)                      \
108
  V(InstructionGap)                             \
109
  V(Integer32ToDouble)                          \
110
  V(Integer32ToSmi)                             \
111
  V(InvokeFunction)                             \
112
  V(IsConstructCallAndBranch)                   \
113
  V(IsObjectAndBranch)                          \
114
  V(IsStringAndBranch)                          \
115
  V(IsSmiAndBranch)                             \
116
  V(IsUndetectableAndBranch)                    \
117
  V(Label)                                      \
118
  V(LazyBailout)                                \
119
  V(LoadContextSlot)                            \
120
  V(LoadExternalArrayPointer)                   \
121
  V(LoadRoot)                                   \
122
  V(LoadFieldByIndex)                           \
123
  V(LoadFunctionPrototype)                      \
124
  V(LoadGlobalCell)                             \
125
  V(LoadGlobalGeneric)                          \
126
  V(LoadKeyed)                                  \
127
  V(LoadKeyedGeneric)                           \
128
  V(LoadNamedField)                             \
129
  V(LoadNamedGeneric)                           \
130
  V(MapEnumLength)                              \
131
  V(MathAbs)                                    \
132
  V(MathCos)                                    \
133
  V(MathExp)                                    \
134
  V(MathFloor)                                  \
135
  V(MathFloorOfDiv)                             \
136
  V(MathLog)                                    \
137
  V(MathMinMax)                                 \
138
  V(MathPowHalf)                                \
139
  V(MathRound)                                  \
140
  V(MathSin)                                    \
141
  V(MathSqrt)                                   \
142
  V(MathTan)                                    \
143
  V(ModI)                                       \
144
  V(MulI)                                       \
145
  V(MultiplyAddD)                               \
146
  V(MultiplySubD)                               \
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(PushArgument)                               \
156
  V(Random)                                     \
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(RSubI)                                      \
178
  V(TaggedToI)                                  \
179
  V(ThisFunction)                               \
180
  V(Throw)                                      \
181
  V(ToFastProperties)                           \
182
  V(TransitionElementsKind)                     \
183
  V(TrapAllocationMemento)                      \
184
  V(Typeof)                                     \
185
  V(TypeofIsAndBranch)                          \
186
  V(Uint32ToDouble)                             \
187
  V(Uint32ToSmi)                                \
188
  V(UnknownOSRValue)                            \
189
  V(ValueOf)                                    \
190
  V(WrapReceiver)
191

    
192

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

    
206

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

    
212

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

    
221
  virtual ~LInstruction() {}
222

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

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

    
237
  virtual Opcode opcode() const = 0;
238

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

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

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

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

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

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

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

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

    
267
  // Interface to the register allocator and iterators.
268
  bool ClobbersTemps() const { return IsCall(); }
269
  bool ClobbersRegisters() const { return IsCall(); }
270
  virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
271

    
272
  // Interface to the register allocator and iterators.
273
  bool IsMarkedAsCall() const { return IsCall(); }
274

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

    
278
  LOperand* FirstInput() { return InputAt(0); }
279
  LOperand* Output() { return HasResult() ? result() : NULL; }
280

    
281
  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
282

    
283
#ifdef DEBUG
284
  void VerifyCall();
285
#endif
286

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

    
293
  friend class TempIterator;
294
  virtual int TempCount() = 0;
295
  virtual LOperand* TempAt(int i) = 0;
296

    
297
  class IsCallBits: public BitField<bool, 0, 1> {};
298

    
299
  LEnvironment* environment_;
300
  SetOncePointer<LPointerMap> pointer_map_;
301
  HValue* hydrogen_value_;
302
  int bit_field_;
303
};
304

    
305

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

    
320
 protected:
321
  EmbeddedContainer<LOperand*, R> results_;
322
  EmbeddedContainer<LOperand*, I> inputs_;
323
  EmbeddedContainer<LOperand*, T> temps_;
324

    
325
 private:
326
  virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
327
  virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
328

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

    
333

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

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

    
352
  bool IsRedundant() const;
353

    
354
  HBasicBlock* block() const { return block_; }
355

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

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

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

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

    
381

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

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

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

    
393

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

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

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

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

    
409

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

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

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

    
421
 private:
422
  int gap_instructions_size_;
423
};
424

    
425

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

    
434

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

    
441

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

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

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

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

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

    
467

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

    
474

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

    
481
  LOperand* context() { return inputs_[0]; }
482

    
483
  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
484
  DECLARE_HYDROGEN_ACCESSOR(CallStub)
485

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

    
491

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

    
500

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

    
506
  virtual bool IsControl() const V8_FINAL V8_OVERRIDE { return true; }
507

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

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

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

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

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

    
540
  Label* false_label_;
541
  Label* true_label_;
542
};
543

    
544

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

    
552
  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
553

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

    
558

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

    
571
  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
572

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

    
579

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

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

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

    
594
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
595
};
596

    
597

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

    
604
  LOperand* elements() { return inputs_[0]; }
605

    
606
  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
607
};
608

    
609

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

    
616

    
617
class LModI V8_FINAL : public LTemplateInstruction<1, 2, 2> {
618
 public:
619
  LModI(LOperand* left,
620
        LOperand* right,
621
        LOperand* temp = NULL,
622
        LOperand* temp2 = NULL) {
623
    inputs_[0] = left;
624
    inputs_[1] = right;
625
    temps_[0] = temp;
626
    temps_[1] = temp2;
627
  }
628

    
629
  LOperand* left() { return inputs_[0]; }
630
  LOperand* right() { return inputs_[1]; }
631
  LOperand* temp() { return temps_[0]; }
632
  LOperand* temp2() { return temps_[1]; }
633

    
634
  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
635
  DECLARE_HYDROGEN_ACCESSOR(Mod)
636
};
637

    
638

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

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

    
651
  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
652
  DECLARE_HYDROGEN_ACCESSOR(Div)
653
};
654

    
655

    
656
class LMathFloorOfDiv V8_FINAL : public LTemplateInstruction<1, 2, 1> {
657
 public:
658
  LMathFloorOfDiv(LOperand* left,
659
                  LOperand* right,
660
                  LOperand* temp = NULL) {
661
    inputs_[0] = left;
662
    inputs_[1] = right;
663
    temps_[0] = temp;
664
  }
665

    
666
  LOperand* left() { return inputs_[0]; }
667
  LOperand* right() { return inputs_[1]; }
668
  LOperand* temp() { return temps_[0]; }
669

    
670
  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
671
  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
672
};
673

    
674

    
675
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
676
 public:
677
  LMulI(LOperand* left, LOperand* right) {
678
    inputs_[0] = left;
679
    inputs_[1] = right;
680
  }
681

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

    
685
  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
686
  DECLARE_HYDROGEN_ACCESSOR(Mul)
687
};
688

    
689

    
690
// Instruction for computing multiplier * multiplicand + addend.
691
class LMultiplyAddD V8_FINAL : public LTemplateInstruction<1, 3, 0> {
692
 public:
693
  LMultiplyAddD(LOperand* addend, LOperand* multiplier,
694
                LOperand* multiplicand) {
695
    inputs_[0] = addend;
696
    inputs_[1] = multiplier;
697
    inputs_[2] = multiplicand;
698
  }
699

    
700
  LOperand* addend() { return inputs_[0]; }
701
  LOperand* multiplier() { return inputs_[1]; }
702
  LOperand* multiplicand() { return inputs_[2]; }
703

    
704
  DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
705
};
706

    
707

    
708
// Instruction for computing minuend - multiplier * multiplicand.
709
class LMultiplySubD V8_FINAL : public LTemplateInstruction<1, 3, 0> {
710
 public:
711
  LMultiplySubD(LOperand* minuend, LOperand* multiplier,
712
                LOperand* multiplicand) {
713
    inputs_[0] = minuend;
714
    inputs_[1] = multiplier;
715
    inputs_[2] = multiplicand;
716
  }
717

    
718
  LOperand* minuend() { return inputs_[0]; }
719
  LOperand* multiplier() { return inputs_[1]; }
720
  LOperand* multiplicand() { return inputs_[2]; }
721

    
722
  DECLARE_CONCRETE_INSTRUCTION(MultiplySubD, "multiply-sub-d")
723
};
724

    
725

    
726
class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> {
727
 public:
728
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
729
};
730

    
731

    
732
class LCompareNumericAndBranch V8_FINAL : public LControlInstruction<2, 0> {
733
 public:
734
  LCompareNumericAndBranch(LOperand* left, LOperand* right) {
735
    inputs_[0] = left;
736
    inputs_[1] = right;
737
  }
738

    
739
  LOperand* left() { return inputs_[0]; }
740
  LOperand* right() { return inputs_[1]; }
741

    
742
  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
743
                               "compare-numeric-and-branch")
744
  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
745

    
746
  Token::Value op() const { return hydrogen()->token(); }
747
  bool is_double() const {
748
    return hydrogen()->representation().IsDouble();
749
  }
750

    
751
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
752
};
753

    
754

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

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

    
763
  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
764
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
765
};
766

    
767

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

    
775
  LOperand* value() { return inputs_[0]; }
776
  LOperand* temp() { return temps_[0]; }
777

    
778
  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
779
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
780
};
781

    
782

    
783
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
784
 public:
785
  LMathAbs(LOperand* context, LOperand* value) {
786
    inputs_[1] = context;
787
    inputs_[0] = value;
788
  }
789

    
790
  LOperand* context() { return inputs_[1]; }
791
  LOperand* value() { return inputs_[0]; }
792

    
793
  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
794
  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
795
};
796

    
797

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

    
804
  LOperand* value() { return inputs_[0]; }
805

    
806
  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
807
};
808

    
809

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

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

    
818
  DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
819
};
820

    
821

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

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

    
830
  DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
831
};
832

    
833

    
834
class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
835
 public:
836
  explicit LMathTan(LOperand* value) {
837
    inputs_[0] = value;
838
  }
839

    
840
  LOperand* value() { return inputs_[0]; }
841

    
842
  DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
843
};
844

    
845

    
846
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 3> {
847
 public:
848
  LMathExp(LOperand* value,
849
           LOperand* double_temp,
850
           LOperand* temp1,
851
           LOperand* temp2) {
852
    inputs_[0] = value;
853
    temps_[0] = temp1;
854
    temps_[1] = temp2;
855
    temps_[2] = double_temp;
856
    ExternalReference::InitializeMathExpData();
857
  }
858

    
859
  LOperand* value() { return inputs_[0]; }
860
  LOperand* temp1() { return temps_[0]; }
861
  LOperand* temp2() { return temps_[1]; }
862
  LOperand* double_temp() { return temps_[2]; }
863

    
864
  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
865
};
866

    
867

    
868
class LMathSqrt V8_FINAL : public LTemplateInstruction<1, 1, 0> {
869
 public:
870
  explicit LMathSqrt(LOperand* value) {
871
    inputs_[0] = value;
872
  }
873

    
874
  LOperand* value() { return inputs_[0]; }
875

    
876
  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
877
};
878

    
879

    
880
class LMathPowHalf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
881
 public:
882
  LMathPowHalf(LOperand* value, LOperand* temp) {
883
    inputs_[0] = value;
884
    temps_[0] = temp;
885
  }
886

    
887
  LOperand* value() { return inputs_[0]; }
888
  LOperand* temp() { return temps_[0]; }
889

    
890
  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
891
};
892

    
893

    
894
class LCmpObjectEqAndBranch V8_FINAL : public LControlInstruction<2, 0> {
895
 public:
896
  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
897
    inputs_[0] = left;
898
    inputs_[1] = right;
899
  }
900

    
901
  LOperand* left() { return inputs_[0]; }
902
  LOperand* right() { return inputs_[1]; }
903

    
904
  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
905
  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
906
};
907

    
908

    
909
class LCmpHoleAndBranch V8_FINAL : public LControlInstruction<1, 0> {
910
 public:
911
  explicit LCmpHoleAndBranch(LOperand* object) {
912
    inputs_[0] = object;
913
  }
914

    
915
  LOperand* object() { return inputs_[0]; }
916

    
917
  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
918
  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
919
};
920

    
921

    
922
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
923
 public:
924
  LIsObjectAndBranch(LOperand* value, LOperand* temp) {
925
    inputs_[0] = value;
926
    temps_[0] = temp;
927
  }
928

    
929
  LOperand* value() { return inputs_[0]; }
930
  LOperand* temp() { return temps_[0]; }
931

    
932
  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
933
  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
934

    
935
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
936
};
937

    
938

    
939
class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
940
 public:
941
  LIsStringAndBranch(LOperand* value, LOperand* temp) {
942
    inputs_[0] = value;
943
    temps_[0] = temp;
944
  }
945

    
946
  LOperand* value() { return inputs_[0]; }
947
  LOperand* temp() { return temps_[0]; }
948

    
949
  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
950
  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
951

    
952
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
953
};
954

    
955

    
956
class LIsSmiAndBranch V8_FINAL : public LControlInstruction<1, 0> {
957
 public:
958
  explicit LIsSmiAndBranch(LOperand* value) {
959
    inputs_[0] = value;
960
  }
961

    
962
  LOperand* value() { return inputs_[0]; }
963

    
964
  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
965
  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
966

    
967
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
968
};
969

    
970

    
971
class LIsUndetectableAndBranch V8_FINAL : public LControlInstruction<1, 1> {
972
 public:
973
  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
974
    inputs_[0] = value;
975
    temps_[0] = temp;
976
  }
977

    
978
  LOperand* value() { return inputs_[0]; }
979
  LOperand* temp() { return temps_[0]; }
980

    
981
  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
982
                               "is-undetectable-and-branch")
983
  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
984

    
985
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
986
};
987

    
988

    
989
class LStringCompareAndBranch V8_FINAL : public LControlInstruction<3, 0> {
990
 public:
991
  LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
992
    inputs_[0] = context;
993
    inputs_[1] = left;
994
    inputs_[2] = right;
995
  }
996

    
997
  LOperand* context() { return inputs_[0]; }
998
  LOperand* left() { return inputs_[1]; }
999
  LOperand* right() { return inputs_[2]; }
1000

    
1001
  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
1002
                               "string-compare-and-branch")
1003
  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
1004

    
1005
  Token::Value op() const { return hydrogen()->token(); }
1006

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

    
1010

    
1011
class LHasInstanceTypeAndBranch V8_FINAL : public LControlInstruction<1, 0> {
1012
 public:
1013
  explicit LHasInstanceTypeAndBranch(LOperand* value) {
1014
    inputs_[0] = value;
1015
  }
1016

    
1017
  LOperand* value() { return inputs_[0]; }
1018

    
1019
  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1020
                               "has-instance-type-and-branch")
1021
  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1022

    
1023
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1024
};
1025

    
1026

    
1027
class LGetCachedArrayIndex V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1028
 public:
1029
  explicit LGetCachedArrayIndex(LOperand* value) {
1030
    inputs_[0] = value;
1031
  }
1032

    
1033
  LOperand* value() { return inputs_[0]; }
1034

    
1035
  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1036
  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1037
};
1038

    
1039

    
1040
class LHasCachedArrayIndexAndBranch V8_FINAL
1041
    : public LControlInstruction<1, 0> {
1042
 public:
1043
  explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
1044
    inputs_[0] = value;
1045
  }
1046

    
1047
  LOperand* value() { return inputs_[0]; }
1048

    
1049
  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1050
                               "has-cached-array-index-and-branch")
1051
  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
1052

    
1053
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1054
};
1055

    
1056

    
1057
class LClassOfTestAndBranch V8_FINAL : public LControlInstruction<1, 1> {
1058
 public:
1059
  LClassOfTestAndBranch(LOperand* value, LOperand* temp) {
1060
    inputs_[0] = value;
1061
    temps_[0] = temp;
1062
  }
1063

    
1064
  LOperand* value() { return inputs_[0]; }
1065
  LOperand* temp() { return temps_[0]; }
1066

    
1067
  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1068
                               "class-of-test-and-branch")
1069
  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1070

    
1071
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1072
};
1073

    
1074

    
1075
class LCmpT V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1076
 public:
1077
  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1078
    inputs_[0] = context;
1079
    inputs_[1] = left;
1080
    inputs_[2] = right;
1081
  }
1082

    
1083
  LOperand* context() { return inputs_[0]; }
1084
  LOperand* left() { return inputs_[1]; }
1085
  LOperand* right() { return inputs_[2]; }
1086

    
1087
  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1088
  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1089

    
1090
  Token::Value op() const { return hydrogen()->token(); }
1091
};
1092

    
1093

    
1094
class LInstanceOf V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1095
 public:
1096
  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1097
    inputs_[0] = context;
1098
    inputs_[1] = left;
1099
    inputs_[2] = right;
1100
  }
1101

    
1102
  LOperand* context() { return inputs_[0]; }
1103
  LOperand* left() { return inputs_[1]; }
1104
  LOperand* right() { return inputs_[2]; }
1105

    
1106
  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1107
};
1108

    
1109

    
1110
class LInstanceOfKnownGlobal V8_FINAL : public LTemplateInstruction<1, 2, 1> {
1111
 public:
1112
  LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
1113
    inputs_[0] = context;
1114
    inputs_[1] = value;
1115
    temps_[0] = temp;
1116
  }
1117

    
1118
  LOperand* context() { return inputs_[0]; }
1119
  LOperand* value() { return inputs_[1]; }
1120
  LOperand* temp() { return temps_[0]; }
1121

    
1122
  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1123
                               "instance-of-known-global")
1124
  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1125

    
1126
  Handle<JSFunction> function() const { return hydrogen()->function(); }
1127
  LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
1128
    return lazy_deopt_env_;
1129
  }
1130
  virtual void SetDeferredLazyDeoptimizationEnvironment(
1131
      LEnvironment* env) V8_OVERRIDE {
1132
    lazy_deopt_env_ = env;
1133
  }
1134

    
1135
 private:
1136
  LEnvironment* lazy_deopt_env_;
1137
};
1138

    
1139

    
1140
class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1141
 public:
1142
  LBoundsCheck(LOperand* index, LOperand* length) {
1143
    inputs_[0] = index;
1144
    inputs_[1] = length;
1145
  }
1146

    
1147
  LOperand* index() { return inputs_[0]; }
1148
  LOperand* length() { return inputs_[1]; }
1149

    
1150
  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1151
  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1152
};
1153

    
1154

    
1155
class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1156
 public:
1157
  LBitI(LOperand* left, LOperand* right) {
1158
    inputs_[0] = left;
1159
    inputs_[1] = right;
1160
  }
1161

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

    
1165
  Token::Value op() const { return hydrogen()->op(); }
1166

    
1167
  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1168
  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1169
};
1170

    
1171

    
1172
class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1173
 public:
1174
  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1175
      : op_(op), can_deopt_(can_deopt) {
1176
    inputs_[0] = left;
1177
    inputs_[1] = right;
1178
  }
1179

    
1180
  Token::Value op() const { return op_; }
1181
  LOperand* left() { return inputs_[0]; }
1182
  LOperand* right() { return inputs_[1]; }
1183
  bool can_deopt() const { return can_deopt_; }
1184

    
1185
  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1186

    
1187
 private:
1188
  Token::Value op_;
1189
  bool can_deopt_;
1190
};
1191

    
1192

    
1193
class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1194
 public:
1195
  LSubI(LOperand* left, LOperand* right) {
1196
    inputs_[0] = left;
1197
    inputs_[1] = right;
1198
  }
1199

    
1200
  LOperand* left() { return inputs_[0]; }
1201
  LOperand* right() { return inputs_[1]; }
1202

    
1203
  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1204
  DECLARE_HYDROGEN_ACCESSOR(Sub)
1205
};
1206

    
1207

    
1208
class LRSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1209
 public:
1210
  LRSubI(LOperand* left, LOperand* right) {
1211
    inputs_[0] = left;
1212
    inputs_[1] = right;
1213
  }
1214

    
1215
  LOperand* left() { return inputs_[0]; }
1216
  LOperand* right() { return inputs_[1]; }
1217

    
1218
  DECLARE_CONCRETE_INSTRUCTION(RSubI, "rsub-i")
1219
  DECLARE_HYDROGEN_ACCESSOR(Sub)
1220
};
1221

    
1222

    
1223
class LConstantI V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1224
 public:
1225
  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1226
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1227

    
1228
  int32_t value() const { return hydrogen()->Integer32Value(); }
1229
};
1230

    
1231

    
1232
class LConstantS V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1233
 public:
1234
  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1235
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1236

    
1237
  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1238
};
1239

    
1240

    
1241
class LConstantD V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1242
 public:
1243
  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1244
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1245

    
1246
  double value() const { return hydrogen()->DoubleValue(); }
1247
};
1248

    
1249

    
1250
class LConstantE V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1251
 public:
1252
  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1253
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1254

    
1255
  ExternalReference value() const {
1256
    return hydrogen()->ExternalReferenceValue();
1257
  }
1258
};
1259

    
1260

    
1261
class LConstantT V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1262
 public:
1263
  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1264
  DECLARE_HYDROGEN_ACCESSOR(Constant)
1265

    
1266
  Handle<Object> value(Isolate* isolate) const {
1267
    return hydrogen()->handle(isolate);
1268
  }
1269
};
1270

    
1271

    
1272
class LBranch V8_FINAL : public LControlInstruction<1, 0> {
1273
 public:
1274
  explicit LBranch(LOperand* value) {
1275
    inputs_[0] = value;
1276
  }
1277

    
1278
  LOperand* value() { return inputs_[0]; }
1279

    
1280
  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1281
  DECLARE_HYDROGEN_ACCESSOR(Branch)
1282

    
1283
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1284
};
1285

    
1286

    
1287
class LCmpMapAndBranch V8_FINAL : public LControlInstruction<1, 1> {
1288
 public:
1289
  LCmpMapAndBranch(LOperand* value, LOperand* temp) {
1290
    inputs_[0] = value;
1291
    temps_[0] = temp;
1292
  }
1293

    
1294
  LOperand* value() { return inputs_[0]; }
1295
  LOperand* temp() { return temps_[0]; }
1296

    
1297
  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1298
  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1299

    
1300
  Handle<Map> map() const { return hydrogen()->map().handle(); }
1301
};
1302

    
1303

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

    
1310
  LOperand* value() { return inputs_[0]; }
1311

    
1312
  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1313
};
1314

    
1315

    
1316
class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1317
 public:
1318
  explicit LElementsKind(LOperand* value) {
1319
    inputs_[0] = value;
1320
  }
1321

    
1322
  LOperand* value() { return inputs_[0]; }
1323

    
1324
  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
1325
  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
1326
};
1327

    
1328

    
1329
class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1330
 public:
1331
  LValueOf(LOperand* value, LOperand* temp) {
1332
    inputs_[0] = value;
1333
    temps_[0] = temp;
1334
  }
1335

    
1336
  LOperand* value() { return inputs_[0]; }
1337
  LOperand* temp() { return temps_[0]; }
1338

    
1339
  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1340
  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1341
};
1342

    
1343

    
1344
class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 1> {
1345
 public:
1346
  LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
1347
    inputs_[0] = date;
1348
    temps_[0] = temp;
1349
  }
1350

    
1351
  LOperand* date() { return inputs_[0]; }
1352
  LOperand* temp() { return temps_[0]; }
1353
  Smi* index() const { return index_; }
1354

    
1355
  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1356
  DECLARE_HYDROGEN_ACCESSOR(DateField)
1357

    
1358
 private:
1359
  Smi* index_;
1360
};
1361

    
1362

    
1363
class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1364
 public:
1365
  LSeqStringSetChar(String::Encoding encoding,
1366
                    LOperand* string,
1367
                    LOperand* index,
1368
                    LOperand* value) : encoding_(encoding) {
1369
    inputs_[0] = string;
1370
    inputs_[1] = index;
1371
    inputs_[2] = value;
1372
  }
1373

    
1374
  String::Encoding encoding() { return encoding_; }
1375
  LOperand* string() { return inputs_[0]; }
1376
  LOperand* index() { return inputs_[1]; }
1377
  LOperand* value() { return inputs_[2]; }
1378

    
1379
  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1380
  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1381

    
1382
 private:
1383
  String::Encoding encoding_;
1384
};
1385

    
1386

    
1387
class LThrow V8_FINAL : public LTemplateInstruction<0, 2, 0> {
1388
 public:
1389
  LThrow(LOperand* context, LOperand* value) {
1390
    inputs_[0] = context;
1391
    inputs_[1] = value;
1392
  }
1393

    
1394
  LOperand* context() { return inputs_[0]; }
1395
  LOperand* value() { return inputs_[1]; }
1396

    
1397
  DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1398
};
1399

    
1400

    
1401
class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1402
 public:
1403
  LAddI(LOperand* left, LOperand* right) {
1404
    inputs_[0] = left;
1405
    inputs_[1] = right;
1406
  }
1407

    
1408
  LOperand* left() { return inputs_[0]; }
1409
  LOperand* right() { return inputs_[1]; }
1410

    
1411
  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1412
  DECLARE_HYDROGEN_ACCESSOR(Add)
1413
};
1414

    
1415

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

    
1423
  LOperand* left() { return inputs_[0]; }
1424
  LOperand* right() { return inputs_[1]; }
1425

    
1426
  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1427
  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1428
};
1429

    
1430

    
1431
class LPower V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1432
 public:
1433
  LPower(LOperand* left, LOperand* right) {
1434
    inputs_[0] = left;
1435
    inputs_[1] = right;
1436
  }
1437

    
1438
  LOperand* left() { return inputs_[0]; }
1439
  LOperand* right() { return inputs_[1]; }
1440

    
1441
  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1442
  DECLARE_HYDROGEN_ACCESSOR(Power)
1443
};
1444

    
1445

    
1446
class LRandom V8_FINAL : public LTemplateInstruction<1, 1, 3> {
1447
 public:
1448
  LRandom(LOperand* global_object,
1449
          LOperand* scratch,
1450
          LOperand* scratch2,
1451
          LOperand* scratch3) {
1452
    inputs_[0] = global_object;
1453
    temps_[0] = scratch;
1454
    temps_[1] = scratch2;
1455
    temps_[2] = scratch3;
1456
  }
1457

    
1458
  LOperand* global_object() const { return inputs_[0]; }
1459
  LOperand* scratch() const { return temps_[0]; }
1460
  LOperand* scratch2() const { return temps_[1]; }
1461
  LOperand* scratch3() const { return temps_[2]; }
1462

    
1463
  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
1464
  DECLARE_HYDROGEN_ACCESSOR(Random)
1465
};
1466

    
1467

    
1468
class LArithmeticD V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1469
 public:
1470
  LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1471
      : op_(op) {
1472
    inputs_[0] = left;
1473
    inputs_[1] = right;
1474
  }
1475

    
1476
  Token::Value op() const { return op_; }
1477
  LOperand* left() { return inputs_[0]; }
1478
  LOperand* right() { return inputs_[1]; }
1479

    
1480
  virtual Opcode opcode() const V8_OVERRIDE {
1481
    return LInstruction::kArithmeticD;
1482
  }
1483
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1484
  virtual const char* Mnemonic() const V8_OVERRIDE;
1485

    
1486
 private:
1487
  Token::Value op_;
1488
};
1489

    
1490

    
1491
class LArithmeticT V8_FINAL : public LTemplateInstruction<1, 3, 0> {
1492
 public:
1493
  LArithmeticT(Token::Value op,
1494
               LOperand* context,
1495
               LOperand* left,
1496
               LOperand* right)
1497
      : op_(op) {
1498
    inputs_[0] = context;
1499
    inputs_[1] = left;
1500
    inputs_[2] = right;
1501
  }
1502

    
1503
  LOperand* context() { return inputs_[0]; }
1504
  LOperand* left() { return inputs_[1]; }
1505
  LOperand* right() { return inputs_[2]; }
1506
  Token::Value op() const { return op_; }
1507

    
1508
  virtual Opcode opcode() const V8_OVERRIDE {
1509
    return LInstruction::kArithmeticT;
1510
  }
1511
  virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
1512
  virtual const char* Mnemonic() const V8_OVERRIDE;
1513

    
1514
 private:
1515
  Token::Value op_;
1516
};
1517

    
1518

    
1519
class LReturn V8_FINAL : public LTemplateInstruction<0, 3, 0> {
1520
 public:
1521
  LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) {
1522
    inputs_[0] = value;
1523
    inputs_[1] = context;
1524
    inputs_[2] = parameter_count;
1525
  }
1526

    
1527
  LOperand* value() { return inputs_[0]; }
1528

    
1529
  bool has_constant_parameter_count() {
1530
    return parameter_count()->IsConstantOperand();
1531
  }
1532
  LConstantOperand* constant_parameter_count() {
1533
    ASSERT(has_constant_parameter_count());
1534
    return LConstantOperand::cast(parameter_count());
1535
  }
1536
  LOperand* parameter_count() { return inputs_[2]; }
1537

    
1538
  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1539
};
1540

    
1541

    
1542
class LLoadNamedField V8_FINAL : public LTemplateInstruction<1, 1, 0> {
1543
 public:
1544
  explicit LLoadNamedField(LOperand* object) {
1545
    inputs_[0] = object;
1546
  }
1547

    
1548
  LOperand* object() { return inputs_[0]; }
1549

    
1550
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1551
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1552
};
1553

    
1554

    
1555
class LLoadNamedGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1556
 public:
1557
  LLoadNamedGeneric(LOperand* context, LOperand* object) {
1558
    inputs_[0] = context;
1559
    inputs_[1] = object;
1560
  }
1561

    
1562
  LOperand* context() { return inputs_[0]; }
1563
  LOperand* object() { return inputs_[1]; }
1564

    
1565
  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1566
  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1567

    
1568
  Handle<Object> name() const { return hydrogen()->name(); }
1569
};
1570

    
1571

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

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

    
1580
  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1581
  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1582
};
1583

    
1584

    
1585
class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
1586
 public:
1587
  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1588
  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1589

    
1590
  Heap::RootListIndex index() const { return hydrogen()->index(); }
1591
};
1592

    
1593

    
1594
class LLoadExternalArrayPointer V8_FINAL
1595
    : public LTemplateInstruction<1, 1, 0> {
1596
 public:
1597
  explicit LLoadExternalArrayPointer(LOperand* object) {
1598
    inputs_[0] = object;
1599
  }
1600

    
1601
  LOperand* object() { return inputs_[0]; }
1602

    
1603
  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1604
                               "load-external-array-pointer")
1605
};
1606

    
1607

    
1608
class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
1609
 public:
1610
  LLoadKeyed(LOperand* elements, LOperand* key) {
1611
    inputs_[0] = elements;
1612
    inputs_[1] = key;
1613
  }
1614

    
1615
  LOperand* elements() { return inputs_[0]; }
1616
  LOperand* key() { return inputs_[1]; }
1617
  ElementsKind elements_kind() const {
1618
    return hydrogen()->elements_kind();
1619
  }
1620
  bool is_external() const {
1621
    return hydrogen()->is_external();
1622
  }
1623

    
1624
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1625
  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1626

    
1627
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1628
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1629
};
1630

    
1631

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

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

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

    
1647

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

    
1654

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

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

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

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

    
1672

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

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

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

    
1687

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

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

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

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

    
1709

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

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

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

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

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

    
1726

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

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

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

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

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

    
1745

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

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

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

    
1757

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

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

    
1764
  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1765

    
1766
 private:
1767
  int count_;
1768
};
1769

    
1770

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

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

    
1781
  virtual void PrintDataTo(StringStream* stream);
1782

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

    
1787

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

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

    
1797
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1798

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

    
1803

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

    
1810

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

    
1817

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

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

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

    
1829

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

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

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

    
1842

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

    
1849
  DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1850

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

    
1854

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

    
1861
  LOperand* global_object() { return inputs_[0]; }
1862

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

    
1866

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

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

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

    
1878

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

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

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

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

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

    
1897

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

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

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

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

    
1913
  int arity() const { return hydrogen()->argument_count() - 1; }
1914
};
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
  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, 0> {
2067
 public:
2068
  explicit LUint32ToDouble(LOperand* value) {
2069
    inputs_[0] = value;
2070
  }
2071

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

    
2074
  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
2075
};
2076

    
2077

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

    
2084
  LOperand* value() { return inputs_[0]; }
2085

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

    
2090

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

    
2097
  LOperand* value() { return inputs_[0]; }
2098

    
2099
  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
2100
};
2101

    
2102

    
2103
class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2104
 public:
2105
  explicit LNumberTagU(LOperand* value) {
2106
    inputs_[0] = value;
2107
  }
2108

    
2109
  LOperand* value() { return inputs_[0]; }
2110

    
2111
  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
2112
};
2113

    
2114

    
2115
class LNumberTagD V8_FINAL : public LTemplateInstruction<1, 1, 2> {
2116
 public:
2117
  LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
2118
    inputs_[0] = value;
2119
    temps_[0] = temp;
2120
    temps_[1] = temp2;
2121
  }
2122

    
2123
  LOperand* value() { return inputs_[0]; }
2124
  LOperand* temp() { return temps_[0]; }
2125
  LOperand* temp2() { return temps_[1]; }
2126

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

    
2131

    
2132
class LDoubleToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2133
 public:
2134
  explicit LDoubleToSmi(LOperand* value) {
2135
    inputs_[0] = value;
2136
  }
2137

    
2138
  LOperand* value() { return inputs_[0]; }
2139

    
2140
  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2141
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2142

    
2143
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2144
};
2145

    
2146

    
2147
// Sometimes truncating conversion from a tagged value to an int32.
2148
class LDoubleToI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2149
 public:
2150
  explicit LDoubleToI(LOperand* value) {
2151
    inputs_[0] = value;
2152
  }
2153

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

    
2156
  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2157
  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2158

    
2159
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2160
};
2161

    
2162

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

    
2174
  LOperand* value() { return inputs_[0]; }
2175
  LOperand* temp() { return temps_[0]; }
2176
  LOperand* temp2() { return temps_[1]; }
2177

    
2178
  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2179
  DECLARE_HYDROGEN_ACCESSOR(Change)
2180

    
2181
  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2182
};
2183

    
2184

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

    
2191
  LOperand* value() { return inputs_[0]; }
2192

    
2193
  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2194
};
2195

    
2196

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

    
2203
  LOperand* value() { return inputs_[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
  bool needs_check() const { return needs_check_; }
2219

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

    
2222
 private:
2223
  bool needs_check_;
2224
};
2225

    
2226

    
2227
class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
2228
 public:
2229
  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
2230
    inputs_[0] = object;
2231
    inputs_[1] = value;
2232
    temps_[0] = temp;
2233
  }
2234

    
2235
  LOperand* object() { return inputs_[0]; }
2236
  LOperand* value() { return inputs_[1]; }
2237
  LOperand* temp() { return temps_[0]; }
2238

    
2239
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2240
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2241

    
2242
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2243

    
2244
  Handle<Map> transition() const { return hydrogen()->transition_map(); }
2245
  Representation representation() const {
2246
    return hydrogen()->field_representation();
2247
  }
2248
};
2249

    
2250

    
2251
class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2252
 public:
2253
  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2254
    inputs_[0] = context;
2255
    inputs_[1] = object;
2256
    inputs_[2] = value;
2257
  }
2258

    
2259
  LOperand* context() { return inputs_[0]; }
2260
  LOperand* object() { return inputs_[1]; }
2261
  LOperand* value() { return inputs_[2]; }
2262

    
2263
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2264
  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2265

    
2266
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2267

    
2268
  Handle<Object> name() const { return hydrogen()->name(); }
2269
  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
2270
};
2271

    
2272

    
2273
class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
2274
 public:
2275
  LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
2276
    inputs_[0] = object;
2277
    inputs_[1] = key;
2278
    inputs_[2] = value;
2279
  }
2280

    
2281
  bool is_external() const { return hydrogen()->is_external(); }
2282
  LOperand* elements() { return inputs_[0]; }
2283
  LOperand* key() { return inputs_[1]; }
2284
  LOperand* value() { return inputs_[2]; }
2285
  ElementsKind elements_kind() const {
2286
    return hydrogen()->elements_kind();
2287
  }
2288

    
2289
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2290
  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2291

    
2292
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2293
  bool NeedsCanonicalization() {
2294
    if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
2295
        hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
2296
      return false;
2297
    }
2298
    return hydrogen()->NeedsCanonicalization();
2299
  }
2300
  uint32_t additional_index() const { return hydrogen()->index_offset(); }
2301
};
2302

    
2303

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

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

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

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

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

    
2329

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

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

    
2344
  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2345
                               "transition-elements-kind")
2346
  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2347

    
2348
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2349

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

    
2358

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

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

    
2370
  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2371
                               "trap-allocation-memento")
2372
};
2373

    
2374

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

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

    
2387
  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2388
  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2389
};
2390

    
2391

    
2392

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

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

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

    
2409

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

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

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

    
2424

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

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

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

    
2437

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

    
2444
  LOperand* value() { return inputs_[0]; }
2445

    
2446
  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2447
  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2448
};
2449

    
2450

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

    
2457
  LOperand* value() { return inputs_[0]; }
2458

    
2459
  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2460
  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2461
};
2462

    
2463

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

    
2470
  LOperand* value() { return inputs_[0]; }
2471

    
2472
  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2473
};
2474

    
2475

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

    
2482
  LOperand* value() { return inputs_[0]; }
2483

    
2484
  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2485
  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2486
};
2487

    
2488

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

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

    
2497
  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2498
};
2499

    
2500

    
2501
class LClampIToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2502
 public:
2503
  explicit LClampIToUint8(LOperand* unclamped) {
2504
    inputs_[0] = unclamped;
2505
  }
2506

    
2507
  LOperand* unclamped() { return inputs_[0]; }
2508

    
2509
  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2510
};
2511

    
2512

    
2513
class LClampTToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> {
2514
 public:
2515
  LClampTToUint8(LOperand* unclamped, LOperand* temp) {
2516
    inputs_[0] = unclamped;
2517
    temps_[0] = temp;
2518
  }
2519

    
2520
  LOperand* unclamped() { return inputs_[0]; }
2521
  LOperand* temp() { return temps_[0]; }
2522

    
2523
  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2524
};
2525

    
2526

    
2527
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 2> {
2528
 public:
2529
  LAllocate(LOperand* context,
2530
            LOperand* size,
2531
            LOperand* temp1,
2532
            LOperand* temp2) {
2533
    inputs_[0] = context;
2534
    inputs_[1] = size;
2535
    temps_[0] = temp1;
2536
    temps_[1] = temp2;
2537
  }
2538

    
2539
  LOperand* context() { return inputs_[0]; }
2540
  LOperand* size() { return inputs_[1]; }
2541
  LOperand* temp1() { return temps_[0]; }
2542
  LOperand* temp2() { return temps_[1]; }
2543

    
2544
  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2545
  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2546
};
2547

    
2548

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

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

    
2557
  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2558
  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2559
};
2560

    
2561

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

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

    
2570
  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2571
  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2572
};
2573

    
2574

    
2575
class LToFastProperties V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2576
 public:
2577
  explicit LToFastProperties(LOperand* value) {
2578
    inputs_[0] = value;
2579
  }
2580

    
2581
  LOperand* value() { return inputs_[0]; }
2582

    
2583
  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2584
  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2585
};
2586

    
2587

    
2588
class LTypeof V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2589
 public:
2590
  LTypeof(LOperand* context, LOperand* value) {
2591
    inputs_[0] = context;
2592
    inputs_[1] = value;
2593
  }
2594

    
2595
  LOperand* context() { return inputs_[0]; }
2596
  LOperand* value() { return inputs_[1]; }
2597

    
2598
  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2599
};
2600

    
2601

    
2602
class LTypeofIsAndBranch V8_FINAL : public LControlInstruction<1, 0> {
2603
 public:
2604
  explicit LTypeofIsAndBranch(LOperand* value) {
2605
    inputs_[0] = value;
2606
  }
2607

    
2608
  LOperand* value() { return inputs_[0]; }
2609

    
2610
  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2611
  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2612

    
2613
  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2614

    
2615
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2616
};
2617

    
2618

    
2619
class LIsConstructCallAndBranch V8_FINAL : public LControlInstruction<0, 1> {
2620
 public:
2621
  explicit LIsConstructCallAndBranch(LOperand* temp) {
2622
    temps_[0] = temp;
2623
  }
2624

    
2625
  LOperand* temp() { return temps_[0]; }
2626

    
2627
  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2628
                               "is-construct-call-and-branch")
2629
};
2630

    
2631

    
2632
class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
2633
 public:
2634
  LOsrEntry() {}
2635

    
2636
  virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
2637
    return false;
2638
  }
2639
  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2640
};
2641

    
2642

    
2643
class LStackCheck V8_FINAL : public LTemplateInstruction<0, 1, 0> {
2644
 public:
2645
  explicit LStackCheck(LOperand* context) {
2646
    inputs_[0] = context;
2647
  }
2648

    
2649
  LOperand* context() { return inputs_[0]; }
2650

    
2651
  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2652
  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2653

    
2654
  Label* done_label() { return &done_label_; }
2655

    
2656
 private:
2657
  Label done_label_;
2658
};
2659

    
2660

    
2661
class LForInPrepareMap V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2662
 public:
2663
  LForInPrepareMap(LOperand* context, LOperand* object) {
2664
    inputs_[0] = context;
2665
    inputs_[1] = object;
2666
  }
2667

    
2668
  LOperand* context() { return inputs_[0]; }
2669
  LOperand* object() { return inputs_[1]; }
2670

    
2671
  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2672
};
2673

    
2674

    
2675
class LForInCacheArray V8_FINAL : public LTemplateInstruction<1, 1, 0> {
2676
 public:
2677
  explicit LForInCacheArray(LOperand* map) {
2678
    inputs_[0] = map;
2679
  }
2680

    
2681
  LOperand* map() { return inputs_[0]; }
2682

    
2683
  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2684

    
2685
  int idx() {
2686
    return HForInCacheArray::cast(this->hydrogen_value())->idx();
2687
  }
2688
};
2689

    
2690

    
2691
class LCheckMapValue V8_FINAL : public LTemplateInstruction<0, 2, 0> {
2692
 public:
2693
  LCheckMapValue(LOperand* value, LOperand* map) {
2694
    inputs_[0] = value;
2695
    inputs_[1] = map;
2696
  }
2697

    
2698
  LOperand* value() { return inputs_[0]; }
2699
  LOperand* map() { return inputs_[1]; }
2700

    
2701
  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2702
};
2703

    
2704

    
2705
class LLoadFieldByIndex V8_FINAL : public LTemplateInstruction<1, 2, 0> {
2706
 public:
2707
  LLoadFieldByIndex(LOperand* object, LOperand* index) {
2708
    inputs_[0] = object;
2709
    inputs_[1] = index;
2710
  }
2711

    
2712
  LOperand* object() { return inputs_[0]; }
2713
  LOperand* index() { return inputs_[1]; }
2714

    
2715
  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2716
};
2717

    
2718

    
2719
class LChunkBuilder;
2720
class LPlatformChunk V8_FINAL : public LChunk {
2721
 public:
2722
  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2723
      : LChunk(info, graph) { }
2724

    
2725
  int GetNextSpillIndex(RegisterKind kind);
2726
  LOperand* GetNextSpillSlot(RegisterKind kind);
2727
};
2728

    
2729

    
2730
class LChunkBuilder V8_FINAL BASE_EMBEDDED {
2731
 public:
2732
  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2733
      : chunk_(NULL),
2734
        info_(info),
2735
        graph_(graph),
2736
        zone_(graph->zone()),
2737
        status_(UNUSED),
2738
        current_instruction_(NULL),
2739
        current_block_(NULL),
2740
        next_block_(NULL),
2741
        argument_count_(0),
2742
        allocator_(allocator),
2743
        position_(RelocInfo::kNoPosition),
2744
        instruction_pending_deoptimization_environment_(NULL),
2745
        pending_deoptimization_ast_id_(BailoutId::None()) { }
2746

    
2747
  // Build the sequence for the graph.
2748
  LPlatformChunk* Build();
2749

    
2750
  LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
2751

    
2752
  // Declare methods that deal with the individual node types.
2753
#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2754
  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2755
#undef DECLARE_DO
2756

    
2757
  LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
2758
  LInstruction* DoMultiplySub(HValue* minuend, HMul* mul);
2759
  LInstruction* DoRSub(HSub* instr);
2760

    
2761
  static bool HasMagicNumberForDivisor(int32_t divisor);
2762
  static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2763

    
2764
  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2765
  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2766
  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2767
  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2768
  LInstruction* DoMathSin(HUnaryMathOperation* instr);
2769
  LInstruction* DoMathCos(HUnaryMathOperation* instr);
2770
  LInstruction* DoMathTan(HUnaryMathOperation* instr);
2771
  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2772
  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2773
  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2774

    
2775
 private:
2776
  enum Status {
2777
    UNUSED,
2778
    BUILDING,
2779
    DONE,
2780
    ABORTED
2781
  };
2782

    
2783
  LPlatformChunk* chunk() const { return chunk_; }
2784
  CompilationInfo* info() const { return info_; }
2785
  HGraph* graph() const { return graph_; }
2786
  Zone* zone() const { return zone_; }
2787

    
2788
  bool is_unused() const { return status_ == UNUSED; }
2789
  bool is_building() const { return status_ == BUILDING; }
2790
  bool is_done() const { return status_ == DONE; }
2791
  bool is_aborted() const { return status_ == ABORTED; }
2792

    
2793
  void Abort(BailoutReason reason);
2794

    
2795
  // Methods for getting operands for Use / Define / Temp.
2796
  LUnallocated* ToUnallocated(Register reg);
2797
  LUnallocated* ToUnallocated(DoubleRegister reg);
2798

    
2799
  // Methods for setting up define-use relationships.
2800
  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2801
  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2802
  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2803
                                           DoubleRegister fixed_register);
2804

    
2805
  // A value that is guaranteed to be allocated to a register.
2806
  // Operand created by UseRegister is guaranteed to be live until the end of
2807
  // instruction. This means that register allocator will not reuse it's
2808
  // register for any other operand inside instruction.
2809
  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2810
  // instruction start. Register allocator is free to assign the same register
2811
  // to some other operand used inside instruction (i.e. temporary or
2812
  // output).
2813
  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2814
  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2815

    
2816
  // An input operand in a register that may be trashed.
2817
  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2818

    
2819
  // An input operand in a register or stack slot.
2820
  MUST_USE_RESULT LOperand* Use(HValue* value);
2821
  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2822

    
2823
  // An input operand in a register, stack slot or a constant operand.
2824
  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2825
  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2826

    
2827
  // An input operand in a register or a constant operand.
2828
  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2829
  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2830

    
2831
  // An input operand in a constant operand.
2832
  MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2833

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

    
2838
  // Temporary operand that must be in a register.
2839
  MUST_USE_RESULT LUnallocated* TempRegister();
2840
  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2841
  MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
2842

    
2843
  // Methods for setting up define-use relationships.
2844
  // Return the same instruction that they are passed.
2845
  template<int I, int T>
2846
      LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2847
                           LUnallocated* result);
2848
  template<int I, int T>
2849
      LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2850
  template<int I, int T>
2851
      LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2852
                                    int index);
2853
  template<int I, int T>
2854
      LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2855
  template<int I, int T>
2856
      LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2857
                                Register reg);
2858
  template<int I, int T>
2859
      LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2860
                                      DoubleRegister reg);
2861
  LInstruction* AssignEnvironment(LInstruction* instr);
2862
  LInstruction* AssignPointerMap(LInstruction* instr);
2863

    
2864
  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2865

    
2866
  // By default we assume that instruction sequences generated for calls
2867
  // cannot deoptimize eagerly and we do not attach environment to this
2868
  // instruction.
2869
  LInstruction* MarkAsCall(
2870
      LInstruction* instr,
2871
      HInstruction* hinstr,
2872
      CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2873

    
2874
  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2875
                                  int* argument_index_accumulator,
2876
                                  ZoneList<HValue*>* objects_to_materialize);
2877

    
2878
  void VisitInstruction(HInstruction* current);
2879

    
2880
  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2881
  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2882
  LInstruction* DoArithmeticD(Token::Value op,
2883
                              HArithmeticBinaryOperation* instr);
2884
  LInstruction* DoArithmeticT(Token::Value op,
2885
                              HBinaryOperation* instr);
2886

    
2887
  LPlatformChunk* chunk_;
2888
  CompilationInfo* info_;
2889
  HGraph* const graph_;
2890
  Zone* zone_;
2891
  Status status_;
2892
  HInstruction* current_instruction_;
2893
  HBasicBlock* current_block_;
2894
  HBasicBlock* next_block_;
2895
  int argument_count_;
2896
  LAllocator* allocator_;
2897
  int position_;
2898
  LInstruction* instruction_pending_deoptimization_environment_;
2899
  BailoutId pending_deoptimization_ast_id_;
2900

    
2901
  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2902
};
2903

    
2904
#undef DECLARE_HYDROGEN_ACCESSOR
2905
#undef DECLARE_CONCRETE_INSTRUCTION
2906

    
2907
} }  // namespace v8::internal
2908

    
2909
#endif  // V8_ARM_LITHIUM_ARM_H_