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