Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: src/a64/lithium-a64.h

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

Powered by Google App Engine
This is Rietveld 408576698