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