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