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