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